Virtual Tour Creator
Run ID: 69cc6a843e7fb09ff16a1adc2026-04-01Real Estate
PantheraHive BOS
BOS Dashboard

Virtual Tour Generation Complete: Your Immersive Property Experience Awaits!

We are thrilled to present the professional virtual tour for your property, meticulously crafted to provide an immersive and engaging experience for potential buyers. This tour leverages advanced technology to showcase every detail, designed specifically to elevate your real estate listings and attract serious inquiries.


Introduction

Your bespoke 360° virtual tour has been successfully generated. This powerful tool transforms static listings into dynamic, interactive explorations, allowing prospective buyers to navigate through properties from anywhere in the world. Engineered for clarity, ease of use, and lead generation, this tour is now ready to significantly enhance your marketing efforts.


Key Features of Your New Virtual Tour

Your virtual tour is equipped with a suite of features designed to provide a comprehensive and interactive property viewing experience:

* High-Quality Stitching: Individual photos have been expertly stitched together to create fluid, high-resolution 360-degree panoramas for each room and key area.

* Immersive Experience: Viewers can pan, tilt, and zoom to explore every corner of the property, offering a true sense of space and flow.

* Crystal Clear Imagery: Optimized for visual fidelity, ensuring details like finishes, textures, and lighting are accurately represented.

* Effortless Transitions: Users can easily move between different rooms and areas of the property with a single click or tap, mimicking a real-life walk-through.

* Floor Plan Integration (Optional/If provided): If a floor plan was supplied, navigation points are often overlaid, providing a clear spatial context for each room's location within the property.

* User-Friendly Interface: Clear directional indicators and a logical flow ensure viewers never get lost and can explore at their own pace.

* Enhanced Information Delivery: Strategically placed "hotspots" within the tour highlight key features, amenities, and unique selling points of each space.

* Rich Media Support: Hotspots can contain text descriptions, additional images, video clips, or links to external resources (e.g., appliance specifications, neighborhood details).

* Engaging Details: Draw attention to premium fixtures, smart home features, unique architectural elements, or recent renovations, providing context that static photos cannot.

* Direct Inquiry Path: A discreet, non-intrusive contact form is embedded directly within the virtual tour interface.

* Instant Lead Generation: Interested prospects can submit their details (name, email, phone, message) directly from the tour, making it easy for them to express interest or ask questions.

* Streamlined Follow-Up: All submissions are immediately routed to your designated contact email, ensuring no lead is missed and enabling prompt follow-up.

* Increased Engagement: Virtual tours significantly boost viewer engagement and time spent on your listings compared to traditional photos.

* Wider Reach: Attracts out-of-town or international buyers who can't physically visit the property.

* Pre-Qualified Viewers: By offering a detailed preview, the tour helps pre-qualify potential buyers, leading to more productive in-person showings.

* Brand Professionalism: Positions your listings and brand as modern, technologically advanced, and committed to providing the best possible viewing experience.


Accessing and Sharing Your Virtual Tour

Your virtual tour is now live and ready to be shared!

* You can access your complete virtual tour directly via this unique link:

[INSERT_VIRTUAL_TOUR_URL_HERE]

Please test this link thoroughly to ensure all features function as expected.*

* To embed the tour seamlessly into your website or MLS listing, use the following iframe code:

html • 203 chars
        <iframe src="[INSERT_VIRTUAL_TOUR_URL_HERE]" width="100%" height="600px" frameborder="0" allowfullscreen allow="vr; xr; accelerometer; gyroscope; magnetometer; webvr; autoplay"></iframe>
        
Sandboxed live preview

Step 1 of 2: AI Image Preparation for Your Virtual Tour

This document outlines the detailed process and expected output for the "AI Image Preparation" step, which is crucial for creating a high-quality 360 virtual tour. This phase focuses on optimizing individual source images to ensure seamless stitching and a professional final presentation.


1. Introduction: AI Image Preparation for Your Virtual Tour

