@three-blocks/devtools 1.0.0-alpha.176.g8ff8a72e6369

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +76 -0
  3. package/NOTICE +32 -0
  4. package/README.md +254 -0
  5. package/dist/browser/environment-bake.js +1 -0
  6. package/dist/browser/shader-capture.d.ts +45 -0
  7. package/dist/browser/shader-capture.js +3 -0
  8. package/dist/browser-smoke-76626IZQ.js +254 -0
  9. package/dist/chunk-26FK4CRS.js +6 -0
  10. package/dist/chunk-4EHPYBKA.cjs +1 -0
  11. package/dist/chunk-5L2VS3BN.js +2 -0
  12. package/dist/chunk-76WRV5MZ.js +7 -0
  13. package/dist/chunk-EI7MMDWY.js +1 -0
  14. package/dist/chunk-HOZDD6PW.js +2 -0
  15. package/dist/chunk-HRYYNBVC.js +3 -0
  16. package/dist/chunk-INDAJN42.js +94 -0
  17. package/dist/chunk-JMS5NTP7.js +3 -0
  18. package/dist/chunk-ME3X2KFY.js +14 -0
  19. package/dist/chunk-NE7SC2BX.js +2 -0
  20. package/dist/chunk-SCJNCGMF.js +17 -0
  21. package/dist/chunk-UDUICSME.js +1 -0
  22. package/dist/chunk-VGJ3V4QQ.js +78 -0
  23. package/dist/chunk-ZDNZCQUQ.js +2 -0
  24. package/dist/chunk-ZKK6E42X.js +1 -0
  25. package/dist/chunk-ZT6T2W4B.js +2 -0
  26. package/dist/cli.js +24 -0
  27. package/dist/environment-bake-5P4IAL4O.js +4 -0
  28. package/dist/index.d.ts +1183 -0
  29. package/dist/index.js +272 -0
  30. package/dist/shader-autowire-DCODBFMX.js +18 -0
  31. package/dist/shader-browser-65V22LLL.js +1 -0
  32. package/dist/shader-browser-JII6ZFCW.js +2 -0
  33. package/dist/shader-capture-server.d.ts +272 -0
  34. package/dist/shader-capture-server.js +19 -0
  35. package/dist/shader-config-4EXO5DKK.js +2 -0
  36. package/dist/shader-parity-QXJWR6OZ.js +1 -0
  37. package/dist/shader-parity-XPKQQK26.js +2 -0
  38. package/dist/shader-project-runner-GUR3LTYS.js +5 -0
  39. package/dist/shader-transform-CUkZn5Oa.d.ts +55 -0
  40. package/dist/shader-watch-QHTNTSZE.js +2 -0
  41. package/dist/shader-workflow-U4G565EB.js +2 -0
  42. package/dist/status-DV2BYZHR.js +2 -0
  43. package/dist/text-atlas-BHPSDU7C.js +2 -0
  44. package/dist/transform.cjs +1 -0
  45. package/dist/transform.d.ts +62 -0
  46. package/dist/transform.js +1 -0
  47. package/dist/webpack-loader.cjs +1 -0
  48. package/dist/webpack-loader.d.ts +17 -0
  49. package/dist/webpack-loader.js +1 -0
  50. package/fonts/OFL-1.1.txt +93 -0
  51. package/package.json +113 -0
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ import {b,a as a$3}from'./chunk-26FK4CRS.js';import'./chunk-76WRV5MZ.js';import'./chunk-JMS5NTP7.js';import'./chunk-ME3X2KFY.js';import'./chunk-INDAJN42.js';import {a as a$2,b as b$1,c as c$1}from'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import {a as a$1}from'./chunk-ZDNZCQUQ.js';import {j,a as a$4,c}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {randomUUID}from'crypto';import {mkdir,realpath,writeFile,rename,rm}from'fs/promises';import F from'path';import {PNG}from'pngjs';var ye="virtual:three-blocks-devtools/browser-smoke",ve=`\0${ye}`,Ke=`/@id/__x00__${ye}`,Be=9e4;async function Ee(){try{let[e,r]=await Promise.all([import('playwright'),import('vite')]);return {chromium:e.chromium,vite:r}}catch(e){throw new Error('Browser smoke and preview require the optional "playwright" and "vite" packages. Install both in the project and run `npx playwright install chromium`.',{cause:e})}}a(Ee,"loadBrowserSmokeTools");function V(e,r,o,t,n){let a=e??n;if(!Number.isSafeInteger(a)||a<o||a>t)throw new Error(`${r} must be an integer in ${o}...${t}.`);return a}a(V,"boundedInteger");function _e(e,r,o,t,n){let a=e??n;if(!Number.isFinite(a)||a<o||a>t)throw new Error(`${r} must be a finite number in ${o}...${t}.`);return a}a(_e,"boundedRatio");function Pe(e){let r=e??"/";if(r.length===0||r.length>2048||/[\u0000-\u001f\u007f]/u.test(r))throw new Error("Browser smoke route must be a bounded project URL.");let o=new URL(r,"http://three-blocks.invalid/");if(o.origin!=="http://three-blocks.invalid"||o.hash.length>0)throw new Error("Browser smoke route must stay within the project and have no fragment.");return `${o.pathname}${o.search}`}a(Pe,"safeRoute");function N(e,r){return e[r]===true}a(N,"booleanField");function $(e,r){if(!a$1(e)||!a$1(e.value))return {source:"missing",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:r,textReady:!r,firstFrame:false};let o=e.value,t=e.source==="public";if(t&&o.protocolVersion!==1)return {source:"public",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:r,textReady:!r,firstFrame:false};let n=a$1(o.readiness)?o.readiness:o,a=o.worker,d=t&&a$1(a)?a.offscreenCanvas===true&&a.visible===true:a===true;return {source:t?"public":"legacy",backend:t&&a$1(a)?a.offscreenCanvas===true?"OffscreenCanvas":"MainThread":a===true?"OffscreenCanvas":"unknown",worker:d,workerReady:N(n,"workerReady"),assetsReady:N(n,"assetsReady")||N(n,"loadEnd"),compileEnd:N(n,"compileEnd"),textEnabled:r,textReady:!r||N(n,"textReady"),firstFrame:N(n,"firstFrame")}}a($,"parseBrowserSmokeLifecycle");function ie(e){let r=PNG.sync.read(e),o=Math.floor(r.width*.25),t=Math.floor(r.width*.75),n=Math.floor(r.height*.25),a=Math.floor(r.height*.75),d=0,c=0;for(let f=n;f<a;f+=2)for(let p=o;p<t;p+=2){let h=(f*r.width+p)*4,l=r.data[h],i=r.data[h+1],s=r.data[h+2];l===void 0||i===void 0||s===void 0||(d+=Math.max(l,i,s),c+=1);}return c===0?0:d/c}a(ie,"screenshotLuminance");function Je(){return `
3
+ import * as THREE from 'three/webgpu';
4
+ import { createAssetLoaderRegistry, createAssetManager, createThreeAssetAdapters, defineAssets } from 'three-blocks/assets';
5
+ import { SceneHotReloader } from 'three-blocks/hmr';
6
+ import { createShaderCache } from 'three-blocks/shaders';
7
+ import { createStatsWorker } from 'three-blocks/stats';
8
+ import { threeBlocksBuildReceipt, threeBlocksConfig, loadThreeBlocksMeshoptDecoder } from 'three-blocks/vite/config';
9
+
10
+ const root = globalThis;
11
+ const hmr = root.__threeBlocksSmokeProbe ??= { before: 0, after: 0 };
12
+ if ( import.meta.hot ) {
13
+ import.meta.hot.on( 'vite:beforeUpdate', () => { hmr.before += 1; } );
14
+ import.meta.hot.on( 'vite:afterUpdate', () => { hmr.after += 1; } );
15
+ import.meta.hot.accept();
16
+ }
17
+
18
+ async function externalCodec( name, config, pathKey ) {
19
+ if ( config === false ) return { name, state: 'disabled', routes: [], decoded: false, evidence: 'delivery', blocker: null, error: null };
20
+ const routes = [];
21
+ try {
22
+ for ( const file of config.files ) {
23
+ const route = config[ pathKey ] + file;
24
+ const response = await fetch( new URL( route, location.origin ), { cache: 'no-store' } );
25
+ const body = await response.arrayBuffer();
26
+ if ( ! response.ok ) throw new Error( route + ' returned HTTP ' + response.status );
27
+ if ( body.byteLength === 0 ) throw new Error( route + ' returned an empty body' );
28
+ routes.push( { route: new URL( route, location.origin ).pathname, bytes: body.byteLength, contentType: response.headers.get( 'content-type' ) ?? '' } );
29
+ }
30
+ return {
31
+ name,
32
+ state: 'ready',
33
+ routes,
34
+ decoded: false,
35
+ evidence: 'delivery',
36
+ blocker: null,
37
+ error: null,
38
+ };
39
+ } catch ( error ) {
40
+ return { name, state: 'error', routes, decoded: false, evidence: 'delivery', blocker: null, error: error instanceof Error ? error.message : String( error ) };
41
+ }
42
+ }
43
+
44
+ async function meshoptCodec() {
45
+ if ( threeBlocksConfig.codecs.meshopt === false ) return { name: 'meshopt', state: 'disabled', routes: [], decoded: false, evidence: 'decoder-ready', blocker: null, error: null };
46
+ try {
47
+ const decoder = await loadThreeBlocksMeshoptDecoder();
48
+ await decoder.ready;
49
+ if ( decoder.supported !== true ) throw new Error( 'Meshopt decoder reports supported=false' );
50
+ return {
51
+ name: 'meshopt',
52
+ state: 'ready',
53
+ routes: [],
54
+ decoded: false,
55
+ evidence: 'decoder-ready',
56
+ blocker: null,
57
+ error: null,
58
+ };
59
+ } catch ( error ) {
60
+ return { name: 'meshopt', state: 'error', routes: [], decoded: false, evidence: 'decoder-ready', blocker: null, error: error instanceof Error ? error.message : String( error ) };
61
+ }
62
+ }
63
+
64
+ async function decodeCodecFixtures() {
65
+ const fixtureRoot = '/__three-blocks-codec-fixtures';
66
+ const available = await fetch( fixtureRoot + '/Box.gltf', { cache: 'no-store' } ).then( async response => {
67
+ if ( ! response.ok ) return false;
68
+ try {
69
+ const value = JSON.parse( await response.text() );
70
+ return Array.isArray( value?.extensionsUsed ) && value.extensionsUsed.includes( 'KHR_draco_mesh_compression' );
71
+ } catch {
72
+ return false;
73
+ }
74
+ }, () => false );
75
+ if ( ! available ) return null;
76
+ const canvas = document.createElement( 'canvas' );
77
+ canvas.width = 4;
78
+ canvas.height = 4;
79
+ const renderer = new THREE.WebGPURenderer( { canvas, antialias: false } );
80
+ let runtime;
81
+ let manager;
82
+ try {
83
+ await renderer.init();
84
+ runtime = createThreeAssetAdapters( {
85
+ renderer,
86
+ codecs: threeBlocksConfig.codecs,
87
+ loadMeshopt: loadThreeBlocksMeshoptDecoder,
88
+ } );
89
+ manager = createAssetManager( runtime.registry );
90
+ const load = async ( name, definition, validate ) => {
91
+ try {
92
+ const lease = await manager.lease( defineAssets( { fixture: definition } ) );
93
+ try {
94
+ if ( ! validate( lease.assets.fixture ) ) throw new Error( name + ' returned the wrong decoded object.' );
95
+ return { ok: true, error: null };
96
+ } finally {
97
+ lease.release();
98
+ }
99
+ } catch ( error ) {
100
+ return { ok: false, error: error instanceof Error ? error.message : String( error ) };
101
+ }
102
+ };
103
+ return {
104
+ draco: await load( 'Draco', { type: 'gltf', url: fixtureRoot + '/Box.gltf' }, value => value?.scene?.isObject3D === true ),
105
+ meshopt: await load( 'Meshopt', { type: 'gltf', url: fixtureRoot + '/Meshopt.gltf' }, value => value?.scene?.isObject3D === true ),
106
+ ktx2: await load( 'KTX2', { type: 'ktx2', url: fixtureRoot + '/geist.msdf.ktx2' }, value => value?.isTexture === true ),
107
+ };
108
+ } finally {
109
+ await manager?.shutdown();
110
+ await runtime?.dispose();
111
+ renderer.dispose();
112
+ }
113
+ }
114
+
115
+ async function proveHotRuntime() {
116
+ const sharedAsset = { id: 'shared-browser-smoke-asset' };
117
+ let disposedAssets = 0;
118
+ const registry = createAssetLoaderRegistry( {
119
+ json: {
120
+ type: 'json',
121
+ load: async () => sharedAsset,
122
+ dispose: () => { disposedAssets += 1; },
123
+ },
124
+ } );
125
+ const manager = createAssetManager( registry );
126
+ const manifest = { shared: { type: 'json', url: '/__three-blocks-smoke-shared.json' } };
127
+ const createScene = async ( name ) => {
128
+ const scope = manager.createScope();
129
+ const assets = await scope.load( manifest );
130
+ return {
131
+ name,
132
+ asset: assets.shared,
133
+ hot: { state: 0 },
134
+ dispose() { scope.dispose(); },
135
+ };
136
+ };
137
+ const first = await createScene( 'first' );
138
+ first.hot.state = 37;
139
+ let now = 0;
140
+ const pushed = [];
141
+ const profiler = {
142
+ init() {}, begin() {}, end() {}, update() {}, dispose() {},
143
+ getData: () => ( { fps: 60, cpu: 1, gpu: 2, gpuCompute: 3 } ),
144
+ };
145
+ const stats = createStatsWorker( {
146
+ sampleRate: 4,
147
+ now: () => now,
148
+ publish: ( value ) => pushed.push( value ),
149
+ createProfiler: async () => profiler,
150
+ } );
151
+ await stats.init( {} );
152
+ stats.beginFrame();
153
+ stats.endFrame();
154
+ const stableStats = stats;
155
+ const reloader = new SceneHotReloader( first, {
156
+ context: { manager, stats },
157
+ compile: ( candidate ) => {
158
+ if ( candidate.name === 'failed' ) throw new Error( 'intentional browser-smoke compile failure' );
159
+ },
160
+ } );
161
+ const replaced = await reloader.replace( () => createScene( 'second' ) );
162
+ now = 300;
163
+ stats.beginFrame();
164
+ stats.endFrame();
165
+ const cacheAfterCommit = manager.cacheSnapshot();
166
+ const committed = reloader.current;
167
+ let rollbackPhase = null;
168
+ try {
169
+ await reloader.replace( () => createScene( 'failed' ) );
170
+ } catch ( error ) {
171
+ rollbackPhase = error && typeof error === 'object' ? error.phase : null;
172
+ }
173
+ const cacheAfterRollback = manager.cacheSnapshot();
174
+ const shaderCache = createShaderCache( 'browser-smoke' );
175
+ const firstMaterial = {};
176
+ const firstRegistration = shaderCache.forScene( 'browser-smoke' ).material( 'browser-smoke/material', firstMaterial );
177
+ const nextMaterial = {};
178
+ const nextRegistration = shaderCache.forScene( 'browser-smoke', { replaceExisting: true } )
179
+ .material( 'browser-smoke/material', nextMaterial );
180
+ firstRegistration.dispose();
181
+ const invalidation = shaderCache.invalidationFor( 'browser-smoke/material', 'browser-smoke' );
182
+ const shaderReplacementActive = shaderCache.registration( 'browser-smoke/material', 'browser-smoke' )?.target === nextMaterial;
183
+ nextRegistration.dispose();
184
+ const result = {
185
+ sceneIdentityReplaced: replaced.previous === first && replaced.current === committed && committed !== first,
186
+ stateRestored: committed.hot.state === 37,
187
+ assetIdentityPreserved: first.asset === committed.asset && committed.asset === sharedAsset,
188
+ assetReferencesPreserved: cacheAfterCommit.length === 1 && cacheAfterCommit[ 0 ]?.references === 1 && disposedAssets === 0,
189
+ statsIdentityPreserved: stats === stableStats,
190
+ statsSequenceAdvanced: pushed.length === 2 && pushed[ 0 ]?.sequence === 0 && pushed[ 1 ]?.sequence === 1,
191
+ shaderInvalidated: shaderReplacementActive && invalidation?.key === 'browser-smoke/material' && /replaced during HMR/.test( invalidation.reason ),
192
+ rollbackPreserved: rollbackPhase === 'compile' && reloader.current === committed && cacheAfterRollback.length === 1 && cacheAfterRollback[ 0 ]?.references === 1,
193
+ };
194
+ committed.dispose();
195
+ stats.dispose();
196
+ await manager.shutdown();
197
+ return result;
198
+ }
199
+
200
+ export async function probe() {
201
+ const codecs = [
202
+ await externalCodec( 'draco', threeBlocksConfig.codecs.draco, 'decoderPath' ),
203
+ await externalCodec( 'ktx2', threeBlocksConfig.codecs.ktx2, 'transcoderPath' ),
204
+ await meshoptCodec(),
205
+ ];
206
+ const decoded = await decodeCodecFixtures();
207
+ if ( decoded ) {
208
+ for ( const codec of codecs ) {
209
+ const result = decoded[ codec.name ];
210
+ if ( result?.ok ) {
211
+ codec.decoded = true;
212
+ codec.evidence = 'asset-manager-decoded';
213
+ codec.blocker = null;
214
+ } else if ( result ) {
215
+ codec.state = 'error';
216
+ codec.error = result.error;
217
+ }
218
+ }
219
+ }
220
+ return {
221
+ textEnabled: threeBlocksConfig.text.enabled,
222
+ receipt: threeBlocksBuildReceipt,
223
+ hmrEvidence: await proveHotRuntime(),
224
+ codecs,
225
+ };
226
+ }
227
+ `}a(Je,"browserProbeSource");function Xe(){return {name:"three-blocks:browser-smoke-probe",enforce:"post",resolveId(e){return e===ye?ve:void 0},load(e){return e===ve?Je():void 0}}}a(Xe,"browserProbePlugin");function Te(e){let r={console:[],page:[]};return e.on("console",o=>{o.type()!=="error"||a$2(o.text())||r.console.push(o.text());}),e.on("pageerror",o=>{a$2(o.message)||r.page.push(o.message);}),r}a(Te,"collectPageErrors");async function U(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksSmoke;if(o!==void 0)return {source:"public",value:o};let t=r.__threeBlocksBrowserTools;if(t&&typeof t=="object"){let n=Reflect.get(t,"smoke");if(n!==void 0)return {source:"public",value:n}}return {source:r.__threeBlocks===void 0?"missing":"legacy",value:r.__threeBlocks??null}})}a(U,"readBridge");async function Ye(e){return e.evaluate(()=>{let r=globalThis,o=r.document.querySelector("[data-tb-fatal-code]"),t=o?.getAttribute("data-tb-fatal-code")??"",n=(o?.title||o?.textContent||"")?.replace(/^three-blocks — error:\s*/u,"").replace(/^Uncaught(?:\s+Error)?:\s*/u,"").trim()??"";return {fatalVisible:o!==null&&/^[a-z][a-z0-9-]{0,63}$/u.test(t)&&r.getComputedStyle(o).display!=="none"&&r.getComputedStyle(o).visibility!=="hidden",code:t.length>0?t:null,detail:n.length>0?n:null}})}a(Ye,"readCompatibilityFailure");async function xe(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksTextFallbackProbe?.states,t=Array.isArray(o)?o.filter(c=>typeof c=="string").slice(0,32):[],n=t.indexOf("fallback"),a=t.lastIndexOf("ready"),d=[...r.document.querySelectorAll("[data-canvas-text]")];return {states:t,fallbackObserved:n>=0,recovered:n>=0&&a>n,visibleElements:d.filter(c=>c.getAttribute("data-canvas-text-fallback")!=="false").length,totalElements:d.length}})}a(xe,"readTextFallbackEvidence");async function Y(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksSmoke?.diagnostics?.shaderMode;return {snapshots:Math.max(0,Number(r.__threeBlocksSmoke?.stats?.snapshots)||0),textures:Math.max(0,Number(r.__threeBlocksSmoke?.stats?.textures)||0),shaderMode:o==="precompiled"||o==="live"?o:null,mainPanels:r.document.querySelector("[data-three-blocks-stats-mode]")!==null}})}a(Y,"readBrowserRuntimeObservation");async function Ze(e,r){let o=Buffer.from(`${JSON.stringify(r,null,2)}
228
+ `,"utf8");if(o.byteLength>b)throw new Error(`Runtime status receipt exceeds ${b} bytes.`);let t=F.join(e,...a$3.split("/")),n=F.dirname(t);await mkdir(n,{recursive:true});let a=await realpath(n),d=F.relative(e,a);if(d.startsWith("..")||F.isAbsolute(d))throw new Error("Runtime status receipt directory escapes the project root.");let c=F.join(a,`.status.${process.pid}.${randomUUID()}.tmp`);try{await writeFile(c,o,{flag:"wx",mode:384}),await rename(c,t);}finally{await rm(c,{force:true});}}a(Ze,"writeRuntimeStatusReceipt");async function Z(e,r,o){await e.waitForFunction(t=>{let n=globalThis,a=n.__threeBlocksSmoke,d=a!==void 0;if(a===void 0){let l=n.__threeBlocksBrowserTools;l&&typeof l=="object"&&(a=Reflect.get(l,"smoke")),d=a!==void 0;}if(a===void 0&&(a=n.__threeBlocks),!a||typeof a!="object")return false;let c=a;if(d&&c.protocolVersion!==1)return false;let f=c.readiness&&typeof c.readiness=="object"?c.readiness:c,p=c.worker;return (d&&p&&typeof p=="object"?Reflect.get(p,"offscreenCanvas")===true&&Reflect.get(p,"visible")===true:p===true)&&f.workerReady===true&&(f.assetsReady===true||f.loadEnd===true)&&f.compileEnd===true&&f.firstFrame===true&&(!t||f.textReady===true)},r,{timeout:o});}a(Z,"waitForLifecycle");async function Se(e,r){await e.waitForFunction(()=>{let t=[...globalThis.document.querySelectorAll("[data-canvas-text]")];return t.length>0&&t.every(n=>n.getAttribute("data-canvas-text-fallback")==="true")},void 0,{timeout:Math.min(r,3e4)});}a(Se,"waitForTextFallback");async function de(e,r,o){await r();let t=250,n=performance.now()+Math.min(o,5e3),a$1=performance.now(),d=a(()=>{a$1=performance.now();},"navigated");e.on("framenavigated",d);try{for(;performance.now()-a$1<t;){if(performance.now()>=n)throw new Error("Timed out waiting for startup navigation to settle.");await e.waitForTimeout(25);}}finally{e.off("framenavigated",d);}await r();}a(de,"waitForStableReadiness");async function Re(e,r){return await e(),r()}a(Re,"readAfterInitialReadiness");function Qe(e,r,o){if(!a$1(e)||typeof e.route!="string"||!e.route.startsWith("/")||e.route.length>2048||!Number.isSafeInteger(e.bytes)||Number(e.bytes)<=0||typeof e.contentType!="string"||e.contentType.length>256)throw new Error(`Browser codec ${r} route ${o} is invalid.`);let t=e.route.endsWith(".wasm")?"application/wasm":"javascript";if(!e.contentType.includes(t))throw new Error(`Browser codec route ${e.route} returned unexpected content-type ${JSON.stringify(e.contentType)}.`);return {route:e.route,bytes:Number(e.bytes),contentType:e.contentType}}a(Qe,"parseCodecRoute");function G(e,r,o){if(typeof e!="string"||!r.includes(e))throw new Error(`${o} is invalid.`);return e}a(G,"literal");function le(e,r){if(!Number.isSafeInteger(e)||Number(e)<0)throw new Error(`${r} is invalid.`);return Number(e)}a(le,"nonnegativeInteger");function er(e){if(!a$1(e)||e.schemaVersion!==2||!a$1(e.renderer)||!a$1(e.assets)||!a$1(e.shaders)||!a$1(e.stats)||typeof e.output!="string"||e.output.length===0||e.output.length>2048||typeof e.threeVersion!="string"||e.threeVersion.length===0||e.threeVersion.length>128)throw new Error("Browser build receipt is invalid.");if(e.renderer.owner!=="worker"||e.renderer.api!=="WebGPU"||e.renderer.fallback!=="WebGL")throw new Error("Browser build receipt does not declare the worker-owned WebGPU/WebGL renderer contract.");let r=e.text;if(r!==void 0&&(!a$1(r)||!["ready","generating","fallback","missing","invalid"].includes(String(r.state))))throw new Error("Browser build receipt text state is invalid.");return {schemaVersion:2,renderer:{owner:"worker",api:"WebGPU",fallback:"WebGL"},assets:{draco:G(e.assets.draco,["ready","disabled"],"Browser build receipt Draco state"),ktx2:G(e.assets.ktx2,["ready","disabled"],"Browser build receipt KTX2 state"),meshopt:G(e.assets.meshopt,["lazy","disabled"],"Browser build receipt Meshopt state")},shaders:{state:G(e.shaders.state,["fresh","stale","invalid","missing"],"Browser build receipt shader state"),mode:G(e.shaders.mode,["precompiled","live"],"Browser build receipt shader mode"),pipelines:le(e.shaders.pipelines,"Browser build receipt shader pipeline count")},...r===void 0?{}:{text:{state:G(r.state,["ready","generating","fallback","missing","invalid"],"Browser build receipt text state"),atlases:le(r.atlases,"Browser build receipt text atlas count"),glyphs:le(r.glyphs,"Browser build receipt text glyph count")}},stats:{enabled:e.stats.enabled===true,production:e.stats.production===true},output:e.output,threeVersion:e.threeVersion}}a(er,"parseBuildReceipt");var ce=Object.freeze({sceneIdentityReplaced:false,stateRestored:false,assetIdentityPreserved:false,assetReferencesPreserved:false,statsIdentityPreserved:false,statsSequenceAdvanced:false,shaderInvalidated:false,rollbackPreserved:false}),J=Object.freeze({requested:false,appIdentityStable:false,contentIdentityStable:false,canvasReplaced:false,workerIdentityChanged:false,generationAdvanced:false,restartCountAdvanced:false,stateReplayed:false,readinessRestored:false,shaderModeStable:false,statsSnapshotsAdvanced:false,statsTextureTransferred:false,statsTextureStopped:false,error:null}),rr=Object.freeze(["three-blocks/assets","three-blocks/hmr","three-blocks/runtime","three-blocks/shaders","three-blocks/stats","three-blocks/text","three-blocks/worker"]);function tr(e){if(!a$1(e))throw new Error("Browser HMR evidence is invalid.");let r={...ce};for(let o of Object.keys(r)){if(e[o]!==true)throw new Error(`Browser HMR evidence ${o} did not pass.`);r[o]=true;}return r}a(tr,"parseHmrEvidence");function or(e){if(!a$1(e)||typeof e.textEnabled!="boolean"||!Array.isArray(e.codecs)||e.codecs.length!==3)throw new Error("Browser codec probe returned an invalid payload.");let r=["draco","ktx2","meshopt"],o=e.codecs.map((t,n)=>{let a=r[n];if(a===void 0||!a$1(t)||t.name!==a||!["ready","disabled","error"].includes(String(t.state))||!Array.isArray(t.routes)||t.error!==null&&typeof t.error!="string")throw new Error(`Browser codec probe entry ${n} is invalid.`);let d=t.state,c=t.routes.map((p,h)=>Qe(p,a,h)),f=G(t.evidence,["delivery","decoder-ready","text-atlas-decoded","asset-manager-decoded"],`Browser codec ${a} evidence`);if(typeof t.decoded!="boolean"||t.blocker!==null&&typeof t.blocker!="string")throw new Error(`Browser codec ${a} decode evidence is invalid.`);if(d==="ready"&&a!=="meshopt"&&c.length===0)throw new Error(`Browser codec ${a} exposed no routes.`);if(d==="error"&&(typeof t.error!="string"||t.error.length===0||t.error.length>8192))throw new Error(`Browser codec ${a} has an invalid error.`);return {name:a,state:d,routes:c,decoded:t.decoded,evidence:f,blocker:typeof t.blocker=="string"?t.blocker:null,error:typeof t.error=="string"?t.error:null}});return {textEnabled:e.textEnabled,codecs:o,receipt:er(e.receipt),hmrEvidence:tr(e.hmrEvidence)}}a(or,"parseCodecProbe");async function nr(e){let r=await e.evaluate(async o=>{let t=await import(o);if(typeof t.probe!="function")throw new Error("Browser smoke probe module has no probe() export.");return await t.probe()},Ke);return or(r)}a(nr,"probeCodecs");function ar(e){return e instanceof Error&&/execution context was destroyed|most likely because of a navigation/iu.test(e.message)}a(ar,"isNavigationRace");async function sr(e,r,o){for(let t=0;t<3;t++)try{return await nr(e)}catch(n){if(!ar(n)||t===2)throw n;await de(e,r,o);}throw new Error("Browser codec probe did not complete.")}a(sr,"probeCodecsAfterNavigation");async function ue(e){return e.evaluate(()=>{let r=globalThis,o=0;for(let t of r.document.querySelectorAll("canvas")){if(t.width<=0||t.height<=0)continue;let n=null;try{n=t.getContext("2d");}catch{continue}if(n)try{let a=n.getImageData(0,0,t.width,t.height).data,d=0,c=0;for(let f=0;f+2<a.length;f+=4)d+=Math.max(a[f]??0,a[f+1]??0,a[f+2]??0),c+=1;c>0&&(o=Math.max(o,d/c));}catch{}}return o})}a(ue,"panelLuminance");function lr(e){return e.split(F.sep).join("/")}a(lr,"portablePath");async function ir(e){return e.evaluate(()=>{let o=globalThis.__threeBlocksSmokeProbe;if(!o||typeof o!="object")return 0;let t=Reflect.get(o,"after");return typeof t=="number"&&Number.isSafeInteger(t)?t:0})}a(ir,"hmrEventCount");async function dr(e,r,o,t,n,a,d){if(t===void 0)return {requested:false,module:null,dispatched:false,acknowledged:false,lifecycleStable:true,sourceUnchanged:true,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null};let c$1=lr(t),f=false,p=false,h=false,l=false;try{let i=await j(o,F.join(o,t),a$4.semanticInput,"HMR scene module"),s=c(i.data),w=e.moduleGraph.getModulesByFile(i.path);if(!w||w.size===0)throw new Error(`HMR scene module ${JSON.stringify(c$1)} is not in Vite's module graph.`);let m=await ir(r);e.watcher.emit("change",i.path),f=!0,await r.waitForFunction(T=>{let y=globalThis.__threeBlocksSmokeProbe;return !!(y&&typeof y=="object"&&Number(Reflect.get(y,"after"))>T)},m,{timeout:Math.min(n,3e4)}),p=!0,await Z(r,a,Math.min(n,3e4)),h=!0;let g=await j(o,i.path,a$4.semanticInput,"HMR scene module");if(l=c(g.data)===s,!l)throw new Error("HMR scene source changed during the smoke run.");return {requested:!0,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null}}catch(i){return {requested:true,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:i instanceof Error?i.message:String(i)}}}a(dr,"exerciseHmr");async function cr(e,r,o,t){let n="stats-baseline";try{let a=await e.evaluate(()=>{let l=globalThis;return new URL(l.location.href).searchParams.get("tbStats")==="1"});a&&(n="stats-query-boot",await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!0,void 0,{timeout:Math.min(r,3e4)}));let d=await e.evaluate(()=>{let l=globalThis;return {panelVisible:l.__threeBlocksSmoke?.stats?.panelVisible,textures:Number(l.__threeBlocksSmoke?.stats?.textures)||0,panelAttached:l.document.querySelector("[data-three-blocks-stats-mode]")!==null}});if(!a&&(d.panelVisible!==!1||d.textures!==0||d.panelAttached))throw new Error("Generated stats panel is not default-off before browser-smoke activation.");n="stats-enable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function"||typeof i.setPanelMode!="function")throw new Error("Generated stats panel controls are unavailable.");if(await Reflect.apply(i.setPanelVisible,i,[!0])!==!0)throw new Error("Generated stats panel could not be enabled.");if(await Reflect.apply(i.setPanelMode,i,["expanded"])!==!0)throw new Error("Generated stats panel could not be expanded.")}),n="stats-expanded",await e.waitForFunction(()=>{let l=globalThis;return l.__threeBlocksSmoke?.stats?.panelVisible===!0&&l.document.querySelector('[data-three-blocks-stats-mode="expanded"]')!==null},void 0,{timeout:Math.min(r,3e4)}),n="stats-initial-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,d.textures,{timeout:Math.min(r,3e4)}),n="snapshot";let c=await e.evaluate(()=>{let l=globalThis,i=l.__threeBlocksSmoke,s=l.document.querySelector("#app"),w=l.document.querySelector("#scene"),m=l.document.querySelector("main")??s;if(!i||typeof i.restartWorker!="function"||!s||!w||!m||typeof i.diagnostics?.workerId!="string")throw new Error("Generated worker restart diagnostics are unavailable.");return l.__threeBlocksWorkerRestartProbe={app:s,content:m,canvas:w},{workerId:i.diagnostics.workerId,generation:i.worker.generation,restartCount:i.restart.count,snapshots:i.stats.snapshots,textures:i.stats.textures}});n="restart-call",await e.evaluate(async()=>{let l=globalThis,i=l.__threeBlocksSmoke?.restartWorker;if(typeof i!="function")throw new Error("Generated restartWorker() is unavailable.");await Reflect.apply(i,l.__threeBlocksSmoke,["browser smoke worker restart"]);}),n="restart-readiness",await e.waitForFunction(l=>{let s=globalThis.__threeBlocksSmoke,w=s?.readiness;return typeof s?.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId&&Number(s.worker?.generation)>l.generation&&s.restart?.stateReplayed===!0&&w?.workerReady===!0&&w.assetsReady===!0&&w.compileEnd===!0&&w.firstFrame===!0&&(!l.textEnabled||w.textReady===!0)},{workerId:c.workerId,generation:c.generation,textEnabled:o},{timeout:Math.min(r,45e3)}),n="stats-snapshot",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.snapshots)>l,c.snapshots,{timeout:Math.min(r,3e4)}),n="stats-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,c.textures,{timeout:Math.min(r,3e4)});let f=await e.evaluate(l=>{let i=globalThis,s=i.__threeBlocksSmoke,w=i.__threeBlocksWorkerRestartProbe,m=s?.readiness;if(!s||!w||!m)throw new Error("Generated restart evidence disappeared.");return {requested:!0,appIdentityStable:w.app===i.document.querySelector("#app"),contentIdentityStable:w.content===(i.document.querySelector("main")??i.document.querySelector("#app")),canvasReplaced:s.restart.canvasReplaced&&w.canvas!==i.document.querySelector("#scene"),workerIdentityChanged:typeof s.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId,generationAdvanced:s.worker.generation===l.generation+1,restartCountAdvanced:s.restart.count===l.restartCount+1,stateReplayed:s.restart.stateReplayed&&s.restart.lastReason==="browser smoke worker restart",readinessRestored:m.workerReady===!0&&m.assetsReady===!0&&m.compileEnd===!0&&m.firstFrame===!0&&(!l.textEnabled||m.textReady===!0),shaderModeStable:s.diagnostics?.shaderMode===l.expectedShaderMode,statsSnapshotsAdvanced:s.stats.snapshots>l.snapshots,statsTextureTransferred:s.stats.textures>l.textures,statsTextureStopped:!1,error:null}},{...c,textEnabled:o,expectedShaderMode:t});n="stats-disable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function")throw new Error("Generated stats visibility control disappeared before disable.");if(await Reflect.apply(i.setPanelVisible,i,[!1])!==!0)throw new Error("Generated stats panel could not be disabled.")}),await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!1,void 0,{timeout:Math.min(r,3e4)}),await e.waitForTimeout(750);let p=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);await e.waitForTimeout(1100);let h=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);if(h!==p)throw new Error(`Stats textures advanced after disable (${p} -> ${h}).`);return {...f,statsTextureStopped:!0}}catch(a){return {...J,requested:true,error:`${n}: ${a instanceof Error?a.message:String(a)}`}}}a(cr,"exerciseWorkerRestart");function D(e){return [...new Set(e)].sort((r,o)=>r.localeCompare(o))}a(D,"sortedUnique");function ur(e,r,o){let t=D(e),n=D(r),a=o?D([...t,...n].filter(c=>/MSDF atlases are missing code points:/iu.test(c))):[],d=new Set(a);return {console:t.filter(c=>!d.has(c)),page:n.filter(c=>!d.has(c)),resolved:a}}a(ur,"classifyRecoveredTextErrors");function mr(e){return e.replace(/\u001b\[[0-?]*[ -/]*[@-~]/gu,"")}a(mr,"stripTerminalControl");function yr(e,r,o){let t=e.config.base.startsWith("/")?e.config.base:"/";return new URL(o.replace(/^\/+/,""),`${r}${t.endsWith("/")?t:`${t}/`}`).href}a(yr,"projectUrl");async function xr(e){let{chromium:r,vite:{createLogger:o,createServer:t}}=await Ee();if(e.forceWebgl===true&&e.unsupportedWorker===true)throw new Error("Browser smoke forceWebgl and unsupportedWorker modes are mutually exclusive.");if(e.unsupportedWorker===true&&e.expectTextGenerationFailure===true)throw new Error("Browser smoke unsupportedWorker and expectTextGenerationFailure modes are mutually exclusive.");let n=await realpath(e.root),a$1=Pe(e.route),d=V(e.timeoutMs,"Browser smoke timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser smoke settleMs",0,1e4,1e3),f={width:V(e.viewport?.width,"Browser smoke viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser smoke viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser smoke minimumLuminance",0,255,2),h,l,i,s,w=false,m=$(void 0,false),g=[],T=null,z=ce,y={requested:e.hmrModule!==void 0,module:e.hmrModule??null,dispatched:false,acknowledged:false,lifecycleStable:e.hmrModule===void 0,sourceUnchanged:e.hmrModule===void 0,evidenceSource:"public-runtime-browser-probe",evidence:ce,restart:J,error:e.hmrModule===void 0?null:"HMR was not reached."},q=false,B=false,O={fatalVisible:false,code:null,detail:null},E={states:[],fallbackObserved:false,recovered:false,visibleElements:0,totalElements:0},v={snapshots:0,textures:0,shaderMode:null,mainPanels:false},A=[],I=0,L=0,P={console:[],page:[]},j,K=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),K].filter(Boolean).join(F.delimiter);try{let k=o("silent");k.warn=H=>{A.push(mr(H));},h=await t({root:n,logLevel:"silent",customLogger:k,plugins:[Xe()],optimizeDeps:{force:!0,include:[...rr]},server:{host:"127.0.0.1",port:0,strictPort:!1}}),await h.listen();let x=h.httpServer?.address();if(!x||typeof x=="string")throw new Error("Vite did not expose an ephemeral TCP address.");let R=`http://127.0.0.1:${x.port}`;l=await r.launch({headless:c$1(e.headed===!0),args:[...b$1()]}),i=await l.newContext({viewport:f}),await i.addInitScript({content:`
229
+ (() => {
230
+ const key = '__three-blocks-text-fallback-states-v1';
231
+ let states = [];
232
+ try { states = JSON.parse( sessionStorage.getItem( key ) || '[]' ); } catch {}
233
+ const probe = globalThis.__threeBlocksTextFallbackProbe = { states };
234
+ const record = value => {
235
+ if ( typeof value !== 'string' || value.length === 0 || probe.states.at( -1 ) === value || probe.states.length >= 32 ) return;
236
+ probe.states.push( value );
237
+ try { sessionStorage.setItem( key, JSON.stringify( probe.states ) ); } catch {}
238
+ };
239
+ const inspect = node => {
240
+ if ( node && node.nodeType === 1 ) record( node.getAttribute( 'data-three-blocks-text-state' ) );
241
+ };
242
+ new MutationObserver( records => {
243
+ for ( const mutation of records ) {
244
+ inspect( mutation.target );
245
+ for ( const node of mutation.addedNodes || [] ) {
246
+ inspect( node );
247
+ if ( node.querySelectorAll ) for ( const child of node.querySelectorAll( '[data-three-blocks-text-state]' ) ) inspect( child );
248
+ }
249
+ }
250
+ } ).observe( document, { subtree: true, childList: true, attributes: true, attributeFilter: [ 'data-three-blocks-text-state' ] } );
251
+ })();
252
+ `}),e.forceWebgl===!0&&await i.addInitScript(()=>{Object.defineProperty(Navigator.prototype,"gpu",{configurable:!0,value:void 0});}),e.unsupportedWorker===!0&&await i.addInitScript(()=>{Object.defineProperty(globalThis,"Worker",{configurable:!0,value:void 0});}),s=await i.newPage();let C=s;if(j=Te(s),s.on("console",H=>{/WebGPU is not available, running under WebGL2 backend/iu.test(H.text())&&(B=!0);}),await s.goto(yr(h,R,a$1),{waitUntil:"domcontentloaded",timeout:d}),e.unsupportedWorker===!0)q=await Re(async()=>{await de(C,a(async()=>{await C.waitForFunction(()=>globalThis.document.querySelector("#three-blocks-dev-overlay")?.shadowRoot?.querySelector(".dot")?.dataset.tone==="error",void 0,{timeout:Math.min(d,15e3)});},"waitForFailure"),d);},()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0)),O=await Ye(s),m=$(await U(s),!1);else {let H=a(()=>e.expectTextGenerationFailure===!0?Se(C,d):Z(C,!1,d),"initialReadiness");q=await Re(()=>de(C,H,d),()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0));let _=await sr(s,H,d);if(w=_.textEnabled,g=_.codecs,T=_.receipt,z=_.hmrEvidence,e.expectTextGenerationFailure===!0){if(!_.textEnabled)throw new Error("Expected text-generation failure mode requires a text-enabled project.");await Se(s,d);let W=performance.now()+Math.min(d,3e4);for(;!A.some(je=>/automatic atlas generation failed/iu.test(je));){if(performance.now()>=W)throw new Error("Timed out waiting for the automatic text-generation failure warning.");await s.waitForTimeout(50);}m=$(await U(s),!0);}else if(await Z(s,_.textEnabled,d),m=$(await U(s),_.textEnabled),_.textEnabled&&m.textReady&&(g=g.map(W=>W.name==="ktx2"?{...W,decoded:!0,evidence:"text-atlas-decoded",blocker:null}:W)),y=await dr(h,s,n,e.hmrModule,d,_.textEnabled,z),e.hmrModule!==void 0){let W=await cr(s,d,_.textEnabled,_.receipt.shaders.mode);y={...y,restart:W},m=$(await U(s),_.textEnabled);}}c>0&&await s.waitForTimeout(c),E=await xe(s),v=await Y(s);let Oe=await s.screenshot({type:"png"});I=ie(Oe),L=await ue(s);}catch(k){if(s!==void 0)try{m=$(await U(s),w),E=await xe(s),v=await Y(s);let x=await s.screenshot({type:"png"});I=ie(x),L=await ue(s);}catch(x){P.page.push(`Failure diagnostics could not be captured: ${x instanceof Error?x.message:String(x)}`);}P.page.push(k instanceof Error?k.message:String(k));}finally{j!==void 0&&(P.console.push(...j.console),P.page.push(...j.page)),await i?.close().catch(R=>{P.page.push(`Browser context cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),await l?.close().catch(R=>{P.page.push(`Browser cleanup failed: ${R instanceof Error?R.message:String(R)}`);});let k=h?.httpServer,x=k?Reflect.get(k,"closeAllConnections"):void 0;k&&typeof x=="function"&&Reflect.apply(x,k,[]),await h?.close().catch(R=>{P.page.push(`Vite cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),K===void 0?delete process.env.PATH:process.env.PATH=K;}let X=Number(I.toFixed(2)),M=Number(L.toFixed(2)),fe=I<=p&&L<=p,Q=ur(P.console,P.page,E.recovered),pe=Q.console,we=Q.page,Me=Q.resolved,he=m.worker&&m.workerReady&&m.assetsReady&&m.compileEnd&&m.textReady&&m.firstFrame,Ce=g.length===3&&g.every(k=>k.state!=="error"),Fe=Object.values(y.evidence).every(Boolean),Ae=!y.restart.requested||y.restart.error===null&&[y.restart.appIdentityStable,y.restart.contentIdentityStable,y.restart.canvasReplaced,y.restart.workerIdentityChanged,y.restart.generationAdvanced,y.restart.restartCountAdvanced,y.restart.stateReplayed,y.restart.readinessRestored,y.restart.shaderModeStable,y.restart.statsSnapshotsAdvanced,y.restart.statsTextureTransferred,y.restart.statsTextureStopped].every(Boolean),be=!y.requested||y.dispatched&&y.acknowledged&&y.lifecycleStable&&y.sourceUnchanged&&Fe&&Ae&&y.error===null,ke=A.filter(k=>/automatic atlas generation failed/iu.test(k)),$e=ke.reduce((k,x)=>k+(x.match(/three-blocks text generate/gu)?.length??0),0),Ie=e.expectTextGenerationFailure===true&&w&&E.fallbackObserved&&!E.recovered&&E.totalElements>0&&E.visibleElements===E.totalElements&&ke.length===1&&$e===1,Le=e.unsupportedWorker===true&&O.fatalVisible&&O.code==="render-worker-unavailable"&&!m.workerReady&&!m.compileEnd&&!m.firstFrame,We=e.unsupportedWorker===true?"unsupported-worker":e.forceWebgl===true?"WebGL-fallback":"WebGPU-first",Ve=e.unsupportedWorker===true?"none":he?e.forceWebgl===true||!q?"WebGL":"WebGPU":"unknown",qe=m.workerReady&&m.compileEnd&&m.firstFrame,b={schemaVersion:1,command:"browser smoke",passed:e.unsupportedWorker===true?Le:e.expectTextGenerationFailure===true?Ie:he&&Ce&&be&&!fe&&pe.length===0&&we.length===0,scene:a$1,lifecycle:m,renderer:{requested:We,active:Ve,navigatorGpu:q,workerOwned:qe,fallbackDiagnostic:B},compatibility:{...O,silentMainThreadRenderer:e.unsupportedWorker===true&&(m.compileEnd||m.firstFrame)},receipt:T,textFallback:E,warnings:D(A),rendering:{luminance:X,panelLuminance:M,threshold:p,blackFrame:fe},codecs:g,hmr:y,errors:{console:pe,page:we,resolved:Me}};if(b.passed&&e.unsupportedWorker!==true&&e.expectTextGenerationFailure!==true){if(b.receipt===null||b.lifecycle.backend==="unknown"||b.renderer.active!=="WebGPU"&&b.renderer.active!=="WebGL")throw new Error("A successful browser smoke cannot write runtime status without an observed backend and renderer/build receipt.");let k=b.hmr.requested,x=k?be:null,R={schemaVersion:1,observedAt:new Date().toISOString(),worker:{backend:b.lifecycle.backend,renderer:b.renderer.active,protocolVersion:1},assets:{codecs:b.codecs.map(C=>({name:C.name,available:C.state==="ready",decoded:C.decoded})),resources:0},hmr:{capabilities:{scene:true,component:true,assetManifest:true,workerRestart:true},outcome:{attempted:k,succeeded:x,rollbackPreserved:k?b.hmr.evidence.rollbackPreserved:null,workerRestarted:b.hmr.restart.requested&&b.hmr.restart.workerIdentityChanged}},stats:{snapshots:v.snapshots,textures:v.textures,workerProfiler:v.snapshots>0,mainPanels:v.mainPanels},lifecycle:{state:"first frame",workerReady:b.lifecycle.workerReady,assetsReady:b.lifecycle.assetsReady,compiled:b.lifecycle.compileEnd,firstFrame:b.lifecycle.firstFrame},shaders:{mode:v.shaderMode??b.receipt.shaders.mode,pipelines:b.receipt.shaders.pipelines},...b.receipt.text===void 0?{}:{text:{state:b.receipt.text.state,atlases:b.receipt.text.atlases,glyphs:b.receipt.text.glyphs,requiredGlyphs:b.receipt.text.glyphs}},error:null};await Ze(n,R);}return b}a(xr,"runBrowserSmoke");function Sr(e){let r=e.lifecycle,o=[`${e.passed?"\u2713":"\u2717"} Browser ${e.scene} \xB7 worker ${r.worker&&r.workerReady?"ready":"failed"} \xB7 assets ${r.assetsReady?"ready":"failed"} \xB7 compile ${r.compileEnd?"ready":"failed"}`,` Renderer ${e.renderer.active} \xB7 ${e.renderer.workerOwned?"worker-owned":e.renderer.requested}`,` Frame ${e.rendering.luminance.toFixed(2)} \xB7 panel ${e.rendering.panelLuminance.toFixed(2)}${e.rendering.blackFrame?" \xB7 black":""}`,` Codecs ${e.codecs.map(t=>`${t.name} ${t.state}${t.decoded?" decoded":""}`).join(" \xB7 ")||"not observed"}`];e.compatibility.fatalVisible&&o.push(` Compatibility ${e.compatibility.detail??"fatal compatibility screen visible"}`),e.textFallback.states.length>0&&o.push(` Text ${e.textFallback.states.join(" \u2192 ")}`),e.hmr.requested&&o.push(` HMR ${e.hmr.acknowledged&&e.hmr.sourceUnchanged&&Object.values(e.hmr.evidence).every(Boolean)?"ready":"failed"} \xB7 ${e.hmr.module??"unknown module"}`),e.hmr.restart.requested&&o.push(` Restart ${e.hmr.restart.error===null&&e.hmr.restart.workerIdentityChanged&&e.hmr.restart.stateReplayed?"ready":"failed"} \xB7 worker/state/stats`);for(let t of e.warnings)o.push(` Warning ${t}`);for(let t of e.errors.console)o.push(` Console ${t}`);for(let t of e.errors.page)o.push(` Page ${t}`);for(let t of e.errors.resolved)o.push(` Recovered ${t}`);e.hmr.error&&o.push(` HMR error ${e.hmr.error}`),e.hmr.restart.error&&o.push(` Restart error ${e.hmr.restart.error}`);for(let t of e.codecs)t.error&&o.push(` ${t.name} error ${t.error}`);return o.join(`
253
+ `)}a(Sr,"formatBrowserSmokeReport");async function Rr(e){let{chromium:r,vite:{build:o,preview:t}}=await Ee(),n=await realpath(e.root),a=(e.routes===void 0||e.routes.length===0?["/"]:e.routes).map(Pe),d=V(e.timeoutMs,"Browser preview timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser preview settleMs",0,1e4,500),f={width:V(e.viewport?.width,"Browser preview viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser preview viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser preview minimumLuminance",0,255,2),h=e.expectShaders??"precompiled",l=e.text===true,i=[],s,w,m=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),m].filter(Boolean).join(F.delimiter);try{await o({root:n,logLevel:"warn",...e.buildMode===void 0?{}:{mode:e.buildMode}}),s=await t({root:n,logLevel:"warn",preview:{host:"127.0.0.1",port:0,strictPort:!1,open:!1}});let g=s.httpServer?.address();if(!g||typeof g=="string")throw new Error("Vite preview did not expose an ephemeral TCP address.");let T=s.config.base.startsWith("/")?s.config.base:"/",z=`http://127.0.0.1:${g.port}${T.endsWith("/")?T:`${T}/`}`;w=await r.launch({headless:c$1(e.headed===!0),args:[...b$1()]});for(let y of a){let q=await w.newContext({viewport:f}),B=await q.newPage(),O=Te(B),E=[],v=$(void 0,l),A=null,I=0,L=0;try{await B.goto(new URL(y.replace(/^\/+/,""),z).href,{waitUntil:"domcontentloaded",timeout:d}),await Z(B,l,d),c>0&&await B.waitForTimeout(c),v=$(await U(B),l),A=(await Y(B)).shaderMode;let M=await B.screenshot({type:"png"});I=ie(M),L=await ue(B);}catch(M){try{v=$(await U(B),l),A=(await Y(B)).shaderMode;}catch{}E.push(M instanceof Error?M.message:String(M));}finally{await q.close().catch(M=>{E.push(`Browser context cleanup failed: ${M instanceof Error?M.message:String(M)}`);});}let P=D(O.console),j=D([...O.page,...E]),K=v.worker&&v.workerReady&&v.assetsReady&&v.compileEnd&&v.textReady&&v.firstFrame,X=I<=p&&L<=p;i.push({route:y,passed:K&&!X&&A===h&&P.length===0&&j.length===0,lifecycle:v,shaderMode:A,rendering:{luminance:Number(I.toFixed(2)),panelLuminance:Number(L.toFixed(2)),threshold:p,blackFrame:X},errors:{console:P,page:j}});}}finally{await w?.close().catch(()=>{});let g=s?.httpServer,T=g?Reflect.get(g,"closeAllConnections"):void 0;g&&typeof T=="function"&&Reflect.apply(T,g,[]),await s?.close().catch(()=>{}),m===void 0?delete process.env.PATH:process.env.PATH=m;}return {schemaVersion:1,command:"browser preview",passed:i.length>0&&i.every(g=>g.passed),buildMode:e.buildMode??null,expectShaders:h,routes:i}}a(Rr,"runBrowserPreview");function Br(e){let r=[`${e.passed?"\u2713":"\u2717"} Preview production build${e.buildMode===null?"":` \xB7 --mode ${e.buildMode}`} \xB7 expects shaders ${e.expectShaders}`];for(let o of e.routes){let t=o.lifecycle;r.push(` ${o.passed?"\u2713":"\u2717"} ${o.route} \xB7 worker ${t.worker&&t.workerReady?"ready":"failed"} \xB7 compile ${t.compileEnd?"ready":"failed"} \xB7 shaders ${o.shaderMode??"unobserved"} \xB7 frame ${o.rendering.luminance.toFixed(2)}${o.rendering.blackFrame?" \xB7 black":""}`);for(let n of o.errors.console)r.push(` Console ${n}`);for(let n of o.errors.page)r.push(` Page ${n}`);}return r.join(`
254
+ `)}a(Br,"formatBrowserPreviewReport");export{rr as BROWSER_SMOKE_OPTIMIZE_DEPENDENCIES,ur as classifyRecoveredTextErrors,Br as formatBrowserPreviewReport,Sr as formatBrowserSmokeReport,$ as parseBrowserSmokeLifecycle,Re as readAfterInitialReadiness,Rr as runBrowserPreview,xr as runBrowserSmoke,ie as screenshotLuminance};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import {d as d$2,b as b$2,c as c$3,g as g$2}from'./chunk-76WRV5MZ.js';import {g as g$1}from'./chunk-JMS5NTP7.js';import {a as a$3,c as c$2,b,d as d$1}from'./chunk-ME3X2KFY.js';import {a as a$1,c,b as b$1}from'./chunk-ZDNZCQUQ.js';import {j,d,i,a as a$2,c as c$1}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath}from'fs/promises';import h from'path';var re=".three-blocks/runtime/status.json",se=256*1024,H="three-blocks browser smoke",ne=["three-blocks.json","three-blocks.shaders.json","three-blocks.text.ts"];function ee(e){return "kind"in e&&e.kind==="adopted"}a(ee,"isAdoptedProjectStatus");async function O(e,t,r,s){let n=await j(e,t,r,s);return JSON.parse(n.data.toString("utf8"))}a(O,"readJsonWithin");var ae=["starting","worker ready","assets ready","compiled","first frame","updating","error"],oe=["ready","generating","fallback","missing","invalid"],ie=["WebGPU","WebGL"],de=["OffscreenCanvas","MainThread"],ce=/^[0-9A-Za-z][0-9A-Za-z._-]{0,63}$/,X=16,K=1e9;function g(e,t,r,s=[]){if(!a$1(e))throw new Error(`${t} must be an object.`);let n=new Set([...r,...s]);for(let o of r)if(!Object.hasOwn(e,o))throw new Error(`${t}.${o} is required.`);for(let o of Object.keys(e))if(!n.has(o))throw new Error(`${t}.${o} is not supported by schema v1.`);return e}a(g,"exactRecord");function A(e,t,r){if(typeof e!="string"||!t.includes(e))throw new Error(`${r} has an unsupported value.`);return e}a(A,"enumValue");function p(e,t){if(typeof e!="boolean")throw new Error(`${t} must be a boolean.`);return e}a(p,"booleanValue");function Y(e,t){return e===null?null:p(e,t)}a(Y,"nullableBoolean");function E(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<0||e>K)throw new Error(`${t} must be a non-negative integer no greater than ${K}.`);return e}a(E,"boundedCounter");function ue(e){if(typeof e!="string"||e.length>32)throw new Error("Runtime status receipt observedAt must be a bounded ISO timestamp.");let t=Date.parse(e);if(!Number.isFinite(t)||new Date(t).toISOString()!==e)throw new Error("Runtime status receipt observedAt must be an exact ISO timestamp.");return e}a(ue,"observedTimestamp");function le(e){if(e===null)return null;if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error("Runtime status receipt error must be null or one bounded display-safe line.");return e}a(le,"receiptError");function me(e){if(!Array.isArray(e)||e.length>X)throw new Error(`Runtime status receipt assets.codecs must contain at most ${X} entries.`);let t=e.map((r,s)=>{let n=g(r,`Runtime status receipt assets.codecs[${s}]`,["name","available","decoded"]);if(typeof n.name!="string"||!ce.test(n.name))throw new Error(`Runtime status receipt assets.codecs[${s}].name is invalid.`);let o=p(n.available,`Runtime status receipt assets.codecs[${s}].available`),a=p(n.decoded,`Runtime status receipt assets.codecs[${s}].decoded`);if(a&&!o)throw new Error(`Runtime status receipt codec ${JSON.stringify(n.name)} cannot be decoded when unavailable.`);return {name:n.name,available:o,decoded:a}});if(new Set(t.map(r=>r.name)).size!==t.length)throw new Error("Runtime status receipt assets.codecs must have unique names.");return t}a(me,"parseRuntimeCodecs");function pe(e){if(e.assetsReady&&!e.workerReady)throw new Error("Runtime lifecycle assetsReady requires workerReady.");if(e.compiled&&!e.assetsReady)throw new Error("Runtime lifecycle compiled requires assetsReady.");if(e.firstFrame&&!e.compiled)throw new Error("Runtime lifecycle firstFrame requires compiled.");let t=e.state==="starting"?[false,false,false,false]:e.state==="worker ready"?[true,false,false,false]:e.state==="assets ready"?[true,true,false,false]:e.state==="compiled"?[true,true,true,false]:e.state==="first frame"||e.state==="updating"?[true,true,true,true]:null;if(t!==null&&![e.workerReady,e.assetsReady,e.compiled,e.firstFrame].every((r,s)=>r===t[s]))throw new Error(`Runtime lifecycle flags do not match state ${JSON.stringify(e.state)}.`)}a(pe,"validateLifecycle");function he(e){let t=g(e,"Runtime status receipt",["schemaVersion","observedAt","worker","assets","hmr","stats","lifecycle","shaders","error"],["text"]);if(t.schemaVersion!==1)throw new Error("Runtime status receipt must use schemaVersion 1.");let r=g(t.worker,"Runtime status receipt worker",["backend","renderer","protocolVersion"]);if(r.protocolVersion!==1)throw new Error("Runtime status receipt worker.protocolVersion must be 1.");let s=g(t.assets,"Runtime status receipt assets",["codecs","resources"]),n=g(t.hmr,"Runtime status receipt hmr",["capabilities","outcome"]),o=g(n.capabilities,"Runtime status receipt hmr.capabilities",["scene","component","assetManifest","workerRestart"]),a=g(n.outcome,"Runtime status receipt hmr.outcome",["attempted","succeeded","rollbackPreserved","workerRestarted"]),d=p(a.attempted,"Runtime status receipt hmr.outcome.attempted"),l=Y(a.succeeded,"Runtime status receipt hmr.outcome.succeeded"),m=Y(a.rollbackPreserved,"Runtime status receipt hmr.outcome.rollbackPreserved"),y=p(a.workerRestarted,"Runtime status receipt hmr.outcome.workerRestarted");if(d?l===null||m===null:l!==null||m!==null||y)throw new Error("Runtime status receipt HMR outcome fields are inconsistent with attempted.");let k={scene:p(o.scene,"Runtime status receipt hmr.capabilities.scene"),component:p(o.component,"Runtime status receipt hmr.capabilities.component"),assetManifest:p(o.assetManifest,"Runtime status receipt hmr.capabilities.assetManifest"),workerRestart:p(o.workerRestart,"Runtime status receipt hmr.capabilities.workerRestart")};if(d&&!k.scene)throw new Error("Runtime status receipt cannot attempt HMR without the scene capability.");if(y&&!k.workerRestart)throw new Error("Runtime status receipt cannot restart a worker without the workerRestart capability.");let x=g(t.stats,"Runtime status receipt stats",["snapshots","textures","workerProfiler","mainPanels"]),R=g(t.lifecycle,"Runtime status receipt lifecycle",["state","workerReady","assetsReady","compiled","firstFrame"]),S={state:A(R.state,ae,"Runtime status receipt lifecycle.state"),workerReady:p(R.workerReady,"Runtime status receipt lifecycle.workerReady"),assetsReady:p(R.assetsReady,"Runtime status receipt lifecycle.assetsReady"),compiled:p(R.compiled,"Runtime status receipt lifecycle.compiled"),firstFrame:p(R.firstFrame,"Runtime status receipt lifecycle.firstFrame")};pe(S);let V=g(t.shaders,"Runtime status receipt shaders",["mode","pipelines"]),P=A(V.mode,["precompiled","live"],"Runtime status receipt shaders.mode"),T=E(V.pipelines,"Runtime status receipt shaders.pipelines");if(P==="precompiled"&&T===0)throw new Error("A precompiled runtime receipt must observe at least one shader pipeline.");let f;if(t.text!==void 0){let I=g(t.text,"Runtime status receipt text",["state","atlases","glyphs","requiredGlyphs"]);if(f={state:A(I.state,oe,"Runtime status receipt text.state"),atlases:E(I.atlases,"Runtime status receipt text.atlases"),glyphs:E(I.glyphs,"Runtime status receipt text.glyphs"),requiredGlyphs:E(I.requiredGlyphs,"Runtime status receipt text.requiredGlyphs")},f.state==="ready"&&(f.atlases===0||f.requiredGlyphs===0||f.glyphs<f.requiredGlyphs))throw new Error("A ready text receipt must cover a non-empty required glyph set with at least one atlas.")}let b=le(t.error);if(S.state==="error"?b===null:b!==null)throw new Error("Runtime status receipt error must be present only when lifecycle.state is error.");return {schemaVersion:1,observedAt:ue(t.observedAt),worker:{backend:A(r.backend,de,"Runtime status receipt worker.backend"),renderer:A(r.renderer,ie,"Runtime status receipt worker.renderer"),protocolVersion:1},assets:{codecs:me(s.codecs),resources:E(s.resources,"Runtime status receipt assets.resources")},hmr:{capabilities:k,outcome:{attempted:d,succeeded:l,rollbackPreserved:m,workerRestarted:y}},stats:{snapshots:E(x.snapshots,"Runtime status receipt stats.snapshots"),textures:E(x.textures,"Runtime status receipt stats.textures"),workerProfiler:p(x.workerProfiler,"Runtime status receipt stats.workerProfiler"),mainPanels:p(x.mainPanels,"Runtime status receipt stats.mainPanels")},lifecycle:S,shaders:{mode:P,pipelines:T},...f===void 0?{}:{text:f},error:b}}a(he,"parseRuntimeStatusReceipt");function fe(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(fe,"sameCoverage");async function te(e=process.cwd()){let t=h.resolve(e);for(;;){if((await Promise.all(ne.map(s=>d(h.join(t,s))))).some(Boolean))return realpath(t);let r=h.dirname(t);if(r===t)return realpath(h.resolve(e));t=r;}}a(te,"findProjectRoot");async function ye(e,t){let r=t.template,s=h.join(e,".three-blocks","shaders"),n=h.join(s,"meta.json");if(!await d(s)||!await d(n))return {state:"missing",scene:r,reason:t.artifacts?.shaders==="pending"?"The selected template has no verified shader capture yet.":".three-blocks/shaders/meta.json is absent."};try{let o=await i(e,s,"Shader artifact directory"),a=c(await O(o,n,a$2.receipt,"Shader receipt")),d=a.scenes[r];if(d===void 0)return {state:"invalid",scene:r,reason:`Shader receipt has no "${r}" scene.`};let l=await j(o,h.join(o,d.artifact),a$2.manifest,"Shader manifest");if(c$1(l.data)!==d.artifactHash)return {state:"invalid",scene:r,reason:"The selected shader manifest checksum does not match its receipt."};let m=a$3(l.data.toString("utf8"),l.path,r);if(!fe(m,d.coverage))return {state:"invalid",scene:r,reason:"Shader receipt coverage does not match the manifest entries.",coverage:m};let{three:y,threeBlocks:k,threeBlocksShaderClosure:x}=await c$2(e);if(a.runtime.three!==y||t.runtime.three!==y||a.runtime.threeBlocks!==k||t.runtime.threeBlocks!==k)return {state:"stale",scene:r,reason:`Installed runtime versions (${y}, ${k}) do not match the metadata and shader receipt.`,coverage:m};if(a.runtime.threeBlocksShaderClosure!==x)return {state:"stale",scene:r,reason:"The installed three-blocks/shaders runtime closure differs from the capture receipt.",coverage:m};let R=await b(e),S=Object.keys(R),V=Object.keys(d.inputs),P=S.filter(b=>!Object.hasOwn(d.inputs,b)),T=V.filter(b=>!Object.hasOwn(R,b)),f=S.filter(b=>Object.hasOwn(d.inputs,b)&&d.inputs[b]!==R[b]);return P.length>0||T.length>0||f.length>0?{state:"stale",scene:r,reason:`${P.length} added, ${T.length} removed, and ${f.length} changed semantic shader inputs.`,coverage:m,...f.length>0?{changedInputs:f}:{},...P.length>0?{addedInputs:P}:{},...T.length>0?{removedInputs:T}:{}}:{state:"fresh",scene:r,reason:"Manifest, installed shader runtime closure, and the shader-relevant source snapshot match.",coverage:m}}catch(o){return {state:"invalid",scene:r,reason:o instanceof Error?o.message:String(o)}}}a(ye,"inspectShaders");async function Re(e,t){if(t.artifacts?.text==="pending")return {state:"missing",reason:"The template has no verified text artifacts yet.",atlases:[]};let r=await g$1(e);return {state:r.state,reason:r.reason,atlases:r.atlases.map(s=>({name:s.font.key,glyphs:s.codePoints.length,width:s.texture.width,height:s.texture.height}))}}a(Re,"inspectText");function be(e,t){if(e.lifecycle.assetsReady&&e.assets.codecs.some(r=>!r.available))throw new Error("Runtime status receipt claims assets ready while a configured codec is unavailable.");if(t.features.text!==(e.text!==void 0))throw new Error("Runtime status receipt text observation does not match three-blocks.json.")}a(be,"validateRuntimeReceiptForProject");async function ge(e,t){let r=h.join(e,...re.split("/"));if(!await d(r))return {kind:"absent",receipt:null,reason:"No browser observation receipt is available."};try{let s=await i(e,h.dirname(r),"Runtime status receipt directory"),n=he(await O(s,h.join(s,h.basename(r)),se,"Runtime status receipt"));return be(n,t),{kind:"valid",receipt:n,reason:n.error??`Browser observation captured at ${n.observedAt}.`}}catch(s){return {kind:"invalid",receipt:null,reason:`Runtime status receipt is invalid: ${s instanceof Error?s.message:String(s)}`}}}a(ge,"inspectRuntimeReceipt");function we(){return {scene:false,component:false,assetManifest:false,workerRestart:false}}a(we,"emptyCapabilities");function ke(){return {attempted:false,succeeded:null,rollbackPreserved:null,workerRestarted:false}}a(ke,"emptyOutcome");function Se(){return []}a(Se,"configuredCodecs");function xe(e,t,r){if(t.state!=="fresh")return "three-blocks shaders capture";if(r!==void 0&&r.state!=="ready")return "three-blocks text generate";let s=e.receipt;return e.kind!=="valid"||s===null||s.lifecycle.state==="error"?H:s.text!==void 0&&s.text.state!=="ready"?"three-blocks text generate":H}a(xe,"recoveryCommand");async function $e(e=process.cwd()){let t=await te(e),r=b$1(await O(t,h.join(t,"three-blocks.json"),a$2.metadata,"Project metadata")),s=await ye(t,r),n=r.features.text?await Re(t,r):void 0,o=await ge(t,r),a=o.receipt,d=o.kind==="invalid",l=d||a?.lifecycle.state==="error",m=a===null?{state:d?"error":"starting",backend:null,renderer:null,protocolVersion:1}:{state:l?"error":a.lifecycle.workerReady?"worker ready":"starting",backend:a.worker.backend,renderer:a.worker.renderer,protocolVersion:a.worker.protocolVersion},y=a===null?{state:d?"error":"starting",codecs:Se(),resources:0}:{state:l?"error":a.lifecycle.assetsReady?"assets ready":"starting",codecs:a.assets.codecs,resources:a.assets.resources},k=a===null?{state:d?"error":"starting",capabilities:we(),outcome:ke()}:{state:l||a.hmr.outcome.attempted&&(a.hmr.outcome.succeeded!==true||a.hmr.outcome.rollbackPreserved!==true)?"error":a.hmr.outcome.attempted?"first frame":"starting",capabilities:a.hmr.capabilities,outcome:a.hmr.outcome},x=a===null?{state:d?"error":"starting",snapshots:0,textures:0,workerProfiler:false,mainPanels:false}:{state:l?"error":a.stats.snapshots>0&&a.stats.workerProfiler&&a.stats.mainPanels?"first frame":"starting",...a.stats},R=a===null?{state:d?"error":"starting",mode:null,pipelines:0,artifactState:s.state}:{state:l?"error":a.lifecycle.compiled?s.state==="fresh"?a.shaders.mode:s.state:a.lifecycle.state,mode:a.shaders.mode,pipelines:a.shaders.pipelines,artifactState:s.state},S=n===void 0?void 0:a?.text===void 0?{state:d?"error":"starting",atlases:0,glyphs:0,requiredGlyphs:0}:{state:l?"error":n.state==="ready"?a.text.state:n.state,atlases:a.text.atlases,glyphs:a.text.glyphs,requiredGlyphs:a.text.requiredGlyphs};return {schemaVersion:1,root:t,metadata:r,configuration:{worker:m,assets:y,hmr:k,optimization:R,stats:x,...S===void 0?{}:{text:S}},runtime:{state:d?"error":a?.lifecycle.state??"starting",observed:a!==null,observedAt:a?.observedAt??null,reason:o.reason,recovery:xe(o,s,n),observation:a},shaders:s,...n?{text:n}:{}}}a($e,"inspectProject");async function Z(e){let[t,r]=await Promise.all([d(h.join(e,"three-blocks.shaders.json")),d(h.join(e,"three-blocks.text.ts"))]),[s,n]=await Promise.all([t?d$1(e):Promise.resolve(void 0),r?g$1(e):Promise.resolve(void 0)]);return {schemaVersion:1,root:e,kind:"adopted",markers:{shaders:t,text:r},...s===void 0?{}:{shaders:s},...n===void 0?{}:{text:n}}}a(Z,"inspectAdoptedProject");async function qe(e=process.cwd()){let t=await te(e),r=h.join(t,"three-blocks.json");if(await d(r)){try{b$1(await O(t,r,a$2.metadata,"Project metadata"));}catch{return Z(t)}return $e(t)}return Z(t)}a(qe,"inspectThreeBlocksStatus");function Ge(e){return ee(e)?(e.markers.shaders||e.markers.text)&&(e.shaders===void 0||e.shaders.state==="fresh")&&(e.text===void 0||e.text.state==="ready"):e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"}a(Ge,"threeBlocksStatusIsFresh");function ve(e){return e==="ktx2"?"KTX2":e==="draco"?"Draco":e==="meshopt"?"Meshopt":e}a(ve,"codecName");function Pe(e,t=Date.now()){let r=t-Date.parse(e);if(!Number.isFinite(r)||r<0)return e;let s=Math.round(r/1e3);if(s<60)return "just now";let n=Math.round(s/60);if(n<60)return `${n} minute${n===1?"":"s"} ago`;let o=Math.round(n/60);return o<48?`${o} hour${o===1?"":"s"} ago`:`${Math.round(o/24)} days ago`}a(Pe,"relativeTime");function w(e,t,r){return `${e} ${d$2(t,12)} ${r}`}a(w,"row");function v(e,t){return ` ${d$2(b$2.dim(e),12)} ${b$2.dim(t)}`}a(v,"subRow");function Q(e){return e<100?e.toFixed(1):Math.round(e).toString()}a(Q,"milliseconds");function Te(e){return e?`${e.render} render \xB7 ${e.compute} compute`:"no coverage"}a(Te,"coverageText");function je(e){let t=[w(g$2(e.state),"shaders",`${e.state==="fresh"?"fresh":b$2.warn(e.state)} ${c$3.dot} ${b$2.dim(e.reason)}`)];for(let r of e.scenes){let s=r.timing,n=s?.source==="committed-capture"?`Committed capture \xB7 recorded on ${s.adapter??"unknown adapter"}`:"Latest local capture",o=s===void 0?"":`n=${s.runs}`,a=s===void 0?"":`\u2248${Q(s.avoidedBuildMs)} ms \xB1 ${Q(s.spreadMs)} TSL build time saved`,d=s===void 0?r.state==="fresh"?` ${c$3.dot} ${b$2.dim("Build timing not recorded for this capture \xB7 run three-blocks shaders test")}`:"":` ${c$3.dot} ${b$2.dim(`${a} \xB7 ${o} \xB7 ${n}`)}`;t.push(w(g$2(r.state),r.scene,`${r.state} ${c$3.dot} ${Te(r.coverage)}${d}`)),s!==void 0&&s.spreadMs>s.avoidedBuildMs*.4&&t.push(v("measure",b$2.warn("noisy measurement \u2014 close other GPU apps and re-run")));let l=[...r.changedInputs??[],...r.addedInputs??[],...r.removedInputs??[]];l.length>0&&t.push(v("changed",l.join(", ")));}return e.state!=="fresh"&&t.push(`${c$3.info} ${b$2.accent("three-blocks shaders capture")}`),t.join(`
3
+ `)}a(je,"formatShaderMatrixStatus");function Ee(e){let t=e.scene,r=e.coverage,s=r?`${r.render} render \xB7 ${r.compute} compute`:"no coverage";if(e.state==="fresh")return [w(g$2("fresh"),t,`fresh ${c$3.dot} ${s} ${c$3.dot} ${b$2.dim("precompiled at runtime")}`)];let n=[w(g$2(e.state),t,`${e.state==="missing"?b$2.dim("missing"):b$2.warn(e.state)} ${c$3.dot} ${b$2.dim(e.reason)}`)],o=[...e.changedInputs??[],...e.addedInputs??[],...e.removedInputs??[]];return o.length>0&&n.push(v("changed",o.join(", "))),n}a(Ee,"shaderRow");function Me(e,t=Date.now()){let r=c$3.mark?`${c$3.mark} `:"",s=e.metadata.runtime,n=[`${r}${b$2.bold("three-blocks")} ${b$2.dim("status")}`,v("project",e.root),"",b$2.bold("Project"),w(c$3.tick,e.metadata.template,`three ${s.three} ${c$3.dot} three-blocks ${s.threeBlocks}`),"",b$2.bold("Shaders"),...Ee(e.shaders)];if(e.text){let d=e.text,l=d.atlases.reduce((m,y)=>m+y.glyphs,0);n.push("",b$2.bold("Text"),w(g$2(d.state),"coverage",d.state==="ready"?`ready ${c$3.dot} ${l} glyphs ${c$3.dot} ${d.atlases.length} atlas${d.atlases.length===1?"":"es"}`:`${b$2.warn(d.state)} ${c$3.dot} ${b$2.dim(d.reason)}`),...d.atlases.map(m=>v("atlas",`${m.name} \xB7 ${m.glyphs} glyphs \xB7 ${m.width}\xD7${m.height}`)));}let o=e.runtime.observation;if(n.push("",b$2.bold("Browser check")),o!==null&&e.runtime.state!=="error"){let d=o.assets.codecs.map(l=>`${ve(l.name)}${l.decoded?"":l.available?" (idle)":" (unavailable)"}`).join(" \xB7 ");n.push(w(c$3.tick,"verified",`${Pe(o.observedAt,t)} ${c$3.dot} ${o.worker.renderer} worker ${c$3.dot} ${o.lifecycle.state} ${c$3.dot} ${o.shaders.pipelines} pipeline${o.shaders.pipelines===1?"":"s"} ${o.shaders.mode}`),v("codecs",d||"none configured")),o.hmr.outcome.attempted&&n.push(v("hmr",o.hmr.outcome.succeeded?`update succeeded${o.hmr.outcome.workerRestarted?" \xB7 worker restarted":""}`:"update failed"));}else e.runtime.state==="error"?n.push(w(c$3.cross,"runtime",b$2.danger(e.runtime.reason))):n.push(w(c$3.ring,"unverified",b$2.dim(`no browser run recorded \u2014 ${H}`)));return e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"||n.push("",b$2.bold("Next"),`${c$3.info} ${b$2.accent(e.runtime.recovery)}`),n.join(`
4
+ `)}a(Me,"formatStatus");function He(e,t=Date.now()){if(!ee(e))return Me(e,t);let r=c$3.mark?`${c$3.mark} `:"",s=e.markers.shaders||e.markers.text,n=[`${r}${b$2.bold("three-blocks")} ${b$2.dim("status")}`,v("project",e.root)];if(!s)return n.push("",`${c$3.dot} ${b$2.dim("no Three Blocks project markers found")}`,` ${b$2.dim("shaders:")} add three-blocks.shaders.json \u2014 /docs/tools/devtools`,` ${b$2.dim("starter:")} npx three-blocks starter`),n.join(`
5
+ `);if(e.shaders!==void 0&&n.push("",b$2.bold("Shaders"),je(e.shaders)),e.text!==void 0){let o=e.text.atlases.reduce((a,d)=>a+d.codePoints.length,0);n.push("",b$2.bold("Text"),w(g$2(e.text.state),"coverage",e.text.state==="ready"?`ready ${c$3.dot} ${o} glyphs ${c$3.dot} ${e.text.atlases.length} atlas${e.text.atlases.length===1?"":"es"}`:`${b$2.warn(e.text.state)} ${c$3.dot} ${b$2.dim(e.text.reason)}`));}return n.join(`
6
+ `)}a(He,"formatThreeBlocksStatus");export{re as a,se as b,H as c,he as d,te as e,$e as f,qe as g,Ge as h,je as i,Me as j,He as k};
@@ -0,0 +1 @@
1
+ 'use strict';var fs=require('fs'),module$1=require('module'),d=require('path'),shaders=require('three-blocks/shaders'),vite=require('three-blocks/vite');require('fs/promises'),require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var d__default=/*#__PURE__*/_interopDefault(d);var x=Object.defineProperty;var i=(e,r)=>x(e,"name",{value:r,configurable:true});function g(e){let r=e.split("?",1)[0];return r===void 0?false:r.split(d__default.default.sep).join("/").endsWith("/build/three.webgpu.js")}i(g,"isThreeWebGPUModule");function M(e){let r=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(e);return r?.[1]==="0"&&r[2]==="185"}i(M,"supportedVersion");function m(e,r,t={}){if(!M(r))throw new Error(`Shader provider transform ${shaders.THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${r}".`);let n=vite.transformThreeWebgpuProviderHooks(e,{threeVersion:r,id:"three/build/three.webgpu.js"}),s=n.state==="already-applied",o=n.code;return t.instrumentCapture&&(o=vite.transformThreeWebgpuCaptureInstrumentation(o,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport}}).code),{code:o,alreadyPresent:s,captureApplied:t.instrumentCapture===true}}i(m,"applyShaderProviderTransform");var y="@three-blocks/devtools/webpack-loader";function w(e){if(typeof e=="string")return e===y;if(Array.isArray(e))return e.some(w);if(e===null||typeof e!="object")return false;let r=e;return r.loader===y||w(r.use)}i(w,"webpackRuleUsesShaderLoader");function E(e){let r=S(process.cwd()),t=i(s=>T(r,s),"exact"),n={...e.resolve?.alias,...t("three")===void 0?{}:{three$:t("three")},...t("three/webgpu")===void 0?{}:{"three/webgpu$":t("three/webgpu")},...t("three/tsl")===void 0?{}:{"three/tsl$":t("three/tsl")},"three/addons":d__default.default.join(r.root,"examples/jsm"),"three/examples/jsm":d__default.default.join(r.root,"examples/jsm")};return {...e,resolve:{...e.resolve,alias:n}}}i(E,"withTargetThreeAliases");function k(e){let r=E(e),t=r.module?.rules??[];return t.some(w)?r:{...r,module:{...r.module,rules:[...t,{enforce:"pre",test:/three[\\/]build[\\/]three\.webgpu\.js$/u,use:[{loader:y}]}]}}}i(k,"withShaderWebpackRule");function pr(e){return k(e)}i(pr,"withThreeBlocksWebpack");function fr(e){let t=e.webpack;return {...e,webpack(n,...s){let o=t?.call(this,n,...s)??n,a=s[0];return a!==null&&typeof a=="object"&&Reflect.get(a,"isServer")===true?E(o):k(o)}}}i(fr,"withThreeBlocksNext");function S(e){let r;try{r=module$1.createRequire(d__default.default.join(d__default.default.resolve(e),"package.json")).resolve("three");}catch(o){throw new Error("The shader adapter could not resolve Three.js from the target project.",{cause:o})}let t=d__default.default.dirname(r),n,s;for(;;){let o=d__default.default.join(t,"package.json");if(fs.existsSync(o)){let c=JSON.parse(fs.readFileSync(o,"utf8"));if(c.name==="three"){n=o,s=c;break}}let a=d__default.default.dirname(t);if(a===t)break;t=a;}if(n===void 0)throw new Error(`The shader adapter could not locate Three.js package metadata from ${r}.`);if(typeof s?.version!="string"||s.version.length===0)throw new Error(`The resolved Three.js package has no version: ${n}`);return {root:d__default.default.dirname(n),version:s.version,exports:s.exports}}i(S,"resolveThreePackage");function F(e=process.cwd()){return S(e).version}i(F,"resolveShaderAdapterThreeVersion");function R(e){return {version:e.threeVersion??F(e.root),capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"}}i(R,"resolvedOptions");function mr(e,r,t={}){if(!g(r))return null;let n=R(t);return m(e,n.version,{instrumentCapture:n.capture})}i(mr,"transformThreeWebGPUModule");function h(e){if(typeof e=="string")return e;if(Array.isArray(e)){for(let t of e){let n=h(t);if(n!==void 0)return n}return}if(e===null||typeof e!="object")return;let r=e;for(let t of ["browser","import","default"]){let n=h(r[t]);if(n!==void 0)return n}}i(h,"exportTarget");function T(e,r){if(e.exports===null||typeof e.exports!="object")return;let t=e.exports,n=r==="three"?".":`./${r.slice(6)}`,s=h(t[n]);if(s!==void 0)return d__default.default.resolve(e.root,s);for(let[o,a]of Object.entries(t)){let c=o.indexOf("*");if(c<0)continue;let u=o.slice(0,c),l=o.slice(c+1);if(!n.startsWith(u)||!n.endsWith(l))continue;let p=n.slice(u.length,n.length-l.length),f=h(a);if(f!==void 0)return d__default.default.resolve(e.root,f.replaceAll("*",p))}}i(T,"resolveThreeExport");function hr(e={}){let r=e.root??process.cwd(),t=S(r),n={version:e.threeVersion??t.version,capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"};return {name:"three-blocks-shader-provider",setup(s){s.onResolve?.({filter:/^three(?:\/.*)?$/},o=>{let a=T(t,o.path);return a===void 0?void 0:{path:a}}),s.onLoad({filter:/three[\\/]build[\\/]three\.webgpu\.js$/},async o=>{let a=await new Promise((u,l)=>{fs.readFile(o.path,"utf8",(p,f)=>{p?l(p):u(f);});});return {contents:m(a,n.version,{instrumentCapture:n.capture}).code,loader:"js"}});}}}i(hr,"createEsbuildShaderPlugin");function gr(e={}){let r=R(e);return {name:"three-blocks-shader-provider",enforce:"pre",transform(t,n){return g(n)?{code:m(t,r.version,{instrumentCapture:r.capture}).code,map:null}:null}}}i(gr,"createRollupShaderPlugin");exports.a=i;exports.b=y;exports.c=pr;exports.d=fr;exports.e=F;exports.f=mr;exports.g=hr;exports.h=gr;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import {a}from'./chunk-HOZDD6PW.js';import {createHash,randomUUID}from'crypto';import {lstat,open,realpath,mkdir,rename,rm,link,readdir}from'fs/promises';import a$1 from'path';var L=Object.freeze({metadata:1024*1024,receipt:2*1024*1024,manifest:32*1024*1024,semanticInput:8*1024*1024,semanticTotal:64*1024*1024,metrics:8*1024*1024,texture:128*1024*1024,packageJson:1024*1024});function h(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:void 0}a(h,"errorCode");function R(e){return createHash("sha256").update(e).digest("hex")}a(R,"sha256");async function D(e){try{return await lstat(e),!0}catch(i){if(h(i)==="ENOENT")return false;throw i}}a(D,"pathExists");function m(e,i){let t=a$1.relative(e,i);return t===""||!a$1.isAbsolute(t)&&t!==".."&&!t.startsWith(`..${a$1.sep}`)}a(m,"isWithin");function w(e){return JSON.stringify(e)}a(w,"displayPath");async function F(e,i,t){let n=await open(e,"r");try{let[r,o,l]=await Promise.all([lstat(e),n.stat(),realpath(e)]);if(r.isSymbolicLink())throw new Error(`${t} must not be a symbolic link: ${w(e)}.`);if(!o.isFile())throw new Error(`${t} must be a regular file: ${w(e)}.`);if(o.size>i)throw new Error(`${t} exceeds the ${i}-byte inspection limit: ${w(e)}.`);let c=await n.readFile();if(c.byteLength>i)throw new Error(`${t} grew beyond the ${i}-byte inspection limit while being read.`);return {path:l,data:c}}finally{await n.close();}}a(F,"readBoundedRegularFile");async function U(e,i){let t=a$1.dirname(e);await mkdir(t,{recursive:true});try{if((await lstat(e)).isSymbolicLink())throw new Error(`Atomic write target must not be a symbolic link: ${w(e)}.`)}catch(o){if(h(o)!=="ENOENT")throw o}let n=a$1.join(t,`.${a$1.basename(e)}.${process.pid}.${randomUUID()}.tmp`),r;try{r=await open(n,"wx",384),await r.writeFile(i),await r.sync(),await r.close(),r=void 0,await rename(n,e);}finally{await r?.close().catch(()=>{}),await rm(n,{force:true});}}a(U,"writeAtomicRegularFile");async function O(e,i){let t=a$1.dirname(e);await mkdir(t,{recursive:true});let n=a$1.join(t,`.${a$1.basename(e)}.${process.pid}.${randomUUID()}.tmp`),r;try{r=await open(n,"wx",384),await r.writeFile(i),await r.sync(),await r.close(),r=void 0;try{return await link(n,e),!0}catch(o){if(h(o)==="EEXIST")return !1;throw o}}finally{await r?.close().catch(()=>{}),await rm(n,{force:true});}}a(O,"writeNewRegularFile");async function W(e,i,t){return F(e,i,t)}a(W,"readExternalRegularFile");async function $(e,i,t){let n=a$1.resolve(e),r=a$1.resolve(i);if(!m(n,r))throw new Error(`${t} escapes its allowed directory.`);let o=await lstat(r);if(o.isSymbolicLink())throw new Error(`${t} must not be a symbolic link.`);if(!o.isDirectory())throw new Error(`${t} must be a directory.`);let[l,c]=await Promise.all([realpath(n),realpath(r)]);if(!m(l,c))throw new Error(`${t} resolves outside its allowed directory.`);return c}a($,"canonicalDirectoryWithin");async function j(e,i,t,n){let r=a$1.resolve(e),o=a$1.resolve(i);if(!m(r,o)||r===o)throw new Error(`${n} escapes its allowed directory.`);let l=await F(o,t,n),c=await realpath(r);if(!m(c,l.path)||c===l.path)throw new Error(`${n} resolves outside its allowed directory.`);return l}a(j,"readRegularFileWithin");async function z(e,i,t,n=8192){let o=[await $(e,i,"Inspected directory")],l=[],c=0;for(;o.length>0;){let p=o.shift();if(p===void 0)break;let v=(await readdir(p,{withFileTypes:true})).sort((d,u)=>d.name.localeCompare(u.name));for(let d of v){if(c+=1,c>n)throw new Error(`Inspected directory exceeds the ${n}-entry limit.`);let u=a$1.join(p,d.name);if(d.isSymbolicLink())throw new Error(`Inspected directory contains a symbolic link: ${w(a$1.relative(e,u))}.`);if(d.isDirectory()){o.push(await $(e,u,"Nested inspected directory"));continue}if(d.isFile()&&t(d.name))l.push(u);else if(t(d.name))throw new Error(`Semantic input is not a regular file: ${w(u)}.`)}}return l.sort()}a(z,"listRegularFilesRecursively");export{L as a,h as b,R as c,D as d,m as e,U as f,O as g,W as h,$ as i,j,z as k};
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import {a}from'./chunk-HOZDD6PW.js';function C(n=process.env,r=process.stdout){if(n.NO_COLOR!==void 0)return 0;if(n.FORCE_COLOR!==void 0){let t=String(n.FORCE_COLOR);return t==="0"||t==="false"?0:t==="3"?24:t==="2"?8:4}return !r||!r.isTTY||n.TERM==="dumb"?0:/^(truecolor|24bit)$/i.test(n.COLORTERM??"")||n.WT_SESSION||n.TERM_PROGRAM==="iTerm.app"||n.TERM_PROGRAM==="vscode"?24:/-256(color)?$/i.test(n.TERM??"")?8:4}a(C,"resolveColorDepth");function I(n=process.env,r=process.platform){return r!=="win32"?true:!!(n.WT_SESSION||n.TERM_PROGRAM||n.ConEmuANSI||/-256(color)?$/i.test(n.TERM??""))}a(I,"resolveUnicode");function k(n=process.stdout){let r=n?.columns;return typeof r=="number"&&Number.isInteger(r)&&r>0?r:80}a(k,"termWidth");var S={depth:C(),unicode:I(),fancy:!!process.stdout.isTTY&&process.env.TERM!=="dumb",get width(){return k()}},g={logo:{square:[30,84,200]},accent:[86,132,230],gold:[244,174,12],danger:[221,76,51],live:[212,255,71]};function W(n,r,t){if(Math.max(n,r,t)-Math.min(n,r,t)<12){let u=Math.round((n+r+t)/3);return u<8?16:u>238?231:232+Math.round((u-8)/10)}let s=a(u=>u<48?0:u<115?1:Math.min(5,Math.round((u-35)/40)),"level");return 16+36*s(n)+6*s(r)+s(t)}a(W,"ansi256");function m(n,r,t){return t>=24?`38;2;${n[0]};${n[1]};${n[2]}`:t>=8?`38;5;${W(n[0],n[1],n[2])}`:String(r)}a(m,"fgOpen");function A(n=S.depth,r=S.unicode){let t=n>0?(s,u=39)=>o=>`\x1B[${s}m${String(o)}\x1B[${u}m`:()=>s=>String(s);return {depth:n,unicode:r,accent:t(m(g.accent,94,n)),live:t(m(g.live,92,n)),danger:t(m(g.danger,91,n)),gold:t(m(g.gold,33,n)),deep:t(m(g.logo.square,34,n)),warn:t(m(g.gold,33,n)),dim:t(2,22),bold:t(1,22)}}a(A,"createTheme");function N(n){let r=n.unicode;return {tick:n.live(r?"\u2713":"\u221A"),cross:n.danger(r?"\u2717":"x"),warn:n.warn(r?"\u25B2":"!"),info:n.accent(r?"\u203A":">"),pointer:n.accent(r?"\u276F":">"),dot:n.dim(r?"\xB7":"."),ring:n.dim(r?"\u25CB":"o"),bar:r?"\u2502":"|",ellipsis:r?"\u2026":"...",mark:r?`${n.gold("\u25B2")} ${n.danger("\u25CF")} ${n.deep("\u25A0")}`:null,spin:r?["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]:["-","\\","|","/"]}}a(N,"createSymbols");var $=A(),d=N($),_=/\x1b\[[0-9;]*m/g,G=/(\x1b\[[0-9;]*m)/;function Y(n){return String(n).replace(_,"")}a(Y,"stripAnsi");function M(n){return n===8203||n===8205||n>=768&&n<=879||n>=65024&&n<=65039?0:n>=4352&&n<=4447||n>=11904&&n<=42191||n>=44032&&n<=55203||n>=63744&&n<=64255||n>=65072&&n<=65103||n>=65280&&n<=65376||n>=65504&&n<=65510||n>=127744&&n<=129791||n>=131072&&n<=262141?2:1}a(M,"charWidth");function b(n){let r=0;for(let t of Y(n))r+=M(t.codePointAt(0)??0);return r}a(b,"visibleWidth");function T(n){let r=Number(n.split(";")[0]);return r>=30&&r<=38||r>=90&&r<=97}a(T,"isForeground");function D(n,r){let t=r.slice(2,-1);if(t===""||t==="0")return [];let s=t.split(";")[0];if(s==="22")return n.filter(o=>o!=="1"&&o!=="2");if(s==="39")return n.filter(o=>!T(o));let u=T(t)?n.filter(o=>!T(o)):n.filter(o=>o!==t);return u.push(t),u}a(D,"advanceSgr");var v=a(n=>n.length?"\x1B[0m":"","closeIf");function E(n,r,t="\u2026"){let s=String(n);if(b(s)<=r)return s;let u=Math.max(0,r-b(t)),o="",a=0,l=[];for(let p of s.split(G))if(p){if(p.startsWith("\x1B[")){l=D(l,p),o+=p;continue}for(let c of p){let i=M(c.codePointAt(0)??0);if(a+i>u)return o+v(l)+t;o+=c,a+=i;}}return o+v(l)+t}a(E,"truncateAnsi");function L(n,r){let t=r-b(String(n));return t>0?String(n)+" ".repeat(t):String(n)}a(L,"padEndAnsi");function K(n,r={}){let{gap:t=2,indent:s=0,maxWidth:u}=r;if(!n.length)return [];let o=Math.max(...n.map(c=>c.length)),a$1=new Array(o).fill(0);for(let c of n)c.forEach((i,f)=>{a$1[f]=Math.max(a$1[f]??0,b(i));});if(u){let c=a(()=>s+a$1.reduce((i,f)=>i+f,0)+t*(o-1),"total");for(;c()>u;){let i=a$1.indexOf(Math.max(...a$1)),f=a$1[i];if(f===void 0||f<=6)break;a$1[i]=f-1;}}let l=" ".repeat(s),p=" ".repeat(t);return n.map(c=>(l+c.map((i,f)=>{let x=a$1[f]??0,h=E(i,x);return f===c.length-1?h:L(h,x)}).join(p)).trimEnd())}a(K,"columns");function j(n="",r=process.stdout){r.write(`${n}
3
+ `);}a(j,"log");function q(n){return ["fresh","ready","precompiled","passed","captured","verified","first frame","compiled","worker ready","assets ready"].includes(n)?d.tick:["stale","live","generating","fallback","updating","skipped"].includes(n)?d.warn:["missing","starting","not-observed","unobserved"].includes(n)?d.ring:d.cross}a(q,"stateMark");var w=new Set,O=false;function B(){if(!O){O=true,process.on("exit",R);for(let n of ["SIGINT","SIGTERM"])process.on(n,()=>{R(),process.exit(n==="SIGINT"?130:143);});}}a(B,"hook");function y(n){return B(),w.add(n),()=>w.delete(n)}a(y,"registerCleanup");function R(){for(let n of [...w].reverse()){w.delete(n);try{n();}catch{}}}a(R,"runCleanups");function F(n){if(!n.isTTY)return ()=>{};n.write("\x1B[?25l");let r=false,t=a(()=>{r||(r=true,n.write("\x1B[?25h"));},"show"),s=y(t);return ()=>{t(),s();}}a(F,"hideCursor");function J(n,r=process.stdout){let t=n;if(!r.isTTY)return r.write(`${d.dot} ${t}
4
+ `),{update(i){i!==t&&(t=i,r.write(`${d.dot} ${t}
5
+ `));},stop(i){i&&r.write(`${i}
6
+ `);}};let s=Date.now(),u=0,o=F(r),a$1=a(()=>{let i=Date.now()-s,f=i>=2e3?$.dim(` ${Math.round(i/1e3)}s`):"",x=`${$.accent(d.spin[u++%d.spin.length]??"")} ${t}${f}`;r.write(`\r\x1B[2K${E(x,k(r)-1)}`);},"render");a$1();let l=setInterval(a$1,80);l.unref?.();let p=y(()=>{clearInterval(l),r.write("\r\x1B[2K");}),c=false;return {update(i){t=i;},stop(i){c||(c=true,clearInterval(l),p(),o(),r.write("\r\x1B[2K"),i&&r.write(`${i}
7
+ `));}}}a(J,"spinner");export{S as a,$ as b,d as c,L as d,K as e,j as f,q as g,J as h};
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var d=(a,b)=>c(a,"name",{value:b,configurable:true});export{d as a};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ var c=Object.defineProperty;var d=(a,b)=>c(a,"name",{value:b,configurable:true});export{d as a};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {a as a$1,b as b$1}from'./chunk-ZDNZCQUQ.js';import {d as d$1,j as j$1,a as a$2,g}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath,readFile}from'fs/promises';import d from'path';var b="three-blocks.shaders.json",I=".three-blocks/shaders",O=".three-blocks/shaders/parity",_=/^[a-z0-9][a-z0-9_-]{0,63}$/u,C=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u,R=64,E=64,j={schemaVersion:1,scenes:[{key:"default",url:"/"}]};function x(n,r,e){if(n===void 0)return e;if(typeof n!="string"||n.length===0||n.length>512||d.isAbsolute(n)||/[\u0000-\u001f\u007f]/u.test(n))throw new Error(`${r} must be a bounded project-relative directory.`);let i=d.posix.normalize(n.replaceAll("\\","/")).replace(/\/+$/u,"");if(i==="."||i===".."||i.startsWith("../"))throw new Error(`${r} must stay inside the project.`);return i}a(x,"safeProjectDirectory");function P(n,r){let e=x(n,r,"");if(typeof n!="string"||n.endsWith("/"))throw new Error(`${r} must be a project-relative file.`);return e}a(P,"safeProjectFile");function u(n,r,e,i,o){if(n===void 0)return o;if(!Number.isSafeInteger(n)||Number(n)<e||Number(n)>i)throw new Error(`${r} must be an integer in ${e}...${i}.`);return Number(n)}a(u,"boundedInteger");function $(n,r,e){if(n===void 0)return e;if(typeof n!="number"||!Number.isFinite(n)||n<0||n>1)throw new Error(`${r} must be a finite ratio in 0...1.`);return n}a($,"finiteRatio");function T(n,r){if(typeof n!="string"||n.length===0||n.length>2048||/[\u0000-\u001f\u007f]/u.test(n))throw new Error(`${r} must be a bounded project-relative URL.`);let e;try{e=new URL(n,"http://three-blocks.invalid/");}catch{throw new Error(`${r} is not a valid URL.`)}if(e.origin!=="http://three-blocks.invalid"||e.hash.length>0)throw new Error(`${r} must stay within the project and must not contain a fragment.`);return `${e.pathname}${e.search}`}a(T,"safeBrowserUrl");function A(n){if(!Array.isArray(n)||n.length===0||n.length>R)throw new Error(`Shader config scenes must contain 1...${R} entries.`);let r=new Set;return n.map((e,i)=>{if(!a$1(e)||typeof e.key!="string"||!_.test(e.key))throw new Error(`Shader config scene ${i} has an invalid key.`);if(r.has(e.key))throw new Error(`Shader config scene key "${e.key}" is duplicated.`);r.add(e.key);let o=e.parityFrames,t=e.maxDiffRatio;if(e.inputs!==void 0&&(!Array.isArray(e.inputs)||e.inputs.length===0||e.inputs.length>E))throw new Error(`Shader config scene "${e.key}" inputs must contain 1...${E} files.`);let a=e.inputs===void 0?void 0:e.inputs.map((l,h)=>P(l,`Shader config scene "${e.key}" input ${h}`));if(a!==void 0&&new Set(a).size!==a.length)throw new Error(`Shader config scene "${e.key}" inputs must be unique.`);if(e.allowPipelineReuse!==void 0&&typeof e.allowPipelineReuse!="boolean")throw new Error(`Shader config scene "${e.key}" allowPipelineReuse must be a boolean.`);if(e.runtimeMotion!==void 0&&typeof e.runtimeMotion!="boolean")throw new Error(`Shader config scene "${e.key}" runtimeMotion must be a boolean.`);return {key:e.key,url:T(e.url,`Shader config scene "${e.key}" URL`),requiresText:e.requiresText===true,...a===void 0?{}:{inputs:a},...o===void 0?{}:{parityFrames:u(o,`Shader config scene "${e.key}" parityFrames`,0,1e4,0)},...t===void 0?{}:{maxDiffRatio:$(t,`Shader config scene "${e.key}" maxDiffRatio`,.01)},...e.allowPipelineReuse===true?{allowPipelineReuse:true}:{},...e.runtimeMotion===true?{runtimeMotion:true}:{}}})}a(A,"parseScenes");function y(n){if(!a$1(n)||n.schemaVersion!==void 0&&n.schemaVersion!==1)throw new Error("Shader config must use schemaVersion 1.");let r=n.viewport;if(r!==void 0&&!a$1(r))throw new Error("Shader config viewport must be an object.");let e=n.parity;if(e!==void 0&&!a$1(e))throw new Error("Shader config parity must be an object.");let i=n.bridge;if(i!==void 0&&!a$1(i))throw new Error("Shader config bridge must be an object.");let o=a$1(i)?i.deterministicModule:void 0;o!==void 0&&T(o,"Shader deterministic module");let t=n.readiness;if(t!==void 0&&!a$1(t))throw new Error("Shader config readiness must be an object.");let a=a$1(t)?t.selector:void 0;if(a!==void 0&&(typeof a!="string"||a.length===0||a.length>512||/[\u0000-\u001f\u007f]/u.test(a)))throw new Error("Shader readiness selector must be a bounded, non-empty CSS selector.");let l=a$1(t)?t.global:void 0;if(l!==void 0&&(typeof l!="string"||!C.test(l)))throw new Error("Shader readiness global must be a dot-separated JavaScript property path.");return {schemaVersion:1,scenes:A(n.scenes),settleFrames:u(n.settleFrames,"Shader settleFrames",0,1e4,60),settleTimeoutMs:u(n.settleTimeoutMs,"Shader settleTimeoutMs",1e3,15*6e4,3e4),browserRelaunchScenes:u(n.browserRelaunchScenes,"Shader browserRelaunchScenes",1,64,8),timeoutMs:u(n.timeoutMs,"Shader timeoutMs",1e3,15*6e4,24e4),viewport:{width:u(a$1(r)?r.width:void 0,"Shader viewport width",64,8192,1024),height:u(a$1(r)?r.height:void 0,"Shader viewport height",64,8192,640)},parity:{frames:u(a$1(e)?e.frames:void 0,"Shader parity frames",0,1e4,90),channelTolerance:u(a$1(e)?e.channelTolerance:void 0,"Shader parity channelTolerance",0,255,8),maxDiffRatio:$(a$1(e)?e.maxDiffRatio:void 0,"Shader parity maxDiffRatio",.01)},bridge:{legacyLab:a$1(i)&&i.legacyLab===true,...typeof o=="string"?{deterministicModule:o}:{}},readiness:{...typeof a=="string"?{selector:a}:{},...typeof l=="string"?{global:l}:{}},publicDir:x(n.publicDir,"Shader publicDir","public"),allowLiveBuilds:n.allowLiveBuilds!==false}}a(y,"parseShaderToolConfig");async function v(n=process.cwd()){let r=d.resolve(n);for(;;){if(await d$1(d.join(r,b))||await d$1(d.join(r,"three-blocks.json")))return realpath(r);let e=d.join(r,"package.json");if(await d$1(e)){let o=await j$1(r,e,a$2.packageJson,"Project package.json"),t;try{t=JSON.parse(o.data.toString("utf8"));}catch{throw new Error(`Project package.json is not valid JSON: ${e}.`)}if(a$1(t)&&[t.dependencies,t.devDependencies,t.peerDependencies,t.optionalDependencies].filter(a$1).some(h=>typeof h.three=="string"||typeof h["three-blocks"]=="string"||typeof h["@three-blocks/devtools"]=="string"))return realpath(r)}let i=d.dirname(r);if(i===r)throw new Error(`No Three Blocks shader project found from ${JSON.stringify(d.resolve(n))}; add Three.js to package.json or pass --root.`);r=i;}}a(v,"findShaderProjectRoot");async function w(n){let r=await realpath(n),e=d.join(r,b);if(await d$1(e)){let o=await j$1(r,e,a$2.metadata,"Shader configuration");return y(JSON.parse(o.data.toString("utf8")))}let i=d.join(r,"three-blocks.json");if(await d$1(i)){let o=b$1(JSON.parse(await readFile(i,"utf8")));return y({schemaVersion:1,scenes:[{key:o.template,url:"/",requiresText:o.features.text}]})}return y(j)}a(w,"loadShaderToolConfig");async function U(n){let r=await realpath(n);for(let t of ["vite.config.ts","vite.config.mts","vite.config.js","vite.config.mjs","vite.config.cts","vite.config.cjs"])if(await d$1(d.join(r,t)))return {driverKind:"vite",reason:`Detected ${t}.`};let e,i=d.join(r,"package.json");if(await d$1(i)){let t=await j$1(r,i,a$2.packageJson,"Project package.json"),a=JSON.parse(t.data.toString("utf8"));a$1(a)&&(e=a);}let o=a(t=>[e?.dependencies,e?.devDependencies,e?.peerDependencies,e?.optionalDependencies].some(a=>a$1(a)&&typeof a[t]=="string"),"hasDependency");if(o("vite"))return {driverKind:"vite",reason:"Detected the Vite dependency."};for(let t of ["dist","build","out"])if(await d$1(d.join(r,t,"index.html")))return {driverKind:"static",serve:t,reason:`Detected the built ${t}/index.html application.`};if(o("next"))throw new Error("Detected Next.js without an attach URL. Run `shaders capture` without an explicit driver or URL to preview the withThreeBlocksNext adapter and start a project-local capture server, or pass --url <local-url> for a server you manage.");if(o("webpack")||o("esbuild")||o("rollup"))throw new Error("Detected a non-Vite bundler but no static index.html. Run `shaders capture` without an explicit driver or URL to preview adapter wiring and build the project, or build it yourself and pass --driver static --serve <directory>.");return {driverKind:"vite",reason:"Using the Vite golden-path driver."}}a(U,"inferShaderCaptureTarget");async function V(n){let r=await realpath(n),e=d.join(r,b);if(await d$1(e))return {config:await w(r),file:e,created:false};let i=d.join(r,"three-blocks.json");if(await d$1(i))return {config:await w(r),file:i,created:false};let o=j,t=y(o),a=await g(e,`${JSON.stringify(o,null,2)}
3
+ `);return {config:a?t:await w(r),file:e,created:a}}a(V,"ensureShaderToolConfig");export{b as a,I as b,O as c,y as d,v as e,w as f,U as g,V as h};