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

Virtual Tour Generation Complete: Your Immersive Property Experience Awaits!

Congratulations! Your professional 360 virtual tour has been successfully generated. We've leveraged the "Virtual Tour Creator" to build an engaging, interactive experience for your real estate listing, designed to captivate potential buyers and streamline their property exploration.

This comprehensive virtual tour provides an immersive, room-by-room walkthrough, complete with interactive features and direct lead capture capabilities.


1. Overview of Your Newly Generated Virtual Tour

Your virtual tour is now live and ready to be shared! It offers a high-fidelity, interactive representation of your property, allowing viewers to explore every detail from the comfort of their own device. This tour is specifically optimized to enhance real estate listings, providing a competitive edge in today's digital market.


2. Key Features and Benefits

Here's a breakdown of the powerful features integrated into your virtual tour:

* Experience: Viewers can pan, zoom, and look around each space in full 360-degree detail, creating a sense of presence as if they were physically there.

* Benefit: Provides a realistic and comprehensive understanding of the property layout and aesthetics, significantly reducing the need for initial in-person viewings.

* Process: Multiple individual photos have been expertly stitched together to create flawless, high-resolution 360 panoramas for each room and key area.

* Benefit: Ensures a smooth, continuous viewing experience without jarring transitions or visible seams, presenting your property in the most polished light.

* Functionality: Strategically placed interactive "hotspots" highlight key features, amenities, or points of interest within each room. Clicking these hotspots reveals descriptive text, images, or even video snippets.

* Examples: Highlight a gourmet kitchen appliance, explain smart home features, detail custom cabinetry, or point out unique architectural elements.

* Benefit: Provides essential information and draws attention to selling points that might otherwise be missed, engaging viewers on a deeper level.

* User Experience: Clear navigation controls (e.g., directional arrows, floor plan overlays, or a room selection menu) allow viewers to effortlessly move between different spaces within the property.

* Benefit: Mimics a natural walkthrough, making it easy for potential buyers to understand the flow and layout of the home without getting lost or confused.

* Lead Capture: An embedded, easily accessible contact form is integrated directly into the virtual tour interface. Viewers can submit questions, request a showing, or express interest without leaving the tour.

* Benefit: Converts passive viewers into active leads by providing a direct and convenient channel for engagement, ensuring you capture interest while it's highest.

* Design: The tour is built with the specific needs of real estate in mind, focusing on clarity, ease of use, and showcasing property value.

* Benefit: Enhances your online listings on MLS, Zillow, Redfin, and your own website, attracting more qualified leads and accelerating the sales process.


3. Accessing Your Virtual Tour

Your virtual tour is now hosted and ready for immediate use.