Welcome to the initial phase of crafting your immersive 360 virtual tour! In this step, our advanced AI systems will meticulously process and enhance the individual photographs you provide. The goal is to transform raw images into perfectly optimized components, ready for seamless integration into a stunning panoramic view. This foundational step is critical for achieving the high-resolution, visually consistent, and professional-grade virtual tour your real estate listing deserves.


2. Purpose & Benefits of AI Image Preparation

The "AI Image Preparation" step serves as the cornerstone for a superior virtual tour experience. Its primary objectives and benefits include:

  • Optimized Image Quality: Enhancing clarity, color accuracy, and exposure across all images to meet professional standards.
  • Consistency Across Shots: Ensuring uniform lighting, color temperature, and visual style, which is vital for smooth transitions in a 360 panorama.
  • Correction of Imperfections: Addressing common photographic issues such as lens distortion, noise, and minor alignment discrepancies before stitching.
  • Seamless Stitching Foundation: Providing the subsequent stitch_360_photos step with the highest quality, pre-aligned image data, significantly reducing stitching errors and artifacts.
  • Time Efficiency: Automating complex image adjustments, allowing for faster processing and delivery of your virtual tour.

3. Optimal Image Capture Guidelines (Input for AI)

To achieve the best possible 360 virtual tour, the quality of the source images is paramount. Please adhere to the following guidelines when capturing your photographs:

  • Camera Type & Settings:

* Recommended: Use a DSLR or mirrorless camera with a wide-angle lens (e.g., 10-18mm on APS-C, 16-24mm on full-frame) or a dedicated 360 camera.

* Manual Mode: Shoot in manual mode to maintain consistent exposure, white balance, and focus across all shots for a single scene.

* RAW Format (Preferred): Capture images in RAW format if possible, as it provides maximum flexibility for post-processing and enhancement. High-quality JPEG is also acceptable.

  • Resolution & Quality:

* High Resolution: Always shoot at the highest native resolution your camera offers. Higher resolution images yield sharper, more detailed virtual tours.

* Lowest ISO: Use the lowest ISO setting possible (e.g., ISO 100-400) to minimize digital noise.

  • Lighting:

* Even Illumination: Aim for consistent and even lighting throughout the room. Avoid harsh shadows or blown-out highlights. Natural light is often best; supplement with artificial lighting if necessary, ensuring it's balanced.

* Avoid Direct Sunlight: Direct sunlight streaming through windows can create overexposed areas and harsh contrasts. Consider shooting on an overcast day or during "golden hour" for softer light.

  • Image Overlap (Crucial for Stitching):

* 30-50% Overlap: Each consecutive photo must overlap the previous one by approximately 30-50%. This overlap provides sufficient data for the stitching software to accurately align and blend the images.

  • Number of Shots per Scene:

* Full Spherical Coverage: Take enough photos to cover a full 360-degree horizontal panorama, plus zenith (upwards) and nadir (downwards) shots if a full spherical (360x180) tour is desired.

* Typical Example: For a wide-angle lens, this might involve 6-12 horizontal shots, 1-2 upward shots, and 1-2 downward shots (often requiring tripod removal or nadir adapter).

  • Tripod & Leveling:

* Essential: Always use a sturdy tripod to ensure stability and consistent camera height.

* Level Camera: Use a spirit level (built-in or external) to ensure your camera is perfectly level. This prevents horizon lines from warping and simplifies stitching.

  • Subject Matter & Staging:

* Decluttered Spaces: Ensure rooms are clean, tidy, and free of unnecessary clutter. Remove personal items.

* No Moving Objects: Ensure no people, pets, or moving objects are in the frame during capture, as they can cause ghosting or stitching errors.

* Doors/Windows: Decide whether doors should be open or closed, and ensure consistency. Blinds/curtains should also be consistent.

  • Consistency in Capture:

* Consistent Camera Height: Maintain the same camera height for all shots within a single panoramic sequence.

* Consistent Rotation Point: Rotate the camera around its nodal point (no-parallax point) to minimize parallax errors, especially for closer objects.


4. AI-Powered Image Enhancement & Optimization

