From 9ff8c0686c21afc442574230ecebe1a2111d3b60 Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Thu, 14 Mar 2024 06:14:09 +0000 Subject: [PATCH] deploy: 1bb0e9d7e0f107d17d527d58e12de43990ef9638 --- ...encia-street-san-francisco.md.donotpublish | 1 + 404.html | 4 +- ...8d96f.40246681.js => 0608d96f.0ca046ee.js} | 2 +- assets/js/0afd36a3.15c8c7e0.js | 1 - ...139d8.d9fa967b.js => 0afd36a3.3d84968d.js} | 2 +- ...8d4d7.af4398b1.js => 132139d8.ad178cc6.js} | 2 +- assets/js/3b085c01.15d96e0f.js | 1 + assets/js/3b085c01.c94bcd2f.js | 1 - ...5b4f0.35d96d3e.js => 3d85b4f0.8b2d142f.js} | 2 +- assets/js/3e0df243.b4ef2ed4.js | 1 + assets/js/4200b1a9.30cafe92.js | 1 - assets/js/4200b1a9.5b66eaa4.js | 1 + ...1b14e.bd3fa7b1.js => 4271b14e.a48241f1.js} | 2 +- ...dd983.cd77351a.js => 486dd983.349dea54.js} | 2 +- ...a4964.52408134.js => 5c6a4964.ac0cb292.js} | 2 +- ...c228a.72397e3f.js => 625c228a.587857c6.js} | 2 +- ...5ef6c.2026e58c.js => 66d5ef6c.6f1303fa.js} | 2 +- assets/js/6d8ec5d0.54a6a317.js | 1 - ...629c2.0c878aab.js => 7bf629c2.c57c4bac.js} | 2 +- ...df243.1f7b2113.js => 7d48d4d7.7f8c6a7b.js} | 2 +- ...e47c4.e41b30c4.js => 83ee47c4.f7e0eecf.js} | 2 +- ...e532b.4565fc63.js => 8c0e532b.68f4d1b8.js} | 2 +- assets/js/95b96bb9.910a965e.js | 1 - assets/js/95b96bb9.df041972.js | 1 + ...a1f4a.0a8fc8dc.js => 98da1f4a.2fcff044.js} | 2 +- ...f5f54.d1c25906.js => a53f5f54.4d371dc6.js} | 2 +- ...98721.65979789.js => a7098721.9b500676.js} | 2 +- assets/js/aaa1f5ea.aea537fc.js | 1 - ...bb3d0.e44acdf9.js => bb0bb3d0.a0b4485b.js} | 2 +- ...6f58e.a6c77524.js => ce36f58e.46a76085.js} | 2 +- ...67e84.c71c82de.js => d8867e84.4f83b2d6.js} | 2 +- ...05362.67006002.js => dba05362.da0a8cd2.js} | 2 +- assets/js/e0f141dc.9219a7c3.js | 1 + assets/js/e0f141dc.c893cb19.js | 1 - ...52c02.8f884e40.js => f2352c02.f5dda918.js} | 2 +- assets/js/main.aea791ea.js | 2 - assets/js/main.e749f53d.js | 2 + ...CENSE.txt => main.e749f53d.js.LICENSE.txt} | 0 assets/js/runtime~main.81d77a0a.js | 1 - assets/js/runtime~main.fa8c62de.js | 1 + .../index.html | 8 +-- .../index.html | 6 +- .../01/29/partner-spotlight-zade/index.html | 6 +- .../index.html | 8 +-- .../index.html | 57 ---------------- blog/archive/index.html | 6 +- blog/atom.xml | 66 ++----------------- blog/index.html | 8 +-- blog/rss.xml | 54 +-------------- blog/tags/adobe-aero/index.html | 8 +-- blog/tags/ar/index.html | 8 +-- blog/tags/developer/index.html | 6 +- blog/tags/development/index.html | 6 +- blog/tags/devshop/index.html | 6 +- blog/tags/gaussian-splats/index.html | 6 +- blog/tags/gltf/index.html | 8 +-- blog/tags/headset/index.html | 6 +- blog/tags/index.html | 6 +- blog/tags/localization/index.html | 8 +-- blog/tags/mixed-reality/index.html | 6 +- blog/tags/partner/index.html | 6 +- blog/tags/photogrammetry/index.html | 6 +- blog/tags/react/index.html | 6 +- blog/tags/splats/index.html | 6 +- blog/tags/streetmix/index.html | 8 +-- blog/tags/vps/index.html | 8 +-- blog/tags/vr/index.html | 6 +- blog/tags/web/index.html | 6 +- blog/tags/webxr/index.html | 8 +-- .../layers-properties-panels/index.html | 4 +- .../overview-3dstreet-editor/index.html | 4 +- .../save-export-scene/index.html | 4 +- .../saving-and-loading-scenes/index.html | 4 +- .../select-move-objects/index.html | 4 +- .../3dstreet-brand-voice/index.html | 4 +- .../3dstreet-llc-entity/index.html | 4 +- .../overview-vision-mission/index.html | 4 +- .../about-3dstreet/primary-metrics/index.html | 4 +- docs/about-3dstreet/user-personas/index.html | 4 +- docs/category/3dstreet-editor/index.html | 4 +- docs/category/about-3dstreet/index.html | 4 +- docs/category/development/index.html | 4 +- .../index.html | 4 +- docs/contributing/index.html | 4 +- docs/development/alpha-labs/index.html | 4 +- .../index.html | 4 +- docs/development/releases/index.html | 4 +- docs/index.html | 4 +- docs/pricing/index.html | 4 +- docs/services/index.html | 4 +- .../congratulations/index.html | 4 +- .../index.html | 4 +- .../create-a-streetmix-account/index.html | 4 +- .../index.html | 4 +- .../overview-streetmix-3dstreet/index.html | 4 +- docs/viewer-and-editor/index.html | 4 +- index.html | 6 +- sitemap.xml | 2 +- 98 files changed, 184 insertions(+), 350 deletions(-) rename 2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md => 2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md.donotpublish (91%) rename assets/js/{0608d96f.40246681.js => 0608d96f.0ca046ee.js} (75%) delete mode 100644 assets/js/0afd36a3.15c8c7e0.js rename assets/js/{132139d8.d9fa967b.js => 0afd36a3.3d84968d.js} (91%) rename assets/js/{7d48d4d7.af4398b1.js => 132139d8.ad178cc6.js} (92%) create mode 100644 assets/js/3b085c01.15d96e0f.js delete mode 100644 assets/js/3b085c01.c94bcd2f.js rename assets/js/{3d85b4f0.35d96d3e.js => 3d85b4f0.8b2d142f.js} (93%) create mode 100644 assets/js/3e0df243.b4ef2ed4.js delete mode 100644 assets/js/4200b1a9.30cafe92.js create mode 100644 assets/js/4200b1a9.5b66eaa4.js rename assets/js/{4271b14e.bd3fa7b1.js => 4271b14e.a48241f1.js} (76%) rename assets/js/{486dd983.cd77351a.js => 486dd983.349dea54.js} (76%) rename assets/js/{5c6a4964.52408134.js => 5c6a4964.ac0cb292.js} (98%) rename assets/js/{625c228a.72397e3f.js => 625c228a.587857c6.js} (76%) rename assets/js/{66d5ef6c.2026e58c.js => 66d5ef6c.6f1303fa.js} (66%) delete mode 100644 assets/js/6d8ec5d0.54a6a317.js rename assets/js/{7bf629c2.0c878aab.js => 7bf629c2.c57c4bac.js} (78%) rename assets/js/{3e0df243.1f7b2113.js => 7d48d4d7.7f8c6a7b.js} (89%) rename assets/js/{83ee47c4.e41b30c4.js => 83ee47c4.f7e0eecf.js} (83%) rename assets/js/{8c0e532b.4565fc63.js => 8c0e532b.68f4d1b8.js} (82%) delete mode 100644 assets/js/95b96bb9.910a965e.js create mode 100644 assets/js/95b96bb9.df041972.js rename assets/js/{98da1f4a.0a8fc8dc.js => 98da1f4a.2fcff044.js} (76%) rename assets/js/{a53f5f54.d1c25906.js => a53f5f54.4d371dc6.js} (81%) rename assets/js/{a7098721.65979789.js => a7098721.9b500676.js} (75%) delete mode 100644 assets/js/aaa1f5ea.aea537fc.js rename assets/js/{bb0bb3d0.e44acdf9.js => bb0bb3d0.a0b4485b.js} (81%) rename assets/js/{ce36f58e.a6c77524.js => ce36f58e.46a76085.js} (78%) rename assets/js/{d8867e84.c71c82de.js => d8867e84.4f83b2d6.js} (75%) rename assets/js/{dba05362.67006002.js => dba05362.da0a8cd2.js} (76%) create mode 100644 assets/js/e0f141dc.9219a7c3.js delete mode 100644 assets/js/e0f141dc.c893cb19.js rename assets/js/{f2352c02.8f884e40.js => f2352c02.f5dda918.js} (76%) delete mode 100644 assets/js/main.aea791ea.js create mode 100644 assets/js/main.e749f53d.js rename assets/js/{main.aea791ea.js.LICENSE.txt => main.e749f53d.js.LICENSE.txt} (100%) delete mode 100644 assets/js/runtime~main.81d77a0a.js create mode 100644 assets/js/runtime~main.fa8c62de.js delete mode 100644 blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco/index.html diff --git a/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md b/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md.donotpublish similarity index 91% rename from 2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md rename to 2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md.donotpublish index 8cc40359..aa297d2c 100644 --- a/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md +++ b/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md.donotpublish @@ -9,6 +9,7 @@ hide_table_of_contents: false ![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png) +Greetings! I'm Marc Schlossberg, and I've been working alongside [Danny Pimentel](https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend) and graduate student [Luke Walker](https://www.linkedin.com/in/luke-walker-439b78119/) at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let's roll up our sleeves and get our hands digitally dirty! ## Getting Started: Measuring and Designing diff --git a/404.html b/404.html index 3d8b9f31..a09f9aa5 100644 --- a/404.html +++ b/404.html @@ -11,8 +11,8 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/assets/js/0608d96f.40246681.js b/assets/js/0608d96f.0ca046ee.js similarity index 75% rename from assets/js/0608d96f.40246681.js rename to assets/js/0608d96f.0ca046ee.js index 22b45fa1..ea9bf4d8 100644 --- a/assets/js/0608d96f.40246681.js +++ b/assets/js/0608d96f.0ca046ee.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7568],{7158:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/vps","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7568],{7158:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/vps","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/0afd36a3.15c8c7e0.js b/assets/js/0afd36a3.15c8c7e0.js deleted file mode 100644 index 998721b4..00000000 --- a/assets/js/0afd36a3.15c8c7e0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4134],{5734:e=>{e.exports=JSON.parse('{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"imageURL":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","blogURL":"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco"}')}}]); \ No newline at end of file diff --git a/assets/js/132139d8.d9fa967b.js b/assets/js/0afd36a3.3d84968d.js similarity index 91% rename from assets/js/132139d8.d9fa967b.js rename to assets/js/0afd36a3.3d84968d.js index 1b315b8b..0d7df5fe 100644 --- a/assets/js/132139d8.d9fa967b.js +++ b/assets/js/0afd36a3.3d84968d.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1617],{8074:e=>{e.exports=JSON.parse('{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"imageURL":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","blogURL":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4134],{5734:e=>{e.exports=JSON.parse('{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"imageURL":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","blogURL":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"}')}}]); \ No newline at end of file diff --git a/assets/js/7d48d4d7.af4398b1.js b/assets/js/132139d8.ad178cc6.js similarity index 92% rename from assets/js/7d48d4d7.af4398b1.js rename to assets/js/132139d8.ad178cc6.js index 9d2bdbf3..1d448911 100644 --- a/assets/js/7d48d4d7.af4398b1.js +++ b/assets/js/132139d8.ad178cc6.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5616],{9106:t=>{t.exports=JSON.parse('{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","authors":[{"name":"Ivan Denysyuk","title":"CEO at Zade","url":"https://www.linkedin.com/in/ivan-denysyuk-171585148/","imageURL":"https://media.licdn.com/dms/image/C4E03AQFalzhqOpaXYw/profile-displayphoto-shrink_800_800/0/1650363550337?e=1712188800&v=beta&t=z1C-cetFrHoP5ao_i9cLsJmCi3quhrcZ0kmhd9OGz3s","key":"idenysyuk"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"imageURL":"https://i.imgur.com/YyKGZA7.jpeg","blogURL":"/blog/2024/01/29/partner-spotlight-zade"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1617],{8074:t=>{t.exports=JSON.parse('{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","authors":[{"name":"Ivan Denysyuk","title":"CEO at Zade","url":"https://www.linkedin.com/in/ivan-denysyuk-171585148/","imageURL":"https://media.licdn.com/dms/image/C4E03AQFalzhqOpaXYw/profile-displayphoto-shrink_800_800/0/1650363550337?e=1712188800&v=beta&t=z1C-cetFrHoP5ao_i9cLsJmCi3quhrcZ0kmhd9OGz3s","key":"idenysyuk"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"imageURL":"https://i.imgur.com/YyKGZA7.jpeg","blogURL":"/blog/2024/01/29/partner-spotlight-zade"}')}}]); \ No newline at end of file diff --git a/assets/js/3b085c01.15d96e0f.js b/assets/js/3b085c01.15d96e0f.js new file mode 100644 index 00000000..3131c23d --- /dev/null +++ b/assets/js/3b085c01.15d96e0f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7700],{8903:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var n=i(5893),s=i(1151);const a={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},r=void 0,o={permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero",source:"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-01-30T00:00:00.000Z",formattedDate:"January 30, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.455,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Partner Spotlight: Zade's Contributions to 3DStreet in 2023",permalink:"/blog/2024/01/29/partner-spotlight-zade"}},l={image:i(1350).Z,authorsImageUrls:[void 0]},d=[{value:"Getting Started: Measuring and Designing",id:"getting-started-measuring-and-designing",level:2},{value:"Viewing Your Creation: 3DStreet's Magic",id:"viewing-your-creation-3dstreets-magic",level:2},{value:"Optional Tweaks: A Blender Bonus",id:"optional-tweaks-a-blender-bonus",level:2},{value:"Bringing It to Life: Augmented Reality Integration",id:"bringing-it-to-life-augmented-reality-integration",level:2},{value:"Sharing Your Vision: Universal Access",id:"sharing-your-vision-universal-access",level:2},{value:"Wrapping It Up",id:"wrapping-it-up",level:2}];function h(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",img:"img",p:"p",strong:"strong",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["Greetings! I'm Marc Schlossberg, and I've been working alongside ",(0,n.jsx)(t.a,{href:"https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend",children:"Danny Pimentel"})," and graduate student ",(0,n.jsx)(t.a,{href:"https://www.linkedin.com/in/luke-walker-439b78119/",children:"Luke Walker"})," at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let's roll up our sleeves and get our hands digitally dirty!"]}),"\n",(0,n.jsx)(t.h2,{id:"getting-started-measuring-and-designing",children:"Getting Started: Measuring and Designing"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(7695).Z+"",width:"640",height:"360"}),(0,n.jsx)(t.strong,{children:"First things first\u2014measure up!"})]}),"\n",(0,n.jsx)(t.p,{children:"To kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It's okay if it's not pinpoint accurate \u2014 we just need a ballpark figure."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Crafting Your Street: Easy as Pie with Streetmix"})}),"\n",(0,n.jsx)(t.p,{children:"Once you've got your measurements, it's time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart's content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(4613).Z+"",width:"640",height:"360"}),"For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: ",(0,n.jsx)(t.a,{href:"https://streetmix.net/schlossb/20/demo-st",children:"https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.h2,{id:"viewing-your-creation-3dstreets-magic",children:"Viewing Your Creation: 3DStreet's Magic"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(8957).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["With your design all set in Streetmix, it's time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It's a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: ",(0,n.jsx)(t.a,{href:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st",children:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Trimming the Excess for AR"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(366).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To prep for AR, you'll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that's ready for the world of augmented reality."}),"\n",(0,n.jsxs)(t.p,{children:['To delete a layer, select the layer in the left-hand panel -- such as "Buildings & Blocks Container" in the screenshot above -- then press the ',(0,n.jsx)(t.code,{children:"delete"})," key and click ",(0,n.jsx)(t.code,{children:"ok"}),". This will remove buildings and grounds from lots that are not needed for our AR project."]}),"\n",(0,n.jsx)(t.h2,{id:"optional-tweaks-a-blender-bonus",children:"Optional Tweaks: A Blender Bonus"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(3872).Z+"",width:"640",height:"360"}),"For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined."]}),"\n",(0,n.jsx)(t.h2,{id:"bringing-it-to-life-augmented-reality-integration",children:"Bringing It to Life: Augmented Reality Integration"}),"\n",(0,n.jsxs)(t.p,{children:["Alright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use ",(0,n.jsx)(t.a,{href:"https://www.adobe.com/products/aero.html",children:"Adobe Aero"}),', thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the "quick and dirty" path.']}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6092).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"AR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Geolocation: Pinning It to the Real World"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(2625).Z+"",width:"640",height:"360"}),"What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it's not mandatory; you can always opt to apply your scene freely to any street you wish."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.h2,{id:"sharing-your-vision-universal-access",children:"Sharing Your Vision: Universal Access"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3975).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"Once your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes."}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you've done, and really start to reimagine, well, what would this street look like if it wasn't a street as has been, but is actually a park, a place for people in this particular example?\""}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(7812).Z+"",width:"164",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3543).Z+"",width:"167",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design."}),"\n",(0,n.jsx)(t.h2,{id:"wrapping-it-up",children:"Wrapping It Up"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6120).Z+"",width:"165",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"And there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces."}),"\n",(0,n.jsx)(t.p,{children:"Until next time, happy designing and thanks for joining me on this digital adventure. Bye for now!"}),"\n",(0,n.jsx)(t.h1,{id:"video-version-of-this-post",children:"Video version of this post"}),"\n",(0,n.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/AP1CwWuD7uA?si=y2_qAYNtR9HpATAl",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0})]})}function c(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1350:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},3543:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/0ek0kL6ZzdbicjxigM67-181.43-22c585226e335ee1b14b58e95f808d17.png"},8957:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/29P0QTWEp8JbvCQ8PeH3-63.32-928dbe2dd89a827b1be96ce08a2405c4.png"},366:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/IkXMBseXhrpqImEJSANN-73.23-6ef8699ad042fd310f99859136492bb0.png"},4613:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/J7eHGPI8MA57Pyzgsd8i-41.61-d8f2c4d7d54a990318659f4ac3f4bdbc.png"},3975:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/KffxVJZ1prku9AeBBemu-158.27-35b296c693dca9c18355a51cd4cec663.png"},2625:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/M5vycvy2ClFbSLnLm6FY-133.23-1df718f2655ad0733ab2392a4b55bf57.png"},6120:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/SjGd11l5Keu216ORRZav-189.75-a07c9c70fba466aa3c58909d4c55a87b.png"},7812:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/XP1Nfq1sugGz8zrILMJb-179.54-ef26283fc536ad6544d4f738185a220f.png"},3872:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/kmXnEg7FMoHUxW0GgLiu-95.91-578b25b18098f554dd052bb2c580bdaa.png"},7695:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/lVthCNUM7YLUyBGXixqk-10.87-80c85fce3c339171a8196f2efa2d7431.png"},5117:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},6092:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/tSVcvVL1kH92J4F4ALF8-112.94-b8f411524c96f6c05320da8bb061eba1.png"},1151:(e,t,i)=>{i.d(t,{Z:()=>o,a:()=>r});var n=i(7294);const s={},a=n.createContext(s);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b085c01.c94bcd2f.js b/assets/js/3b085c01.c94bcd2f.js deleted file mode 100644 index b9510209..00000000 --- a/assets/js/3b085c01.c94bcd2f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7700],{8903:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var n=i(5893),s=i(1151);const a={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},r=void 0,o={permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero",source:"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-01-30T00:00:00.000Z",formattedDate:"January 30, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.455,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",permalink:"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco"},nextItem:{title:"Partner Spotlight: Zade's Contributions to 3DStreet in 2023",permalink:"/blog/2024/01/29/partner-spotlight-zade"}},l={image:i(1350).Z,authorsImageUrls:[void 0]},d=[{value:"Getting Started: Measuring and Designing",id:"getting-started-measuring-and-designing",level:2},{value:"Viewing Your Creation: 3DStreet's Magic",id:"viewing-your-creation-3dstreets-magic",level:2},{value:"Optional Tweaks: A Blender Bonus",id:"optional-tweaks-a-blender-bonus",level:2},{value:"Bringing It to Life: Augmented Reality Integration",id:"bringing-it-to-life-augmented-reality-integration",level:2},{value:"Sharing Your Vision: Universal Access",id:"sharing-your-vision-universal-access",level:2},{value:"Wrapping It Up",id:"wrapping-it-up",level:2}];function h(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",img:"img",p:"p",strong:"strong",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["Greetings! I'm Marc Schlossberg, and I've been working alongside ",(0,n.jsx)(t.a,{href:"https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend",children:"Danny Pimentel"})," and graduate student ",(0,n.jsx)(t.a,{href:"https://www.linkedin.com/in/luke-walker-439b78119/",children:"Luke Walker"})," at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let's roll up our sleeves and get our hands digitally dirty!"]}),"\n",(0,n.jsx)(t.h2,{id:"getting-started-measuring-and-designing",children:"Getting Started: Measuring and Designing"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(7695).Z+"",width:"640",height:"360"}),(0,n.jsx)(t.strong,{children:"First things first\u2014measure up!"})]}),"\n",(0,n.jsx)(t.p,{children:"To kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It's okay if it's not pinpoint accurate \u2014 we just need a ballpark figure."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Crafting Your Street: Easy as Pie with Streetmix"})}),"\n",(0,n.jsx)(t.p,{children:"Once you've got your measurements, it's time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart's content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(4613).Z+"",width:"640",height:"360"}),"For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: ",(0,n.jsx)(t.a,{href:"https://streetmix.net/schlossb/20/demo-st",children:"https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.h2,{id:"viewing-your-creation-3dstreets-magic",children:"Viewing Your Creation: 3DStreet's Magic"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(8957).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["With your design all set in Streetmix, it's time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It's a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: ",(0,n.jsx)(t.a,{href:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st",children:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Trimming the Excess for AR"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(366).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To prep for AR, you'll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that's ready for the world of augmented reality."}),"\n",(0,n.jsxs)(t.p,{children:['To delete a layer, select the layer in the left-hand panel -- such as "Buildings & Blocks Container" in the screenshot above -- then press the ',(0,n.jsx)(t.code,{children:"delete"})," key and click ",(0,n.jsx)(t.code,{children:"ok"}),". This will remove buildings and grounds from lots that are not needed for our AR project."]}),"\n",(0,n.jsx)(t.h2,{id:"optional-tweaks-a-blender-bonus",children:"Optional Tweaks: A Blender Bonus"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(3872).Z+"",width:"640",height:"360"}),"For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined."]}),"\n",(0,n.jsx)(t.h2,{id:"bringing-it-to-life-augmented-reality-integration",children:"Bringing It to Life: Augmented Reality Integration"}),"\n",(0,n.jsxs)(t.p,{children:["Alright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use ",(0,n.jsx)(t.a,{href:"https://www.adobe.com/products/aero.html",children:"Adobe Aero"}),', thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the "quick and dirty" path.']}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6092).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"AR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Geolocation: Pinning It to the Real World"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(2625).Z+"",width:"640",height:"360"}),"What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it's not mandatory; you can always opt to apply your scene freely to any street you wish."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.h2,{id:"sharing-your-vision-universal-access",children:"Sharing Your Vision: Universal Access"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3975).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"Once your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes."}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you've done, and really start to reimagine, well, what would this street look like if it wasn't a street as has been, but is actually a park, a place for people in this particular example?\""}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(7812).Z+"",width:"164",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3543).Z+"",width:"167",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design."}),"\n",(0,n.jsx)(t.h2,{id:"wrapping-it-up",children:"Wrapping It Up"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6120).Z+"",width:"165",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"And there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces."}),"\n",(0,n.jsx)(t.p,{children:"Until next time, happy designing and thanks for joining me on this digital adventure. Bye for now!"}),"\n",(0,n.jsx)(t.h1,{id:"video-version-of-this-post",children:"Video version of this post"}),"\n",(0,n.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/AP1CwWuD7uA?si=y2_qAYNtR9HpATAl",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0})]})}function c(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1350:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},3543:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/0ek0kL6ZzdbicjxigM67-181.43-22c585226e335ee1b14b58e95f808d17.png"},8957:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/29P0QTWEp8JbvCQ8PeH3-63.32-928dbe2dd89a827b1be96ce08a2405c4.png"},366:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/IkXMBseXhrpqImEJSANN-73.23-6ef8699ad042fd310f99859136492bb0.png"},4613:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/J7eHGPI8MA57Pyzgsd8i-41.61-d8f2c4d7d54a990318659f4ac3f4bdbc.png"},3975:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/KffxVJZ1prku9AeBBemu-158.27-35b296c693dca9c18355a51cd4cec663.png"},2625:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/M5vycvy2ClFbSLnLm6FY-133.23-1df718f2655ad0733ab2392a4b55bf57.png"},6120:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/SjGd11l5Keu216ORRZav-189.75-a07c9c70fba466aa3c58909d4c55a87b.png"},7812:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/XP1Nfq1sugGz8zrILMJb-179.54-ef26283fc536ad6544d4f738185a220f.png"},3872:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/kmXnEg7FMoHUxW0GgLiu-95.91-578b25b18098f554dd052bb2c580bdaa.png"},7695:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/lVthCNUM7YLUyBGXixqk-10.87-80c85fce3c339171a8196f2efa2d7431.png"},5117:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},6092:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/tSVcvVL1kH92J4F4ALF8-112.94-b8f411524c96f6c05320da8bb061eba1.png"},1151:(e,t,i)=>{i.d(t,{Z:()=>o,a:()=>r});var n=i(7294);const s={},a=n.createContext(s);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d85b4f0.35d96d3e.js b/assets/js/3d85b4f0.8b2d142f.js similarity index 93% rename from assets/js/3d85b4f0.35d96d3e.js rename to assets/js/3d85b4f0.8b2d142f.js index 580701c7..771a9a77 100644 --- a/assets/js/3d85b4f0.35d96d3e.js +++ b/assets/js/3d85b4f0.8b2d142f.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6297],{5707:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var a=s(5893),n=s(1151);const r={title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},i="Gaussian splats are ground-breaking visualization technology",o={permalink:"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes",source:"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md",title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",date:"2023-12-21T00:00:00.000Z",formattedDate:"December 21, 2023",tags:[{label:"gaussian splats",permalink:"/blog/tags/gaussian-splats"},{label:"splats",permalink:"/blog/tags/splats"},{label:"photogrammetry",permalink:"/blog/tags/photogrammetry"}],readingTime:6.345,hasTruncateMarker:!0,authors:[{name:"Kieran Farr",title:"Creator of 3DStreet",url:"https://github.com/kfarr",imageURL:"https://github.com/kfarr.png",key:"kfarr"},{name:"Arthur Mougin",title:"3DStreet Contributor, WebXR Developer",url:"https://github.com/arthurmougin",imageURL:"https://github.com/arthurmougin.png",key:"amougin"}],frontMatter:{title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Impact on WebXR Application Design from New Mixed Reality Headsets",permalink:"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},l={image:s(8515).Z,authorsImageUrls:[void 0,void 0]},p=[];function c(e){const t={a:"a",em:"em",img:"img",p:"p",...(0,n.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"3DStreet's mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode."}),"\n",(0,a.jsxs)(t.p,{children:["Enter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a ",(0,a.jsx)(t.a,{href:"https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/",children:"research paper published at SIGGRAPH 2023"}),". I believe splatting to be ",(0,a.jsx)(t.em,{children:(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=HVv_IQKlafQ",children:"the best modern method"})})," to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=lowscL9YIjM",children:"plants"}),", ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=hr7P8_z0PSk",children:"trees"}),", flowers and other natural elements -- all things we'd like to see more of in our streets!"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques",src:s(654).Z+"",width:"1000",height:"405"})}),"\n",(0,a.jsx)(t.p,{children:"This is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet."})]})}function m(e={}){const{wrapper:t}={...(0,n.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},8515:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},654:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3d-mesh-vs-splat-16d7a8d0df770ca631c2b903d3b62a3f.jpg"},1151:(e,t,s)=>{s.d(t,{Z:()=>o,a:()=>i});var a=s(7294);const n={},r=a.createContext(n);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6297],{5707:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var a=s(5893),n=s(1151);const r={title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},i="Gaussian splats are ground-breaking visualization technology",o={permalink:"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes",source:"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md",title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",date:"2023-12-21T00:00:00.000Z",formattedDate:"December 21, 2023",tags:[{label:"gaussian splats",permalink:"/blog/tags/gaussian-splats"},{label:"splats",permalink:"/blog/tags/splats"},{label:"photogrammetry",permalink:"/blog/tags/photogrammetry"}],readingTime:6.345,hasTruncateMarker:!0,authors:[{name:"Arthur Mougin",title:"3DStreet Contributor, WebXR Developer",url:"https://github.com/arthurmougin",imageURL:"https://github.com/arthurmougin.png",key:"amougin"},{name:"Kieran Farr",title:"Creator of 3DStreet",url:"https://github.com/kfarr",imageURL:"https://github.com/kfarr.png",key:"kfarr"}],frontMatter:{title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Impact on WebXR Application Design from New Mixed Reality Headsets",permalink:"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},l={image:s(8515).Z,authorsImageUrls:[void 0,void 0]},p=[];function c(e){const t={a:"a",em:"em",img:"img",p:"p",...(0,n.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"3DStreet's mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode."}),"\n",(0,a.jsxs)(t.p,{children:["Enter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a ",(0,a.jsx)(t.a,{href:"https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/",children:"research paper published at SIGGRAPH 2023"}),". I believe splatting to be ",(0,a.jsx)(t.em,{children:(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=HVv_IQKlafQ",children:"the best modern method"})})," to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=lowscL9YIjM",children:"plants"}),", ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=hr7P8_z0PSk",children:"trees"}),", flowers and other natural elements -- all things we'd like to see more of in our streets!"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques",src:s(654).Z+"",width:"1000",height:"405"})}),"\n",(0,a.jsx)(t.p,{children:"This is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet."})]})}function m(e={}){const{wrapper:t}={...(0,n.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},8515:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},654:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3d-mesh-vs-splat-16d7a8d0df770ca631c2b903d3b62a3f.jpg"},1151:(e,t,s)=>{s.d(t,{Z:()=>o,a:()=>i});var a=s(7294);const n={},r=a.createContext(n);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e0df243.b4ef2ed4.js b/assets/js/3e0df243.b4ef2ed4.js new file mode 100644 index 00000000..558ee2ae --- /dev/null +++ b/assets/js/3e0df243.b4ef2ed4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4683],{9093:e=>{e.exports=JSON.parse('{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","description":"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.","authors":[{"name":"Arthur Mougin","title":"3DStreet Contributor, WebXR Developer","url":"https://github.com/arthurmougin","imageURL":"https://github.com/arthurmougin.png","key":"amougin"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"imageURL":"./splat-blog/3dstreet-splat-compositing-demo.jpg","blogURL":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes"}')}}]); \ No newline at end of file diff --git a/assets/js/4200b1a9.30cafe92.js b/assets/js/4200b1a9.30cafe92.js deleted file mode 100644 index 3a79dab1..00000000 --- a/assets/js/4200b1a9.30cafe92.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[866],{4612:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco","metadata":{"permalink":"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco","source":"@site/blog/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md","title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","date":"2024-02-19T00:00:00.000Z","formattedDate":"February 19, 2024","tags":[{"label":"webxr","permalink":"/blog/tags/webxr"},{"label":"gltf","permalink":"/blog/tags/gltf"},{"label":"adobe aero","permalink":"/blog/tags/adobe-aero"},{"label":"streetmix","permalink":"/blog/tags/streetmix"},{"label":"ar","permalink":"/blog/tags/ar"},{"label":"vps","permalink":"/blog/tags/vps"},{"label":"localization","permalink":"/blog/tags/localization"}],"readingTime":4.11,"hasTruncateMarker":true,"authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"frontMatter":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":"mschlossberg","tags":["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],"image":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","hide_table_of_contents":false},"unlisted":false,"nextItem":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"}},"content":"![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\n\\n\x3c!-- truncate --\x3e\\n## Getting Started: Measuring and Designing\\n\\n![](./images/2024-01-30/lVthCNUM7YLUyBGXixqk-10.87.png)**First things first\u2014measure up!**\\n\\nTo kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It\'s okay if it\'s not pinpoint accurate \u2014 we just need a ballpark figure.\\n\\n**Crafting Your Street: Easy as Pie with Streetmix**\\n\\nOnce you\'ve got your measurements, it\'s time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart\'s content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!\\n\\n![](./images/2024-01-30/J7eHGPI8MA57Pyzgsd8i-41.61.png)For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: https://streetmix.net/schlossb/20/demo-st \\n\\n## Viewing Your Creation: 3DStreet\'s Magic\\n\\n![](./images/2024-01-30/29P0QTWEp8JbvCQ8PeH3-63.32.png)\\n\\nWith your design all set in Streetmix, it\'s time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It\'s a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st \\n\\n**Trimming the Excess for AR**\\n\\n![](./images/2024-01-30/IkXMBseXhrpqImEJSANN-73.23.png)\\n\\nTo prep for AR, you\'ll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that\'s ready for the world of augmented reality.\\n\\nTo delete a layer, select the layer in the left-hand panel -- such as \\"Buildings & Blocks Container\\" in the screenshot above -- then press the `delete` key and click `ok`. This will remove buildings and grounds from lots that are not needed for our AR project.\\n\\n## Optional Tweaks: A Blender Bonus\\n\\n![](./images/2024-01-30/kmXnEg7FMoHUxW0GgLiu-95.91.png)For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined.\\n\\n## Bringing It to Life: Augmented Reality Integration\\n\\nAlright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use [Adobe Aero](https://www.adobe.com/products/aero.html), thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the \\"quick and dirty\\" path.\\n\\n![](./images/2024-01-30/tSVcvVL1kH92J4F4ALF8-112.94.png)\\n\\nAR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet.\\n\\n**Geolocation: Pinning It to the Real World**\\n\\n![](./images/2024-01-30/M5vycvy2ClFbSLnLm6FY-133.23.png)What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it\'s not mandatory; you can always opt to apply your scene freely to any street you wish.\\n\\n![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\n## Sharing Your Vision: Universal Access\\n\\n![](./images/2024-01-30/KffxVJZ1prku9AeBBemu-158.27.png)\\n\\nOnce your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes.\\n\\n> \\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you\'ve done, and really start to reimagine, well, what would this street look like if it wasn\'t a street as has been, but is actually a park, a place for people in this particular example?\\"\\n\\n![](./images/2024-01-30/XP1Nfq1sugGz8zrILMJb-179.54.png)\\n\\n![](./images/2024-01-30/0ek0kL6ZzdbicjxigM67-181.43.png)\\n\\nTo illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design.\\n\\n## Wrapping It Up\\n\\n![](./images/2024-01-30/SjGd11l5Keu216ORRZav-189.75.png)\\n\\nAnd there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces.\\n\\nUntil next time, happy designing and thanks for joining me on this digital adventure. Bye for now!\\n\\n# Video version of this post\\n"},{"id":"/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","metadata":{"permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","source":"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md","title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","date":"2024-01-30T00:00:00.000Z","formattedDate":"January 30, 2024","tags":[{"label":"webxr","permalink":"/blog/tags/webxr"},{"label":"gltf","permalink":"/blog/tags/gltf"},{"label":"adobe aero","permalink":"/blog/tags/adobe-aero"},{"label":"streetmix","permalink":"/blog/tags/streetmix"},{"label":"ar","permalink":"/blog/tags/ar"},{"label":"vps","permalink":"/blog/tags/vps"},{"label":"localization","permalink":"/blog/tags/localization"}],"readingTime":4.455,"hasTruncateMarker":true,"authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"frontMatter":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":"mschlossberg","tags":["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],"image":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco"},"nextItem":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade"}},"content":"![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\nGreetings! I\'m Marc Schlossberg, and I\'ve been working alongside [Danny Pimentel](https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend) and graduate student [Luke Walker](https://www.linkedin.com/in/luke-walker-439b78119/) at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let\'s roll up our sleeves and get our hands digitally dirty!\\n\\n\x3c!-- truncate --\x3e\\n\\n## Getting Started: Measuring and Designing\\n\\n![](./images/2024-01-30/lVthCNUM7YLUyBGXixqk-10.87.png)**First things first\u2014measure up!**\\n\\nTo kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It\'s okay if it\'s not pinpoint accurate \u2014 we just need a ballpark figure.\\n\\n**Crafting Your Street: Easy as Pie with Streetmix**\\n\\nOnce you\'ve got your measurements, it\'s time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart\'s content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!\\n\\n![](./images/2024-01-30/J7eHGPI8MA57Pyzgsd8i-41.61.png)For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: https://streetmix.net/schlossb/20/demo-st\\n\\n## Viewing Your Creation: 3DStreet\'s Magic\\n\\n![](./images/2024-01-30/29P0QTWEp8JbvCQ8PeH3-63.32.png)\\n\\nWith your design all set in Streetmix, it\'s time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It\'s a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st\\n\\n**Trimming the Excess for AR**\\n\\n![](./images/2024-01-30/IkXMBseXhrpqImEJSANN-73.23.png)\\n\\nTo prep for AR, you\'ll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that\'s ready for the world of augmented reality.\\n\\nTo delete a layer, select the layer in the left-hand panel -- such as \\"Buildings & Blocks Container\\" in the screenshot above -- then press the `delete` key and click `ok`. This will remove buildings and grounds from lots that are not needed for our AR project.\\n\\n## Optional Tweaks: A Blender Bonus\\n\\n![](./images/2024-01-30/kmXnEg7FMoHUxW0GgLiu-95.91.png)For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined.\\n\\n## Bringing It to Life: Augmented Reality Integration\\n\\nAlright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use [Adobe Aero](https://www.adobe.com/products/aero.html), thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the \\"quick and dirty\\" path.\\n\\n![](./images/2024-01-30/tSVcvVL1kH92J4F4ALF8-112.94.png)\\n\\nAR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet.\\n\\n**Geolocation: Pinning It to the Real World**\\n\\n![](./images/2024-01-30/M5vycvy2ClFbSLnLm6FY-133.23.png)What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it\'s not mandatory; you can always opt to apply your scene freely to any street you wish.\\n\\n![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\n## Sharing Your Vision: Universal Access\\n\\n![](./images/2024-01-30/KffxVJZ1prku9AeBBemu-158.27.png)\\n\\nOnce your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes.\\n\\n> \\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you\'ve done, and really start to reimagine, well, what would this street look like if it wasn\'t a street as has been, but is actually a park, a place for people in this particular example?\\"\\n\\n![](./images/2024-01-30/XP1Nfq1sugGz8zrILMJb-179.54.png)\\n\\n![](./images/2024-01-30/0ek0kL6ZzdbicjxigM67-181.43.png)\\n\\nTo illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design.\\n\\n## Wrapping It Up\\n\\n![](./images/2024-01-30/SjGd11l5Keu216ORRZav-189.75.png)\\n\\nAnd there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces.\\n\\nUntil next time, happy designing and thanks for joining me on this digital adventure. Bye for now!\\n\\n# Video version of this post\\n\\n"},{"id":"/2024/01/29/partner-spotlight-zade","metadata":{"permalink":"/blog/2024/01/29/partner-spotlight-zade","source":"@site/blog/2024-01-29-partner-spotlight-zade.md","title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","date":"2024-01-29T00:00:00.000Z","formattedDate":"January 29, 2024","tags":[{"label":"react","permalink":"/blog/tags/react"},{"label":"development","permalink":"/blog/tags/development"},{"label":"partner","permalink":"/blog/tags/partner"},{"label":"devshop","permalink":"/blog/tags/devshop"},{"label":"web","permalink":"/blog/tags/web"},{"label":"developer","permalink":"/blog/tags/developer"}],"readingTime":2.74,"hasTruncateMarker":true,"authors":[{"name":"Ivan Denysyuk","title":"CEO at Zade","url":"https://www.linkedin.com/in/ivan-denysyuk-171585148/","imageURL":"https://media.licdn.com/dms/image/C4E03AQFalzhqOpaXYw/profile-displayphoto-shrink_800_800/0/1650363550337?e=1712188800&v=beta&t=z1C-cetFrHoP5ao_i9cLsJmCi3quhrcZ0kmhd9OGz3s","key":"idenysyuk"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"frontMatter":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","authors":["kfarr","idenysyuk"],"tags":["react","development","partner","devshop","web","developer"],"image":"https://i.imgur.com/YyKGZA7.jpeg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"},"nextItem":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},"content":"2023 marks a significant year for 3DStreet, made possible through our [talented community of contributors](https://github.com/3DStreet/3dstreet/graphs/contributors) both volunteer and paid. [Zade Agency](https://zade.agency/) fits in the latter category as a software development team for-hire based in Ukraine. Over the past year Zade emerged as a major boost to our development productivity and I wanted to share how their contributions have helped 3DStreet in a critical time for the organization.\\n\\n\x3c!-- truncate --\x3e\\n\\n### The Challenge for 3DStreet\\n\\nTo meet our timeline for a [public beta launch of 3DStreet Editor in 2023](https://www.youtube.com/watch?v=WnjtUW4J8uc), we faced several challenges. A primary concern was the gap in React expertise among our existing development team. While we are skilled in various aspects, existing React knowledge was crucial for implementing deep and rapid modifications to [3DStreet Editor](https://github.com/3DStreet/3dstreet-editor) which is a heavily modified version of the [A-Frame inspector](https://github.com/aframevr/aframe-inspector).\\n\\nAdditionally, as a [self-funded project](https://www.3dstreet.org/docs/about-3dstreet/3dstreet-llc-entity) we have very real budgetary constraints making it imperative to optimize every resource.\\n\\n### Zade\'s Solution to Boost React Development\\n\\nWe found Zade through a direct personal referral via our designer [Daria Dombrovska](https://www.linkedin.com/in/daria-dombrovska-933902207/). Zade immediately brought a wealth of React knowledge through their team of both senior and junior engineers, filling the crucial skill gap in our team.\\n\\nAs a self-trained software developer myself, I worked directly with a senior engineer at the beginning to confirm our architectural approaches and details of our tech stack. I also worked with our account manager to agree on the use of [GitHub Projects, issues, and PRs](https://github.com/orgs/3DStreet/projects/5) to manage our working relationship.\\n\\nFor day-to-day tasks I create [GitHub issues](https://github.com/3DStreet/3dstreet-editor/issues/) that are prioritized in [Projects](https://github.com/orgs/3DStreet/projects/5) and tackled via a junior engineer who is mentored by the experienced staff. Even as a junior engineer, they have way more experience in React fundamentals than I do given my [rather myopic focus on A-Frame and three.js development]() over the past decade.\\n\\n### 2023 Highlight: Launching 3DStreet Cloud\\n\\nOne of the most notable achievements in 2023 was the [launch of 3DStreet Cloud](https://www.youtube.com/watch?v=WnjtUW4J8uc), a React application using [Firebase Firestore](https://firebase.google.com/docs/firestore) on [Google Cloud Platform](https://cloud.google.com/).\\n\\n3DStreet Cloud is the foundation of the growth engine of the [3DStreet Editor product](https://3dstreet.app/) -- it is the system that allows our users to collaborate on safe street designs and fulfill our core mission.\\n\\n### Zade: Empowering Startups with React Expertise\\n\\nNow it\'s time for the pitch, because the Zade team deserves it!\\n\\nAre you an early-stage startup founder needing flexible React development solutions? Zade specializes in helping launch new startups and accelerating growth for existing ones. Their unique ecosystem is tailor-made for product development in the startup world.\\n\\n**Zade\'s Offerings:**\\n\\n- [**LaunchKit:**](https://zade.agency/launchkit/) A program designed to bring your vision to life within a month.\\n- **Integrated Team:** Seamlessly scale your startup with Zade\'s integrated design and development team.\\n\\n**Special Offer for 3DStreet Community:**\\nWhile there\'s no such thing as a free lunch in contract development, Zade extends a special offer to the 3DStreet community. Mention 3DStreet to receive a 15% discount on your first month with Zade \u2013 a deal that might just be more valuable than a few gourmet lunches, depending on your project\'s scale.\\n\\n### Connect with Zade\\n\\nInterested in learning more? Reach out to Zade at ivan@zade.agency, or contact me directly for an introduction. Let\'s embark on a journey of innovation and growth together with Zade\'s expert team!"},{"id":"/2023/12/29/new-mixed-reality-devices-impact-on-webxr","metadata":{"permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr","source":"@site/blog/2023-12-29-new-mixed-reality-devices-impact-on-webxr.md","title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","date":"2023-12-29T00:00:00.000Z","formattedDate":"December 29, 2023","tags":[{"label":"webxr","permalink":"/blog/tags/webxr"},{"label":"headset","permalink":"/blog/tags/headset"},{"label":"mixed-reality","permalink":"/blog/tags/mixed-reality"},{"label":"ar","permalink":"/blog/tags/ar"},{"label":"vr","permalink":"/blog/tags/vr"}],"readingTime":4.385,"hasTruncateMarker":true,"authors":[{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"frontMatter":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","authors":"kfarr","tags":["webxr","headset","mixed-reality","ar","vr"],"image":"./images/visionOS-platform-compressed.jpg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade"},"nextItem":{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes"}},"content":"A few weeks ago I attended a \\"developer day\\" at a local electronics company down the road featuring their new mixed reality VR headset. I spent the entire day testing many different WebXR applications with a heavy focus on evaluating which user interaction elements will be relevant for developers.\\n\\nBelow are some notes intended for other 3DStreet code contributors to reference as we work on supporting new WebXR compatible devices.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Gaze works very well as a primary user input mechanism\\nGaze interaction *\\"just works\\"* for native applications in this headset, however it\'s a privacy nightmare as gaze movement can be use to fingerprint (identify) individuals for tracking purposes, so that information isn\'t even given to native application. \\n\\nTo enable gaze user interface while not exposing gaze to the application, apps need to provide \\"hot spots\\" or hints as to areas that can be hovered. [There is a great video guide on how to adapt 2D DOM CSS website for gaze highlight interaction](https://developer.apple.com/videos/play/wwdc2023/10279/), but there\'s no clear equivalent to this CSS hinting that can be done in the WebXR \\"3D DOM\\" or 3D space. The need has been recognized however, [there is a new ticket opened in the WebXR `immersive-web` GitHub repository that I recently added to.](https://github.com/immersive-web/proposals/issues/86)\\n\\n## Hand tracking is the most accessible input, not controllers\\nImagine a world where WebXR experiences are 100% hands-free, where a simple ray from the wrist and a pitch of the hand can activate functions. This is not just a possibility but now a necessity -- going forward, all WebXR experiences must be accessible via hands first.\\n\\nWe should now regard hand tracking as the \\"lowest common denominator\\" of user input for headset experiences. Controllers will still offer higher precision, off-camera movement tracking, more button trigger inputs, etc. but they are no longer the most accessible \\"default\\" option.\\n\\n## Launching WebXR applications\\nGetting WebXR working on this device is cumbersome. WebXR must be activated by searching through multiple Safari flags (System Settings > Apps > Safari > Blah blah blah). Then, on the web page itself a user must accept 2 separate approval popups when entering WebXR mode -- one for enabling immersive mode, the other for enabling hand tracking.\\n\\nIt may be possible to \\"pull\\" some advanced users into using WebXR on these devices with instruction on feature flag setting, but it will be impossible to use WebXR on this platform to \\"push\\" more people to your WebXR experience in its present form.\\n\\n## Space, Immersion and Passthrough with WebXR\\nIn WebXR mode on the device, a scene is rendered in _Full Space_ meaning no other application windows are present, unlike native apps that can choose to run in _Shared Space_ amongst other applications. An additional limitation is that the device does not currently support WebXR with _Passthrough_ mode, therefore you cannot run WebAR apps that make use of external cameras.\\n\\n*Therefore only your WebXR scene will appear in _Full Space_ immersion mode with no _Passthrough_.* This may be desirable for traditional VR applications but not as useful for next generation mixed reality applications.\\n\\nAn additional limitation is that WebXR Immersive mode is limited to a 1.5m radius from the user-specified origin, usually where the user was located when entering XR mode. Beyond this radius the immersive scene _Full Space_ begins fading into _Passthrough_ without the scene persisting. If a user continues moving away from the origin the will see a round Safari icon at the origin point, presumably indicating that the user has an open WebXR Safari session with an origin at that point.\\n\\n## Diorama vs. Full Room Scale\\nThe [visionOS developer documentation](https://developer.apple.com/documentation/visionos/) is excellent and signals clear directions for the market.\\n\\nThe Diorama appears to be major application interface concept, [featured as a sample application](https://developer.apple.com/documentation/visionos/diorama) and a prime example of output from the new Reality Composer Pro authoring tool.\\n\\nThis is a useful concept to adopt with 3DStreet. With 3DStreet there are cases for both Diorama and Full Scale modes: some users may wish to view a scene in Full Scale life-size to get an accurate viewpoint of dimension, while other users may wish to shrink a scene down to a Diorama view to easily manipulate a large scene from a smaller workspace.\\n\\n## Combining WebXR with native applications\\n* Native applications can ask for rights such as _Passthrough_ or _Shared Space_ that are not currently accessible via Safari WebXR. It is definitely worth exploring the use of an embedded webkit-based webview in a visionOS application which may expand the ability for WebXR application to offer augmented reality experiences with a native-like experience.\\n* Reality Composer Pro looks like a powerful tool for non-developers. It is worth exploring a pipeline of 3DStreet > Reality Composer Pro > App Publishing. Therefore it is likely worth exploring tools to convert glTF exporting to USDZ format, or directly exporting the three.js / A-Frame scene into USDZ format.\\n\\n## Summary\\n* WebXR appears to be purposefully limited on this device with a degraded user experience. Consider webview or another mechanism to adapt WebXR application into a native app.\\n* Hand tracking is now a minimum requirement for WebXR apps, controllers are optional.\\n* Gaze interface is very effective but needs standardization work to enable in WebXR mode."},{"id":"/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","metadata":{"permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","source":"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md","title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","description":"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.","date":"2023-12-21T00:00:00.000Z","formattedDate":"December 21, 2023","tags":[{"label":"gaussian splats","permalink":"/blog/tags/gaussian-splats"},{"label":"splats","permalink":"/blog/tags/splats"},{"label":"photogrammetry","permalink":"/blog/tags/photogrammetry"}],"readingTime":6.345,"hasTruncateMarker":true,"authors":[{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"},{"name":"Arthur Mougin","title":"3DStreet Contributor, WebXR Developer","url":"https://github.com/arthurmougin","imageURL":"https://github.com/arthurmougin.png","key":"amougin"}],"frontMatter":{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","description":"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.","authors":["kfarr","amougin"],"tags":["gaussian splats","splats","photogrammetry"],"image":"./splat-blog/3dstreet-splat-compositing-demo.jpg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},"content":"3DStreet\'s mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode.\\n\\nEnter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a [research paper published at SIGGRAPH 2023](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/). I believe splatting to be *[the best modern method](https://www.youtube.com/watch?v=HVv_IQKlafQ)* to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially [plants](https://www.youtube.com/watch?v=lowscL9YIjM), [trees](https://www.youtube.com/watch?v=hr7P8_z0PSk), flowers and other natural elements -- all things we\'d like to see more of in our streets! \\n\\n![Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques](./splat-blog/3d-mesh-vs-splat.jpg)\\n\\nThis is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet.\\n\\n\x3c!-- truncate --\x3e\\n\\n# A splatting explosion!\\nA slew of gaussian splat tools have come to market -- creation apps for 3D scanning with your phone ([Polycam](https://poly.cam/) and [Luma](https://lumalabs.ai/)) and viewers for every platform and device imaginable ([too many to list](https://github.com/tomiwaAdey/awesome-gaussian-splatting?tab=readme-ov-file#rendering-and-visualisation-tools)) and even [browser-based cropping and editing tools](https://playcanvas.com/super-splat).\\n\\nHowever, much of the existing gaussian splat research and development focuses on scenes with just one single large splat.\\n\\nWith 3DStreet we\'re exploring something new -- constructing brand new street scenes from bits and pieces of existing 3D splats.\\n\\n# The problem: multiple splats in three.js are Hard\\nIf we can draw one gaussian splat in our scene, why not more? Well it turns out it\'s Hard. Compositing wasn\u2019t supported yet by the existing three.js / A-Frame splat viewing libraries so it resulted in things just not good enough for people to use as a product, like this fire hydrant and tree being occluded by a flower box further away.\\n\\n![Picture of error in splat ordering resulting in distant objects incorrectly occluding closer objects](./splat-blog/splat-render-order-error.jpg)\\n\\nTo solve this problem, we collaborated with [Arthur Mougin, a WebXR and full stack developer](https://arthurmoug.in/) who was excited to tackle a new challenge. Here is his writeup on how we enabled proper splat sorting, concluded by some discussion on what is coming next.\\n\\n# Use depth buffer with `depthWrite:true`\\nAfter analyzing the shader and rendering pipeline of threejs, we identified first that we needed to have proper scene-level occlusion.\\n\\nAt the scene level, Splats are just classic opaque objects with a unique drawing method. That\u2019s great because we can take advantage of the depth buffer. It\u2019s a grayscale image that shaders use to know if their pixel below or above something that was already painted. By default, splats did not write into it, causing strange artifacts when the draw order does not match the depth order. Same thing for recursive occlusion. \\n\\nSo, we [added the ability to write the rendered splats to the depth buffer](https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/dfa56ea471749e4864bfdedfcdd9c7c4aac9a656) with `depthWrite:true`. Turning it on improved our occlusion issues drastically. \\n\\n![partial-splat-compositing-progress-occlusion-with-artifacts](./splat-blog/partial-splat-compositing-progress-occlusion-with-artifacts.jpg)\\n\\n# Fixing border and edge blending issues\\nSometimes the border is not completely clean, we also wanted a way to improve it. \\n\\nIt was done this time in the fragment shader, where discarding cause the pixel not to be drawn. [We compare there for each blob\u2019s pixel their opacity, and if it\u2019s lower than our limit, it\u2019s not rendered.](https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/00d11e42f41a2adea824008ad81283001192176a)\\n\\nThis limit, the discard filter, has no effect when set to 0, but help cleanup unnecessary blobs that could ruin a proper transition between two splats. As it applies to all splat\u2019s blobs, turning it on will impact the splats quality.\\n\\n![gaussian-splat-depth-write-true-false-comparison](./splat-blog/gaussian-splat-depth-write-true-false-comparison.jpg)\\n\\nUnfortunately there is a trade off between different methods. As you can see in this next example below. On the right is the test scene with the original A-Frame splatting component that does not respect occlusion. On the left uses depthWrite which properly sorts the occlusion of the tree, fire hydrant, and flower box, but also results in artifacts especially visible on the bottom of the flower box where it meets the sidewalk.\\n\\n![splat-compare-discard-filter-0-and-0.2](./splat-blog/splat-compare-discard-filter-0-and-0.2.jpg)\\n\\nAdjusting `discardFilter` gives you control to find the right value, however as you continue to increase the `discardFilter` value approaching 1 the splats start to develop holes in the substrate and appear to be further apart. \\n\\n![splat-compare-discard-filter-0.1-and-0.3](./splat-blog/splat-compare-discard-filter-0.1-and-0.3.jpg)\\n\\nA partially effective mitigation for the artifacts is to tightly crop your splats using a tool like [SuperSplat from PlayCanvas](https://playcanvas.com/super-splat).\\n\\n# Updating the `aframe-gaussian-splatting` repository\\nIn the past we have been contributing changes directly to the [original A-Frame Gaussian Splat library by quadjr](https://github.com/quadjr/aframe-gaussian-splatting), and [Arthur has suggested a PR with these changes](https://github.com/quadjr/aframe-gaussian-splatting/pull/25), but we wanted to publish this piece before those are able to merged so we have forked this repo in the 3DStreet GitHub organization for now.\\n\\n#### GitHub: https://github.com/3dstreet/aframe-gaussian-splatting\\n\\n#### Demo scene (move around with `WASD` keys): https://3dstreet.github.io/splat-playground/basic/compositing-demo.html\\n\\n#### Demo scene source (also uses cutout entity): https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html \\n\\n# Combining rasterization methods to add splats to 3DStreet scenes\\nNow that we have support in the library for splat compositing, it\'s time to test what these look like in 3DStreet scenes.\\n\\nWe created a sample scene that loads a 3DStreet street scene with manually placed splat entities placed around the scene in appropriate locations. This was a first attempt to see how well the splats might fit in to a scene and what changes we need to make to 3DStreet Editor to support managing these with a user interface.\\n\\nThis picture shows a side-by-side view of the splat and low-poly mesh counterparts for the hybrid sedan and bus stop.\\n![3dstreet-splat-compositing-demo](./splat-blog/3dstreet-splat-compositing-demo.jpg)\\n\\nSince each of these splats are A-Frame entities, the 3DStreet Editor can provide a quick way to move them around and arrange a custom scene.\\n![3dstreet-editor-changing-scene-compositing-gaussian-splat](./splat-blog/3dstreet-editor-changing-scene-compositing-gaussian-splat.jpg)\\n\\n# Try it for yourself\\n\\nWe\'ve created a proof of concept demo showing splats that I have scanned around San Francisco, combined with polygon mesh models automatically created from 3DStreet.\\n\\n__Example scene (move around with `WASD` keys): https://github.com/3DStreet/splat-playground/__\\n\\n:::warning\\n\\nGaussian Splats in 3DStreet is a research project. Sometimes you need to reload once or twice for the splats to look better. If you\'re really adventurous press ctl + alt + i to access Editor but saving these scenes won\'t work and it will probably break. Be careful using this for real projects.\\n\\n:::\\n\\nDoes it work in WebXR? Yes, barely -- it requires a powerful device to maintain frame rate. Quest headsets and older phones have a hard time rendering this at full framerate.\\n\\n# What\'s next\\nThis is still a research technology. Even just in the past week there was a [whole new WegGL splat viewing library released by Luma AI](https://lumalabs.ai/luma-web-library) and more research on this topic seems to drop every week. Likely the method that we\'ve come up with will be replaced with a fancy new algorithm soon.\\n\\nWe\'ll keep iterating on the applications of this technology for street safety and more general urban design use cases. If this resonates with users we can explore how to make this accessible so that all users can create custom splat scenes with models they scan from their own streets.\\n\\n[Join our community to continue the conversation!](https://discord.gg/VN242sx9qu)\\n\\n# Video version of this post\\n"}]}')}}]); \ No newline at end of file diff --git a/assets/js/4200b1a9.5b66eaa4.js b/assets/js/4200b1a9.5b66eaa4.js new file mode 100644 index 00000000..02013882 --- /dev/null +++ b/assets/js/4200b1a9.5b66eaa4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[866],{4612:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","metadata":{"permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","source":"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md","title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","date":"2024-01-30T00:00:00.000Z","formattedDate":"January 30, 2024","tags":[{"label":"webxr","permalink":"/blog/tags/webxr"},{"label":"gltf","permalink":"/blog/tags/gltf"},{"label":"adobe aero","permalink":"/blog/tags/adobe-aero"},{"label":"streetmix","permalink":"/blog/tags/streetmix"},{"label":"ar","permalink":"/blog/tags/ar"},{"label":"vps","permalink":"/blog/tags/vps"},{"label":"localization","permalink":"/blog/tags/localization"}],"readingTime":4.455,"hasTruncateMarker":true,"authors":[{"name":"Marc Schlossberg","title":"Professor, City & Regional Planning, University of Oregon","url":"https://pppm.uoregon.edu/directory/profiles/all/schlossb","imageURL":"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg","key":"mschlossberg"}],"frontMatter":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","description":"End-to-end street design to augmented reality (AR) visualization workflow.","authors":"mschlossberg","tags":["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],"image":"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png","hide_table_of_contents":false},"unlisted":false,"nextItem":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade"}},"content":"![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\nGreetings! I\'m Marc Schlossberg, and I\'ve been working alongside [Danny Pimentel](https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend) and graduate student [Luke Walker](https://www.linkedin.com/in/luke-walker-439b78119/) at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let\'s roll up our sleeves and get our hands digitally dirty!\\n\\n\x3c!-- truncate --\x3e\\n\\n## Getting Started: Measuring and Designing\\n\\n![](./images/2024-01-30/lVthCNUM7YLUyBGXixqk-10.87.png)**First things first\u2014measure up!**\\n\\nTo kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It\'s okay if it\'s not pinpoint accurate \u2014 we just need a ballpark figure.\\n\\n**Crafting Your Street: Easy as Pie with Streetmix**\\n\\nOnce you\'ve got your measurements, it\'s time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart\'s content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!\\n\\n![](./images/2024-01-30/J7eHGPI8MA57Pyzgsd8i-41.61.png)For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: https://streetmix.net/schlossb/20/demo-st\\n\\n## Viewing Your Creation: 3DStreet\'s Magic\\n\\n![](./images/2024-01-30/29P0QTWEp8JbvCQ8PeH3-63.32.png)\\n\\nWith your design all set in Streetmix, it\'s time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It\'s a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st\\n\\n**Trimming the Excess for AR**\\n\\n![](./images/2024-01-30/IkXMBseXhrpqImEJSANN-73.23.png)\\n\\nTo prep for AR, you\'ll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that\'s ready for the world of augmented reality.\\n\\nTo delete a layer, select the layer in the left-hand panel -- such as \\"Buildings & Blocks Container\\" in the screenshot above -- then press the `delete` key and click `ok`. This will remove buildings and grounds from lots that are not needed for our AR project.\\n\\n## Optional Tweaks: A Blender Bonus\\n\\n![](./images/2024-01-30/kmXnEg7FMoHUxW0GgLiu-95.91.png)For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined.\\n\\n## Bringing It to Life: Augmented Reality Integration\\n\\nAlright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use [Adobe Aero](https://www.adobe.com/products/aero.html), thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the \\"quick and dirty\\" path.\\n\\n![](./images/2024-01-30/tSVcvVL1kH92J4F4ALF8-112.94.png)\\n\\nAR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet.\\n\\n**Geolocation: Pinning It to the Real World**\\n\\n![](./images/2024-01-30/M5vycvy2ClFbSLnLm6FY-133.23.png)What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it\'s not mandatory; you can always opt to apply your scene freely to any street you wish.\\n\\n![](./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png)\\n\\n## Sharing Your Vision: Universal Access\\n\\n![](./images/2024-01-30/KffxVJZ1prku9AeBBemu-158.27.png)\\n\\nOnce your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes.\\n\\n> \\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you\'ve done, and really start to reimagine, well, what would this street look like if it wasn\'t a street as has been, but is actually a park, a place for people in this particular example?\\"\\n\\n![](./images/2024-01-30/XP1Nfq1sugGz8zrILMJb-179.54.png)\\n\\n![](./images/2024-01-30/0ek0kL6ZzdbicjxigM67-181.43.png)\\n\\nTo illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design.\\n\\n## Wrapping It Up\\n\\n![](./images/2024-01-30/SjGd11l5Keu216ORRZav-189.75.png)\\n\\nAnd there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces.\\n\\nUntil next time, happy designing and thanks for joining me on this digital adventure. Bye for now!\\n\\n# Video version of this post\\n\\n"},{"id":"/2024/01/29/partner-spotlight-zade","metadata":{"permalink":"/blog/2024/01/29/partner-spotlight-zade","source":"@site/blog/2024-01-29-partner-spotlight-zade.md","title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","date":"2024-01-29T00:00:00.000Z","formattedDate":"January 29, 2024","tags":[{"label":"react","permalink":"/blog/tags/react"},{"label":"development","permalink":"/blog/tags/development"},{"label":"partner","permalink":"/blog/tags/partner"},{"label":"devshop","permalink":"/blog/tags/devshop"},{"label":"web","permalink":"/blog/tags/web"},{"label":"developer","permalink":"/blog/tags/developer"}],"readingTime":2.74,"hasTruncateMarker":true,"authors":[{"name":"Ivan Denysyuk","title":"CEO at Zade","url":"https://www.linkedin.com/in/ivan-denysyuk-171585148/","imageURL":"https://media.licdn.com/dms/image/C4E03AQFalzhqOpaXYw/profile-displayphoto-shrink_800_800/0/1650363550337?e=1712188800&v=beta&t=z1C-cetFrHoP5ao_i9cLsJmCi3quhrcZ0kmhd9OGz3s","key":"idenysyuk"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"frontMatter":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","description":"A spotlight on the contributions to 3DStreet from the software development team at Zade.","authors":["kfarr","idenysyuk"],"tags":["react","development","partner","devshop","web","developer"],"image":"https://i.imgur.com/YyKGZA7.jpeg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"},"nextItem":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},"content":"2023 marks a significant year for 3DStreet, made possible through our [talented community of contributors](https://github.com/3DStreet/3dstreet/graphs/contributors) both volunteer and paid. [Zade Agency](https://zade.agency/) fits in the latter category as a software development team for-hire based in Ukraine. Over the past year Zade emerged as a major boost to our development productivity and I wanted to share how their contributions have helped 3DStreet in a critical time for the organization.\\n\\n\x3c!-- truncate --\x3e\\n\\n### The Challenge for 3DStreet\\n\\nTo meet our timeline for a [public beta launch of 3DStreet Editor in 2023](https://www.youtube.com/watch?v=WnjtUW4J8uc), we faced several challenges. A primary concern was the gap in React expertise among our existing development team. While we are skilled in various aspects, existing React knowledge was crucial for implementing deep and rapid modifications to [3DStreet Editor](https://github.com/3DStreet/3dstreet-editor) which is a heavily modified version of the [A-Frame inspector](https://github.com/aframevr/aframe-inspector).\\n\\nAdditionally, as a [self-funded project](https://www.3dstreet.org/docs/about-3dstreet/3dstreet-llc-entity) we have very real budgetary constraints making it imperative to optimize every resource.\\n\\n### Zade\'s Solution to Boost React Development\\n\\nWe found Zade through a direct personal referral via our designer [Daria Dombrovska](https://www.linkedin.com/in/daria-dombrovska-933902207/). Zade immediately brought a wealth of React knowledge through their team of both senior and junior engineers, filling the crucial skill gap in our team.\\n\\nAs a self-trained software developer myself, I worked directly with a senior engineer at the beginning to confirm our architectural approaches and details of our tech stack. I also worked with our account manager to agree on the use of [GitHub Projects, issues, and PRs](https://github.com/orgs/3DStreet/projects/5) to manage our working relationship.\\n\\nFor day-to-day tasks I create [GitHub issues](https://github.com/3DStreet/3dstreet-editor/issues/) that are prioritized in [Projects](https://github.com/orgs/3DStreet/projects/5) and tackled via a junior engineer who is mentored by the experienced staff. Even as a junior engineer, they have way more experience in React fundamentals than I do given my [rather myopic focus on A-Frame and three.js development]() over the past decade.\\n\\n### 2023 Highlight: Launching 3DStreet Cloud\\n\\nOne of the most notable achievements in 2023 was the [launch of 3DStreet Cloud](https://www.youtube.com/watch?v=WnjtUW4J8uc), a React application using [Firebase Firestore](https://firebase.google.com/docs/firestore) on [Google Cloud Platform](https://cloud.google.com/).\\n\\n3DStreet Cloud is the foundation of the growth engine of the [3DStreet Editor product](https://3dstreet.app/) -- it is the system that allows our users to collaborate on safe street designs and fulfill our core mission.\\n\\n### Zade: Empowering Startups with React Expertise\\n\\nNow it\'s time for the pitch, because the Zade team deserves it!\\n\\nAre you an early-stage startup founder needing flexible React development solutions? Zade specializes in helping launch new startups and accelerating growth for existing ones. Their unique ecosystem is tailor-made for product development in the startup world.\\n\\n**Zade\'s Offerings:**\\n\\n- [**LaunchKit:**](https://zade.agency/launchkit/) A program designed to bring your vision to life within a month.\\n- **Integrated Team:** Seamlessly scale your startup with Zade\'s integrated design and development team.\\n\\n**Special Offer for 3DStreet Community:**\\nWhile there\'s no such thing as a free lunch in contract development, Zade extends a special offer to the 3DStreet community. Mention 3DStreet to receive a 15% discount on your first month with Zade \u2013 a deal that might just be more valuable than a few gourmet lunches, depending on your project\'s scale.\\n\\n### Connect with Zade\\n\\nInterested in learning more? Reach out to Zade at ivan@zade.agency, or contact me directly for an introduction. Let\'s embark on a journey of innovation and growth together with Zade\'s expert team!"},{"id":"/2023/12/29/new-mixed-reality-devices-impact-on-webxr","metadata":{"permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr","source":"@site/blog/2023-12-29-new-mixed-reality-devices-impact-on-webxr.md","title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","date":"2023-12-29T00:00:00.000Z","formattedDate":"December 29, 2023","tags":[{"label":"webxr","permalink":"/blog/tags/webxr"},{"label":"headset","permalink":"/blog/tags/headset"},{"label":"mixed-reality","permalink":"/blog/tags/mixed-reality"},{"label":"ar","permalink":"/blog/tags/ar"},{"label":"vr","permalink":"/blog/tags/vr"}],"readingTime":4.385,"hasTruncateMarker":true,"authors":[{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"frontMatter":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","authors":"kfarr","tags":["webxr","headset","mixed-reality","ar","vr"],"image":"./images/visionOS-platform-compressed.jpg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade"},"nextItem":{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes"}},"content":"A few weeks ago I attended a \\"developer day\\" at a local electronics company down the road featuring their new mixed reality VR headset. I spent the entire day testing many different WebXR applications with a heavy focus on evaluating which user interaction elements will be relevant for developers.\\n\\nBelow are some notes intended for other 3DStreet code contributors to reference as we work on supporting new WebXR compatible devices.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Gaze works very well as a primary user input mechanism\\nGaze interaction *\\"just works\\"* for native applications in this headset, however it\'s a privacy nightmare as gaze movement can be use to fingerprint (identify) individuals for tracking purposes, so that information isn\'t even given to native application. \\n\\nTo enable gaze user interface while not exposing gaze to the application, apps need to provide \\"hot spots\\" or hints as to areas that can be hovered. [There is a great video guide on how to adapt 2D DOM CSS website for gaze highlight interaction](https://developer.apple.com/videos/play/wwdc2023/10279/), but there\'s no clear equivalent to this CSS hinting that can be done in the WebXR \\"3D DOM\\" or 3D space. The need has been recognized however, [there is a new ticket opened in the WebXR `immersive-web` GitHub repository that I recently added to.](https://github.com/immersive-web/proposals/issues/86)\\n\\n## Hand tracking is the most accessible input, not controllers\\nImagine a world where WebXR experiences are 100% hands-free, where a simple ray from the wrist and a pitch of the hand can activate functions. This is not just a possibility but now a necessity -- going forward, all WebXR experiences must be accessible via hands first.\\n\\nWe should now regard hand tracking as the \\"lowest common denominator\\" of user input for headset experiences. Controllers will still offer higher precision, off-camera movement tracking, more button trigger inputs, etc. but they are no longer the most accessible \\"default\\" option.\\n\\n## Launching WebXR applications\\nGetting WebXR working on this device is cumbersome. WebXR must be activated by searching through multiple Safari flags (System Settings > Apps > Safari > Blah blah blah). Then, on the web page itself a user must accept 2 separate approval popups when entering WebXR mode -- one for enabling immersive mode, the other for enabling hand tracking.\\n\\nIt may be possible to \\"pull\\" some advanced users into using WebXR on these devices with instruction on feature flag setting, but it will be impossible to use WebXR on this platform to \\"push\\" more people to your WebXR experience in its present form.\\n\\n## Space, Immersion and Passthrough with WebXR\\nIn WebXR mode on the device, a scene is rendered in _Full Space_ meaning no other application windows are present, unlike native apps that can choose to run in _Shared Space_ amongst other applications. An additional limitation is that the device does not currently support WebXR with _Passthrough_ mode, therefore you cannot run WebAR apps that make use of external cameras.\\n\\n*Therefore only your WebXR scene will appear in _Full Space_ immersion mode with no _Passthrough_.* This may be desirable for traditional VR applications but not as useful for next generation mixed reality applications.\\n\\nAn additional limitation is that WebXR Immersive mode is limited to a 1.5m radius from the user-specified origin, usually where the user was located when entering XR mode. Beyond this radius the immersive scene _Full Space_ begins fading into _Passthrough_ without the scene persisting. If a user continues moving away from the origin the will see a round Safari icon at the origin point, presumably indicating that the user has an open WebXR Safari session with an origin at that point.\\n\\n## Diorama vs. Full Room Scale\\nThe [visionOS developer documentation](https://developer.apple.com/documentation/visionos/) is excellent and signals clear directions for the market.\\n\\nThe Diorama appears to be major application interface concept, [featured as a sample application](https://developer.apple.com/documentation/visionos/diorama) and a prime example of output from the new Reality Composer Pro authoring tool.\\n\\nThis is a useful concept to adopt with 3DStreet. With 3DStreet there are cases for both Diorama and Full Scale modes: some users may wish to view a scene in Full Scale life-size to get an accurate viewpoint of dimension, while other users may wish to shrink a scene down to a Diorama view to easily manipulate a large scene from a smaller workspace.\\n\\n## Combining WebXR with native applications\\n* Native applications can ask for rights such as _Passthrough_ or _Shared Space_ that are not currently accessible via Safari WebXR. It is definitely worth exploring the use of an embedded webkit-based webview in a visionOS application which may expand the ability for WebXR application to offer augmented reality experiences with a native-like experience.\\n* Reality Composer Pro looks like a powerful tool for non-developers. It is worth exploring a pipeline of 3DStreet > Reality Composer Pro > App Publishing. Therefore it is likely worth exploring tools to convert glTF exporting to USDZ format, or directly exporting the three.js / A-Frame scene into USDZ format.\\n\\n## Summary\\n* WebXR appears to be purposefully limited on this device with a degraded user experience. Consider webview or another mechanism to adapt WebXR application into a native app.\\n* Hand tracking is now a minimum requirement for WebXR apps, controllers are optional.\\n* Gaze interface is very effective but needs standardization work to enable in WebXR mode."},{"id":"/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","metadata":{"permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","source":"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md","title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","description":"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.","date":"2023-12-21T00:00:00.000Z","formattedDate":"December 21, 2023","tags":[{"label":"gaussian splats","permalink":"/blog/tags/gaussian-splats"},{"label":"splats","permalink":"/blog/tags/splats"},{"label":"photogrammetry","permalink":"/blog/tags/photogrammetry"}],"readingTime":6.345,"hasTruncateMarker":true,"authors":[{"name":"Arthur Mougin","title":"3DStreet Contributor, WebXR Developer","url":"https://github.com/arthurmougin","imageURL":"https://github.com/arthurmougin.png","key":"amougin"},{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"frontMatter":{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","description":"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.","authors":["kfarr","amougin"],"tags":["gaussian splats","splats","photogrammetry"],"image":"./splat-blog/3dstreet-splat-compositing-demo.jpg","hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},"content":"3DStreet\'s mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode.\\n\\nEnter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a [research paper published at SIGGRAPH 2023](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/). I believe splatting to be *[the best modern method](https://www.youtube.com/watch?v=HVv_IQKlafQ)* to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially [plants](https://www.youtube.com/watch?v=lowscL9YIjM), [trees](https://www.youtube.com/watch?v=hr7P8_z0PSk), flowers and other natural elements -- all things we\'d like to see more of in our streets! \\n\\n![Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques](./splat-blog/3d-mesh-vs-splat.jpg)\\n\\nThis is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet.\\n\\n\x3c!-- truncate --\x3e\\n\\n# A splatting explosion!\\nA slew of gaussian splat tools have come to market -- creation apps for 3D scanning with your phone ([Polycam](https://poly.cam/) and [Luma](https://lumalabs.ai/)) and viewers for every platform and device imaginable ([too many to list](https://github.com/tomiwaAdey/awesome-gaussian-splatting?tab=readme-ov-file#rendering-and-visualisation-tools)) and even [browser-based cropping and editing tools](https://playcanvas.com/super-splat).\\n\\nHowever, much of the existing gaussian splat research and development focuses on scenes with just one single large splat.\\n\\nWith 3DStreet we\'re exploring something new -- constructing brand new street scenes from bits and pieces of existing 3D splats.\\n\\n# The problem: multiple splats in three.js are Hard\\nIf we can draw one gaussian splat in our scene, why not more? Well it turns out it\'s Hard. Compositing wasn\u2019t supported yet by the existing three.js / A-Frame splat viewing libraries so it resulted in things just not good enough for people to use as a product, like this fire hydrant and tree being occluded by a flower box further away.\\n\\n![Picture of error in splat ordering resulting in distant objects incorrectly occluding closer objects](./splat-blog/splat-render-order-error.jpg)\\n\\nTo solve this problem, we collaborated with [Arthur Mougin, a WebXR and full stack developer](https://arthurmoug.in/) who was excited to tackle a new challenge. Here is his writeup on how we enabled proper splat sorting, concluded by some discussion on what is coming next.\\n\\n# Use depth buffer with `depthWrite:true`\\nAfter analyzing the shader and rendering pipeline of threejs, we identified first that we needed to have proper scene-level occlusion.\\n\\nAt the scene level, Splats are just classic opaque objects with a unique drawing method. That\u2019s great because we can take advantage of the depth buffer. It\u2019s a grayscale image that shaders use to know if their pixel below or above something that was already painted. By default, splats did not write into it, causing strange artifacts when the draw order does not match the depth order. Same thing for recursive occlusion. \\n\\nSo, we [added the ability to write the rendered splats to the depth buffer](https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/dfa56ea471749e4864bfdedfcdd9c7c4aac9a656) with `depthWrite:true`. Turning it on improved our occlusion issues drastically. \\n\\n![partial-splat-compositing-progress-occlusion-with-artifacts](./splat-blog/partial-splat-compositing-progress-occlusion-with-artifacts.jpg)\\n\\n# Fixing border and edge blending issues\\nSometimes the border is not completely clean, we also wanted a way to improve it. \\n\\nIt was done this time in the fragment shader, where discarding cause the pixel not to be drawn. [We compare there for each blob\u2019s pixel their opacity, and if it\u2019s lower than our limit, it\u2019s not rendered.](https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/00d11e42f41a2adea824008ad81283001192176a)\\n\\nThis limit, the discard filter, has no effect when set to 0, but help cleanup unnecessary blobs that could ruin a proper transition between two splats. As it applies to all splat\u2019s blobs, turning it on will impact the splats quality.\\n\\n![gaussian-splat-depth-write-true-false-comparison](./splat-blog/gaussian-splat-depth-write-true-false-comparison.jpg)\\n\\nUnfortunately there is a trade off between different methods. As you can see in this next example below. On the right is the test scene with the original A-Frame splatting component that does not respect occlusion. On the left uses depthWrite which properly sorts the occlusion of the tree, fire hydrant, and flower box, but also results in artifacts especially visible on the bottom of the flower box where it meets the sidewalk.\\n\\n![splat-compare-discard-filter-0-and-0.2](./splat-blog/splat-compare-discard-filter-0-and-0.2.jpg)\\n\\nAdjusting `discardFilter` gives you control to find the right value, however as you continue to increase the `discardFilter` value approaching 1 the splats start to develop holes in the substrate and appear to be further apart. \\n\\n![splat-compare-discard-filter-0.1-and-0.3](./splat-blog/splat-compare-discard-filter-0.1-and-0.3.jpg)\\n\\nA partially effective mitigation for the artifacts is to tightly crop your splats using a tool like [SuperSplat from PlayCanvas](https://playcanvas.com/super-splat).\\n\\n# Updating the `aframe-gaussian-splatting` repository\\nIn the past we have been contributing changes directly to the [original A-Frame Gaussian Splat library by quadjr](https://github.com/quadjr/aframe-gaussian-splatting), and [Arthur has suggested a PR with these changes](https://github.com/quadjr/aframe-gaussian-splatting/pull/25), but we wanted to publish this piece before those are able to merged so we have forked this repo in the 3DStreet GitHub organization for now.\\n\\n#### GitHub: https://github.com/3dstreet/aframe-gaussian-splatting\\n\\n#### Demo scene (move around with `WASD` keys): https://3dstreet.github.io/splat-playground/basic/compositing-demo.html\\n\\n#### Demo scene source (also uses cutout entity): https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html \\n\\n# Combining rasterization methods to add splats to 3DStreet scenes\\nNow that we have support in the library for splat compositing, it\'s time to test what these look like in 3DStreet scenes.\\n\\nWe created a sample scene that loads a 3DStreet street scene with manually placed splat entities placed around the scene in appropriate locations. This was a first attempt to see how well the splats might fit in to a scene and what changes we need to make to 3DStreet Editor to support managing these with a user interface.\\n\\nThis picture shows a side-by-side view of the splat and low-poly mesh counterparts for the hybrid sedan and bus stop.\\n![3dstreet-splat-compositing-demo](./splat-blog/3dstreet-splat-compositing-demo.jpg)\\n\\nSince each of these splats are A-Frame entities, the 3DStreet Editor can provide a quick way to move them around and arrange a custom scene.\\n![3dstreet-editor-changing-scene-compositing-gaussian-splat](./splat-blog/3dstreet-editor-changing-scene-compositing-gaussian-splat.jpg)\\n\\n# Try it for yourself\\n\\nWe\'ve created a proof of concept demo showing splats that I have scanned around San Francisco, combined with polygon mesh models automatically created from 3DStreet.\\n\\n__Example scene (move around with `WASD` keys): https://github.com/3DStreet/splat-playground/__\\n\\n:::warning\\n\\nGaussian Splats in 3DStreet is a research project. Sometimes you need to reload once or twice for the splats to look better. If you\'re really adventurous press ctl + alt + i to access Editor but saving these scenes won\'t work and it will probably break. Be careful using this for real projects.\\n\\n:::\\n\\nDoes it work in WebXR? Yes, barely -- it requires a powerful device to maintain frame rate. Quest headsets and older phones have a hard time rendering this at full framerate.\\n\\n# What\'s next\\nThis is still a research technology. Even just in the past week there was a [whole new WegGL splat viewing library released by Luma AI](https://lumalabs.ai/luma-web-library) and more research on this topic seems to drop every week. Likely the method that we\'ve come up with will be replaced with a fancy new algorithm soon.\\n\\nWe\'ll keep iterating on the applications of this technology for street safety and more general urban design use cases. If this resonates with users we can explore how to make this accessible so that all users can create custom splat scenes with models they scan from their own streets.\\n\\n[Join our community to continue the conversation!](https://discord.gg/VN242sx9qu)\\n\\n# Video version of this post\\n"}]}')}}]); \ No newline at end of file diff --git a/assets/js/4271b14e.bd3fa7b1.js b/assets/js/4271b14e.a48241f1.js similarity index 76% rename from assets/js/4271b14e.bd3fa7b1.js rename to assets/js/4271b14e.a48241f1.js index 2dd19e0b..e3e50cf5 100644 --- a/assets/js/4271b14e.bd3fa7b1.js +++ b/assets/js/4271b14e.a48241f1.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[2256],{8112:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/adobe-aero","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[2256],{8112:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/adobe-aero","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/486dd983.cd77351a.js b/assets/js/486dd983.349dea54.js similarity index 76% rename from assets/js/486dd983.cd77351a.js rename to assets/js/486dd983.349dea54.js index e49a9e6f..a4be19b7 100644 --- a/assets/js/486dd983.cd77351a.js +++ b/assets/js/486dd983.349dea54.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5195],{9424:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/webxr","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5195],{9424:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/webxr","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/5c6a4964.52408134.js b/assets/js/5c6a4964.ac0cb292.js similarity index 98% rename from assets/js/5c6a4964.52408134.js rename to assets/js/5c6a4964.ac0cb292.js index 85caeecf..ea9a9228 100644 --- a/assets/js/5c6a4964.52408134.js +++ b/assets/js/5c6a4964.ac0cb292.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[9352],{5836:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>n,metadata:()=>o,toc:()=>h});var a=s(5893),i=s(1151);const n={title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},r="Gaussian splats are ground-breaking visualization technology",o={permalink:"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes",source:"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md",title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",date:"2023-12-21T00:00:00.000Z",formattedDate:"December 21, 2023",tags:[{label:"gaussian splats",permalink:"/blog/tags/gaussian-splats"},{label:"splats",permalink:"/blog/tags/splats"},{label:"photogrammetry",permalink:"/blog/tags/photogrammetry"}],readingTime:6.345,hasTruncateMarker:!0,authors:[{name:"Kieran Farr",title:"Creator of 3DStreet",url:"https://github.com/kfarr",imageURL:"https://github.com/kfarr.png",key:"kfarr"},{name:"Arthur Mougin",title:"3DStreet Contributor, WebXR Developer",url:"https://github.com/arthurmougin",imageURL:"https://github.com/arthurmougin.png",key:"amougin"}],frontMatter:{title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Impact on WebXR Application Design from New Mixed Reality Headsets",permalink:"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},l={image:s(8515).Z,authorsImageUrls:[void 0,void 0]},h=[{value:"GitHub: https://github.com/3dstreet/aframe-gaussian-splatting",id:"github-httpsgithubcom3dstreetaframe-gaussian-splatting",level:4},{value:"Demo scene (move around with WASD keys): https://3dstreet.github.io/splat-playground/basic/compositing-demo.html",id:"demo-scene-move-around-with-wasd-keys-https3dstreetgithubiosplat-playgroundbasiccompositing-demohtml",level:4},{value:"Demo scene source (also uses cutout entity): https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html",id:"demo-scene-source-also-uses-cutout-entity-httpsgithubcom3dstreetsplat-playgroundblobmainbasiccompositing-demohtml",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h4:"h4",img:"img",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"3DStreet's mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode."}),"\n",(0,a.jsxs)(t.p,{children:["Enter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a ",(0,a.jsx)(t.a,{href:"https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/",children:"research paper published at SIGGRAPH 2023"}),". I believe splatting to be ",(0,a.jsx)(t.em,{children:(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=HVv_IQKlafQ",children:"the best modern method"})})," to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=lowscL9YIjM",children:"plants"}),", ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=hr7P8_z0PSk",children:"trees"}),", flowers and other natural elements -- all things we'd like to see more of in our streets!"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques",src:s(654).Z+"",width:"1000",height:"405"})}),"\n",(0,a.jsx)(t.p,{children:"This is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet."}),"\n",(0,a.jsx)(t.h1,{id:"a-splatting-explosion",children:"A splatting explosion!"}),"\n",(0,a.jsxs)(t.p,{children:["A slew of gaussian splat tools have come to market -- creation apps for 3D scanning with your phone (",(0,a.jsx)(t.a,{href:"https://poly.cam/",children:"Polycam"})," and ",(0,a.jsx)(t.a,{href:"https://lumalabs.ai/",children:"Luma"}),") and viewers for every platform and device imaginable (",(0,a.jsx)(t.a,{href:"https://github.com/tomiwaAdey/awesome-gaussian-splatting?tab=readme-ov-file#rendering-and-visualisation-tools",children:"too many to list"}),") and even ",(0,a.jsx)(t.a,{href:"https://playcanvas.com/super-splat",children:"browser-based cropping and editing tools"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"However, much of the existing gaussian splat research and development focuses on scenes with just one single large splat."}),"\n",(0,a.jsx)(t.p,{children:"With 3DStreet we're exploring something new -- constructing brand new street scenes from bits and pieces of existing 3D splats."}),"\n",(0,a.jsx)(t.h1,{id:"the-problem-multiple-splats-in-threejs-are-hard",children:"The problem: multiple splats in three.js are Hard"}),"\n",(0,a.jsx)(t.p,{children:"If we can draw one gaussian splat in our scene, why not more? Well it turns out it's Hard. Compositing wasn\u2019t supported yet by the existing three.js / A-Frame splat viewing libraries so it resulted in things just not good enough for people to use as a product, like this fire hydrant and tree being occluded by a flower box further away."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Picture of error in splat ordering resulting in distant objects incorrectly occluding closer objects",src:s(9413).Z+"",width:"592",height:"338"})}),"\n",(0,a.jsxs)(t.p,{children:["To solve this problem, we collaborated with ",(0,a.jsx)(t.a,{href:"https://arthurmoug.in/",children:"Arthur Mougin, a WebXR and full stack developer"})," who was excited to tackle a new challenge. Here is his writeup on how we enabled proper splat sorting, concluded by some discussion on what is coming next."]}),"\n",(0,a.jsxs)(t.h1,{id:"use-depth-buffer-with-depthwritetrue",children:["Use depth buffer with ",(0,a.jsx)(t.code,{children:"depthWrite:true"})]}),"\n",(0,a.jsx)(t.p,{children:"After analyzing the shader and rendering pipeline of threejs, we identified first that we needed to have proper scene-level occlusion."}),"\n",(0,a.jsx)(t.p,{children:"At the scene level, Splats are just classic opaque objects with a unique drawing method. That\u2019s great because we can take advantage of the depth buffer. It\u2019s a grayscale image that shaders use to know if their pixel below or above something that was already painted. By default, splats did not write into it, causing strange artifacts when the draw order does not match the depth order. Same thing for recursive occlusion."}),"\n",(0,a.jsxs)(t.p,{children:["So, we ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/dfa56ea471749e4864bfdedfcdd9c7c4aac9a656",children:"added the ability to write the rendered splats to the depth buffer"})," with ",(0,a.jsx)(t.code,{children:"depthWrite:true"}),". Turning it on improved our occlusion issues drastically."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"partial-splat-compositing-progress-occlusion-with-artifacts",src:s(5465).Z+"",width:"863",height:"525"})}),"\n",(0,a.jsx)(t.h1,{id:"fixing-border-and-edge-blending-issues",children:"Fixing border and edge blending issues"}),"\n",(0,a.jsx)(t.p,{children:"Sometimes the border is not completely clean, we also wanted a way to improve it."}),"\n",(0,a.jsxs)(t.p,{children:["It was done this time in the fragment shader, where discarding cause the pixel not to be drawn. ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/00d11e42f41a2adea824008ad81283001192176a",children:"We compare there for each blob\u2019s pixel their opacity, and if it\u2019s lower than our limit, it\u2019s not rendered."})]}),"\n",(0,a.jsx)(t.p,{children:"This limit, the discard filter, has no effect when set to 0, but help cleanup unnecessary blobs that could ruin a proper transition between two splats. As it applies to all splat\u2019s blobs, turning it on will impact the splats quality."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"gaussian-splat-depth-write-true-false-comparison",src:s(1685).Z+"",width:"1640",height:"516"})}),"\n",(0,a.jsx)(t.p,{children:"Unfortunately there is a trade off between different methods. As you can see in this next example below. On the right is the test scene with the original A-Frame splatting component that does not respect occlusion. On the left uses depthWrite which properly sorts the occlusion of the tree, fire hydrant, and flower box, but also results in artifacts especially visible on the bottom of the flower box where it meets the sidewalk."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"splat-compare-discard-filter-0-and-0.2",src:s(2669).Z+"",width:"1408",height:"800"})}),"\n",(0,a.jsxs)(t.p,{children:["Adjusting ",(0,a.jsx)(t.code,{children:"discardFilter"})," gives you control to find the right value, however as you continue to increase the ",(0,a.jsx)(t.code,{children:"discardFilter"})," value approaching 1 the splats start to develop holes in the substrate and appear to be further apart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"splat-compare-discard-filter-0.1-and-0.3",src:s(1681).Z+"",width:"1408",height:"800"})}),"\n",(0,a.jsxs)(t.p,{children:["A partially effective mitigation for the artifacts is to tightly crop your splats using a tool like ",(0,a.jsx)(t.a,{href:"https://playcanvas.com/super-splat",children:"SuperSplat from PlayCanvas"}),"."]}),"\n",(0,a.jsxs)(t.h1,{id:"updating-the-aframe-gaussian-splatting-repository",children:["Updating the ",(0,a.jsx)(t.code,{children:"aframe-gaussian-splatting"})," repository"]}),"\n",(0,a.jsxs)(t.p,{children:["In the past we have been contributing changes directly to the ",(0,a.jsx)(t.a,{href:"https://github.com/quadjr/aframe-gaussian-splatting",children:"original A-Frame Gaussian Splat library by quadjr"}),", and ",(0,a.jsx)(t.a,{href:"https://github.com/quadjr/aframe-gaussian-splatting/pull/25",children:"Arthur has suggested a PR with these changes"}),", but we wanted to publish this piece before those are able to merged so we have forked this repo in the 3DStreet GitHub organization for now."]}),"\n",(0,a.jsxs)(t.h4,{id:"github-httpsgithubcom3dstreetaframe-gaussian-splatting",children:["GitHub: ",(0,a.jsx)(t.a,{href:"https://github.com/3dstreet/aframe-gaussian-splatting",children:"https://github.com/3dstreet/aframe-gaussian-splatting"})]}),"\n",(0,a.jsxs)(t.h4,{id:"demo-scene-move-around-with-wasd-keys-https3dstreetgithubiosplat-playgroundbasiccompositing-demohtml",children:["Demo scene (move around with ",(0,a.jsx)(t.code,{children:"WASD"})," keys): ",(0,a.jsx)(t.a,{href:"https://3dstreet.github.io/splat-playground/basic/compositing-demo.html",children:"https://3dstreet.github.io/splat-playground/basic/compositing-demo.html"})]}),"\n",(0,a.jsxs)(t.h4,{id:"demo-scene-source-also-uses-cutout-entity-httpsgithubcom3dstreetsplat-playgroundblobmainbasiccompositing-demohtml",children:["Demo scene source (also uses cutout entity): ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html",children:"https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html"})]}),"\n",(0,a.jsx)(t.h1,{id:"combining-rasterization-methods-to-add-splats-to-3dstreet-scenes",children:"Combining rasterization methods to add splats to 3DStreet scenes"}),"\n",(0,a.jsx)(t.p,{children:"Now that we have support in the library for splat compositing, it's time to test what these look like in 3DStreet scenes."}),"\n",(0,a.jsx)(t.p,{children:"We created a sample scene that loads a 3DStreet street scene with manually placed splat entities placed around the scene in appropriate locations. This was a first attempt to see how well the splats might fit in to a scene and what changes we need to make to 3DStreet Editor to support managing these with a user interface."}),"\n",(0,a.jsxs)(t.p,{children:["This picture shows a side-by-side view of the splat and low-poly mesh counterparts for the hybrid sedan and bus stop.\n",(0,a.jsx)(t.img,{alt:"3dstreet-splat-compositing-demo",src:s(9928).Z+"",width:"960",height:"517"})]}),"\n",(0,a.jsxs)(t.p,{children:["Since each of these splats are A-Frame entities, the 3DStreet Editor can provide a quick way to move them around and arrange a custom scene.\n",(0,a.jsx)(t.img,{alt:"3dstreet-editor-changing-scene-compositing-gaussian-splat",src:s(8373).Z+"",width:"1194",height:"828"})]}),"\n",(0,a.jsx)(t.h1,{id:"try-it-for-yourself",children:"Try it for yourself"}),"\n",(0,a.jsx)(t.p,{children:"We've created a proof of concept demo showing splats that I have scanned around San Francisco, combined with polygon mesh models automatically created from 3DStreet."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsxs)(t.strong,{children:["Example scene (move around with ",(0,a.jsx)(t.code,{children:"WASD"})," keys): ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/splat-playground/",children:"https://github.com/3DStreet/splat-playground/"})]})}),"\n",(0,a.jsx)(t.admonition,{type:"warning",children:(0,a.jsx)(t.p,{children:"Gaussian Splats in 3DStreet is a research project. Sometimes you need to reload once or twice for the splats to look better. If you're really adventurous press ctl + alt + i to access Editor but saving these scenes won't work and it will probably break. Be careful using this for real projects."})}),"\n",(0,a.jsx)(t.p,{children:"Does it work in WebXR? Yes, barely -- it requires a powerful device to maintain frame rate. Quest headsets and older phones have a hard time rendering this at full framerate."}),"\n",(0,a.jsx)(t.h1,{id:"whats-next",children:"What's next"}),"\n",(0,a.jsxs)(t.p,{children:["This is still a research technology. Even just in the past week there was a ",(0,a.jsx)(t.a,{href:"https://lumalabs.ai/luma-web-library",children:"whole new WegGL splat viewing library released by Luma AI"})," and more research on this topic seems to drop every week. Likely the method that we've come up with will be replaced with a fancy new algorithm soon."]}),"\n",(0,a.jsx)(t.p,{children:"We'll keep iterating on the applications of this technology for street safety and more general urban design use cases. If this resonates with users we can explore how to make this accessible so that all users can create custom splat scenes with models they scan from their own streets."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.a,{href:"https://discord.gg/VN242sx9qu",children:"Join our community to continue the conversation!"})}),"\n",(0,a.jsx)(t.h1,{id:"video-version-of-this-post",children:"Video version of this post"}),"\n",(0,a.jsx)("iframe",{width:"580",height:"420",src:"https://www.youtube.com/embed/Fy8PefDy5VY?si=pJ7F6j_mmmA2yo31",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0})]})}function c(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8515:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},654:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3d-mesh-vs-splat-16d7a8d0df770ca631c2b903d3b62a3f.jpg"},8373:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-editor-changing-scene-compositing-gaussian-splat-9752b16f3f11e2079f946de51ceb9ad6.jpg"},9928:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},1685:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/gaussian-splat-depth-write-true-false-comparison-fa2440f90d576f4eba2e36feee1b5f98.jpg"},5465:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/partial-splat-compositing-progress-occlusion-with-artifacts-4553061baecc737b7e9029329be883ef.jpg"},2669:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-compare-discard-filter-0-and-0.2-f7b44cee1f4a98019c440e3dcf0acf88.jpg"},1681:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-compare-discard-filter-0.1-and-0.3-62e5d345a053a2838d2752379ad95fcb.jpg"},9413:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-render-order-error-b7464f2e90d5d0dc4f2679db3e4052e6.jpg"},1151:(e,t,s)=>{s.d(t,{Z:()=>o,a:()=>r});var a=s(7294);const i={},n=a.createContext(i);function r(e){const t=a.useContext(n);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[9352],{5836:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>n,metadata:()=>o,toc:()=>h});var a=s(5893),i=s(1151);const n={title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},r="Gaussian splats are ground-breaking visualization technology",o={permalink:"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes",source:"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md",title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",date:"2023-12-21T00:00:00.000Z",formattedDate:"December 21, 2023",tags:[{label:"gaussian splats",permalink:"/blog/tags/gaussian-splats"},{label:"splats",permalink:"/blog/tags/splats"},{label:"photogrammetry",permalink:"/blog/tags/photogrammetry"}],readingTime:6.345,hasTruncateMarker:!0,authors:[{name:"Arthur Mougin",title:"3DStreet Contributor, WebXR Developer",url:"https://github.com/arthurmougin",imageURL:"https://github.com/arthurmougin.png",key:"amougin"},{name:"Kieran Farr",title:"Creator of 3DStreet",url:"https://github.com/kfarr",imageURL:"https://github.com/kfarr.png",key:"kfarr"}],frontMatter:{title:"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js",description:"We share research and progress on improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding.",authors:["kfarr","amougin"],tags:["gaussian splats","splats","photogrammetry"],image:"./splat-blog/3dstreet-splat-compositing-demo.jpg",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Impact on WebXR Application Design from New Mixed Reality Headsets",permalink:"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}},l={image:s(8515).Z,authorsImageUrls:[void 0,void 0]},h=[{value:"GitHub: https://github.com/3dstreet/aframe-gaussian-splatting",id:"github-httpsgithubcom3dstreetaframe-gaussian-splatting",level:4},{value:"Demo scene (move around with WASD keys): https://3dstreet.github.io/splat-playground/basic/compositing-demo.html",id:"demo-scene-move-around-with-wasd-keys-https3dstreetgithubiosplat-playgroundbasiccompositing-demohtml",level:4},{value:"Demo scene source (also uses cutout entity): https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html",id:"demo-scene-source-also-uses-cutout-entity-httpsgithubcom3dstreetsplat-playgroundblobmainbasiccompositing-demohtml",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h4:"h4",img:"img",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"3DStreet's mission is to empower anyone to visualize safer streets. A common request to support this mission is to bring in local real-life elements from your actual streets by scanning them into 3D objects. Until now, the best technology for doing this (photogrammetry to textured 3D polygons) resulted in huge file sizes, difficult to edit output files, and gooey visuals like melting trees or cars that you may see on Google Maps in 3D mode."}),"\n",(0,a.jsxs)(t.p,{children:["Enter Gaussian Splatting -- earlier this year a groundbreaking photogrammetry and visualization technique called gaussian splatting was released as part of a ",(0,a.jsx)(t.a,{href:"https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/",children:"research paper published at SIGGRAPH 2023"}),". I believe splatting to be ",(0,a.jsx)(t.em,{children:(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=HVv_IQKlafQ",children:"the best modern method"})})," to allow everyday users like you and me to scan 3D objects with our phones and retain the fine detail of organic material especially ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=lowscL9YIjM",children:"plants"}),", ",(0,a.jsx)(t.a,{href:"https://www.youtube.com/watch?v=hr7P8_z0PSk",children:"trees"}),", flowers and other natural elements -- all things we'd like to see more of in our streets!"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Side by side picture of the same apple tree showing 3d mesh vs. gaussian splat photogrammetry techniques",src:s(654).Z+"",width:"1000",height:"405"})}),"\n",(0,a.jsx)(t.p,{children:"This is still an R&D project, not yet a supported built-in feature of 3DStreet. In this post we share research and progress on how we are improving the visual appearance of compositing new scenes from multiple splats using depth buffer and selective splat discarding in three.js and A-Frame, underlying 3D frameworks supporting 3DStreet."}),"\n",(0,a.jsx)(t.h1,{id:"a-splatting-explosion",children:"A splatting explosion!"}),"\n",(0,a.jsxs)(t.p,{children:["A slew of gaussian splat tools have come to market -- creation apps for 3D scanning with your phone (",(0,a.jsx)(t.a,{href:"https://poly.cam/",children:"Polycam"})," and ",(0,a.jsx)(t.a,{href:"https://lumalabs.ai/",children:"Luma"}),") and viewers for every platform and device imaginable (",(0,a.jsx)(t.a,{href:"https://github.com/tomiwaAdey/awesome-gaussian-splatting?tab=readme-ov-file#rendering-and-visualisation-tools",children:"too many to list"}),") and even ",(0,a.jsx)(t.a,{href:"https://playcanvas.com/super-splat",children:"browser-based cropping and editing tools"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"However, much of the existing gaussian splat research and development focuses on scenes with just one single large splat."}),"\n",(0,a.jsx)(t.p,{children:"With 3DStreet we're exploring something new -- constructing brand new street scenes from bits and pieces of existing 3D splats."}),"\n",(0,a.jsx)(t.h1,{id:"the-problem-multiple-splats-in-threejs-are-hard",children:"The problem: multiple splats in three.js are Hard"}),"\n",(0,a.jsx)(t.p,{children:"If we can draw one gaussian splat in our scene, why not more? Well it turns out it's Hard. Compositing wasn\u2019t supported yet by the existing three.js / A-Frame splat viewing libraries so it resulted in things just not good enough for people to use as a product, like this fire hydrant and tree being occluded by a flower box further away."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Picture of error in splat ordering resulting in distant objects incorrectly occluding closer objects",src:s(9413).Z+"",width:"592",height:"338"})}),"\n",(0,a.jsxs)(t.p,{children:["To solve this problem, we collaborated with ",(0,a.jsx)(t.a,{href:"https://arthurmoug.in/",children:"Arthur Mougin, a WebXR and full stack developer"})," who was excited to tackle a new challenge. Here is his writeup on how we enabled proper splat sorting, concluded by some discussion on what is coming next."]}),"\n",(0,a.jsxs)(t.h1,{id:"use-depth-buffer-with-depthwritetrue",children:["Use depth buffer with ",(0,a.jsx)(t.code,{children:"depthWrite:true"})]}),"\n",(0,a.jsx)(t.p,{children:"After analyzing the shader and rendering pipeline of threejs, we identified first that we needed to have proper scene-level occlusion."}),"\n",(0,a.jsx)(t.p,{children:"At the scene level, Splats are just classic opaque objects with a unique drawing method. That\u2019s great because we can take advantage of the depth buffer. It\u2019s a grayscale image that shaders use to know if their pixel below or above something that was already painted. By default, splats did not write into it, causing strange artifacts when the draw order does not match the depth order. Same thing for recursive occlusion."}),"\n",(0,a.jsxs)(t.p,{children:["So, we ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/dfa56ea471749e4864bfdedfcdd9c7c4aac9a656",children:"added the ability to write the rendered splats to the depth buffer"})," with ",(0,a.jsx)(t.code,{children:"depthWrite:true"}),". Turning it on improved our occlusion issues drastically."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"partial-splat-compositing-progress-occlusion-with-artifacts",src:s(5465).Z+"",width:"863",height:"525"})}),"\n",(0,a.jsx)(t.h1,{id:"fixing-border-and-edge-blending-issues",children:"Fixing border and edge blending issues"}),"\n",(0,a.jsx)(t.p,{children:"Sometimes the border is not completely clean, we also wanted a way to improve it."}),"\n",(0,a.jsxs)(t.p,{children:["It was done this time in the fragment shader, where discarding cause the pixel not to be drawn. ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/aframe-gaussian-splatting/pull/1/commits/00d11e42f41a2adea824008ad81283001192176a",children:"We compare there for each blob\u2019s pixel their opacity, and if it\u2019s lower than our limit, it\u2019s not rendered."})]}),"\n",(0,a.jsx)(t.p,{children:"This limit, the discard filter, has no effect when set to 0, but help cleanup unnecessary blobs that could ruin a proper transition between two splats. As it applies to all splat\u2019s blobs, turning it on will impact the splats quality."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"gaussian-splat-depth-write-true-false-comparison",src:s(1685).Z+"",width:"1640",height:"516"})}),"\n",(0,a.jsx)(t.p,{children:"Unfortunately there is a trade off between different methods. As you can see in this next example below. On the right is the test scene with the original A-Frame splatting component that does not respect occlusion. On the left uses depthWrite which properly sorts the occlusion of the tree, fire hydrant, and flower box, but also results in artifacts especially visible on the bottom of the flower box where it meets the sidewalk."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"splat-compare-discard-filter-0-and-0.2",src:s(2669).Z+"",width:"1408",height:"800"})}),"\n",(0,a.jsxs)(t.p,{children:["Adjusting ",(0,a.jsx)(t.code,{children:"discardFilter"})," gives you control to find the right value, however as you continue to increase the ",(0,a.jsx)(t.code,{children:"discardFilter"})," value approaching 1 the splats start to develop holes in the substrate and appear to be further apart."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"splat-compare-discard-filter-0.1-and-0.3",src:s(1681).Z+"",width:"1408",height:"800"})}),"\n",(0,a.jsxs)(t.p,{children:["A partially effective mitigation for the artifacts is to tightly crop your splats using a tool like ",(0,a.jsx)(t.a,{href:"https://playcanvas.com/super-splat",children:"SuperSplat from PlayCanvas"}),"."]}),"\n",(0,a.jsxs)(t.h1,{id:"updating-the-aframe-gaussian-splatting-repository",children:["Updating the ",(0,a.jsx)(t.code,{children:"aframe-gaussian-splatting"})," repository"]}),"\n",(0,a.jsxs)(t.p,{children:["In the past we have been contributing changes directly to the ",(0,a.jsx)(t.a,{href:"https://github.com/quadjr/aframe-gaussian-splatting",children:"original A-Frame Gaussian Splat library by quadjr"}),", and ",(0,a.jsx)(t.a,{href:"https://github.com/quadjr/aframe-gaussian-splatting/pull/25",children:"Arthur has suggested a PR with these changes"}),", but we wanted to publish this piece before those are able to merged so we have forked this repo in the 3DStreet GitHub organization for now."]}),"\n",(0,a.jsxs)(t.h4,{id:"github-httpsgithubcom3dstreetaframe-gaussian-splatting",children:["GitHub: ",(0,a.jsx)(t.a,{href:"https://github.com/3dstreet/aframe-gaussian-splatting",children:"https://github.com/3dstreet/aframe-gaussian-splatting"})]}),"\n",(0,a.jsxs)(t.h4,{id:"demo-scene-move-around-with-wasd-keys-https3dstreetgithubiosplat-playgroundbasiccompositing-demohtml",children:["Demo scene (move around with ",(0,a.jsx)(t.code,{children:"WASD"})," keys): ",(0,a.jsx)(t.a,{href:"https://3dstreet.github.io/splat-playground/basic/compositing-demo.html",children:"https://3dstreet.github.io/splat-playground/basic/compositing-demo.html"})]}),"\n",(0,a.jsxs)(t.h4,{id:"demo-scene-source-also-uses-cutout-entity-httpsgithubcom3dstreetsplat-playgroundblobmainbasiccompositing-demohtml",children:["Demo scene source (also uses cutout entity): ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html",children:"https://github.com/3DStreet/splat-playground/blob/main/basic/compositing-demo.html"})]}),"\n",(0,a.jsx)(t.h1,{id:"combining-rasterization-methods-to-add-splats-to-3dstreet-scenes",children:"Combining rasterization methods to add splats to 3DStreet scenes"}),"\n",(0,a.jsx)(t.p,{children:"Now that we have support in the library for splat compositing, it's time to test what these look like in 3DStreet scenes."}),"\n",(0,a.jsx)(t.p,{children:"We created a sample scene that loads a 3DStreet street scene with manually placed splat entities placed around the scene in appropriate locations. This was a first attempt to see how well the splats might fit in to a scene and what changes we need to make to 3DStreet Editor to support managing these with a user interface."}),"\n",(0,a.jsxs)(t.p,{children:["This picture shows a side-by-side view of the splat and low-poly mesh counterparts for the hybrid sedan and bus stop.\n",(0,a.jsx)(t.img,{alt:"3dstreet-splat-compositing-demo",src:s(9928).Z+"",width:"960",height:"517"})]}),"\n",(0,a.jsxs)(t.p,{children:["Since each of these splats are A-Frame entities, the 3DStreet Editor can provide a quick way to move them around and arrange a custom scene.\n",(0,a.jsx)(t.img,{alt:"3dstreet-editor-changing-scene-compositing-gaussian-splat",src:s(8373).Z+"",width:"1194",height:"828"})]}),"\n",(0,a.jsx)(t.h1,{id:"try-it-for-yourself",children:"Try it for yourself"}),"\n",(0,a.jsx)(t.p,{children:"We've created a proof of concept demo showing splats that I have scanned around San Francisco, combined with polygon mesh models automatically created from 3DStreet."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsxs)(t.strong,{children:["Example scene (move around with ",(0,a.jsx)(t.code,{children:"WASD"})," keys): ",(0,a.jsx)(t.a,{href:"https://github.com/3DStreet/splat-playground/",children:"https://github.com/3DStreet/splat-playground/"})]})}),"\n",(0,a.jsx)(t.admonition,{type:"warning",children:(0,a.jsx)(t.p,{children:"Gaussian Splats in 3DStreet is a research project. Sometimes you need to reload once or twice for the splats to look better. If you're really adventurous press ctl + alt + i to access Editor but saving these scenes won't work and it will probably break. Be careful using this for real projects."})}),"\n",(0,a.jsx)(t.p,{children:"Does it work in WebXR? Yes, barely -- it requires a powerful device to maintain frame rate. Quest headsets and older phones have a hard time rendering this at full framerate."}),"\n",(0,a.jsx)(t.h1,{id:"whats-next",children:"What's next"}),"\n",(0,a.jsxs)(t.p,{children:["This is still a research technology. Even just in the past week there was a ",(0,a.jsx)(t.a,{href:"https://lumalabs.ai/luma-web-library",children:"whole new WegGL splat viewing library released by Luma AI"})," and more research on this topic seems to drop every week. Likely the method that we've come up with will be replaced with a fancy new algorithm soon."]}),"\n",(0,a.jsx)(t.p,{children:"We'll keep iterating on the applications of this technology for street safety and more general urban design use cases. If this resonates with users we can explore how to make this accessible so that all users can create custom splat scenes with models they scan from their own streets."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.a,{href:"https://discord.gg/VN242sx9qu",children:"Join our community to continue the conversation!"})}),"\n",(0,a.jsx)(t.h1,{id:"video-version-of-this-post",children:"Video version of this post"}),"\n",(0,a.jsx)("iframe",{width:"580",height:"420",src:"https://www.youtube.com/embed/Fy8PefDy5VY?si=pJ7F6j_mmmA2yo31",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0})]})}function c(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8515:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},654:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3d-mesh-vs-splat-16d7a8d0df770ca631c2b903d3b62a3f.jpg"},8373:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-editor-changing-scene-compositing-gaussian-splat-9752b16f3f11e2079f946de51ceb9ad6.jpg"},9928:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/3dstreet-splat-compositing-demo-956f0b9516a47b5f42ebd24dd61de4fd.jpg"},1685:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/gaussian-splat-depth-write-true-false-comparison-fa2440f90d576f4eba2e36feee1b5f98.jpg"},5465:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/partial-splat-compositing-progress-occlusion-with-artifacts-4553061baecc737b7e9029329be883ef.jpg"},2669:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-compare-discard-filter-0-and-0.2-f7b44cee1f4a98019c440e3dcf0acf88.jpg"},1681:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-compare-discard-filter-0.1-and-0.3-62e5d345a053a2838d2752379ad95fcb.jpg"},9413:(e,t,s)=>{s.d(t,{Z:()=>a});const a=s.p+"assets/images/splat-render-order-error-b7464f2e90d5d0dc4f2679db3e4052e6.jpg"},1151:(e,t,s)=>{s.d(t,{Z:()=>o,a:()=>r});var a=s(7294);const i={},n=a.createContext(i);function r(e){const t=a.useContext(n);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/625c228a.72397e3f.js b/assets/js/625c228a.587857c6.js similarity index 76% rename from assets/js/625c228a.72397e3f.js rename to assets/js/625c228a.587857c6.js index 7b9b6ac3..e36e50e4 100644 --- a/assets/js/625c228a.72397e3f.js +++ b/assets/js/625c228a.587857c6.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6618],{9241:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/gltf","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6618],{9241:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/gltf","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/66d5ef6c.2026e58c.js b/assets/js/66d5ef6c.6f1303fa.js similarity index 66% rename from assets/js/66d5ef6c.2026e58c.js rename to assets/js/66d5ef6c.6f1303fa.js index 7b08d0a2..68f20d28 100644 --- a/assets/js/66d5ef6c.2026e58c.js +++ b/assets/js/66d5ef6c.6f1303fa.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[9228],{4087:l=>{l.exports=JSON.parse('[{"label":"webxr","permalink":"/blog/tags/webxr","count":3},{"label":"gltf","permalink":"/blog/tags/gltf","count":2},{"label":"adobe aero","permalink":"/blog/tags/adobe-aero","count":2},{"label":"streetmix","permalink":"/blog/tags/streetmix","count":2},{"label":"ar","permalink":"/blog/tags/ar","count":3},{"label":"vps","permalink":"/blog/tags/vps","count":2},{"label":"localization","permalink":"/blog/tags/localization","count":2},{"label":"react","permalink":"/blog/tags/react","count":1},{"label":"development","permalink":"/blog/tags/development","count":1},{"label":"partner","permalink":"/blog/tags/partner","count":1},{"label":"devshop","permalink":"/blog/tags/devshop","count":1},{"label":"web","permalink":"/blog/tags/web","count":1},{"label":"developer","permalink":"/blog/tags/developer","count":1},{"label":"headset","permalink":"/blog/tags/headset","count":1},{"label":"mixed-reality","permalink":"/blog/tags/mixed-reality","count":1},{"label":"vr","permalink":"/blog/tags/vr","count":1},{"label":"gaussian splats","permalink":"/blog/tags/gaussian-splats","count":1},{"label":"splats","permalink":"/blog/tags/splats","count":1},{"label":"photogrammetry","permalink":"/blog/tags/photogrammetry","count":1}]')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[9228],{4087:l=>{l.exports=JSON.parse('[{"label":"webxr","permalink":"/blog/tags/webxr","count":2},{"label":"gltf","permalink":"/blog/tags/gltf","count":1},{"label":"adobe aero","permalink":"/blog/tags/adobe-aero","count":1},{"label":"streetmix","permalink":"/blog/tags/streetmix","count":1},{"label":"ar","permalink":"/blog/tags/ar","count":2},{"label":"vps","permalink":"/blog/tags/vps","count":1},{"label":"localization","permalink":"/blog/tags/localization","count":1},{"label":"react","permalink":"/blog/tags/react","count":1},{"label":"development","permalink":"/blog/tags/development","count":1},{"label":"partner","permalink":"/blog/tags/partner","count":1},{"label":"devshop","permalink":"/blog/tags/devshop","count":1},{"label":"web","permalink":"/blog/tags/web","count":1},{"label":"developer","permalink":"/blog/tags/developer","count":1},{"label":"headset","permalink":"/blog/tags/headset","count":1},{"label":"mixed-reality","permalink":"/blog/tags/mixed-reality","count":1},{"label":"vr","permalink":"/blog/tags/vr","count":1},{"label":"gaussian splats","permalink":"/blog/tags/gaussian-splats","count":1},{"label":"splats","permalink":"/blog/tags/splats","count":1},{"label":"photogrammetry","permalink":"/blog/tags/photogrammetry","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/6d8ec5d0.54a6a317.js b/assets/js/6d8ec5d0.54a6a317.js deleted file mode 100644 index 78911bcc..00000000 --- a/assets/js/6d8ec5d0.54a6a317.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7979],{2463:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var o=a(5893),n=a(1151);const r={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},s=void 0,i={permalink:"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco",source:"@site/blog/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-02-19T00:00:00.000Z",formattedDate:"February 19, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.11,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"}},l={image:a(1350).Z,authorsImageUrls:[void 0]},d=[];function c(e){const t={img:"img",p:"p",...(0,n.a)(),...e.components};return(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:a(5117).Z+"",width:"640",height:"360"})})}function g(e={}){const{wrapper:t}={...(0,n.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1350:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},5117:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},1151:(e,t,a)=>{a.d(t,{Z:()=>i,a:()=>s});var o=a(7294);const n={},r=o.createContext(n);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bf629c2.0c878aab.js b/assets/js/7bf629c2.c57c4bac.js similarity index 78% rename from assets/js/7bf629c2.0c878aab.js rename to assets/js/7bf629c2.c57c4bac.js index 720aa839..56664225 100644 --- a/assets/js/7bf629c2.0c878aab.js +++ b/assets/js/7bf629c2.c57c4bac.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5705],{972:e=>{e.exports=JSON.parse('{"label":"adobe aero","permalink":"/blog/tags/adobe-aero","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5705],{972:e=>{e.exports=JSON.parse('{"label":"adobe aero","permalink":"/blog/tags/adobe-aero","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3e0df243.1f7b2113.js b/assets/js/7d48d4d7.7f8c6a7b.js similarity index 89% rename from assets/js/3e0df243.1f7b2113.js rename to assets/js/7d48d4d7.7f8c6a7b.js index 8dfe3493..df0b23b3 100644 --- a/assets/js/3e0df243.1f7b2113.js +++ b/assets/js/7d48d4d7.7f8c6a7b.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4683],{9093:e=>{e.exports=JSON.parse('{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","authors":[{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"imageURL":"./images/visionOS-platform-compressed.jpg","blogURL":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[5616],{9106:e=>{e.exports=JSON.parse('{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","description":"What changes should WebXR developers consider to their application given new devices coming to market?","authors":[{"name":"Kieran Farr","title":"Creator of 3DStreet","url":"https://github.com/kfarr","imageURL":"https://github.com/kfarr.png","key":"kfarr"}],"imageURL":"./images/visionOS-platform-compressed.jpg","blogURL":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr"}')}}]); \ No newline at end of file diff --git a/assets/js/83ee47c4.e41b30c4.js b/assets/js/83ee47c4.f7e0eecf.js similarity index 83% rename from assets/js/83ee47c4.e41b30c4.js rename to assets/js/83ee47c4.f7e0eecf.js index 3ed83f62..a0f5c060 100644 --- a/assets/js/83ee47c4.e41b30c4.js +++ b/assets/js/83ee47c4.f7e0eecf.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4261],{9706:s=>{s.exports=JSON.parse('{"label":"ar","permalink":"/blog/tags/ar","allTagsPath":"/blog/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4261],{9706:s=>{s.exports=JSON.parse('{"label":"ar","permalink":"/blog/tags/ar","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/8c0e532b.4565fc63.js b/assets/js/8c0e532b.68f4d1b8.js similarity index 82% rename from assets/js/8c0e532b.4565fc63.js rename to assets/js/8c0e532b.68f4d1b8.js index 297905fe..88e7f2c7 100644 --- a/assets/js/8c0e532b.4565fc63.js +++ b/assets/js/8c0e532b.68f4d1b8.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[822],{3968:s=>{s.exports=JSON.parse('{"label":"vps","permalink":"/blog/tags/vps","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[822],{3968:s=>{s.exports=JSON.parse('{"label":"vps","permalink":"/blog/tags/vps","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/95b96bb9.910a965e.js b/assets/js/95b96bb9.910a965e.js deleted file mode 100644 index a33729bf..00000000 --- a/assets/js/95b96bb9.910a965e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3561],{4577:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco","unlisted":false},{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","unlisted":false},{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade","unlisted":false},{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr","unlisted":false},{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","unlisted":false}]}')}}]); \ No newline at end of file diff --git a/assets/js/95b96bb9.df041972.js b/assets/js/95b96bb9.df041972.js new file mode 100644 index 00000000..daa22f8c --- /dev/null +++ b/assets/js/95b96bb9.df041972.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3561],{4577:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero","permalink":"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","unlisted":false},{"title":"Partner Spotlight: Zade\'s Contributions to 3DStreet in 2023","permalink":"/blog/2024/01/29/partner-spotlight-zade","unlisted":false},{"title":"Impact on WebXR Application Design from New Mixed Reality Headsets","permalink":"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr","unlisted":false},{"title":"Creating novel 3D scenes by compositing Gaussian splats with A-Frame and three.js","permalink":"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","unlisted":false}]}')}}]); \ No newline at end of file diff --git a/assets/js/98da1f4a.0a8fc8dc.js b/assets/js/98da1f4a.2fcff044.js similarity index 76% rename from assets/js/98da1f4a.0a8fc8dc.js rename to assets/js/98da1f4a.2fcff044.js index e75b4a1c..a1730672 100644 --- a/assets/js/98da1f4a.0a8fc8dc.js +++ b/assets/js/98da1f4a.2fcff044.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3895],{3371:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/localization","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3895],{3371:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/localization","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/a53f5f54.d1c25906.js b/assets/js/a53f5f54.4d371dc6.js similarity index 81% rename from assets/js/a53f5f54.d1c25906.js rename to assets/js/a53f5f54.4d371dc6.js index 1fff582e..cad51ba6 100644 --- a/assets/js/a53f5f54.d1c25906.js +++ b/assets/js/a53f5f54.4d371dc6.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7034],{1965:e=>{e.exports=JSON.parse('{"label":"webxr","permalink":"/blog/tags/webxr","allTagsPath":"/blog/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[7034],{1965:e=>{e.exports=JSON.parse('{"label":"webxr","permalink":"/blog/tags/webxr","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a7098721.65979789.js b/assets/js/a7098721.9b500676.js similarity index 75% rename from assets/js/a7098721.65979789.js rename to assets/js/a7098721.9b500676.js index 7496b64a..98203518 100644 --- a/assets/js/a7098721.65979789.js +++ b/assets/js/a7098721.9b500676.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1050],{6615:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":5,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1050],{6615:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/aaa1f5ea.aea537fc.js b/assets/js/aaa1f5ea.aea537fc.js deleted file mode 100644 index 70edce01..00000000 --- a/assets/js/aaa1f5ea.aea537fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[4474],{3903:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var n=i(5893),s=i(1151);const a={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},r=void 0,o={permalink:"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco",source:"@site/blog/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-02-19T00:00:00.000Z",formattedDate:"February 19, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.11,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero"}},l={image:i(1350).Z,authorsImageUrls:[void 0]},d=[{value:"Getting Started: Measuring and Designing",id:"getting-started-measuring-and-designing",level:2},{value:"Viewing Your Creation: 3DStreet's Magic",id:"viewing-your-creation-3dstreets-magic",level:2},{value:"Optional Tweaks: A Blender Bonus",id:"optional-tweaks-a-blender-bonus",level:2},{value:"Bringing It to Life: Augmented Reality Integration",id:"bringing-it-to-life-augmented-reality-integration",level:2},{value:"Sharing Your Vision: Universal Access",id:"sharing-your-vision-universal-access",level:2},{value:"Wrapping It Up",id:"wrapping-it-up",level:2}];function c(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",img:"img",p:"p",strong:"strong",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.h2,{id:"getting-started-measuring-and-designing",children:"Getting Started: Measuring and Designing"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(7695).Z+"",width:"640",height:"360"}),(0,n.jsx)(t.strong,{children:"First things first\u2014measure up!"})]}),"\n",(0,n.jsx)(t.p,{children:"To kick things off, you need to know how wide your street is. This is more straightforward than it sounds: just pop over to Google Street View or use an aerial photo, and get an approximate measurement. It's okay if it's not pinpoint accurate \u2014 we just need a ballpark figure."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Crafting Your Street: Easy as Pie with Streetmix"})}),"\n",(0,n.jsx)(t.p,{children:"Once you've got your measurements, it's time to jump onto Streetmix\u2014a free, user-friendly online tool that lets you reimagine that street space to your heart's content. Want to add bike lanes, benches, or green spaces? Simply drag and drop the elements you want to include, adjusting the widths to fit your street\u2019s dimensions. Here\u2019s where your creativity shines!"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(4613).Z+"",width:"640",height:"360"}),"For my project, I took a standard residential street and turned it into a car-free park, a delightful haven for community gatherings. Imagine that \u2014 but on your block! Feel free to start with the street I made - Demo St.: ",(0,n.jsx)(t.a,{href:"https://streetmix.net/schlossb/20/demo-st",children:"https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.h2,{id:"viewing-your-creation-3dstreets-magic",children:"Viewing Your Creation: 3DStreet's Magic"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(8957).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["With your design all set in Streetmix, it's time to give it a touch of 3D flair. 3DStreet is a fantastic plugin that lets you visualize your newly designed street in all its three-dimensional glory. Explore your virtual environment, tweak and tune each element until you\u2019re satisfied. It's a mini-adventure in urban planning from the comfort of your screen! You can go straight to my Demo St. in 3DStreet as well: ",(0,n.jsx)(t.a,{href:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st",children:"https://3dstreet.app/#https://streetmix.net/schlossb/20/demo-st"})]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Trimming the Excess for AR"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(366).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To prep for AR, you'll want to peel away the layers that aren\u2019t needed\u2014like buildings, to keep things neat. After simplifying, you can then export your model directly into a format that's ready for the world of augmented reality."}),"\n",(0,n.jsxs)(t.p,{children:['To delete a layer, select the layer in the left-hand panel -- such as "Buildings & Blocks Container" in the screenshot above -- then press the ',(0,n.jsx)(t.code,{children:"delete"})," key and click ",(0,n.jsx)(t.code,{children:"ok"}),". This will remove buildings and grounds from lots that are not needed for our AR project."]}),"\n",(0,n.jsx)(t.h2,{id:"optional-tweaks-a-blender-bonus",children:"Optional Tweaks: A Blender Bonus"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(3872).Z+"",width:"640",height:"360"}),"For the enthusiasts out there who relish fine-tuning, the free software Blender is your playground. Here, you can manipulate your 3D model to perfection. However, remember this is purely optional\u2014the process is meant to be quick and streamlined."]}),"\n",(0,n.jsx)(t.h2,{id:"bringing-it-to-life-augmented-reality-integration",children:"Bringing It to Life: Augmented Reality Integration"}),"\n",(0,n.jsxs)(t.p,{children:["Alright, now to the magical part\u2014transferring your 3D model to an augmented reality software. I personally use ",(0,n.jsx)(t.a,{href:"https://www.adobe.com/products/aero.html",children:"Adobe Aero"}),', thanks to the site license at the university, but there are other AR apps you can explore. This step allows you to add animations and make your scene come alive, although again, this step is not necessary for the "quick and dirty" path.']}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6092).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"AR software opens with an empty workspace and, at least in Aero, you can simply drag and drop your 3D file onto the workspace and the whole thing magically appears. In many ways it will look exactly like it did in 3DStreet."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"Geolocation: Pinning It to the Real World"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.img,{src:i(2625).Z+"",width:"640",height:"360"}),"What\u2019s truly remarkable with software like Adobe Aero is the ability to anchor your AR scene to a precise location on Earth. While this grounds your creation to a specific spot, it's not mandatory; you can always opt to apply your scene freely to any street you wish."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.h2,{id:"sharing-your-vision-universal-access",children:"Sharing Your Vision: Universal Access"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3975).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"Once your AR scene is polished and ready, you create a shareable link through Adobe Aero. Anyone with this link can open it on their mobile device, head to the designated street, and behold\u2014your digital transformation materializes before their eyes."}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"\"Your street is transformed into your scene that you can actually walk through and see what it would look like on your street, and you can go forward, backward, see all the different things that you've done, and really start to reimagine, well, what would this street look like if it wasn't a street as has been, but is actually a park, a place for people in this particular example?\""}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(7812).Z+"",width:"164",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(3543).Z+"",width:"167",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"To illustrate, envision wandering through the park that was once just a plain street\u2014all through the magic of AR. Moving forward or backward, the entire scene is interactive and truly a game-changer for community engagement and urban design."}),"\n",(0,n.jsx)(t.h2,{id:"wrapping-it-up",children:"Wrapping It Up"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(6120).Z+"",width:"165",height:"360"})}),"\n",(0,n.jsx)(t.p,{children:"And there you have it\u2014a dynamic overview of transforming streets with AR using some clever tools and a pinch of imagination. Not so intimidating now, right? With mostly free resources and a little bit of time, you can be on your way to designing, exploring, and sharing augmented realities that could pave the way for how we perceive and utilize our shared spaces."}),"\n",(0,n.jsx)(t.p,{children:"Until next time, happy designing and thanks for joining me on this digital adventure. Bye for now!"}),"\n",(0,n.jsx)(t.h1,{id:"video-version-of-this-post",children:"Video version of this post"}),"\n",(0,n.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/AP1CwWuD7uA?si=y2_qAYNtR9HpATAl",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},1350:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},3543:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/0ek0kL6ZzdbicjxigM67-181.43-22c585226e335ee1b14b58e95f808d17.png"},8957:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/29P0QTWEp8JbvCQ8PeH3-63.32-928dbe2dd89a827b1be96ce08a2405c4.png"},366:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/IkXMBseXhrpqImEJSANN-73.23-6ef8699ad042fd310f99859136492bb0.png"},4613:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/J7eHGPI8MA57Pyzgsd8i-41.61-d8f2c4d7d54a990318659f4ac3f4bdbc.png"},3975:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/KffxVJZ1prku9AeBBemu-158.27-35b296c693dca9c18355a51cd4cec663.png"},2625:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/M5vycvy2ClFbSLnLm6FY-133.23-1df718f2655ad0733ab2392a4b55bf57.png"},6120:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/SjGd11l5Keu216ORRZav-189.75-a07c9c70fba466aa3c58909d4c55a87b.png"},7812:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/XP1Nfq1sugGz8zrILMJb-179.54-ef26283fc536ad6544d4f738185a220f.png"},3872:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/kmXnEg7FMoHUxW0GgLiu-95.91-578b25b18098f554dd052bb2c580bdaa.png"},7695:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/lVthCNUM7YLUyBGXixqk-10.87-80c85fce3c339171a8196f2efa2d7431.png"},5117:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},6092:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/tSVcvVL1kH92J4F4ALF8-112.94-b8f411524c96f6c05320da8bb061eba1.png"},1151:(e,t,i)=>{i.d(t,{Z:()=>o,a:()=>r});var n=i(7294);const s={},a=n.createContext(s);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bb0bb3d0.e44acdf9.js b/assets/js/bb0bb3d0.a0b4485b.js similarity index 81% rename from assets/js/bb0bb3d0.e44acdf9.js rename to assets/js/bb0bb3d0.a0b4485b.js index 7d0041bf..0a1399d7 100644 --- a/assets/js/bb0bb3d0.e44acdf9.js +++ b/assets/js/bb0bb3d0.a0b4485b.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1173],{4050:s=>{s.exports=JSON.parse('{"label":"gltf","permalink":"/blog/tags/gltf","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1173],{4050:s=>{s.exports=JSON.parse('{"label":"gltf","permalink":"/blog/tags/gltf","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/ce36f58e.a6c77524.js b/assets/js/ce36f58e.46a76085.js similarity index 78% rename from assets/js/ce36f58e.a6c77524.js rename to assets/js/ce36f58e.46a76085.js index 6811e889..7e34a2a3 100644 --- a/assets/js/ce36f58e.a6c77524.js +++ b/assets/js/ce36f58e.46a76085.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[892],{2549:e=>{e.exports=JSON.parse('{"label":"streetmix","permalink":"/blog/tags/streetmix","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[892],{2549:e=>{e.exports=JSON.parse('{"label":"streetmix","permalink":"/blog/tags/streetmix","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d8867e84.c71c82de.js b/assets/js/d8867e84.4f83b2d6.js similarity index 75% rename from assets/js/d8867e84.c71c82de.js rename to assets/js/d8867e84.4f83b2d6.js index 36096bfd..d93077a4 100644 --- a/assets/js/d8867e84.c71c82de.js +++ b/assets/js/d8867e84.4f83b2d6.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[32],{4620:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/ar","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[32],{4620:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/ar","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/dba05362.67006002.js b/assets/js/dba05362.da0a8cd2.js similarity index 76% rename from assets/js/dba05362.67006002.js rename to assets/js/dba05362.da0a8cd2.js index 9457f107..cd91f3d9 100644 --- a/assets/js/dba05362.67006002.js +++ b/assets/js/dba05362.da0a8cd2.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3146],{1974:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/streetmix","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[3146],{1974:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/streetmix","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/e0f141dc.9219a7c3.js b/assets/js/e0f141dc.9219a7c3.js new file mode 100644 index 00000000..b13b2730 --- /dev/null +++ b/assets/js/e0f141dc.9219a7c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1677],{4004:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var n=a(5893),o=a(1151);const r={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},s=void 0,i={permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero",source:"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-01-30T00:00:00.000Z",formattedDate:"January 30, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.455,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Partner Spotlight: Zade's Contributions to 3DStreet in 2023",permalink:"/blog/2024/01/29/partner-spotlight-zade"}},l={image:a(1350).Z,authorsImageUrls:[void 0]},d=[];function g(e){const t={a:"a",img:"img",p:"p",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:a(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["Greetings! I'm Marc Schlossberg, and I've been working alongside ",(0,n.jsx)(t.a,{href:"https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend",children:"Danny Pimentel"})," and graduate student ",(0,n.jsx)(t.a,{href:"https://www.linkedin.com/in/luke-walker-439b78119/",children:"Luke Walker"})," at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let's roll up our sleeves and get our hands digitally dirty!"]})]})}function c(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(g,{...e})}):g(e)}},1350:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},5117:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},1151:(e,t,a)=>{a.d(t,{Z:()=>i,a:()=>s});var n=a(7294);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e0f141dc.c893cb19.js b/assets/js/e0f141dc.c893cb19.js deleted file mode 100644 index c3ffdf65..00000000 --- a/assets/js/e0f141dc.c893cb19.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[1677],{4004:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var n=a(5893),r=a(1151);const o={title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},s=void 0,i={permalink:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero",source:"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md",title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",date:"2024-01-30T00:00:00.000Z",formattedDate:"January 30, 2024",tags:[{label:"webxr",permalink:"/blog/tags/webxr"},{label:"gltf",permalink:"/blog/tags/gltf"},{label:"adobe aero",permalink:"/blog/tags/adobe-aero"},{label:"streetmix",permalink:"/blog/tags/streetmix"},{label:"ar",permalink:"/blog/tags/ar"},{label:"vps",permalink:"/blog/tags/vps"},{label:"localization",permalink:"/blog/tags/localization"}],readingTime:4.455,hasTruncateMarker:!0,authors:[{name:"Marc Schlossberg",title:"Professor, City & Regional Planning, University of Oregon",url:"https://pppm.uoregon.edu/directory/profiles/all/schlossb",imageURL:"https://pppm.uoregon.edu/sites/pppm1.uoregon.edu/files/uo_profiles/schlossb4d2e43.jpg",key:"mschlossberg"}],frontMatter:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",description:"End-to-end street design to augmented reality (AR) visualization workflow.",authors:"mschlossberg",tags:["webxr","gltf","adobe aero","streetmix","ar","vps","localization"],image:"./images/2024-01-30/sZPPzIEDdoKCLolneDd8-145.05.png",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Creating Augmented Reality Street Scenes with Streetmix, 3DStreet and Adobe Aero",permalink:"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco"},nextItem:{title:"Partner Spotlight: Zade's Contributions to 3DStreet in 2023",permalink:"/blog/2024/01/29/partner-spotlight-zade"}},l={image:a(1350).Z,authorsImageUrls:[void 0]},d=[];function g(e){const t={a:"a",img:"img",p:"p",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:a(5117).Z+"",width:"640",height:"360"})}),"\n",(0,n.jsxs)(t.p,{children:["Greetings! I'm Marc Schlossberg, and I've been working alongside ",(0,n.jsx)(t.a,{href:"https://journalism.uoregon.edu/directory/faculty-and-staff/all/pimend",children:"Danny Pimentel"})," and graduate student ",(0,n.jsx)(t.a,{href:"https://www.linkedin.com/in/luke-walker-439b78119/",children:"Luke Walker"})," at the University of Oregon on an exciting project: crafting augmented reality (AR) landscapes for our streets. What I have here is a practical, step-by-step guide designed to walk you through how to bring this innovative vision to your own neighborhood. So, let's roll up our sleeves and get our hands digitally dirty!"]})]})}function c(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(g,{...e})}):g(e)}},1350:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},5117:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/sZPPzIEDdoKCLolneDd8-145.05-2b18a10c24f8055f5cf44db93afee86e.png"},1151:(e,t,a)=>{a.d(t,{Z:()=>i,a:()=>s});var n=a(7294);const r={},o=n.createContext(r);function s(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2352c02.8f884e40.js b/assets/js/f2352c02.f5dda918.js similarity index 76% rename from assets/js/f2352c02.8f884e40.js rename to assets/js/f2352c02.f5dda918.js index d47616c8..ee6070f7 100644 --- a/assets/js/f2352c02.8f884e40.js +++ b/assets/js/f2352c02.f5dda918.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6346],{4913:s=>{s.exports=JSON.parse('{"label":"localization","permalink":"/blog/tags/localization","allTagsPath":"/blog/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[6346],{4913:s=>{s.exports=JSON.parse('{"label":"localization","permalink":"/blog/tags/localization","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/main.aea791ea.js b/assets/js/main.aea791ea.js deleted file mode 100644 index 69b5e830..00000000 --- a/assets/js/main.aea791ea.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.aea791ea.js.LICENSE.txt */ -(self.webpackChunk_3dstreet_docs=self.webpackChunk_3dstreet_docs||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(7294);var r=n(8356),o=n.n(r),a=n(6887);const i={"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"028a5baf":[()=>n.e(3606).then(n.bind(n,2718)),"@site/docs/3dstreet-editor/select-move-objects.md",2718],"033f20e7":[()=>n.e(7581).then(n.bind(n,4037)),"@site/docs/about-3dstreet/primary-metrics.md",4037],"0608d96f":[()=>n.e(7568).then(n.t.bind(n,7158,19)),"~blog/blog/blog-tags-vps-843-list.json",7158],"09464ff2":[()=>n.e(58).then(n.bind(n,5954)),"@site/docs/about-3dstreet/3dstreet-llc-entity.md",5954],"0afd36a3":[()=>n.e(4134).then(n.t.bind(n,5734,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-blog/blog/home-page-recent-post-metadata-0.json",5734],"0e893359":[()=>n.e(8504).then(n.bind(n,5484)),"@site/docs/about-3dstreet/3dstreet-brand-voice.md",5484],"132139d8":[()=>n.e(1617).then(n.t.bind(n,8074,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-blog/blog/home-page-recent-post-metadata-1.json",8074],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],17896441:[()=>Promise.all([n.e(532),n.e(5814),n.e(7918)]).then(n.bind(n,5154)),"@theme/DocItem",5154],"1801e2b8":[()=>n.e(3632).then(n.bind(n,5600)),"@site/docs/development/alpha-labs.md",5600],"1a0cefe5":[()=>n.e(5344).then(n.bind(n,7317)),"@site/docs/3dstreet-editor/saving-and-loading-scenes.md",7317],"1acdfdc0":[()=>n.e(7363).then(n.t.bind(n,2427,19)),"~blog/blog/blog-tags-react-575-list.json",2427],"1bc6901f":[()=>n.e(5678).then(n.t.bind(n,5366,19)),"~blog/blog/blog-tags-headset-f55-list.json",5366],"208c563b":[()=>n.e(9699).then(n.t.bind(n,7836,19)),"~blog/blog/blog-tags-devshop-d51.json",7836],"22c4de1a":[()=>n.e(9477).then(n.bind(n,3112)),"@site/blog/2024-01-29-partner-spotlight-zade.md",3112],"29a92f7f":[()=>n.e(8227).then(n.bind(n,3884)),"@site/docs/viewer-and-editor.md",3884],"2f6a2918":[()=>n.e(6479).then(n.t.bind(n,4925,19)),"~blog/blog/blog-tags-web-0e7.json",4925],"3117c1dd":[()=>n.e(645).then(n.t.bind(n,7344,19)),"~blog/blog/blog-tags-partner-59d-list.json",7344],"397d6e43":[()=>n.e(7116).then(n.t.bind(n,3835,19)),"~docs/default/category-docs-tutorialsidebar-category-3-dstreet-editor-3f3.json",3835],"39b3d978":[()=>n.e(1217).then(n.bind(n,718)),"@site/docs/about-3dstreet/overview-vision-mission.md",718],"3a4e56ec":[()=>n.e(6839).then(n.t.bind(n,6706,19)),"~blog/blog/blog-tags-mixed-reality-3b5-list.json",6706],"3accc24b":[()=>n.e(4506).then(n.t.bind(n,5789,19)),"~blog/blog/blog-tags-vr-617-list.json",5789],"3b085c01":[()=>n.e(7700).then(n.bind(n,8903)),"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md",8903],"3be0e09c":[()=>n.e(7781).then(n.t.bind(n,1294,19)),"~blog/blog/blog-tags-partner-59d.json",1294],"3d85b4f0":[()=>n.e(6297).then(n.bind(n,5707)),"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md?truncated=true",5707],"3e0df243":[()=>n.e(4683).then(n.t.bind(n,9093,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-blog/blog/home-page-recent-post-metadata-3.json",9093],"3fd68248":[()=>n.e(9411).then(n.bind(n,7732)),"@site/docs/pricing.md",7732],"4200b1a9":[()=>n.e(866).then(n.t.bind(n,4612,19)),"~blog/blog/blog-archive-80c.json",4612],"4271b14e":[()=>n.e(2256).then(n.t.bind(n,8112,19)),"~blog/blog/blog-tags-adobe-aero-a10-list.json",8112],"4313cb3d":[()=>n.e(3247).then(n.t.bind(n,4157,19)),"~blog/blog/blog-tags-development-9e5-list.json",4157],"45067d2a":[()=>n.e(7727).then(n.bind(n,2786)),"@site/docs/tutorial-streetmix-to-3dstreet/create-or-remix-a-street-in-streetmix.md",2786],"486dd983":[()=>n.e(5195).then(n.t.bind(n,9424,19)),"~blog/blog/blog-tags-webxr-587-list.json",9424],"4d54d076":[()=>n.e(7080).then(n.bind(n,4651)),"@site/docs/contributing.md",4651],"519b3ca2":[()=>n.e(4117).then(n.t.bind(n,493,19)),"~blog/blog/blog-tags-splats-4d6-list.json",493],"556ed81e":[()=>n.e(5433).then(n.t.bind(n,5847,19)),"~blog/blog/blog-tags-photogrammetry-028-list.json",5847],"5a908ff0":[()=>n.e(3005).then(n.t.bind(n,5804,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",5804],"5c6a4964":[()=>n.e(9352).then(n.bind(n,5836)),"@site/blog/2023-12-21-gaussian-splat-compositing-for-constructed-street-scenes.md",5836],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5f654dc4":[()=>n.e(9389).then(n.bind(n,2233)),"@site/docs/tutorial-streetmix-to-3dstreet/convert-streetmix-street-to-3dstreet-scene.md",2233],"5fbda0ee":[()=>n.e(6065).then(n.t.bind(n,666,19)),"~blog/blog/blog-tags-react-575.json",666],"625c228a":[()=>n.e(6618).then(n.t.bind(n,9241,19)),"~blog/blog/blog-tags-gltf-828-list.json",9241],"66d5ef6c":[()=>n.e(9228).then(n.t.bind(n,4087,19)),"~blog/blog/blog-tags-tags-4c2.json",4087],"6875c492":[()=>Promise.all([n.e(532),n.e(5814),n.e(130),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"6d8ec5d0":[()=>n.e(7979).then(n.bind(n,2463)),"@site/blog/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md?truncated=true",2463],"71f35c7b":[()=>n.e(7664).then(n.t.bind(n,7876,19)),"~docs/default/category-docs-tutorialsidebar-category-development-8c5.json",7876],"7bf629c2":[()=>n.e(5705).then(n.t.bind(n,972,19)),"~blog/blog/blog-tags-adobe-aero-a10.json",972],"7d48d4d7":[()=>n.e(5616).then(n.t.bind(n,9106,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-blog/blog/home-page-recent-post-metadata-2.json",9106],"821a9d98":[()=>n.e(1291).then(n.t.bind(n,6995,19)),"~blog/blog/blog-tags-mixed-reality-3b5.json",6995],"8222faa6":[()=>n.e(3689).then(n.t.bind(n,9215,19)),"~blog/blog/blog-tags-gaussian-splats-029.json",9215],"83ee47c4":[()=>n.e(4261).then(n.t.bind(n,9706,19)),"~blog/blog/blog-tags-ar-c05.json",9706],"8c0e532b":[()=>n.e(822).then(n.t.bind(n,3968,19)),"~blog/blog/blog-tags-vps-843.json",3968],"8cebf530":[()=>n.e(2026).then(n.t.bind(n,538,19)),"~blog/blog/blog-tags-developer-c5c.json",538],"93171db4":[()=>n.e(1293).then(n.t.bind(n,3769,19)),"/home/runner/work/3dstreet-docs/3dstreet-docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"934d83b9":[()=>n.e(668).then(n.bind(n,2591)),"@site/docs/3dstreet-editor/overview-3dstreet-editor.md",2591],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,4577,19)),"~blog/blog/blog-post-list-prop-blog.json",4577],"96213d3b":[()=>n.e(2612).then(n.bind(n,6585)),"@site/blog/2024-01-29-partner-spotlight-zade.md?truncated=true",6585],"989ae605":[()=>n.e(8895).then(n.bind(n,3891)),"@site/docs/services.md",3891],"98da1f4a":[()=>n.e(3895).then(n.t.bind(n,3371,19)),"~blog/blog/blog-tags-localization-d34-list.json",3371],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],a01e980f:[()=>n.e(3563).then(n.t.bind(n,3133,19)),"~docs/default/category-docs-tutorialsidebar-category-tutorial-use-streetmix-to-create-a-3-dstreet-scene-a20.json",3133],a53f5f54:[()=>n.e(7034).then(n.t.bind(n,1965,19)),"~blog/blog/blog-tags-webxr-587.json",1965],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(5814),n.e(130),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a7098721:[()=>n.e(1050).then(n.t.bind(n,6615,19)),"~blog/blog/blog-c06.json",6615],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a90c6a58:[()=>n.e(94).then(n.bind(n,4304)),"@site/docs/tutorial-streetmix-to-3dstreet/create-a-streetmix-account.md",4304],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],aaa1f5ea:[()=>n.e(4474).then(n.bind(n,3903)),"@site/blog/2024-02-19-staff-pick-burrito-plan-for-valencia-street-san-francisco.md",3903],aad6ee88:[()=>n.e(598).then(n.t.bind(n,9303,19)),"~blog/blog/blog-tags-web-0e7-list.json",9303],b3418349:[()=>n.e(5971).then(n.bind(n,7129)),"@site/blog/2023-12-29-new-mixed-reality-devices-impact-on-webxr.md?truncated=true",7129],b6414427:[()=>n.e(8294).then(n.t.bind(n,9527,19)),"~blog/blog/blog-tags-development-9e5.json",9527],b7c60316:[()=>n.e(2730).then(n.t.bind(n,4195,19)),"~blog/blog/blog-tags-photogrammetry-028.json",4195],b9a4dd4f:[()=>n.e(1260).then(n.bind(n,9559)),"@site/docs/3dstreet-editor/layers-properties-panels.md",9559],baf4a824:[()=>n.e(487).then(n.t.bind(n,2020,19)),"~blog/blog/blog-tags-vr-617.json",2020],bb0bb3d0:[()=>n.e(1173).then(n.t.bind(n,4050,19)),"~blog/blog/blog-tags-gltf-828.json",4050],bbbbbb57:[()=>n.e(4489).then(n.t.bind(n,5898,19)),"~blog/blog/blog-tags-gaussian-splats-029-list.json",5898],bc475eff:[()=>n.e(4493).then(n.t.bind(n,6501,19)),"~blog/blog/blog-tags-headset-f55.json",6501],bc76ba0b:[()=>n.e(6952).then(n.bind(n,4544)),"@site/docs/development/releases.md",4544],c0a6d427:[()=>n.e(5565).then(n.bind(n,8087)),"@site/docs/development/overview-developer-documentation.md",8087],c24d0ff5:[()=>n.e(1147).then(n.t.bind(n,2224,19)),"~blog/blog/blog-tags-devshop-d51-list.json",2224],c377a04b:[()=>n.e(6971).then(n.bind(n,9925)),"@site/docs/index.md",9925],c56ca243:[()=>n.e(3826).then(n.bind(n,5408)),"@site/docs/about-3dstreet/user-personas.md",5408],ccc49370:[()=>Promise.all([n.e(532),n.e(5814),n.e(130),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],cd9e707e:[()=>n.e(5958).then(n.bind(n,3734)),"@site/blog/2023-12-29-new-mixed-reality-devices-impact-on-webxr.md",3734],ce36f58e:[()=>n.e(892).then(n.t.bind(n,2549,19)),"~blog/blog/blog-tags-streetmix-c85.json",2549],d0cf7135:[()=>n.e(2072).then(n.t.bind(n,4081,19)),"~docs/default/category-docs-tutorialsidebar-category-about-3-dstreet-38b.json",4081],d7c9acd4:[()=>n.e(3336).then(n.bind(n,1750)),"@site/docs/tutorial-streetmix-to-3dstreet/congratulations.md",1750],d8867e84:[()=>n.e(32).then(n.t.bind(n,4620,19)),"~blog/blog/blog-tags-ar-c05-list.json",4620],da28a654:[()=>n.e(8366).then(n.t.bind(n,437,19)),"~blog/blog/blog-tags-developer-c5c-list.json",437],dba05362:[()=>n.e(3146).then(n.t.bind(n,1974,19)),"~blog/blog/blog-tags-streetmix-c85-list.json",1974],dd986bc4:[()=>n.e(1321).then(n.bind(n,8090)),"@site/docs/tutorial-streetmix-to-3dstreet/overview-streetmix-3dstreet.md",8090],e0f141dc:[()=>n.e(1677).then(n.bind(n,4004)),"@site/blog/2024-01-30-creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero.md?truncated=true",4004],e720b24b:[()=>Promise.all([n.e(532),n.e(4711),n.e(5134)]).then(n.bind(n,3421)),"@site/src/components/Home/index.js",3421],f1d6b137:[()=>n.e(7909).then(n.bind(n,1978)),"@site/docs/3dstreet-editor/save-export-scene.md",1978],f2352c02:[()=>n.e(6346).then(n.t.bind(n,4913,19)),"~blog/blog/blog-tags-localization-d34.json",4913],f31fa0a9:[()=>n.e(6426).then(n.t.bind(n,9944,19)),"~blog/blog/blog-tags-splats-4d6.json",9944]};var l=n(5893);function s(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(t)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(9670),u=n(226);function d(e,t){if("*"===e)return o()({loading:s,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,l.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:s,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const l=n.split(".");l.slice(0,-1).forEach((e=>{i=i[e]})),i[l[l.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;return delete o.__context,(0,l.jsx)(u.z,{value:i,children:(0,l.jsx)(a,{...o,...n})})}})}const p=[{path:"/blog",component:d("/blog","279"),exact:!0},{path:"/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes",component:d("/blog/2023/12/21/gaussian-splat-compositing-for-constructed-street-scenes","43f"),exact:!0},{path:"/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr",component:d("/blog/2023/12/29/new-mixed-reality-devices-impact-on-webxr","5fa"),exact:!0},{path:"/blog/2024/01/29/partner-spotlight-zade",component:d("/blog/2024/01/29/partner-spotlight-zade","71e"),exact:!0},{path:"/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero",component:d("/blog/2024/01/30/creating-augmented-reality-ar-scenes-with-streetmix-3dstreet-adobe-aero","8ec"),exact:!0},{path:"/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco",component:d("/blog/2024/02/19/staff-pick-burrito-plan-for-valencia-street-san-francisco","2b1"),exact:!0},{path:"/blog/archive",component:d("/blog/archive","641"),exact:!0},{path:"/blog/tags",component:d("/blog/tags","442"),exact:!0},{path:"/blog/tags/adobe-aero",component:d("/blog/tags/adobe-aero","96e"),exact:!0},{path:"/blog/tags/ar",component:d("/blog/tags/ar","f41"),exact:!0},{path:"/blog/tags/developer",component:d("/blog/tags/developer","866"),exact:!0},{path:"/blog/tags/development",component:d("/blog/tags/development","7d5"),exact:!0},{path:"/blog/tags/devshop",component:d("/blog/tags/devshop","592"),exact:!0},{path:"/blog/tags/gaussian-splats",component:d("/blog/tags/gaussian-splats","906"),exact:!0},{path:"/blog/tags/gltf",component:d("/blog/tags/gltf","9ca"),exact:!0},{path:"/blog/tags/headset",component:d("/blog/tags/headset","7ca"),exact:!0},{path:"/blog/tags/localization",component:d("/blog/tags/localization","db9"),exact:!0},{path:"/blog/tags/mixed-reality",component:d("/blog/tags/mixed-reality","962"),exact:!0},{path:"/blog/tags/partner",component:d("/blog/tags/partner","f12"),exact:!0},{path:"/blog/tags/photogrammetry",component:d("/blog/tags/photogrammetry","888"),exact:!0},{path:"/blog/tags/react",component:d("/blog/tags/react","3fe"),exact:!0},{path:"/blog/tags/splats",component:d("/blog/tags/splats","46a"),exact:!0},{path:"/blog/tags/streetmix",component:d("/blog/tags/streetmix","1c9"),exact:!0},{path:"/blog/tags/vps",component:d("/blog/tags/vps","6b6"),exact:!0},{path:"/blog/tags/vr",component:d("/blog/tags/vr","342"),exact:!0},{path:"/blog/tags/web",component:d("/blog/tags/web","f01"),exact:!0},{path:"/blog/tags/webxr",component:d("/blog/tags/webxr","2a0"),exact:!0},{path:"/docs",component:d("/docs","05a"),routes:[{path:"/docs",component:d("/docs","b75"),routes:[{path:"/docs",component:d("/docs","d63"),routes:[{path:"/docs/",component:d("/docs/","a8c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/3dstreet-editor/layers-properties-panels",component:d("/docs/3dstreet-editor/layers-properties-panels","510"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/3dstreet-editor/overview-3dstreet-editor",component:d("/docs/3dstreet-editor/overview-3dstreet-editor","d0d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/3dstreet-editor/save-export-scene",component:d("/docs/3dstreet-editor/save-export-scene","e5d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/3dstreet-editor/saving-and-loading-scenes",component:d("/docs/3dstreet-editor/saving-and-loading-scenes","074"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/3dstreet-editor/select-move-objects",component:d("/docs/3dstreet-editor/select-move-objects","c37"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/about-3dstreet/3dstreet-brand-voice",component:d("/docs/about-3dstreet/3dstreet-brand-voice","b5f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/about-3dstreet/3dstreet-llc-entity",component:d("/docs/about-3dstreet/3dstreet-llc-entity","ac8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/about-3dstreet/overview-vision-mission",component:d("/docs/about-3dstreet/overview-vision-mission","1ad"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/about-3dstreet/primary-metrics",component:d("/docs/about-3dstreet/primary-metrics","c66"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/about-3dstreet/user-personas",component:d("/docs/about-3dstreet/user-personas","9bb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/3dstreet-editor",component:d("/docs/category/3dstreet-editor","d62"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/about-3dstreet",component:d("/docs/category/about-3dstreet","ed1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/development",component:d("/docs/category/development","089"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/tutorial-use-streetmix-to-create-a-3dstreet-scene",component:d("/docs/category/tutorial-use-streetmix-to-create-a-3dstreet-scene","da8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contributing",component:d("/docs/contributing","ff2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/development/alpha-labs",component:d("/docs/development/alpha-labs","67e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/development/overview-developer-documentation",component:d("/docs/development/overview-developer-documentation","508"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/development/releases",component:d("/docs/development/releases","192"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/pricing",component:d("/docs/pricing","a8a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/services",component:d("/docs/services","064"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tutorial-streetmix-to-3dstreet/congratulations",component:d("/docs/tutorial-streetmix-to-3dstreet/congratulations","fd3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tutorial-streetmix-to-3dstreet/convert-streetmix-street-to-3dstreet-scene",component:d("/docs/tutorial-streetmix-to-3dstreet/convert-streetmix-street-to-3dstreet-scene","9fb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tutorial-streetmix-to-3dstreet/create-a-streetmix-account",component:d("/docs/tutorial-streetmix-to-3dstreet/create-a-streetmix-account","642"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tutorial-streetmix-to-3dstreet/create-or-remix-a-street-in-streetmix",component:d("/docs/tutorial-streetmix-to-3dstreet/create-or-remix-a-street-in-streetmix","3a6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tutorial-streetmix-to-3dstreet/overview-streetmix-3dstreet",component:d("/docs/tutorial-streetmix-to-3dstreet/overview-streetmix-3dstreet","53e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/viewer-and-editor",component:d("/docs/viewer-and-editor","c43"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/",component:d("/","6de"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>i});var r=n(7294),o=n(5893);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),o=n(745),a=n(3727),i=n(405),l=n(412);const s=[n(6657),n(2497),n(3310),n(8320),n(9337),n(9517)];var c=n(723),u=n(6550),d=n(8790),p=n(5893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(5742),m=n(2263),h=n(4996),b=n(6668),y=n(1944),v=n(4711),w=n(9727),k=n(3320),x=n(8780),S=n(197);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,m.Z)(),r=(0,v.l)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(g.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,m.Z)(),{pathname:r}=(0,u.TH)();return e+(0,x.applyTrailingSlash)((0,h.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function C(){const{i18n:{currentLocale:e}}=(0,m.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(_,{}),(0,p.jsx)(E,{}),(0,p.jsx)(S.Z,{tag:k.HX,locale:e}),(0,p.jsx)(g.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function j(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940),N=n(469);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,N.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),R("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class D extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(P,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const I=D,M="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(9670);const K=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!K.has(e))(e))return!1;K.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(W).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),O(e))},te=Object.freeze(ee),ne=Boolean(!0);if(l.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(a.VK,{children:(0,p.jsx)(V,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},l=()=>{if(ne)r.startTransition((()=>{o.hydrateRoot(e,t,{onRecoverableError:n})}));else{const a=o.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{a.render(t)}))}};O(window.location.pathname).then(l)}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(7294),o=n(6809);const a=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-T65XPDLZ3F"],"anonymizeIP":false,"id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"3dstreet-editor/layers-properties-panels","path":"/docs/3dstreet-editor/layers-properties-panels","sidebar":"tutorialSidebar"},{"id":"3dstreet-editor/overview-3dstreet-editor","path":"/docs/3dstreet-editor/overview-3dstreet-editor","sidebar":"tutorialSidebar"},{"id":"3dstreet-editor/save-export-scene","path":"/docs/3dstreet-editor/save-export-scene","sidebar":"tutorialSidebar"},{"id":"3dstreet-editor/saving-and-loading-scenes","path":"/docs/3dstreet-editor/saving-and-loading-scenes","sidebar":"tutorialSidebar"},{"id":"3dstreet-editor/select-move-objects","path":"/docs/3dstreet-editor/select-move-objects","sidebar":"tutorialSidebar"},{"id":"about-3dstreet/3dstreet-brand-voice","path":"/docs/about-3dstreet/3dstreet-brand-voice","sidebar":"tutorialSidebar"},{"id":"about-3dstreet/3dstreet-llc-entity","path":"/docs/about-3dstreet/3dstreet-llc-entity","sidebar":"tutorialSidebar"},{"id":"about-3dstreet/overview-vision-mission","path":"/docs/about-3dstreet/overview-vision-mission","sidebar":"tutorialSidebar"},{"id":"about-3dstreet/primary-metrics","path":"/docs/about-3dstreet/primary-metrics","sidebar":"tutorialSidebar"},{"id":"about-3dstreet/user-personas","path":"/docs/about-3dstreet/user-personas","sidebar":"tutorialSidebar"},{"id":"contributing","path":"/docs/contributing","sidebar":"tutorialSidebar"},{"id":"development/alpha-labs","path":"/docs/development/alpha-labs","sidebar":"tutorialSidebar"},{"id":"development/overview-developer-documentation","path":"/docs/development/overview-developer-documentation","sidebar":"tutorialSidebar"},{"id":"development/releases","path":"/docs/development/releases","sidebar":"tutorialSidebar"},{"id":"index","path":"/docs/","sidebar":"tutorialSidebar"},{"id":"pricing","path":"/docs/pricing","sidebar":"tutorialSidebar"},{"id":"services","path":"/docs/services","sidebar":"tutorialSidebar"},{"id":"tutorial-streetmix-to-3dstreet/congratulations","path":"/docs/tutorial-streetmix-to-3dstreet/congratulations","sidebar":"tutorialSidebar"},{"id":"tutorial-streetmix-to-3dstreet/convert-streetmix-street-to-3dstreet-scene","path":"/docs/tutorial-streetmix-to-3dstreet/convert-streetmix-street-to-3dstreet-scene","sidebar":"tutorialSidebar"},{"id":"tutorial-streetmix-to-3dstreet/create-a-streetmix-account","path":"/docs/tutorial-streetmix-to-3dstreet/create-a-streetmix-account","sidebar":"tutorialSidebar"},{"id":"tutorial-streetmix-to-3dstreet/create-or-remix-a-street-in-streetmix","path":"/docs/tutorial-streetmix-to-3dstreet/create-or-remix-a-street-in-streetmix","sidebar":"tutorialSidebar"},{"id":"tutorial-streetmix-to-3dstreet/overview-streetmix-3dstreet","path":"/docs/tutorial-streetmix-to-3dstreet/overview-streetmix-3dstreet","sidebar":"tutorialSidebar"},{"id":"viewer-and-editor","path":"/docs/viewer-and-editor","sidebar":"tutorialSidebar"},{"id":"/category/3dstreet-editor","path":"/docs/category/3dstreet-editor","sidebar":"tutorialSidebar"},{"id":"/category/tutorial-use-streetmix-to-create-a-3dstreet-scene","path":"/docs/category/tutorial-use-streetmix-to-create-a-3dstreet-scene","sidebar":"tutorialSidebar"},{"id":"/category/development","path":"/docs/category/development","sidebar":"tutorialSidebar"},{"id":"/category/about-3dstreet","path":"/docs/category/about-3dstreet","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/","label":"index"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"3.0.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.1"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"3.0.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.1"},"docusaurus-plugin-content-blog":{"type":"project"}}}');var c=n(5893);const u={siteConfig:o.default,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(412),a=n(5742),i=n(8780),l=n(6040),s=n(5893);function c(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,s.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,s.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,s.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)(f,{fallback:()=>(0,s.jsx)(c,{error:t,tryAgain:n}),children:[(0,s.jsx)(a.Z,{children:(0,s.jsx)("title",{children:"Page Error"})}),(0,s.jsx)(l.Z,{children:(0,s.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,s.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(405),o=n(5893);function a(e){return(0,o.jsx)(r.ql,{...e})}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(3727),a=n(8780),i=n(2263),l=n(3919),s=n(412),c=n(5893);const u=r.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,i.Z)(),{withBaseUrl:k}=(0,d.C)(),x=(0,r.useContext)(u),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const E=p||f;const _=(0,l.Z)(E),C=E?.replace("pathname://","");let T=void 0!==C?(j=C,b&&(e=>e.startsWith("/"))(j)?k(j):j):void 0;var j;T&&_&&(T=(0,a.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const L=(0,r.useRef)(!1),A=n?o.OL:o.rU,N=s.Z.canUseIntersectionObserver,R=(0,r.useRef)(),P=()=>{L.current||null==T||(window.docusaurus.preload(T),L.current=!0)};(0,r.useEffect)((()=>(!N&&_&&null!=T&&window.docusaurus.prefetch(T),()=>{N&&R.current&&R.current.disconnect()})),[R,T,N,_]);const O=T?.startsWith("#")??!1,D=!T||!_||O;return D||h||x.collectLink(T),D?(0,c.jsx)("a",{ref:S,href:T,...E&&!_&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,c.jsx)(A,{...y,onMouseEnter:P,onTouchStart:P,innerRef:e=>{S.current=e,N&&e&&_&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),R.current.observe(e))},to:T,...n&&{isActive:m,activeClassName:g}})}const f=r.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>s});var r=n(7294),o=n(5893);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(7529);function l(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(l({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=l({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),o=n(2263),a=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8940);function a(){return(0,r.useContext)(o._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8934);function a(){return(0,r.useContext)(o._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const o=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const l=o?`${o}.${a}`:a;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>i});var r=n(7294),o=n(5893);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),l=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:l,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>m,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>g,gB:()=>f});var r=n(6550),o=n(2263),a=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function f(e){return d(e).versions}function g(e){const t=d(e);return l(t)}function m(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6657:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("set","page_path",t.pathname+t.search+t.hash),window.gtag("event","page_view")}))}}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(2573),o=n(6809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(7294);var r=n(512),o=n(5999),a=n(6668),i=n(9960);const l={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var s=n(5893);function c(e){let{as:t,id:n,...c}=e;const{navbar:{hideOnScroll:u}}=(0,a.L)();if("h1"===t||!n)return(0,s.jsx)(t,{...c,id:void 0});const d=(0,o.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,s.jsxs)(t,{...c,className:(0,r.Z)("anchor",u?l.anchorWithHideOnScrollNavbar:l.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,s.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(5893);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},6040:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ft});var r=n(7294),o=n(512),a=n(4763),i=n(1944),l=n(6550),s=n(5999),c=n(5936),u=n(5893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,s.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var h=n(5281),b=n(9727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(m,{className:y.skipToContent})}var w=n(6668),k=n(9689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,s.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function j(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),a&&(0,u.jsx)(E,{onClick:n,className:T.announcementBarClose})]})}var L=n(2961),A=n(2466);var N=n(902),R=n(3102);const P=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,L.e)(),t=(0,R.HY)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,N.D9)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(P.Provider,{value:n,children:t})}function D(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function I(){const e=(0,r.useContext)(P);if(!e)throw new N.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,R.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:D(a)})),[o,a,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=I();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(2949),z=n(2389);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,z.Z)(),l=(0,s.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,s.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(q),Z={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function G(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,F.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?Z.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var V=n(1327);function W(){return(0,u.jsx)(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Q(){const e=(0,L.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,s.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(W,{}),(0,u.jsx)(G,{className:"margin-right--md"}),(0,u.jsx)(Q,{})]})}var K=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:l,prependBaseUrlToHref:s,...c}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=a&&o&&!(0,J.Z)(o),m=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,g&&(0,u.jsx)(te.Z,{...l&&{width:12,height:12}})]})};return o?(0,u.jsx)(K.Z,{href:s?f:o,...c,...m}):(0,u.jsx)(K.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...c,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.Z)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(6043),le=n(8596),se=n(2263);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:i,...l}=e;const s=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[s]),(0,u.jsxs)("div",{ref:s,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,o.Z)("navbar__link",a),...l,onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:l.children??l.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(_e,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:i,...s}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&g(!d)}),[c,d,g]),(0,u.jsxs)("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.Z)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...s,onClick:e=>{e.preventDefault(),f()},children:s.children??s.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(_e,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var ge=n(4711);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";var be=n(1875);const ye={navbarSearchContainer:"navbarSearchContainer_Bca1"};function ve(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.Z)(n,ye.navbarSearchContainer),children:t})}var we=n(143),ke=n(2802);var xe=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.Z)(),p=(0,ge.l)(),{search:f,hash:g}=(0,l.TH)(),m=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],h=t?(0,s.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(me,{className:he}),h]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(ve,{className:n,children:(0,u.jsx)(be.Z,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.Z)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.Iw)(r),i=(0,ke.vY)(t,r),l=a?.path===i?.path;return null===i||i.unlisted&&!l?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>l||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.Iw)(r),i=(0,ke.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,ke.lO)(r)[0],i=t??a.label,l=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:l})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:c,hash:d}=(0,l.TH)(),p=(0,we.Iw)(n),f=(0,we.gB)(n),{savePreferredVersionName:g}=(0,xe.J)(n),m=[...o,...f.map((e=>{const t=p.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...a],h=(0,ke.lO)(n)[0],b=t&&m.length>1?(0,s.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,y=t&&m.length>1?void 0:Se(h).path;return m.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:b,to:y,items:m,isActive:r?()=>!1:void 0})}};function _e(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function Ce(){const e=(0,L.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(_e,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Te(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(s.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function je(){const e=0===(0,w.L)().navbar.items.length,t=I();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Te,{onClick:()=>t.hide()}),t.content]})}function Le(){const e=(0,L.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(Ce,{}),secondaryMenu:(0,u.jsx)(je,{})}):null}const Ae={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ne(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.Z)("navbar-sidebar__backdrop",e.className)})}function Re(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.L)(),i=(0,L.e)(),{navbarRef:l,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,A.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:l,"aria-label":(0,s.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Ae.navbarHideable,!d&&Ae.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ne,{onClick:i.toggle}),(0,u.jsx)(Le,{})]})}var Pe=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function De(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Ie(e){let{error:t}=e;const n=(0,Pe.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Oe.errorBoundaryError,children:n})}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Fe="right";function ze(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function Be(){const{toggle:e,shown:t}=(0,L.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(ze,{})})}const $e={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Me,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(_e,{...e})},t)))})}function qe(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function He(){const e=(0,L.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Fe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(qe,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(Be,{}),(0,u.jsx)(W,{}),(0,u.jsx)(Ue,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ue,{items:r}),(0,u.jsx)(G,{className:$e.colorModeToggle}),!o&&(0,u.jsx)(ve,{children:(0,u.jsx)(be.Z,{})})]})})}function Ze(){return(0,u.jsx)(Re,{children:(0,u.jsx)(He,{})})}function Ge(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,l=(0,X.Z)(n),s=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(K.Z,{className:"footer__link-item",...r?{href:a?s:r}:{to:l},...i,children:[o,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function Ve(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(Ge,{item:t})},t.href??t.to)}function We(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(Ve,{item:e},t)))})]})}function Qe(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(We,{column:e},t)))})}function Ye(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Ke(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(Ge,{item:t})}function Xe(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(Ke,{item:e}),t.length!==n+1&&(0,u.jsx)(Ye,{})]},n)))})})}function Je(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(Qe,{columns:t}):(0,u.jsx)(Xe,{links:t})}var et=n(9965);const tt={footerLogoLink:"footerLogoLink_BH7S"};function nt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(et.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function rt(e){let{logo:t}=e;return t.href?(0,u.jsx)(K.Z,{href:t.href,className:tt.footerLogoLink,target:t.target,children:(0,u.jsx)(nt,{logo:t})}):(0,u.jsx)(nt,{logo:t})}function ot(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function it(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(at,{style:o,links:n&&n.length>0&&(0,u.jsx)(Je,{links:n}),logo:r&&(0,u.jsx)(rt,{logo:r}),copyright:t&&(0,u.jsx)(ot,{copyright:t})})}const lt=r.memo(it),st=(0,N.Qc)([F.S,k.pl,A.OC,xe.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(R.n2,{children:(0,u.jsx)(L.M,{children:(0,u.jsx)(O,{children:t})})})}]);function ct(e){let{children:t}=e;return(0,u.jsx)(st,{children:t})}var ut=n(2503);function dt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(ut.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(s.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(De,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Ie,{error:t})})]})})})}const pt={mainWrapper:"mainWrapper_z2l0"};function ft(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,b.t)(),(0,u.jsxs)(ct,{children:[(0,u.jsx)(i.d,{title:l,description:s}),(0,u.jsx)(v,{}),(0,u.jsx)(j,{}),(0,u.jsx)(Ze,{}),(0,u.jsx)("div",{id:d,className:(0,o.Z)(h.k.wrapper.main,pt.mainWrapper,r),children:(0,u.jsx)(a.Z,{fallback:e=>(0,u.jsx)(dt,{...e}),children:t})}),!n&&(0,u.jsx)(lt,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(9960),o=n(4996),a=n(2263),i=n(6668),l=n(9965),s=n(5893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Z)(t.src),dark:(0,o.Z)(t.srcDark||t.src)},i=(0,s.jsx)(l.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,s.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.Z)(),{navbar:{title:n,logo:l}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.Z)(l?.href||"/"),g=n?"":t,m=l?.alt??g;return(0,s.jsxs)(r.Z,{to:f,...p,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(c,{logo:l,alt:m,imageClassName:u}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(5742),o=n(5893);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.Z,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),o=n(512),a=n(2389),i=n(2949);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(5893);function c(e){let{className:t,children:n}=e;const c=(0,a.Z)(),{colorMode:u}=(0,i.I)();return(0,s.jsx)(s.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.Z)(t,l.themedComponent,l[`themedComponent--${e}`])});return(0,s.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,s.jsx)(c,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,s.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(7294),o=n(412),a=n(469),i=n(1442),l=n(5893);const s="ease-in-out";function c(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??s}`,height:`${t}px`}}function l(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function g(e){if(!o.Z.canUseDOM)return e?u:d}function m(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:s,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,l.jsx)(t,{ref:u,style:c?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:s,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[s,c]=(0,r.useState)(t);return(0,a.Z)((()=>{t||i(!0)}),[t]),(0,a.Z)((()=>{o&&c(t)}),[o,t]),o?(0,l.jsx)(m,{...n,collapsed:s}):null}function b(e){let{lazy:t,...n}=e;const r=t?h:m;return(0,l.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>g});var r=n(7294),o=n(2389),a=n(12),i=n(902),l=n(6668),s=n(5893);const c=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,o.Z)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(f.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>h});var r=n(7294),o=n(412),a=n(902),i=n(12),l=n(6668),s=n(5893);const c=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{d.set(f(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[o,a]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&m(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[o,i])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b});var r=n(7294),o=n(143),a=n(9935),i=n(6668),l=n(2802),s=n(902),c=n(12),u=n(5893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=r.createContext(null);function m(){const e=(0,o._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,l]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return(0,u.jsx)(g.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return l.cE?(0,u.jsx)(h,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(g);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=a.m);const t=(0,o.zh)(e),[n,i]=y(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>s});var r=n(7294),o=n(902),a=n(5893);const i=Symbol("EmptyContext"),l=r.createContext(i);function s(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(l.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new o.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>s,q:()=>l});var r=n(7294),o=n(902),a=n(5893);const i=r.createContext(null);function l(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new o.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>g});var r=n(7294),o=n(3102),a=n(7524),i=n(6550),l=n(902);function s(e){!function(e){const t=(0,i.k6)(),n=(0,l.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668),u=n(5893);const d=r.createContext(void 0);function p(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function f(e){let{children:t}=e;const n=p();return(0,u.jsx)(d.Provider,{value:n,children:t})}function g(){const e=r.useContext(d);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>c,n2:()=>l});var r=n(7294),o=n(902),a=n(5893);const i=r.createContext(null);function l(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,l]=a,s=(0,o.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(7294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>l});var r=n(7294),o=n(412);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){const[e,t]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){t(function(){if(!o.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?a.desktop:a.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>T,LM:()=>g,_F:()=>y,cE:()=>p,jA:()=>m,xz:()=>f,SN:()=>C,lO:()=>S,vY:()=>_,oz:()=>E,s1:()=>x,f:()=>w});var r=n(7294),o=n(6550),a=n(8790),i=n(143),l=n(373),s=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function g(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=g(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,o.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function k(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function x(){const e=(0,c.V)(),{pathname:t}=(0,o.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function S(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),o=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,o].filter(Boolean))),[t,n,o])}function E(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function _(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function C(e){let{route:t}=e;const n=(0,o.TH)(),r=(0,s.E)(),i=t.routes,l=i.find((e=>(0,o.LX)(n.pathname,e)));if(!l)return null;const c=l.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,a.H)(i),sidebarName:c,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!g(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>g});var r=n(7294),o=n(512),a=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2263);var u=n(5893);function d(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const l=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=o?d(o,{absolute:!0}):void 0;return(0,u.jsxs)(a.Z,{children:[t&&(0,u.jsx)("title",{children:l}),t&&(0,u.jsx)("meta",{property:"og:title",content:l}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),l=(0,o.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:l,children:[(0,u.jsx)(a.Z,{children:(0,u.jsx)("html",{className:l})}),n]})}function g(e){let{children:t}=e;const n=l(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,o.Z)(r,a),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>l,Qc:()=>u,Ql:()=>c,i6:()=>s,zX:()=>i});var r=n(7294),o=n(469),a=n(5893);function i(e){const t=(0,r.useRef)(e);return(0,o.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function l(e){const t=(0,r.useRef)();return(0,o.Z)((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),o=n(723),a=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>c,RF:()=>p});var r=n(7294),o=n(412),a=n(2389),i=(n(469),n(902)),l=n(5893);const s=r.createContext(void 0);function c(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(s.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const d=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(d()),a=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>o});n(2263);const r="default";function o(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294);const r="localStorage";function o(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function a(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=a(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),o=n(6550),a=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.Z)(),{pathname:s}=(0,o.TH)(),c=(0,a.applyTrailingSlash)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),o=n(6550),a=n(902);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[o]=e.split(/[#?]/),a="/"===o||o===r?o:(i=o,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(o,a)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}});var a=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>j,Ep:()=>p});var r=n(7462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&o(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var l=n(8776);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,m(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var o=f(n);o&&o!==g&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),m=s(n),h=0;h{"use strict";e.exports=function(e,t,n,r,o,a,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,a,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},9517:(e,t,n)=>{"use strict";n.r(t)},9337:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),c=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),l=e?"-100":a(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var g=e[i],m=n[2],h=n[3],b=n[4],y=n[5],v=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=m&&null!=g&&g!==m,x="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||u,_=b||y;r.push({name:h||a++,prefix:m||"",delimiter:E,optional:S,repeat:x,partial:k,asterisk:!!w,pattern:_?c(_):w?".*":"[^"+s(E)+"]+?"})}}return i{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),o=n(9642),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),a.add(e)}))}i.silent=!1,e.exports=i},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,l=i.length;-1!==n.code.indexOf(o=t(r,l));)++l;return i[l]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=a.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),g=p.indexOf(f);if(g>-1){++o;var m=p.substring(0,g),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(g+f.length),y=[];m&&y.push.apply(y,i([m])),y.push(h),b&&y.push.apply(y,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(Prism)},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},6500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in o(t,a),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),g=u;o(g);){for(var m in p={},g){var h=s[m];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var y in f(b))if(y in u){p[b]=!0;break}for(var v in g=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var a=o?o.series:void 0,i=o?o.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));a?o=a(p,(function(){return r(e)})):r(e)}return l[e]=o}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(3840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n