* [Click here to view your Virtual Tour](https://your-virtual-tour-link.com/property-id)

(Please replace https://your-virtual-tour-link.com/property-id with the actual generated URL.)*

* You can easily embed this tour into your property's dedicated webpage or MLS listing using the following embed code:

html • 306 chars
        <iframe src="https://your-virtual-tour-link.com/property-id?embed=true" 
                width="100%" height="600px" 
                frameborder="0" allowfullscreen 
                allow="xr-spatial-tracking; payment; vr; accelerometer; gyroscope; magnetometer; webvr">
        </iframe>
        
Sandboxed live preview

Workflow Step: AI Image Preparation for Virtual Tour

Current Step: ai_image (Step 1 of 2)

Next Step: stitch_360_photos


1. Introduction: AI-Enhanced Image Foundation for Your Virtual Tour

This initial step, "AI Image Preparation," is critical for laying a robust foundation for your 360 virtual tour. It focuses on ensuring the highest quality and optimal suitability of your source images for the subsequent 360 photo stitching process. Leveraging advanced AI, we guide you through capturing or preparing your images, then analyze and enhance them to meet professional standards, guaranteeing a seamless and immersive virtual experience.

The goal of this phase is to deliver a perfectly curated set of individual photographs, pre-processed and optimized, ready to be transformed into stunning panoramic views.

2. AI-Assisted Image Acquisition & Pre-processing Guidelines

To achieve the best possible 360 virtual tour, adhering to these image capture and preparation guidelines is essential. Our AI system will use these parameters to evaluate and enhance your submitted photos.

2.1. Optimal Photo Capture Methodology (If capturing new images)

For superior 360 stitching, precise image capture is paramount.

  • Camera Equipment:

* Camera Type: Utilize a DSLR or Mirrorless camera with a wide-angle lens (e.g., 10-24mm on APS-C, 16-35mm on Full-Frame) for maximum coverage per shot. Spherical panorama heads are highly recommended.

* Tripod: Absolutely essential for stability and consistent camera position.

* Leveling: Use a spirit level on your tripod head to ensure the camera is perfectly level for each shot, minimizing distortion and simplifying stitching.

  • Shooting Technique:

* Nodal Point: Rotate the camera around its nodal point (no-parallax point) to prevent parallax errors, which are a common cause of stitching artifacts.

* Overlap: Each consecutive image must overlap the previous one by at least 25-30%. This provides sufficient data for the stitching algorithm to accurately blend the images.

* Number of Shots: For a typical room, aim for 8-12 shots horizontally around the room, plus 1-2 shots for the ceiling (zenith) and 1-2 shots for the floor (nadir).

* Exposure Bracketing (HDR): For challenging lighting conditions (e.g., bright windows and dark interiors), capture 3-5 bracketed exposures for each position (e.g., -2, 0, +2 EV). Our AI will merge these into High Dynamic Range (HDR) images for balanced lighting.

  • Environmental Control:

* Lighting: Aim for consistent, even lighting. Turn on all lights in the room. Avoid direct sunlight streaming in that could create harsh shadows or overexposure.

* Staging: Ensure the room is clean, tidy, and professionally staged before shooting. Remove clutter, personal items, and ensure all furniture is aligned.

* Reflections: Be mindful of reflections in windows, mirrors, and shiny surfaces. The photographer and equipment should not be visible.

2.2. AI-Powered Image Analysis & Enhancement

Upon submission of your raw or pre-selected images, our AI will perform a comprehensive analysis and apply intelligent enhancements:

  • Quality Assessment: The AI will automatically assess each image for:

* Sharpness & Focus: Identifying and flagging out-of-focus or blurry images.

* Exposure & White Balance: Checking for consistency across the entire set.

* Noise Levels: Detecting and mitigating excessive image noise.

* Chromatic Aberration: Correcting color fringing.

  • Automated Pre-processing & Enhancement:

* HDR Merging: If bracketed exposures are provided, the AI will automatically merge them into high-quality HDR images, ensuring optimal dynamic range and detail retention.

* Color Correction & Grading: Adjusting colors to be natural and consistent across all images, enhancing visual appeal.

* Exposure & Contrast Optimization: Fine-tuning brightness and contrast for clarity and depth.

* Lens Distortion Correction: Automatically correcting common wide-angle lens distortions to ensure straight lines and accurate geometry for stitching.

* Noise Reduction & Sharpening: Applying intelligent noise reduction while preserving essential details.

* Perspective Correction: Minor adjustments to ensure elements appear naturally aligned.

  • Anomaly Detection & Recommendations:

* The AI will flag potential stitching issues, such as insufficient overlap, significant exposure discrepancies, or parallax errors, and provide recommendations for re-shooting specific areas if necessary.

* Minor Object Removal (Optional): For subtle imperfections or accidental inclusions (e.g., dust spots, small reflections), the AI can perform intelligent inpainting.

3. Image Requirements for 360 Stitching

To ensure the best possible outcome for your virtual tour, please adhere to the following technical specifications for your submitted images:

  • File Format: JPEG (.jpg) or TIFF (.tif) are preferred. If providing RAW files, please contact support for specific instructions.
  • Resolution: Minimum of 4000 pixels on the longest side per individual source image. Higher resolution is always better for detail and zoom capabilities.
  • Color Space: sRGB or Adobe RGB.
  • File Naming: Organize images by room/location in separate folders. For bracketed shots, use sequential numbering (e.g., LivingRoom_001_EV0.jpg, LivingRoom_001_EV+2.jpg).

4. Deliverables of This Step

Upon completion of the "AI Image Preparation" phase, you will receive:

  • Optimized Image Set: A curated collection of individually enhanced and pre-processed images for each room/location, ready for 360 stitching.
  • Quality Assurance Report: A detailed report highlighting the quality of the submitted images, any identified issues, and the enhancements applied by the AI.
  • Recommendations for Re-capture (If Necessary): If critical issues are detected that would severely impact stitching quality, specific guidance on which images or sections need to be re-captured.

5. Next Steps: Automated 360 Photo Stitching

Once the AI-enhanced images are confirmed and ready, they will automatically proceed to the next step: stitch_360_photos. In this phase, our advanced stitching engine will seamlessly blend these individual photographs into complete, high-resolution 360 panoramic images, forming the core of your virtual tour.

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

4. Next Steps & Customization Options

We encourage you to thoroughly review your virtual tour and share it widely!

  • Review and Feedback:

* Explore every room and interact with all hotspots. Ensure all information is accurate and presented effectively.

* If any adjustments are needed (e.g., text edits, hotspot repositioning, adding/removing media), please contact our support team with your feedback.

  • Share Widely:

* Post the direct link on your social media channels (Facebook, Instagram, LinkedIn).

* Include the link in email newsletters and property brochures.

* Update your MLS and personal website listings with the provided embed code.

  • Further Enhancements (Optional):

* Floor Plan Integration: Add an interactive floor plan that shows the viewer's current position.

* Guided Tours: Implement a "play" button for an automated, guided walkthrough.

* Analytics Integration: Track viewer engagement, popular rooms, and hotspot interactions to gain insights.

* High-Resolution Downloads: Request high-res images for print materials.


5. Support & Resources

Should you have any questions, require modifications, or need assistance with embedding your virtual tour, please do not hesitate to contact our dedicated support team:

  • Email: support@pantherahive.com
  • Phone: 1-800-PANTHERA
  • Support Portal: [support.pantherahive.com](https://support.pantherahive.com)

We are committed to helping you maximize the impact of your virtual tour and achieve your real estate goals.


Start showcasing your property like never before. Your immersive virtual experience is now live!

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);}});}