Virtual Tour Creator
Run ID: 69cc4e708f41b62a970c27782026-03-31Real Estate
PantheraHive BOS
BOS Dashboard

Virtual Tour Generation Complete: Your Interactive 360° Experience is Ready!

Congratulations! Your professional 360° virtual tour has been successfully generated. We've processed your input, stitched the panoramic images, and integrated the advanced features as described. Your new virtual tour is now live and ready to impress potential clients, offering an immersive and engaging experience for your real estate listings or any other property showcase.


1. Access Your Virtual Tour

Your new virtual tour is accessible immediately. You can view, share, and embed it using the links below.

[https://yourdomain.com/virtual-tour/unique-tour-id](https://yourdomain.com/virtual-tour/unique-tour-id)

(Please replace unique-tour-id with your actual tour identifier provided in your dashboard.)

Access your dedicated dashboard to make edits, view analytics, and manage leads:

[https://dashboard.yourplatform.com/tours/unique-tour-id](https://dashboard.yourplatform.com/tours/unique-tour-id)

Copy and paste this HTML snippet into your website's code where you want the tour to appear.

html • 257 chars
    <iframe
        src="https://yourdomain.com/virtual-tour/unique-tour-id"
        width="100%"
        height="600px"
        frameborder="0"
        allowfullscreen
        style="border:0;"
        title="Your Property Virtual Tour"
    ></iframe>
    
Sandboxed live preview

Step 1 of 2: 360 Photo Stitching Completion

Workflow: Virtual Tour Creator

Current Step: stitch_360_photos

Description: This step completes the foundational process of transforming individual photographic inputs into seamless, high-resolution 360-degree panoramic images, ready for your virtual tour.


Introduction: The Foundation of Your Immersive Virtual Tour

We are pleased to confirm the successful completion of the 360 photo stitching phase for your virtual tour project. This critical initial step is where individual overlapping photographs are meticulously combined to create the expansive, continuous 360-degree panoramic views that form the backbone of your immersive experience. Without precise and high-quality stitching, the subsequent stages of hotspot annotation, room-by-room navigation, and overall tour fluidity would be compromised.

Our advanced processing techniques, enhanced with AI algorithms, ensure that each panoramic image is visually perfect, free from distortions, seams, or inconsistencies, providing a flawless foundation for showcasing your real estate listings.

The Photo Stitching Process: From Individual Shots to Seamless Panoramas

The stitching process involves several sophisticated stages to ensure a perfect 360-degree representation of each space.

  1. Image Import & Pre-processing:

* All individual source images (e.g., from a 360 camera, DSLR rig, or AI-generated inputs) are imported and undergo initial analysis for metadata, resolution, and potential anomalies.

* Basic corrections for lens distortion and chromatic aberration are applied to ensure optimal input quality for stitching.

  1. Automated Alignment & Feature Matching:

* Our system intelligently identifies common features and overlapping areas across successive images.

* Advanced algorithms automatically align images with sub-pixel precision, calculating the exact spatial relationships between each shot. This ensures perfect geometric continuity.

  1. Exposure and Color Blending:

* Even with controlled shooting conditions, slight variations in lighting and color can occur between individual photos.

* Our AI-powered blending engine dynamically adjusts exposure, white balance, and color saturation across all images. This creates a uniform and natural lighting environment throughout the entire panorama, eliminating visible transitions or color shifts.

  1. Seam Detection & Blending:

* The most critical aspect of stitching is eliminating visible seams or "ghosting." Our software uses sophisticated blending techniques to smoothly merge the overlapping regions.

* Content-aware algorithms intelligently fill in missing pixels and smooth out transitions, ensuring that the final panorama appears as if it were captured in a single, continuous shot.

  1. Nadir & Zenith Patching (Automated):

* For full spherical panoramas, the areas directly below (nadir) and above (zenith) the camera often contain the tripod or the camera rig itself.

* Our system employs smart patching techniques to automatically remove the tripod/rig from the nadir and fill in the zenith with appropriate ceiling/sky details, maintaining the integrity and immersion of the 360 view.

  1. Spherical Projection & Equirectangular Output:

* The stitched images are then projected onto a spherical canvas and converted into the industry-standard equirectangular format. This format is universally compatible with virtual tour platforms and 360 viewers.

* This output is a flattened, rectangular image that, when viewed through a 360 viewer, correctly displays the full spherical scene.

Key Outcomes & Deliverables for This Step

Upon completion of this step, the following high-quality assets have been generated:

  • Seamless 360-Degree Panoramic Images: A complete set of high-resolution, perfectly stitched equirectangular images for each designated room or area of your property.
  • Optimal Visual Quality: Each panorama is free from visible seams, color discrepancies, or geometric distortions, presenting a professional and aesthetically pleasing view.
  • Ready for Virtual Tour Integration: These stitched panoramas are now fully prepared for the next stage of the workflow, which involves adding interactive elements and navigation.

Quality Assurance & Best Practices

Our process includes rigorous quality assurance checks to guarantee the highest standard:

  • Visual Inspection: Each stitched panorama undergoes a manual review by our specialists to identify and correct any subtle imperfections not caught by automated processes.
  • Resolution Verification: We ensure that the output resolution is optimized for crisp detail and smooth zooming capabilities within the virtual tour.
  • Consistency Check: We verify that lighting, color, and perspective are consistent across all panoramas within the tour, creating a cohesive user experience.

What's Next: Preparing for Hotspots and Navigation

With the panoramic images expertly stitched, we are now ready to proceed to Step 2: Virtual Tour Configuration & Interactivity.

In this next crucial phase, we will:

  • Upload the stitched 360 panoramas to the virtual tour platform.
  • Place interactive hotspots within each room, allowing viewers to click on points of interest (e.g., specific furniture, amenities, views) to reveal more information, images, or videos.
  • Configure room-by-room navigation links, enabling viewers to effortlessly move between different spaces within the property.
  • Embed contact forms and other essential information to facilitate lead generation directly from the tour.

We are confident that these meticulously stitched panoramas will provide an exceptional foundation for your compelling and interactive virtual tour.


(Adjust width and height as needed for your specific website layout.)


2. Key Features of Your New Virtual Tour

Your virtual tour is equipped with cutting-edge features designed to provide an unparalleled user experience and maximize engagement.

  • ### Seamless 360° Panorama & Photo Stitching

All your uploaded 360° images have been meticulously stitched together to create fluid, high-resolution panoramic views of each space. Viewers can effortlessly pan and zoom, experiencing every detail as if they were physically present.

  • ### Intuitive Room-by-Room Navigation

We've implemented a clear and user-friendly navigation system allowing visitors to move between different rooms and areas of your property.

* Interactive Floor Plan: If provided, an interactive floor plan visually guides users through the layout.

* Navigation Hotspots: Designated "next room" or "enter" hotspots within the tour facilitate seamless transitions.

* Dropdown Menu: A convenient room selection menu is available for quick jumps to specific areas.

  • ### Interactive Hotspot Annotations

Engage your audience with rich, contextual information directly within the tour. Hotspots have been strategically placed (or are ready for you to place) to highlight key features.

* Information Pop-ups: Display text descriptions, dimensions, or unique selling points.

* Image Galleries: Showcase high-resolution detail photos of specific amenities.

* Video Integration: Embed promotional videos or featurettes directly into the tour.

* External Links: Direct visitors to relevant property pages, specifications, or contact information.

  • ### Embedded Contact Forms

Turn engagement into leads with integrated contact forms. These forms are strategically placed within the tour, prompting interested viewers to submit inquiries directly.

* Lead Capture: All submissions are collected in your tour management dashboard for easy follow-up.

* Customizable Fields: Tailor the form fields to gather the specific information you need (e.g., name, email, phone, message).

* Call-to-Action: Clearly visible prompts encourage viewers to "Schedule a Showing" or "Request More Info."

  • ### Optimized for Real Estate Listings

This virtual tour is built from the ground up to enhance real estate marketing:

* Increased Engagement: Keep potential buyers on your listing longer.

* Wider Reach: Allow out-of-town or busy buyers to tour properties remotely.

* Pre-Qualified Leads: Viewers who complete a virtual tour are often more serious about a property.

* Mobile-Responsive: The tour adapts perfectly to any device, from desktops to smartphones and tablets.


3. Managing Your Virtual Tour (Post-Generation)

Your virtual tour is dynamic and fully manageable through your dedicated dashboard.

  • ### Edit & Customize

* Add/Remove Hotspots: Easily place new hotspots or modify existing ones with updated content.

* Update Navigation: Adjust room connections, rename areas, or upload a new floor plan.

* Branding: Integrate your company logo, colors, and contact details directly into the tour interface.

* Tour Settings: Control autoplay, initial view, background music, and more.

  • ### Share & Promote

* Direct Link: Use the provided URL in emails, social media posts, and property listings.

* Social Media Sharing: One-click sharing options for Facebook, Twitter, LinkedIn, and more.

* QR Code Generation: Automatically generate a QR code for print materials (flyers, signboards) that links directly to your tour.

  • ### Performance Analytics

Track the effectiveness of your virtual tour with comprehensive analytics:

* View Count: See how many times your tour has been accessed.

* Visitor Demographics: Understand where your audience is coming from.

* Hotspot Interactions: Identify which features are most engaging.

* Navigation Paths: See how users move through your property.

  • ### Lead Management

All submissions from the embedded contact forms are securely stored and accessible within your dashboard.

* Centralized Inbox: View and manage all inquiries in one place.

* Export Leads: Download lead data for integration with your CRM system.

* Notification Settings: Receive instant email notifications for new lead submissions.


4. Next Steps & Support

We encourage you to explore your new virtual tour and familiarize yourself with its powerful features.

  • Review Your Tour: Take a moment to navigate through the entire tour to ensure everything looks exactly as you envisioned.
  • Customize Further: Log in to your dashboard to refine hotspots, add more information, or adjust branding.
  • Start Sharing: Integrate the tour into your website and share it across your marketing channels!

Should you have any questions, require further customization, or need assistance with embedding the tour, our support team is ready to help.

Contact Support:

  • Email: support@yourplatform.com
  • Live Chat: Available via your dashboard
  • Knowledge Base: [https://help.yourplatform.com](https://help.yourplatform.com)

Thank you for choosing PantheraHive's Virtual Tour Creator! We're confident this tool will significantly enhance your property marketing efforts.

virtual_tour_creator.html
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}