Upon receiving your source images, our AI will perform a series of sophisticated enhancements to prepare them for the stitch_360_photos step:

  • Automated Color & Exposure Correction:

* Analysis: AI analyzes each image for optimal brightness, contrast, and color balance.

* Adjustment: Automatically corrects underexposed/overexposed areas and balances overall luminance.

  • White Balance Adjustment:

* Detection: Intelligently identifies the dominant light source and adjusts the color temperature to ensure natural and consistent colors across all images, eliminating color casts.

  • Noise Reduction & Sharpening:

* Reduction: Applies intelligent noise reduction algorithms to minimize graininess, especially in lower light shots, without sacrificing detail.

* Sharpening: Selectively sharpens details to enhance clarity and crispness.

  • Lens Distortion Correction:

* Profile Matching: Utilizes lens profiles (if available in EXIF data) or AI-driven analysis to correct barrel and pincushion distortions inherent in wide-angle lenses, ensuring straight lines remain straight.

  • Dynamic Range Optimization:

* Detail Recovery: Optimizes the dynamic range to recover details in both highlights and shadows, providing a richer, more balanced image.

  • Chromatic Aberration Removal:

* Fringe Reduction: Automatically detects and reduces colored fringing (chromatic aberration) that can appear along high-contrast edges.

  • Pre-alignment & Perspective Correction:

* Initial Analysis: The AI performs an initial analysis of image features and overlaps to assist the subsequent stitching process, identifying potential alignment points and correcting minor perspective issues.


5. Output of This Step

The output of the "AI Image Preparation" step will be a comprehensive set of individually optimized, high-resolution digital image files for each scene. These images will have undergone all the aforementioned AI-driven enhancements and corrections.

  • Format: Typically high-quality JPEG or TIFF (depending on source and desired fidelity).
  • Characteristics:

* Consistent color, exposure, and white balance across all images.

* Minimized noise and enhanced sharpness.

* Corrected lens distortions and chromatic aberrations.

* Optimized dynamic range.

* Ready for seamless 360 stitching.

These processed images will then be automatically passed to the next stage of the workflow.


6. Next Step: Seamless 360 Photo Stitching

Upon successful completion of the AI Image Preparation, the optimized individual images will proceed to Step 2: stitch_360_photos. In this next phase, our specialized software will meticulously stitch these images together, creating a flawless, interactive 360-degree panoramic view for each room or scene.


7. Actionable Recommendations for Best Results

To ensure the highest quality virtual tour, please pay close attention to the following:

  • Capture with Care: The better the initial photographs, the better the final virtual tour. Invest time in proper camera setup and technique.
  • Consistency is Key: Maintain consistent lighting, camera settings, and overlap for all images within a single panoramic sequence.
  • Review Your Shots: Before submission, quickly review your captured images to ensure there are no glaring issues (e.g., blurry shots, missing overlaps, unwanted objects).

By following these guidelines, you empower our AI to deliver the most stunning and professional virtual tour possible for your real estate listings.

  • Adjust width and height as needed to fit your specific website layout.
  • Sharing on Social Media:

* Simply copy and paste the Direct Tour URL into your social media posts (Facebook, Instagram, LinkedIn, X, etc.) to share with your audience. The platform will typically generate a preview.


Next Steps & Support

  1. Review Your Tour: Please take some time to thoroughly review the generated virtual tour using the provided URL. Check all rooms, navigation points, and especially the hotspot annotations and contact form functionality.
  2. Feedback & Revisions: If you require any adjustments, have questions about specific features, or notice anything that needs refinement, please do not hesitate to contact our support team at [Support Email/Phone Number].
  3. Start Marketing: Once you are satisfied, begin integrating this powerful tool into all your property marketing channels to maximize its impact!

We are confident that this virtual tour will be an invaluable asset in showcasing your property and attracting the right buyers. Thank you for choosing Virtual Tour Creator!

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
"); 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' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); 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' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- 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",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); 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' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); 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} "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- 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",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "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"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); 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'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); 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} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/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(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/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)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- 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:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== 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(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } 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);}});}