@oeave/bakery3 0.2.0 → 0.3.0
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.
- package/dist/bake/index.js +3 -3
- package/dist/catalog/index.js +1 -1
- package/dist/{chunk-KNUAOILG.js → chunk-3T3FJOSD.js} +4 -4
- package/dist/{chunk-KNUAOILG.js.map → chunk-3T3FJOSD.js.map} +1 -1
- package/dist/{chunk-6FYI6AJM.js → chunk-6FAMQZXB.js} +7 -7
- package/dist/{chunk-6FYI6AJM.js.map → chunk-6FAMQZXB.js.map} +1 -1
- package/dist/{chunk-QRCT5UGZ.js → chunk-CSSJRP5W.js} +9 -6
- package/dist/chunk-CSSJRP5W.js.map +1 -0
- package/dist/{chunk-APWUCEEB.js → chunk-EN4ROBYQ.js} +3 -3
- package/dist/{chunk-APWUCEEB.js.map → chunk-EN4ROBYQ.js.map} +1 -1
- package/dist/{chunk-JFYUDERE.js → chunk-NEK5TBEH.js} +2 -2
- package/dist/chunk-NEK5TBEH.js.map +1 -0
- package/dist/chunk-OPM2L63B.js +253 -0
- package/dist/chunk-OPM2L63B.js.map +1 -0
- package/dist/{chunk-UWBP7B54.js → chunk-R5IUPOWI.js} +3 -3
- package/dist/{chunk-UWBP7B54.js.map → chunk-R5IUPOWI.js.map} +1 -1
- package/dist/{chunk-HNMSWQU7.js → chunk-STRK4SZN.js} +3 -3
- package/dist/{chunk-HNMSWQU7.js.map → chunk-STRK4SZN.js.map} +1 -1
- package/dist/{chunk-Z7IYVH22.js → chunk-WLEFNUOH.js} +30 -279
- package/dist/chunk-WLEFNUOH.js.map +1 -0
- package/dist/{chunk-NXBAZGNB.js → chunk-X6GW43EX.js} +3 -3
- package/dist/{chunk-NXBAZGNB.js.map → chunk-X6GW43EX.js.map} +1 -1
- package/dist/devtools/index.js +7 -6
- package/dist/hotspots/index.d.ts +237 -31
- package/dist/hotspots/index.js +1013 -118
- package/dist/hotspots/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -6
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +2 -2
- package/dist/presets/index.js +2 -2
- package/dist/r3f/index.js +9 -8
- package/dist/r3f/index.js.map +1 -1
- package/dist/{room-FS26KAPQ.js → room-BM7Z7NKG.js} +4 -4
- package/dist/{room-FS26KAPQ.js.map → room-BM7Z7NKG.js.map} +1 -1
- package/dist/session-NPVBESWA.js +9 -0
- package/dist/{session-VCIQEO26.js.map → session-NPVBESWA.js.map} +1 -1
- package/dist/tsl/index.d.ts +14 -1
- package/dist/tsl/index.js +8 -2
- package/dist/tsl/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JFYUDERE.js.map +0 -1
- package/dist/chunk-QRCT5UGZ.js.map +0 -1
- package/dist/chunk-Z7IYVH22.js.map +0 -1
- package/dist/session-VCIQEO26.js +0 -9
package/dist/bake/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { configureLightmap, createBakeSession } from '../chunk-
|
|
2
|
-
export { bakeCandidates } from '../chunk-
|
|
1
|
+
export { configureLightmap, createBakeSession } from '../chunk-3T3FJOSD.js';
|
|
2
|
+
export { bakeCandidates } from '../chunk-NEK5TBEH.js';
|
|
3
3
|
import '../chunk-4E5VV4QY.js';
|
|
4
|
-
export { BAKE_TEXTURE_SIZES, MAX_BAKE_OBJECTS, MAX_BAKE_TEXELS } from '../chunk-
|
|
4
|
+
export { BAKE_TEXTURE_SIZES, MAX_BAKE_OBJECTS, MAX_BAKE_TEXELS } from '../chunk-EN4ROBYQ.js';
|
|
5
5
|
import '../chunk-6NYR73Y7.js';
|
|
6
6
|
import '../chunk-LAKXC4WR.js';
|
|
7
7
|
import '../chunk-3G5QL4F4.js';
|
package/dist/catalog/index.js
CHANGED
|
@@ -83,7 +83,7 @@ function validate(catalog, options) {
|
|
|
83
83
|
}
|
|
84
84
|
async function mountRoom(scene, room) {
|
|
85
85
|
if (!room) return void 0;
|
|
86
|
-
const { createPresetRoom, findPresetRooms } = await import('../room-
|
|
86
|
+
const { createPresetRoom, findPresetRooms } = await import('../room-BM7Z7NKG.js');
|
|
87
87
|
if (findPresetRooms(scene).length) return void 0;
|
|
88
88
|
const group = createPresetRoom(
|
|
89
89
|
room.preset,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { buildPatch, probeTargets, bakeCandidates, configureShadow } from './chunk-
|
|
1
|
+
import { buildPatch, probeTargets, bakeCandidates, configureShadow } from './chunk-NEK5TBEH.js';
|
|
2
2
|
import { presetBaseUrl } from './chunk-4E5VV4QY.js';
|
|
3
|
-
import { prebakedRoomsUnder, findPresetRooms, roomShownBaked } from './chunk-
|
|
3
|
+
import { prebakedRoomsUnder, findPresetRooms, roomShownBaked } from './chunk-EN4ROBYQ.js';
|
|
4
4
|
import { PRESETS_VERSION } from './chunk-6NYR73Y7.js';
|
|
5
5
|
import { Bakery3Error } from './chunk-3G5QL4F4.js';
|
|
6
6
|
import { LinearSRGBColorSpace, SRGBColorSpace, LinearFilter, ClampToEdgeWrapping, TextureLoader, EquirectangularReflectionMapping, NoColorSpace } from 'three';
|
|
@@ -547,5 +547,5 @@ function disposedError(what) {
|
|
|
547
547
|
}
|
|
548
548
|
|
|
549
549
|
export { LIVE, configureLightmap, createBakeSession };
|
|
550
|
-
//# sourceMappingURL=chunk-
|
|
551
|
-
//# sourceMappingURL=chunk-
|
|
550
|
+
//# sourceMappingURL=chunk-3T3FJOSD.js.map
|
|
551
|
+
//# sourceMappingURL=chunk-3T3FJOSD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bake/textures.ts","../src/bake/session.ts"],"names":["byUrl"],"mappings":";;;;;;;;AAoEO,SAAS,iBAAA,CACd,SACA,MAAA,EACS;AACT,EAAA,OAAA,CAAQ,OAAA,GAAU,CAAA;AAClB,EAAA,OAAA,CAAQ,KAAA,GAAQ,KAAA;AAIhB,EAAA,OAAA,CAAQ,UAAA,GAAa,MAAA,KAAW,KAAA,GAAQ,oBAAA,GAAuB,cAAA;AAC/D,EAAA,OAAA,CAAQ,eAAA,GAAkB,KAAA;AAC1B,EAAA,OAAA,CAAQ,SAAA,GAAY,YAAA;AACpB,EAAA,OAAA,CAAQ,SAAA,GAAY,YAAA;AACpB,EAAA,OAAA,CAAQ,KAAA,GAAQ,mBAAA;AAChB,EAAA,OAAA,CAAQ,KAAA,GAAQ,mBAAA;AAChB,EAAA,OAAA,CAAQ,WAAA,GAAc,IAAA;AACtB,EAAA,OAAO,OAAA;AACT;AASO,SAAS,eAAe,OAAA,EAA2B;AACxD,EAAA,OAAA,CAAQ,OAAA,GAAU,gCAAA;AAClB,EAAA,OAAA,CAAQ,UAAA,GAAa,oBAAA;AACrB,EAAA,OAAA,CAAQ,WAAA,GAAc,IAAA;AACtB,EAAA,OAAO,OAAA;AACT;AAYO,SAAS,mBAAA,CACd,SACA,IAAA,EACS;AACT,EAAA,OAAA,CAAQ,OAAA,GAAU,CAAA;AAClB,EAAA,IAAI,SAAS,WAAA,EAAa;AACxB,IAAA,OAAA,CAAQ,UAAA,GAAa,oBAAA;AACrB,IAAA,OAAA,CAAQ,eAAA,GAAkB,KAAA;AAC1B,IAAA,OAAA,CAAQ,SAAA,GAAY,YAAA;AACpB,IAAA,OAAA,CAAQ,SAAA,GAAY,YAAA;AAAA,EACtB,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,KAAA,GAAQ,IAAA;AAChB,IAAA,OAAA,CAAQ,UAAA,GAAa,IAAA,KAAS,OAAA,GAAU,cAAA,GAAiB,YAAA;AAAA,EAC3D;AACA,EAAA,OAAA,CAAQ,KAAA,GAAQ,mBAAA;AAChB,EAAA,OAAA,CAAQ,KAAA,GAAQ,mBAAA;AAChB,EAAA,OAAA,CAAQ,WAAA,GAAc,IAAA;AACtB,EAAA,OAAO,OAAA;AACT;AAUO,SAAS,qBAAA,GAA4C;AAC1D,EAAA,MAAM,GAAA,GAAM,IAAI,SAAA,EAAU;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAI,aAAA,EAAc;AAG9B,EAAA,GAAA,CAAI,eAAe,WAAW,CAAA;AAC9B,EAAA,GAAA,CAAI,eAAe,WAAW,CAAA;AAE9B,EAAA,OAAO,OAAO,MAAA,KAAW;AACvB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,KAAW,KAAA,GAAQ,GAAA,GAAM,GAAA;AAC/C,IAAA,MAAM,UAAU,MAAM,IAAI,OAAA,CAAiB,CAAC,SAAS,MAAA,KAAW;AAC9D,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,MAAA,CAAO,GAAA;AAAA,QACP,CAAC,MAAA,KAAW,OAAA,CAAQ,MAAiB,CAAA;AAAA,QACrC,MAAA;AAAA,QACA,MACE,MAAA;AAAA,UACE,IAAI,YAAA,CAAa;AAAA,YACf,IAAA,EAAM,gBAAA;AAAA,YACN,OAAA,EACE,OAAO,IAAA,KAAS,OAAA,GACZ,yCACA,MAAA,CAAO,IAAA,KAAS,OAAA,IACd,MAAA,CAAO,IAAA,KAAS,QAAA,IAChB,OAAO,IAAA,KAAS,WAAA,GAChB,CAAA,mBAAA,EAAsB,MAAA,CAAO,IAAI,CAAA,SAAA,EAAY,OAAO,QAAQ,CAAA,EAAA,CAAA,GAC5D,CAAA,iCAAA,EAAoC,MAAA,CAAO,QAAQ,CAAA,EAAA,CAAA;AAAA,YAC3D,GAAA,EAAK,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA,mIAAA,CAAA;AAAA,YAClB,GAAA,EAAK;AAAA,WACN;AAAA;AACH,OACJ;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAI,MAAA,CAAO,IAAA,KAAS,OAAA,EAAS,OAAO,eAAe,OAAO,CAAA;AAC1D,IAAA,IAAI,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU,OAAO,gBAAgB,OAAO,CAAA;AAC5D,IAAA,IACE,MAAA,CAAO,SAAS,OAAA,IAChB,MAAA,CAAO,SAAS,QAAA,IAChB,MAAA,CAAO,SAAS,WAAA,EAChB;AACA,MAAA,OAAO,mBAAA,CAAoB,OAAA,EAAS,MAAA,CAAO,IAAI,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,iBAAA,CAAkB,OAAA,EAAS,MAAA,CAAO,MAAM,CAAA;AAAA,EACjD,CAAA;AACF;AASO,SAAS,gBAAA,CAAiB,KAAa,OAAA,EAA0B;AACtE,EAAA,IAAI,sBAAA,CAAuB,KAAK,GAAG,CAAA,IAAK,IAAI,UAAA,CAAW,IAAI,GAAG,OAAO,GAAA;AACrE,EAAA,IAAI,CAAC,SAAS,OAAO,GAAA;AACrB,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,GAAA,EAAK,OAAO,EAAE,QAAA,EAAS;AAAA,EACxC,CAAA,CAAA,MAAQ;AAGN,IAAA,OAAO,GAAA;AAAA,EACT;AACF;;;AC/JO,IAAM,IAAA,GAAO;AAwKb,SAAS,kBAAkB,OAAA,EAA0C;AAC1E,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,CAAA;AACvC,EAAA,MAAM,OAAA,GAAuB,QAAQ,OAAA,IAAW,SAAA;AAChD,EAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,uBAAuB,CAAC,CAAA;AAC7D,EAAA,IAAI,QAAA,GAAW,QAAQ,KAAA,IAAS,IAAA;AAChC,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,cAAA,IAAkB,qBAAA,EAAsB;AAEpE,EAAA,MAAM,cAAgC,EAAC;AACvC,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA8B;AACjD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoC;AAE1D,EAAA,IAAI,OAAA,GAAU,IAAA;AACd,EAAA,IAAI,KAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,UAAA,GAAqC,IAAA;AACzC,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,KAAA,GAA2D,IAAA;AAC/D,EAAA,IAAI,QAAA,GAAW,KAAA;AAGf,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,KAAA,GAAQ,CAAA;AAGZ,EAAA,IAAI,iBAA4C,EAAC;AAEjD,EAAA,SAAS,IAAA,GAAO;AACd,IAAA,KAAA,MAAW,QAAA,IAAY,SAAA,EAAW,QAAA,CAAS,OAAO,CAAA;AAAA,EACpD;AAEA,EAAA,SAAS,YAAA,GAAe;AACtB,IAAA,KAAA,EAAO,OAAA,EAAQ;AACf,IAAA,KAAA,GAAQ,IAAA;AACR,IAAA,SAAA,GAAY,KAAA;AAGZ,IAAA,KAAA,MAAW,IAAA,IAAQ,cAAA,EAAgB,IAAA,CAAK,MAAA,EAAO;AAC/C,IAAA,cAAA,GAAiB,EAAC;AAAA,EACpB;AAEA,EAAA,SAAS,kBAAkB,KAAA,EAAe;AACxC,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAC9B,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,KAAA,MAAW,OAAA,IAAW,IAAI,GAAA,CAAI,KAAA,CAAM,SAAS,MAAA,EAAQ,CAAA,EAAG,OAAA,CAAQ,OAAA,EAAQ;AACxE,IAAA,KAAA,MAAW,OAAA,IAAW,IAAI,GAAA,CAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAA,EAAO,IAAK,EAAE,CAAA;AAC/D,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAClB,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAO,EAAG;AACzC,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,WAAA,EAAa,IAAA,CAAK,IAAI,OAAA,EAAQ;AAAA,WAAA,IACvC,IAAA,CAAK,IAAA,KAAS,WAAA,EAAa,IAAA,CAAK,MAAM,OAAA,EAAQ;AAAA;AAErD,QAAA,KAAA,MAAW,WAAW,CAAC,IAAA,CAAK,OAAO,IAAA,CAAK,MAAA,EAAQ,KAAK,KAAK,CAAA;AACxD,UAAA,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACtB;AACA,IAAA,KAAA,CAAM,OAAO,OAAA,EAAQ;AACrB,IAAA,KAAA,CAAM,QAAQ,OAAA,EAAQ;AACtB,IAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AACnB,IAAA,MAAM,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,IAAA,IAAI,UAAA,aAAuB,MAAA,GAAS,KAAA;AAAA,EACtC;AAEA,EAAA,SAAS,MAAM,IAAA,EAAc;AAC3B,IAAA,IAAI,MAAA,CAAO,QAAQ,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAA,GAAS,CAAC,GAAG,MAAA,CAAO,OAAA,EAAS,CAAA,CAChC,MAAA,CAAO,CAAC,CAAC,KAAK,CAAA,KAAM,KAAA,KAAU,IAAI,CAAA,CAClC,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,GAAS,CAAA,CAAE,CAAC,CAAA,CAAE,MAAM,CAAA;AAC3C,IAAA,OAAO,MAAA,CAAO,IAAA,GAAO,QAAA,IAAY,MAAA,CAAO,MAAA,EAAQ;AAC9C,MAAA,iBAAA,CAAkB,MAAA,CAAO,KAAA,EAAM,CAAG,CAAC,CAAC,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,eAAe,aAAa,KAAA,EAA0C;AACpE,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACjC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,SAAS,EAAE,KAAA;AACpB,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,MAAM,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAqB;AAC1C,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AAIzC,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAqB;AAIvC,IAAA,KAAA,MAAW,KAAA,IAAS,UAAA,CAAW,MAAA,CAAO,OAAA,EAAS;AAC7C,MAAA,IAAI;AACF,QAAA,MAAM,MAAM,gBAAA,CAAiB,KAAA,CAAM,QAAA,CAAS,GAAA,EAAK,WAAW,OAAO,CAAA;AACnE,QAAA,IAAI,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAC3B,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,OAAA,GAAU,MAAM,WAAA,CAAY;AAAA,YAC1B,GAAA;AAAA,YACA,MAAA,EAAQ,MAAM,QAAA,CAAS,MAAA;AAAA,YACvB,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,IAAA,EAAM,MAAM,QAAA,CAAS;AAAA,WACtB,CAAA;AACD,UAAA,KAAA,CAAM,GAAA,CAAI,KAAK,OAAO,CAAA;AAAA,QACxB;AACA,QAAA,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,OAAO,CAAA;AAAA,MACtC,SAAS,KAAA,EAAO;AAId,QAAA,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MAC9C;AAAA,IACF;AACA,IAAA,MAAM,OAAA,uBAAc,GAAA,EAA2B;AAC/C,IAAA,KAAA,MAAW,KAAA,IAAS,UAAA,CAAW,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG;AACnD,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,IAAQ,CAAA,SAAA,EAAY,MAAM,KAAK,CAAA,CAAA;AACnD,MAAA,MAAM,OAAO,CACX,GAAA,EACA,MAAA,EACA,IAAA,EACA,SAEA,WAAA,CAAY;AAAA,QACV,GAAA,EAAK,gBAAA,CAAiB,GAAA,EAAK,UAAA,CAAW,OAAO,CAAA;AAAA,QAC7C,MAAA;AAAA,QACA,QAAA,EAAU,KAAA;AAAA,QACV,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AACH,MAAA,IAAI;AACF,QAAA,IAAI,KAAA,CAAM,SAAS,WAAA,EAAa;AAC9B,UAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAA,EAAO;AAAA,YACvB,IAAA,EAAM,WAAA;AAAA,YACN,GAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAK,KAAA,EAAO,WAAA,EAAa,KAAA,CAAM,GAAA,CAAI,KAAK;AAAA,WACnE,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,WAAA,EAAa;AACrC,UAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAA,EAAO;AAAA,YACvB,IAAA,EAAM,WAAA;AAAA,YACN,OAAO,MAAM,IAAA;AAAA,cACX,MAAM,QAAA,CAAS,GAAA;AAAA,cACf,KAAA;AAAA,cACA,UAAA;AAAA,cACA,MAAM,QAAA,CAAS;AAAA;AACjB,WACD,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA;AAC5B,UAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAA,EAAO;AAAA,YACvB,IAAA,EAAM,MAAA;AAAA,YACN,KAAA,EAAO,MAAM,IAAA,CAAK,KAAA,CAAM,MAAM,GAAA,EAAK,KAAA,EAAO,SAAS,IAAI,CAAA;AAAA,YACvD,MAAA,EAAQ,MAAM,IAAA,CAAK,KAAA,CAAM,OAAO,GAAA,EAAK,KAAA,EAAO,UAAU,IAAI,CAAA;AAAA,YAC1D,KAAA,EAAO,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,GAAA,EAAK,KAAA,EAAO,YAAY,IAAI;AAAA,WAC9D,CAAA;AAAA,QACH;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,QAAA,CAAS,IAAI,CAAA,SAAA,EAAY,KAAA,CAAM,KAAK,CAAA,CAAA,CAAA,EAAK,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MAC1D;AAAA,IACF;AACA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,UAAA,CAAW,OAAO,MAAA,EAAQ;AAC5B,MAAA,MAAM,WAAA,GAAc,WAAW,MAAA,CAAO,MAAA;AACtC,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,eAAA;AAAA,UACP,MAAM,WAAA,CAAY;AAAA,YAChB,GAAA,EAAK,gBAAA,CAAiB,WAAA,CAAY,GAAA,EAAK,WAAW,OAAO,CAAA;AAAA,YACzD,QAAQ,WAAA,CAAY,MAAA;AAAA,YACpB,QAAA,EAAU,QAAA;AAAA,YACV,MAAM,WAAA,CAAY,IAAA;AAAA,YAClB,IAAA,EAAM;AAAA,WACP;AAAA,SACH;AAAA,MACF,SAAS,KAAA,EAAO;AAGd,QAAA,QAAA,CAAS,GAAA,CAAI,QAAA,EAAU,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MACxC;AAAA,IACF;AAIA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI,UAAA;AAGJ,IAAA,MAAM,SAAA,GAAY,gBAAgB,KAAK,CAAA,CAAE,KAAK,cAAc,CAAA,GACxD,MAAA,GACA,UAAA,CAAW,MAAA,CAAO,IAAA;AACtB,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,IAAA,GAAO,CAAA,EAAA,CAAI,OAAA,CAAQ,aAAA,IAAiB,aAAA,EAAc,EAAG,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,EAAA,EAAK,eAAe,CAAA,CAAA,CAAA;AACjG,MAAA,MAAM,MAAM,IAAI,GAAA,CAAI,UAAU,GAAA,EAAK,IAAI,EAAE,QAAA,EAAS;AAClD,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAG,CAAA;AAChC,QAAA,IAAI,CAAC,QAAA,CAAS,EAAA;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAC7D,QAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AACpC,QAAA,MAAM,YAAA,uBAAmB,GAAA,EAAqB;AAC9C,QAAA,MAAMA,MAAAA,uBAAY,GAAA,EAAqB;AACvC,QAAA,KAAA,MAAW,KAAA,IAAS,OAAO,OAAA,EAAS;AAClC,UAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,KAAA,CAAM,QAAA,CAAS,KAAK,GAAG,CAAA;AAC3D,UAAA,IAAI,OAAA,GAAUA,MAAAA,CAAM,GAAA,CAAI,UAAU,CAAA;AAClC,UAAA,IAAI,CAAC,OAAA,EAAS;AACZ,YAAA,OAAA,GAAU,MAAM,WAAA,CAAY;AAAA,cAC1B,GAAA,EAAK,UAAA;AAAA,cACL,MAAA,EAAQ,MAAM,QAAA,CAAS,MAAA;AAAA,cACvB,UAAU,KAAA,CAAM,QAAA;AAAA,cAChB,IAAA,EAAM,MAAM,QAAA,CAAS;AAAA,aACtB,CAAA;AACD,YAAAA,MAAAA,CAAM,GAAA,CAAI,UAAA,EAAY,OAAO,CAAA;AAAA,UAC/B;AACA,UAAA,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,OAAO,CAAA;AAAA,QAC1C;AACA,QAAA,IAAA,GAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,GAAA,EAAK,UAAU,YAAA,EAAa;AAAA,MACxD,SAAS,KAAA,EAAO;AAGd,QAAA,UAAA,GAAa,SAAS,KAAK,CAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAA0B;AAAA,MAC9B,QAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAQ,EAAE,KAAA;AAAA,MACV,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AAAA,MAC3B,GAAI,IAAA,GAAO,EAAE,IAAA,KAAS,EAAC;AAAA,MACvB,GAAI,UAAA,GAAa,EAAE,UAAA,KAAe;AAAC,KACrC;AACA,IAAA,MAAA,CAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AACvB,IAAA,UAAA,CAAW,MAAA,GAAS,IAAA;AACpB,IAAA,OAAO,KAAA;AAAA,EACT;AASA,EAAA,eAAe,WAAA,CACb,OACA,KAAA,EAC8B;AAC9B,IAAA,IAAI,KAAA,CAAM,KAAA,IAAS,KAAA,CAAM,WAAA,SAAoB,KAAA,CAAM,KAAA;AACnD,IAAA,MAAM,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,IAAA,MAAM,UAAA,GAAa,WAAW,MAAA,CAAO,KAAA;AACrC,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,IAAI;AACF,MAAA,KAAA,CAAM,KAAA,GAAQ,cAAA;AAAA,QACZ,MAAM,WAAA,CAAY;AAAA,UAChB,GAAA,EAAK,gBAAA,CAAiB,UAAA,CAAW,GAAA,EAAK,WAAW,OAAO,CAAA;AAAA,UACxD,QAAQ,UAAA,CAAW,MAAA;AAAA,UACnB,QAAA,EAAU,OAAA;AAAA,UACV,MAAM,UAAA,CAAW,KAAA;AAAA,UACjB,IAAA,EAAM;AAAA,SACP;AAAA,OACH;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,KAAA,CAAM,WAAA,GAAc,SAAS,KAAK,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,KAAA,CAAM,KAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAuB;AAAA,IAC3B,IAAI,WAAA,GAAc;AAChB,MAAA,OAAO,WAAA;AAAA,IACT,CAAA;AAAA,IACA,IAAI,OAAA,GAAU;AACZ,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IACA,IAAI,UAAA,GAAa;AACf,MAAA,OAAO,UAAA;AAAA,IACT,CAAA;AAAA,IACA,IAAI,SAAA,GAAY;AACd,MAAA,OAAO,SAAA;AAAA,IACT,CAAA;AAAA,IACA,IAAI,WAAA,GAAc;AAChB,MAAA,OAAO,KAAA,KAAU,IAAA;AAAA,IACnB,CAAA;AAAA,IACA,IAAI,KAAA,GAAQ;AACV,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAAA,IAEA,UAAA,GAAa;AACX,MAAA,OAAO,cAAA,CAAe,EAAE,KAAA,EAAO,CAAA;AAAA,IACjC,CAAA;AAAA,IAEA,aAAA,CAAc,MAAA,EAAQ,UAAA,GAAa,EAAC,EAAG;AACrC,MAAA,IAAI,QAAA,EAAU,MAAM,aAAA,CAAc,eAAe,CAAA;AACjD,MAAA,MAAM,QAAQ,WAAA,CAAY,MAAA;AAC1B,MAAA,WAAA,CAAY,IAAA,CAAK;AAAA,QACf,KAAA;AAAA,QACA,KAAA,EACE,UAAA,CAAW,KAAA,IACX,CAAA,EAAG,MAAA,CAAO,SAAS,WAAW,CAAA,MAAA,EAAM,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,CAAA;AAAA,QAC7D,MAAA;AAAA,QACA,GAAI,WAAW,OAAA,KAAY,MAAA,GACvB,EAAE,OAAA,EAAS,UAAA,CAAW,OAAA,EAAQ,GAC9B,EAAC;AAAA,QACL,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,QACpB,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,IAAA,EAAK;AACL,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,MAAM,KAAA,EAAO;AACjB,MAAA,IAAI,QAAA,EAAU,MAAM,aAAA,CAAc,OAAO,CAAA;AACzC,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,OAAA,CAAQ,MAAA,EAAO;AACf,QAAA,OAAO,UAAA;AAAA,MACT;AACA,MAAA,MAAM,UAAA,GAAa,YAAY,KAAK,CAAA;AACpC,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,MAAM,IAAI,YAAA,CAAa;AAAA,UACrB,IAAA,EAAM,gBAAA;AAAA,UACN,OAAA,EAAS,+BAA+B,KAAK,CAAA,CAAA,CAAA;AAAA,UAC7C,GAAA,EAAK,CAAA,iBAAA,EAAoB,WAAA,CAAY,MAAM,CAAA,eAAA,CAAA;AAAA,UAC3C,GAAA,EAAK;AAAA,SACN,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,QAAQ,EAAE,UAAA;AAChB,MAAA,MAAM,KAAA,GAAQ,MAAM,YAAA,CAAa,KAAK,CAAA;AACtC,MAAA,MAAM,QAAQ,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA,GAAI,MAAA;AAC3D,MAAA,IAAI,UAAU,UAAA,IAAc,QAAA;AAC1B,QAAA,OAAO,UAAA,IAAc,YAAY,KAAK,CAAA;AAGxC,MAAA,YAAA,EAAa;AAEb,MAAA,MAAM,UAGD,EAAC;AACN,MAAA,MAAM,kBAAmC,EAAC;AAC1C,MAAA,KAAA,MAAW,KAAA,IAAS,UAAA,CAAW,MAAA,CAAO,OAAA,EAAS;AAC7C,QAAA,MAAM,OAAA,GAAU,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,MAAM,QAAQ,CAAA;AACjD,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,YACnB,UAAU,KAAA,CAAM,QAAA;AAAA,YAChB,GAAI,MAAM,IAAA,GAAO,EAAE,MAAM,KAAA,CAAM,IAAA,KAAS,EAAC;AAAA,YACzC,IAAA,EAAM,yBAAA;AAAA,YACN,OAAA,EAAS,CAAA,kBAAA,EAAqB,KAAA,CAAM,IAAA,IAAQ,MAAM,QAAQ,CAAA,eAAA,CAAA;AAAA,YAC1D,KACE,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,IACjC,4EAAA;AAAA,YACF,GAAA,EAAK;AAAA,WACN,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,MACjC;AAGA,MAAA,MAAM,eAAe,KAAA,CAAM,IAAA,EAAM,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG,OAAA;AAAA,QACrD,CAAC,KAAA,KAAU;AACT,UAAA,MAAM,UAAU,KAAA,CAAM,IAAA,CAAM,QAAA,CAAS,GAAA,CAAI,MAAM,QAAQ,CAAA;AACvD,UAAA,OAAO,UAAU,CAAC,EAAE,OAAO,OAAA,EAAS,IAAI,EAAC;AAAA,QAC3C;AAAA,OACF;AACA,MAAA,MAAM,SAAS,IAAI,GAAA;AAAA,QACjB,WAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,MAAA,KAAW,OAAO,QAAQ;AAAA,OAC3D;AACA,MAAA,KAAA,MAAW,EAAE,KAAA,EAAM,IAAK,aAAa,MAAA,CAAO,GAAA,CAAI,MAAM,QAAQ,CAAA;AAC9D,MAAA,MAAM,QAAA,GAAA,CAAY,WAAW,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG,OAAA,CAAQ,CAAC,KAAA,KAAU;AACpE,QAAA,MAAM,QAAA,GAAW,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAK,CAAA;AAC9C,QAAA,IAAI,UAAU,OAAO,CAAC,EAAE,KAAA,EAAO,UAAU,CAAA;AACzC,QAAA,eAAA,CAAgB,IAAA,CAAK;AAAA,UACnB,QAAA,EAAU,CAAA,SAAA,EAAY,KAAA,CAAM,KAAK,CAAA,CAAA,CAAA;AAAA,UACjC,GAAI,MAAM,IAAA,GAAO,EAAE,MAAM,KAAA,CAAM,IAAA,KAAS,EAAC;AAAA,UACzC,IAAA,EAAM,yBAAA;AAAA,UACN,OAAA,EAAS,CAAA,2BAAA,EAA8B,KAAA,CAAM,IAAA,IAAQ,MAAM,KAAK,CAAA,eAAA,CAAA;AAAA,UAChE,GAAA,EACE,MAAM,QAAA,CAAS,GAAA,CAAI,YAAY,KAAA,CAAM,KAAK,GAAG,CAAA,IAC7C,sDAAA;AAAA,UACF,GAAA,EAAK;AAAA,SACN,CAAA;AACD,QAAA,OAAO,EAAC;AAAA,MACV,CAAC,CAAA;AAGD,MAAA,KAAA,MAAW,EAAE,OAAM,IAAK,QAAA;AACtB,QAAA,KAAA,MAAW,EAAA,IAAM,KAAA,CAAM,QAAA,EAAU,MAAA,CAAO,IAAI,EAAE,CAAA;AAMhD,MAAA,MAAM,UAAA,uBAAiB,GAAA,EAGrB;AACF,MAAA,KAAA,MAAW,MAAA,IAAU,CAAC,GAAG,WAAA,EAAa,GAAG,OAAO,CAAA;AAC9C,QAAA,UAAA,CAAW,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,QAAA,EAAU,MAAM,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,CAAC,GAAG,UAAA,CAAW,QAAQ,CAAA;AAOvC,MAAA,MAAM,OAAA,uBAAc,GAAA,CAAI;AAAA,QACtB,GAAG,WAAW,IAAA,EAAK;AAAA,QACnB,GAAG,SAAS,OAAA,CAAQ,CAAC,EAAE,KAAA,EAAM,KAAM,MAAM,QAAQ;AAAA,OAClD,CAAA;AACD,MAAA,KAAA,MAAW,EAAE,KAAA,EAAO,MAAA,EAAO,IAAK,kBAAA,CAAmB,KAAK,CAAA,EAAG;AACzD,QAAA,IAAI,UAAU,KAAA,EAAO;AACrB,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,KAAA,CAAM,QAAA,CAAS,CAAC,IAAA,KAAS;AACvB,UAAA,IAAI,QAAQ,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,SAAmB,GAAG,QAAA,GAAW,IAAA;AAAA,QACjE,CAAC,CAAA;AACD,QAAA,IAAI,CAAC,QAAA,EAAU;AACf,QAAA,MAAA,CAAO,OAAA,EAAQ;AACf,QAAA,cAAA,CAAe,KAAK,MAAM,CAAA;AAAA,MAC5B;AAEA,MAAA,MAAM,QAAQ,UAAA,CAAW;AAAA,QACvB,KAAA;AAAA,QACA,OAAA,EAAS,OAAA;AAAA,QACT,SAAA;AAAA,QACA,OAAA;AAAA,QACA,GAAI,KAAA,GACA;AAAA,UACE,KAAA,EAAO;AAAA,YACL,OAAA,EAAS,KAAA;AAAA,YACT,MAAA,EAAQ,YAAA,CAAa,OAAA,CAAQ,UAAA,IAAc,MAAM;AAAA;AACnD,YAEF,EAAC;AAAA,QACL,GAAI,QAAA,CAAS,MAAA,GAAS,EAAE,OAAA,EAAS,QAAA,KAAa,EAAC;AAAA,QAC/C,GAAI,UAAA,CAAW,MAAA,CAAO,MAAA,IAAU,MAAM,MAAA,GAClC;AAAA,UACE,MAAA,EAAQ;AAAA,YACN,MAAA,EAAQ,WAAW,MAAA,CAAO,MAAA;AAAA,YAC1B,SAAS,KAAA,CAAM;AAAA;AACjB,YAEF;AAAC,OACN,CAAA;AACD,MAAA,KAAA,CAAM,MAAM,EAAA,EAAG;AACf,MAAA,KAAA,GAAQ,KAAA,CAAM,KAAA;AACd,MAAA,OAAA,GAAU,KAAA;AAEV,MAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,MAAM,CAAA;AAC/B,MAAA,KAAA,MAAW,QAAQ,UAAA,CAAW,MAAA,CAAO,SAAS,QAAA,CAAS,GAAA,CAAI,KAAK,QAAQ,CAAA;AACxE,MAAA,MAAM,OAAA,GAAU,OAAA,CACb,UAAA,EAAW,CACX,MAAA;AAAA,QACC,CAAC,SAAA,KACC,SAAA,CAAU,QAAA,IACV,SAAA,CAAU,kBACV,CAAC,QAAA,CAAS,GAAA,CAAI,SAAA,CAAU,QAAQ;AAAA,OACpC,CACC,GAAA,CAAI,CAAC,SAAA,KAAc,UAAU,QAAQ,CAAA;AAExC,MAAA,UAAA,GAAa;AAAA,QACX,UAAA,EAAY,KAAA;AAAA,QACZ,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,OAAA;AAAA,QACA,SAAS,CAAC,GAAG,eAAA,EAAiB,GAAG,MAAM,OAAO,CAAA;AAAA,QAC9C,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,GAAI,MAAM,IAAA,GACN;AAAA,UACE,IAAA,EAAM;AAAA,YACJ,IAAA,EAAM,UAAA,CAAW,MAAA,CAAO,IAAA,CAAM,IAAA;AAAA,YAC9B,QAAA,EAAU,UAAA,CAAW,MAAA,CAAO,IAAA,CAAM,QAAA;AAAA,YAClC,SAAS,WAAA,CAAY,MAAA;AAAA,cAAO,CAAC,EAAE,KAAA,EAAM,KACnC,MAAM,OAAA,CAAQ,QAAA,CAAS,MAAM,QAAQ;AAAA,aACvC,CAAE,MAAA;AAAA,YACF,WAAW,WAAA,CAAY,MAAA;AAAA,cAAO,CAAC,EAAE,KAAA,EAAM,KACrC,MAAM,SAAA,CAAU,QAAA,CAAS,MAAM,QAAQ;AAAA,aACzC,CAAE;AAAA;AACJ,YAEF,EAAC;AAAA,QACL,GAAI,MAAM,UAAA,GAAa,EAAE,WAAW,KAAA,CAAM,UAAA,KAAe,EAAC;AAAA,QAC1D,GAAI,YAAY,KAAA,CAAM,WAAA,GAClB,EAAE,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAChC;AAAC,OACP;AACA,MAAA,KAAA,CAAM,KAAK,CAAA;AACX,MAAA,IAAA,EAAK;AACL,MAAA,OAAO,UAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAA,GAAS;AACP,MAAA,YAAA,EAAa;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,UAAA,GAAa,YAAY,IAAI,CAAA;AAC7B,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,IAEA,QAAQ,QAAA,EAAU;AAChB,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,IAAI,QAAA,QAAgB,GAAA,EAAI;AAAA,iBACb,EAAA,EAAG;AACd,MAAA,SAAA,GAAY,QAAA;AACZ,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,IAEA,MAAM,SAAS,EAAA,EAAI;AACjB,MAAA,IAAI,QAAA,EAAU,MAAM,aAAA,CAAc,UAAU,CAAA;AAC5C,MAAA,IAAI,EAAA,KAAO,QAAA,EAAU,OAAO,UAAA,IAAc,YAAY,OAAO,CAAA;AAC7D,MAAA,QAAA,GAAW,EAAA;AAGX,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,IAAA,EAAK;AACL,QAAA,OAAO,UAAA,IAAc,YAAY,IAAI,CAAA;AAAA,MACvC;AACA,MAAA,OAAO,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,IAC9B,CAAA;AAAA,IAEA,WAAW,EAAA,EAAI;AACb,MAAA,IAAI,EAAA,MAAQ,UAAU,IAAA,CAAA,EAAO;AAC7B,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,MAAM,UAAsD,EAAC;AAC7D,QAAA,KAAA,CAAM,QAAA,CAAS,CAAC,MAAA,KAAW;AACzB,UAAA,MAAM,KAAA,GAAQ,MAAA;AACd,UAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AACpB,UAAA,OAAA,CAAQ,KAAK,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,CAAM,WAAW,CAAA;AAClD,UAAA,KAAA,CAAM,SAAA,GAAY,CAAA;AAAA,QACpB,CAAC,CAAA;AACD,QAAA,KAAA,GAAQ,OAAA;AAAA,MACV,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,KAAA,IAAS,KAAA,EAAQ,KAAA,CAAM,KAAA,CAAM,YAAY,KAAA,CAAM,SAAA;AAC1D,QAAA,KAAA,GAAQ,IAAA;AAAA,MACV;AACA,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,IAEA,EAAA,CAAG,QAAQ,QAAA,EAAU;AACnB,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,IACxC,CAAA;AAAA,IAEA,OAAA,GAAU;AACR,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,YAAA,EAAa;AACb,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,KAAA,MAAW,KAAA,IAAS,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,YAAY,KAAA,CAAM,SAAA;AACzD,QAAA,KAAA,GAAQ,IAAA;AAAA,MACV;AACA,MAAA,KAAA,MAAW,KAAA,IAAS,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA,oBAAqB,KAAK,CAAA;AAC/D,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,SAAA,CAAU,KAAA,EAAM;AAAA,IAClB;AAAA,GACF;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,YAAY,UAAA,EAAqC;AACxD,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,WAAW,EAAC;AAAA,IACZ,SAAS,EAAC;AAAA,IACV,SAAS,EAAC;AAAA,IACV,QAAQ,EAAC;AAAA,IACT,UAAU,EAAC;AAAA,IACX,UAAU,EAAC;AAAA,IACX,MAAA,EAAQ;AAAA,GACV;AACF;AAGA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,qBAAqB,KAAA,EAAO;AACpE,IAAA,OAAQ,MAAwC,eAAA,EAAgB;AAAA,EAClE;AACA,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D;AAEA,SAAS,cAAc,IAAA,EAA4B;AACjD,EAAA,OAAO,IAAI,YAAA,CAAa;AAAA,IACtB,IAAA,EAAM,gBAAA;AAAA,IACN,OAAA,EAAS,GAAG,IAAI,CAAA,yCAAA,CAAA;AAAA,IAChB,GAAA,EAAK,yFAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACH","file":"chunk-KNUAOILG.js","sourcesContent":["/**\n * A lightmap URI becomes a `THREE.Texture`, with the settings that make it\n * land the right way up on the right UV set.\n *\n * Orientation is a contract, not a guess: the render worker encodes the flip\n * at bake time, so the pixels and the UV values it ships are already correct\n * for `EXRLoader`'s defaults. This module changes nothing: `flipY = false` on\n * both the EXR and the PNG path, so an LDR fallback lands identically to the\n * HDR one.\n *\n * The bake's unwrap is a second UV set (your own `uv` still maps your\n * albedo). In three the second set is the `uv1` attribute, and\n * `texture.channel = 1` is how a map selects it, under WebGLRenderer and\n * WebGPURenderer alike.\n *\n * No mipmaps: a lightmap atlas is islands separated by a dilation margin, and\n * mipping it averages across island boundaries, which shows as light leaking\n * round the silhouette of every object at distance. Linear filtering with no\n * mips is the right trade for a map that is already low-frequency.\n */\n\nimport {\n ClampToEdgeWrapping,\n EquirectangularReflectionMapping,\n LinearFilter,\n LinearSRGBColorSpace,\n NoColorSpace,\n SRGBColorSpace,\n TextureLoader,\n type Texture,\n} from 'three';\nimport { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';\nimport { configureShadow } from './shadow.js';\nimport { Bakery3Error } from '../errors.js';\n\nexport type BakeTextureSource = {\n /** Already resolved against the bundle's own location. */\n url: string;\n format: 'exr' | 'png';\n /** For error messages: which object's lightmap this is. */\n objectId: string;\n size: number;\n /** What the texture is for. A lightmap (the default) is configured by\n * `configureLightmap`; the reflection probe by `configureProbe`. A factory\n * of your own may ignore this: the session applies the probe's mapping\n * itself either way. */\n role?: 'lightmap' | 'probe' | 'color' | 'normal' | 'billboard' | 'shadow';\n};\n\n/**\n * How a lightmap URI becomes a texture.\n *\n * Injectable for two reasons: a test wants a `DataTexture` and no\n * network, and an application that already has a loading manager, a CDN\n * rewrite or an auth header wants its own fetch in the loop.\n */\nexport type BakeTextureFactory = (\n source: BakeTextureSource,\n) => Promise<Texture>;\n\n/**\n * Apply the settings above to a texture from any source.\n *\n * Exported because a caller supplying their own `BakeTextureFactory` still\n * wants the channel, the color space and the filtering to be the ones the\n * bake was authored against: those are part of the format, not of the\n * loader.\n */\nexport function configureLightmap(\n texture: Texture,\n format: 'exr' | 'png',\n): Texture {\n texture.channel = 1;\n texture.flipY = false;\n // EXR is linear HDR irradiance and must not be decoded. A PNG lightmap is\n // the LDR fallback and is sRGB-encoded; three then decodes it to linear\n // before multiplying, which is what keeps the two formats interchangeable.\n texture.colorSpace = format === 'exr' ? LinearSRGBColorSpace : SRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The reflection probe as an environment map: three's equirect mapping, in\n * linear light, as the render worker wrote it (three's own equirect frame,\n * so no rotation). Everything else (the loader's flip, filtering, mips) is\n * left as `EXRLoader` sets it, which is what an HDRI loaded for\n * `scene.environment` gets.\n */\nexport function configureProbe(texture: Texture): Texture {\n texture.mapping = EquirectangularReflectionMapping;\n texture.colorSpace = LinearSRGBColorSpace;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * A stand-in's own maps (see proxies.ts and `BakedProxy`).\n *\n * `color` and `normal` are ordinary PNGs, the right way up for an ordinary\n * image loader, on the stand-in's first uv set; the color is sRGB and the\n * normals are data. They keep their mipmaps: a bookcase of spines shimmers\n * without them, and the unwrap's margin is what keeps a mip from reaching\n * across islands. `billboard` is linear radiance with alpha, left as\n * `EXRLoader` hands it over apart from the clamp.\n */\nexport function configureStandInMap(\n texture: Texture,\n role: 'color' | 'normal' | 'billboard',\n): Texture {\n texture.channel = 0;\n if (role === 'billboard') {\n texture.colorSpace = LinearSRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n } else {\n texture.flipY = true;\n texture.colorSpace = role === 'color' ? SRGBColorSpace : NoColorSpace;\n }\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The default loader: `EXRLoader` for HDR, `TextureLoader` for the PNG\n * fallback.\n *\n * A failure here is a designed error naming the object and the URL, because\n * \"the bake applied to 11 of 12 objects\" is a question the developer must be\n * able to answer without opening the network tab.\n */\nexport function defaultTextureFactory(): BakeTextureFactory {\n const exr = new EXRLoader();\n const png = new TextureLoader();\n // Both loaders are asked for cross-origin data by default; a bundle served\n // from a CDN on another origin is the normal case, not the exception.\n exr.setCrossOrigin('anonymous');\n png.setCrossOrigin('anonymous');\n\n return async (source) => {\n const loader = source.format === 'exr' ? exr : png;\n const texture = await new Promise<Texture>((resolve, reject) => {\n loader.load(\n source.url,\n (loaded) => resolve(loaded as Texture),\n undefined,\n () =>\n reject(\n new Bakery3Error({\n code: 'InvalidRequest',\n message:\n source.role === 'probe'\n ? 'Could not load the reflection probe.'\n : source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ? `Could not load the ${source.role} map of \"${source.objectId}\".`\n : `Could not load the lightmap for \"${source.objectId}\".`,\n why: `${source.url} did not load. A bundle's uris are relative to where the bundle came from, and the artifacts have to be reachable from the browser.`,\n fix: 'Pass { baseUrl } to addGeneration() if the bundle moved, and check the artifact server allows cross-origin reads.',\n }),\n ),\n );\n });\n if (source.role === 'probe') return configureProbe(texture);\n if (source.role === 'shadow') return configureShadow(texture);\n if (\n source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ) {\n return configureStandInMap(texture, source.role);\n }\n return configureLightmap(texture, source.format);\n };\n}\n\n/**\n * A bundle uri, resolved against where the bundle came from.\n *\n * A uri is left alone when it already names its own origin (`https:`,\n * `data:`, `blob:`, `//host`): a hosted bundle carries signed URLs. `baseUrl`\n * is for a bundle saved to disk and served from somewhere else later.\n */\nexport function resolveBundleUri(uri: string, baseUrl?: string): string {\n if (/^[a-z][a-z0-9+.-]*:/i.test(uri) || uri.startsWith('//')) return uri;\n if (!baseUrl) return uri;\n try {\n return new URL(uri, baseUrl).toString();\n } catch {\n // A baseUrl that is not a URL is a caller mistake, but failing the whole\n // apply over it would be worse than trying the raw uri.\n return uri;\n }\n}\n","/**\n * A bake session: generations of lighting you can step through, over one\n * live scene.\n *\n * The session is the thing a panel binds to. It owns three pieces of state\n * and nothing else: which bundles it knows about, which one is currently\n * applied (`-1` means \"your scene, untouched\"), and whether the realtime\n * lights are muted. Everything visible follows from those.\n *\n * Generations do not stack: `apply(i)` reverts to live first, every time.\n * Applying generation 2 over generation 1 would leave generation 1's cloned\n * materials and rebuilt geometries in the scene under generation 2's\n * textures, and the second revert would restore the first bake rather than\n * your scene.\n *\n * Generations are evicted: twelve objects at 2048² of half-float RGBA is\n * around 400 MB of VRAM per generation, so only the applied generation and\n * the most recent few keep their textures. The rest are disposed and\n * reloaded on demand.\n */\n\nimport { findPresetRooms, roomShownBaked } from '../presets/roomState.js';\nimport type { Light, Object3D, Scene, Texture } from 'three';\nimport type { BakeBundle, BakedObject } from '../protocol/index.js';\nimport { Bakery3Error } from '../errors.js';\nimport { bakeCandidates, type BakeCandidate } from './candidates.js';\nimport { buildPatch, type BakeApplySkip, type BakePatch } from './apply.js';\nimport { probeTargets } from './probe.js';\nimport type { ProxyTextures } from './proxies.js';\nimport { configureShadow } from './shadow.js';\nimport { presetBaseUrl } from '../presets/baseUrl.js';\nimport { prebakedRoomsUnder } from '../presets/roomPrebake.js';\nimport { PRESETS_VERSION } from '../presets/catalog.gen.js';\nimport type { BakeShading } from './shading.js';\nimport {\n configureProbe,\n defaultTextureFactory,\n resolveBundleUri,\n type BakeTextureFactory,\n} from './textures.js';\n\n/** Your own scene, untouched: always a generation you can go back to. */\n/** No generation applied: your scene, untouched. */\nexport const LIVE = -1;\n\nexport type BakeGeneration = {\n /** Stable index into `session.generations`; generations are append-only. */\n index: number;\n /** What the stepper shows: `1024 · standard` unless the host names it. */\n label: string;\n bundle: BakeBundle;\n baseUrl?: string;\n /** When `addGeneration` was called, for \"2m ago\". */\n createdAt: number;\n /** True while this generation's textures are resident. */\n loaded: boolean;\n};\n\n/**\n * What one `apply()` actually managed to do.\n *\n * Reported rather than thrown, because a generation that no longer perfectly\n * matches the scene is the normal case the moment you edit anything, and\n * \"applied 10 of 12, here are the other two\" is more useful than either a\n * failure or a lie.\n */\nexport type BakeApplyReport = {\n /** The generation this report is about, or -1 for your scene untouched. */\n generation: number;\n /** objectIds whose lightmap landed. */\n applied: string[];\n /** Baked objects with nothing in the scene answering to their id. */\n unmatched: string[];\n /** Bakeable meshes in the scene this generation has no lightmap for. */\n unbaked: string[];\n /** Objects the apply refused, each with a reason and a fix. */\n skipped: BakeApplySkip[];\n /** objectIds that received the bake's reflection probe as `envMap`: the\n * meshes the bake did not light (the product, the glass beside it). */\n probed: string[];\n /** Stand-ins that went into the scene, by their place in the request. */\n standIns: number[];\n /** objectIds out of sight because a stand-in took their place. */\n replaced: string[];\n /** Whether the bake's shadow plane is in the scene. */\n shadow: boolean;\n /**\n * The prebaked preset room applied under this generation, and how many of\n * its surfaces found a mesh. A bake in `room: 'preset'` mode covers only\n * the product; this is where the rest of the light came from.\n */\n room?: { name: string; lighting: string; applied: number; unmatched: number };\n /** Why the prebaked room is not on: it was wanted and did not load. The\n * product's own lightmaps applied regardless. */\n roomError?: string;\n /** Why the bundle's probe is on nothing: it was wanted and did not load.\n * The lightmaps applied regardless: a probe costs the product its\n * reflections of the room and nothing else. */\n probeError?: string;\n};\n\nexport type BakeSessionOptions = {\n scene: Scene | Object3D;\n /**\n * Where the preset library lives, for a bundle that stands its objects in\n * a prebaked room (`BakeBundle.room`). Defaults to the CDN the SDK ships\n * with; a test points it somewhere else.\n */\n presetBaseUrl?: string;\n /**\n * How a lightmap uri becomes a texture. Defaults to EXRLoader/TextureLoader\n * with the channel, color space and filtering the format requires.\n * Injected by tests, and by applications that need their own fetch.\n */\n textureFactory?: BakeTextureFactory;\n /** `lightMapIntensity` to write. Default 1: the bake is already in the\n * scene's own light units. */\n intensity?: number;\n /**\n * How the lightmap meets the lights that keep running. `'replace'` (the\n * default) makes it the only diffuse lighting while lamps and the\n * environment still supply specular, the combination that matches the\n * traced still. `'add'` is three's stock behavior, for a bake that\n * deliberately holds only part of the light. See shading.ts.\n */\n shading?: BakeShading;\n /**\n * Put the bake's reflection probe on the objects it did not light, as\n * `envMap`, so a product kept live in a baked room reflects that room\n * rather than the scene's own environment. Default `true`; `false` leaves\n * every material's environment as you set it. See probe.ts.\n */\n probe?: boolean;\n /** How many generations keep their textures. Default 3. */\n residentGenerations?: number;\n};\n\nexport type BakeSession = {\n readonly generations: readonly BakeGeneration[];\n /** Index of the applied generation, or -1 when none is (see `revert()`). */\n readonly current: number;\n /** The last apply's report, for the panel's \"what didn't match\" line. */\n readonly lastReport: BakeApplyReport | null;\n /** True while `compare(true)` is showing the live scene under an applied\n * generation: the applied state is still there, just switched off. */\n readonly comparing: boolean;\n readonly lightsMuted: boolean;\n /** Whether an applied bake puts its reflection probe on the objects it did\n * not light. The `probe` option, until `setProbe` changes it. */\n readonly probe: boolean;\n\n /** Which meshes could be baked, and why the others could not. */\n candidates(): BakeCandidate[];\n\n /** Remember a bundle. Textures are not fetched until it is applied. */\n addGeneration(\n bundle: BakeBundle,\n options?: { baseUrl?: string; label?: string },\n ): number;\n\n /** Revert to live, then apply generation `index`. `revert()` goes back to live. */\n apply(index: number): Promise<BakeApplyReport>;\n /** Back to your scene, exactly. */\n revert(): void;\n /** Hold-to-compare: `true` shows live, `false` puts the bake back. Neither\n * loses the applied patch, so both are instant and lossless. */\n compare(showLive: boolean): void;\n /**\n * The reflection probe on or off. With a generation applied this re-applies\n * it, so the change shows at once and the report says which objects carry\n * the probe; turning it on for the first time fetches the file.\n */\n setProbe(on: boolean): Promise<BakeApplyReport>;\n /**\n * Realtime lights to zero and back. Under the default `'replace'` shading\n * the lamps only add specular, so this shows the bake's diffuse on its own;\n * under `'add'` it is what stops the lamps being counted twice.\n */\n muteLights(on: boolean): void;\n\n on(event: 'change', listener: (session: BakeSession) => void): () => void;\n /** Revert, drop every texture, restore the lights. */\n dispose(): void;\n};\n\ntype LoadedGeneration = {\n textures: Map<string, Texture>;\n /** objectId → why its lightmap did not load. One unreachable artifact\n * costs one object, not the whole apply. */\n failures: Map<string, string>;\n /** Stand-in index → its maps. One that did not load is in `failures`\n * under `simplify[n]` and simply does not go in. */\n proxies: Map<number, ProxyTextures>;\n /** The shadow plane's ratio map. */\n shadow?: Texture;\n /** The prebaked room's own bundle and textures, fetched once. */\n room?: {\n bundle: BakeBundle;\n baseUrl: string;\n textures: Map<string, Texture>;\n };\n roomFailed?: string;\n /** For LRU eviction. */\n usedAt: number;\n /** The bundle's reflection probe, as an equirect environment map. */\n probe?: Texture;\n /** It was asked for and did not load; not asked for again. The reason,\n * for the report. */\n probeFailed?: string;\n};\n\nexport function createBakeSession(options: BakeSessionOptions): BakeSession {\n const scene = options.scene;\n const intensity = options.intensity ?? 1;\n const shading: BakeShading = options.shading ?? 'replace';\n const resident = Math.max(1, options.residentGenerations ?? 3);\n let useProbe = options.probe ?? true;\n const loadTexture = options.textureFactory ?? defaultTextureFactory();\n\n const generations: BakeGeneration[] = [];\n const loaded = new Map<number, LoadedGeneration>();\n const listeners = new Set<(session: BakeSession) => void>();\n\n let current = LIVE;\n let patch: BakePatch | null = null;\n let lastReport: BakeApplyReport | null = null;\n let comparing = false;\n let muted: Array<{ light: Light; intensity: number }> | null = null;\n let disposed = false;\n /** Guards against two applies racing over one scene: the later one wins and\n * the earlier one drops its result rather than half-applying under it. */\n let applyToken = 0;\n let clock = 0;\n /** Preset rooms lit by their own library lightmaps that the applied\n * generation lights over, switched off until it is released. */\n let suspendedRooms: Array<{ resume(): void }> = [];\n\n function emit() {\n for (const listener of listeners) listener(session);\n }\n\n function releasePatch() {\n patch?.dispose();\n patch = null;\n comparing = false;\n // After the patch is gone, so the room's own lightmaps go back on over\n // the materials they were first put on (see presets/roomPrebake.ts).\n for (const room of suspendedRooms) room.resume();\n suspendedRooms = [];\n }\n\n function disposeGeneration(index: number) {\n const entry = loaded.get(index);\n if (!entry) return;\n // Unique textures only: an atlas is one Texture shared by every object.\n for (const texture of new Set(entry.textures.values())) texture.dispose();\n for (const texture of new Set(entry.room?.textures.values() ?? []))\n texture.dispose();\n for (const maps of entry.proxies.values()) {\n if (maps.kind === 'billboard') maps.map.dispose();\n else if (maps.kind === 'decimated') maps.light.dispose();\n else\n for (const texture of [maps.color, maps.normal, maps.light])\n texture.dispose();\n }\n entry.probe?.dispose();\n entry.shadow?.dispose();\n loaded.delete(index);\n const generation = generations[index];\n if (generation) generation.loaded = false;\n }\n\n function evict(keep: number) {\n if (loaded.size <= resident) return;\n const ranked = [...loaded.entries()]\n .filter(([index]) => index !== keep)\n .sort((a, b) => a[1].usedAt - b[1].usedAt);\n while (loaded.size > resident && ranked.length) {\n disposeGeneration(ranked.shift()![0]);\n }\n }\n\n async function ensureLoaded(index: number): Promise<LoadedGeneration> {\n const existing = loaded.get(index);\n if (existing) {\n existing.usedAt = ++clock;\n return existing;\n }\n const generation = generations[index]!;\n const textures = new Map<string, Texture>();\n const failures = new Map<string, string>();\n // One texture per file: an atlas bundle names the same lightmap on every\n // object, and it must be fetched and decoded once and bound once, which\n // is the reason an atlas exists.\n const byUrl = new Map<string, Texture>();\n // Sequential rather than parallel: a twelve-object bundle at 2048² is a\n // lot of megabytes, and a browser that opens twelve HDR decodes at once\n // janks the frame you are watching.\n for (const baked of generation.bundle.objects) {\n try {\n const url = resolveBundleUri(baked.lightmap.uri, generation.baseUrl);\n let texture = byUrl.get(url);\n if (!texture) {\n texture = await loadTexture({\n url,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(url, texture);\n }\n textures.set(baked.objectId, texture);\n } catch (error) {\n // One unreachable artifact must not cost the other eleven objects\n // their lighting: it becomes a per-object skip with the reason\n // instead.\n failures.set(baked.objectId, describe(error));\n }\n }\n const proxies = new Map<number, ProxyTextures>();\n for (const proxy of generation.bundle.proxies ?? []) {\n const label = proxy.name ?? `stand-in ${proxy.index}`;\n const load = (\n uri: string,\n format: 'exr' | 'png',\n role: 'color' | 'normal' | 'billboard' | 'lightmap',\n size: number,\n ) =>\n loadTexture({\n url: resolveBundleUri(uri, generation.baseUrl),\n format,\n objectId: label,\n size,\n role,\n });\n try {\n if (proxy.kind === 'billboard') {\n proxies.set(proxy.index, {\n kind: 'billboard',\n map: await load(proxy.map.uri, 'exr', 'billboard', proxy.map.width),\n });\n } else if (proxy.kind === 'decimated') {\n proxies.set(proxy.index, {\n kind: 'decimated',\n light: await load(\n proxy.lightmap.uri,\n 'exr',\n 'lightmap',\n proxy.lightmap.size,\n ),\n });\n } else {\n const size = proxy.lightmap.size;\n proxies.set(proxy.index, {\n kind: 'mesh',\n color: await load(proxy.color.uri, 'png', 'color', size),\n normal: await load(proxy.normal.uri, 'png', 'normal', size),\n light: await load(proxy.lightmap.uri, 'exr', 'lightmap', size),\n });\n }\n } catch (error) {\n failures.set(`simplify[${proxy.index}]`, describe(error));\n }\n }\n let shadow: Texture | undefined;\n if (generation.bundle.shadow) {\n const shadowEntry = generation.bundle.shadow;\n try {\n shadow = configureShadow(\n await loadTexture({\n url: resolveBundleUri(shadowEntry.uri, generation.baseUrl),\n format: shadowEntry.format,\n objectId: 'shadow',\n size: shadowEntry.size,\n role: 'shadow',\n }),\n );\n } catch (error) {\n // A missing shadow costs the product its contact with the floor and\n // nothing else, so it is a note on the report, not a failed apply.\n failures.set('shadow', describe(error));\n }\n }\n // The prebaked room, when the bundle stands its objects in one. One\n // fetch for a library asset every page that shows this room shares, and\n // the reason a bundle of three objects can light a whole room.\n let room: LoadedGeneration['room'];\n let roomFailed: string | undefined;\n // A room the page shows BAKED is lit already: its own file carries the\n // light the library's lightmaps would bring, so there is nothing to fetch.\n const wantsRoom = findPresetRooms(scene).some(roomShownBaked)\n ? undefined\n : generation.bundle.room;\n if (wantsRoom) {\n const base = `${(options.presetBaseUrl ?? presetBaseUrl()).replace(/\\/$/, '')}/v${PRESETS_VERSION}/`;\n const url = new URL(wantsRoom.uri, base).toString();\n try {\n const response = await fetch(url);\n if (!response.ok)\n throw new Error(`${response.status} ${response.statusText}`);\n const bundle = (await response.json()) as BakeBundle;\n const roomTextures = new Map<string, Texture>();\n const byUrl = new Map<string, Texture>();\n for (const baked of bundle.objects) {\n const textureUrl = resolveBundleUri(baked.lightmap.uri, url);\n let texture = byUrl.get(textureUrl);\n if (!texture) {\n texture = await loadTexture({\n url: textureUrl,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(textureUrl, texture);\n }\n roomTextures.set(baked.objectId, texture);\n }\n room = { bundle, baseUrl: url, textures: roomTextures };\n } catch (error) {\n // The product's own lightmaps still apply. What is lost is the room\n // around them, which is worth saying and not worth failing over.\n roomFailed = describe(error);\n }\n }\n\n const entry: LoadedGeneration = {\n textures,\n failures,\n proxies,\n usedAt: ++clock,\n ...(shadow ? { shadow } : {}),\n ...(room ? { room } : {}),\n ...(roomFailed ? { roomFailed } : {}),\n };\n loaded.set(index, entry);\n generation.loaded = true;\n return entry;\n }\n\n /**\n * The reflection probe, fetched the first time it is wanted, so a session\n * created with `probe: false` never downloads it, and one that turns it on\n * later (`setProbe`) gets it then. A probe that does not load costs the\n * product its reflections of the room and nothing else, so the failure is\n * remembered and the apply goes on without it.\n */\n async function ensureProbe(\n index: number,\n entry: LoadedGeneration,\n ): Promise<Texture | undefined> {\n if (entry.probe || entry.probeFailed) return entry.probe;\n const generation = generations[index]!;\n const probeEntry = generation.bundle.probe;\n if (!probeEntry) return undefined;\n try {\n entry.probe = configureProbe(\n await loadTexture({\n url: resolveBundleUri(probeEntry.uri, generation.baseUrl),\n format: probeEntry.format,\n objectId: 'probe',\n size: probeEntry.width,\n role: 'probe',\n }),\n );\n } catch (error) {\n entry.probeFailed = describe(error);\n }\n return entry.probe;\n }\n\n const session: BakeSession = {\n get generations() {\n return generations;\n },\n get current() {\n return current;\n },\n get lastReport() {\n return lastReport;\n },\n get comparing() {\n return comparing;\n },\n get lightsMuted() {\n return muted !== null;\n },\n get probe() {\n return useProbe;\n },\n\n candidates() {\n return bakeCandidates({ scene });\n },\n\n addGeneration(bundle, addOptions = {}) {\n if (disposed) throw disposedError('addGeneration');\n const index = generations.length;\n generations.push({\n index,\n label:\n addOptions.label ??\n `${bundle.settings.textureSize} · ${bundle.settings.quality}`,\n bundle,\n ...(addOptions.baseUrl !== undefined\n ? { baseUrl: addOptions.baseUrl }\n : {}),\n createdAt: Date.now(),\n loaded: false,\n });\n emit();\n return index;\n },\n\n async apply(index) {\n if (disposed) throw disposedError('apply');\n if (index === LIVE) {\n session.revert();\n return lastReport!;\n }\n const generation = generations[index];\n if (!generation) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `There is no bake generation ${index}.`,\n why: `This session has ${generations.length} generation(s).`,\n fix: 'Call addGeneration(bundle) with a BakeBundle first, or revert() to go back to live.',\n });\n }\n\n const token = ++applyToken;\n const entry = await ensureLoaded(index);\n const probe = useProbe ? await ensureProbe(index, entry) : undefined;\n if (token !== applyToken || disposed)\n return lastReport ?? emptyReport(index);\n\n // Always revert first. See the file header.\n releasePatch();\n\n const objects: Array<{\n baked: (typeof generation.bundle.objects)[number];\n texture: Texture;\n }> = [];\n const missingTextures: BakeApplySkip[] = [];\n for (const baked of generation.bundle.objects) {\n const texture = entry.textures.get(baked.objectId);\n if (!texture) {\n missingTextures.push({\n objectId: baked.objectId,\n ...(baked.name ? { name: baked.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The lightmap for \"${baked.name ?? baked.objectId}\" did not load.`,\n why:\n entry.failures.get(baked.objectId) ??\n 'Its texture is missing from this generation, so there is nothing to apply.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again.',\n });\n continue;\n }\n objects.push({ baked, texture });\n }\n\n // The prebaked room's objects are baked too, just not by this bake.\n const roomObjects = (entry.room?.bundle.objects ?? []).flatMap(\n (baked) => {\n const texture = entry.room!.textures.get(baked.objectId);\n return texture ? [{ baked, texture }] : [];\n },\n );\n const litIds = new Set(\n generation.bundle.objects.map((object) => object.objectId),\n );\n for (const { baked } of roomObjects) litIds.add(baked.objectId);\n const standIns = (generation.bundle.proxies ?? []).flatMap((proxy) => {\n const textures = entry.proxies.get(proxy.index);\n if (textures) return [{ proxy, textures }];\n missingTextures.push({\n objectId: `simplify[${proxy.index}]`,\n ...(proxy.name ? { name: proxy.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The maps for the stand-in \"${proxy.name ?? proxy.index}\" did not load.`,\n why:\n entry.failures.get(`simplify[${proxy.index}]`) ??\n 'One of its textures is missing from this generation.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again. The objects it replaces are left as they were.',\n });\n return [];\n });\n // What a stand-in replaces is out of sight: it is neither unbaked nor\n // something to put the reflection probe on.\n for (const { proxy } of standIns)\n for (const id of proxy.replaces) litIds.add(id);\n // One entry per object. The room's lightmaps go in first and this\n // bake's overwrite them, because a stand the product sits on is in\n // both and only one of the two was traced with the product on it.\n // Applying an id twice would also make revert restore the wrong state:\n // the second touch records the first's edit as the value to put back.\n const byObjectId = new Map<\n string,\n { baked: BakedObject; texture: Texture }\n >();\n for (const entry_ of [...roomObjects, ...objects])\n byObjectId.set(entry_.baked.objectId, entry_);\n const winners = [...byObjectId.values()];\n\n // A preset room already lit by its own library lightmaps: when this\n // generation lights any of its objects, that patch comes off first, so\n // this one records the room's own materials as the thing to restore.\n // The room's session is scoped to its group, which is how it tells\n // itself apart from a session over the whole scene.\n const touched = new Set([\n ...byObjectId.keys(),\n ...standIns.flatMap(({ proxy }) => proxy.replaces),\n ]);\n for (const { group, handle } of prebakedRoomsUnder(scene)) {\n if (group === scene) continue;\n let lightsIt = false;\n group.traverse((node) => {\n if (touched.has(node.userData.bakery3Id as string)) lightsIt = true;\n });\n if (!lightsIt) continue;\n handle.suspend();\n suspendedRooms.push(handle);\n }\n\n const built = buildPatch({\n scene,\n objects: winners,\n intensity,\n shading,\n ...(probe\n ? {\n probe: {\n texture: probe,\n meshes: probeTargets(session.candidates(), litIds),\n },\n }\n : {}),\n ...(standIns.length ? { proxies: standIns } : {}),\n ...(generation.bundle.shadow && entry.shadow\n ? {\n shadow: {\n shadow: generation.bundle.shadow,\n texture: entry.shadow,\n },\n }\n : {}),\n });\n built.patch.on();\n patch = built.patch;\n current = index;\n\n const bakedIds = new Set(litIds);\n for (const skip of generation.bundle.skipped) bakedIds.add(skip.objectId);\n const unbaked = session\n .candidates()\n .filter(\n (candidate) =>\n candidate.bakeable &&\n candidate.defaultInclude &&\n !bakedIds.has(candidate.objectId),\n )\n .map((candidate) => candidate.objectId);\n\n lastReport = {\n generation: index,\n applied: built.applied,\n unmatched: built.unmatched,\n unbaked,\n skipped: [...missingTextures, ...built.skipped],\n probed: built.probed,\n standIns: built.standIns,\n replaced: built.replaced,\n shadow: built.shadow,\n ...(entry.room\n ? {\n room: {\n name: generation.bundle.room!.name,\n lighting: generation.bundle.room!.lighting,\n applied: roomObjects.filter(({ baked }) =>\n built.applied.includes(baked.objectId),\n ).length,\n unmatched: roomObjects.filter(({ baked }) =>\n built.unmatched.includes(baked.objectId),\n ).length,\n },\n }\n : {}),\n ...(entry.roomFailed ? { roomError: entry.roomFailed } : {}),\n ...(useProbe && entry.probeFailed\n ? { probeError: entry.probeFailed }\n : {}),\n };\n evict(index);\n emit();\n return lastReport;\n },\n\n revert() {\n releasePatch();\n current = LIVE;\n lastReport = emptyReport(LIVE);\n emit();\n },\n\n compare(showLive) {\n if (!patch) return;\n if (showLive) patch.off();\n else patch.on();\n comparing = showLive;\n emit();\n },\n\n async setProbe(on) {\n if (disposed) throw disposedError('setProbe');\n if (on === useProbe) return lastReport ?? emptyReport(current);\n useProbe = on;\n // The probe is part of the applied patch, so changing it is an apply:\n // revert, then the same generation with or without it.\n if (current === LIVE) {\n emit();\n return lastReport ?? emptyReport(LIVE);\n }\n return session.apply(current);\n },\n\n muteLights(on) {\n if (on === (muted !== null)) return;\n if (on) {\n const touched: Array<{ light: Light; intensity: number }> = [];\n scene.traverse((object) => {\n const light = object as Light;\n if (!light.isLight) return;\n touched.push({ light, intensity: light.intensity });\n light.intensity = 0;\n });\n muted = touched;\n } else {\n for (const entry of muted!) entry.light.intensity = entry.intensity;\n muted = null;\n }\n emit();\n },\n\n on(_event, listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n dispose() {\n if (disposed) return;\n disposed = true;\n releasePatch();\n if (muted) {\n for (const entry of muted) entry.light.intensity = entry.intensity;\n muted = null;\n }\n for (const index of [...loaded.keys()]) disposeGeneration(index);\n current = LIVE;\n listeners.clear();\n },\n };\n\n return session;\n}\n\nfunction emptyReport(generation: number): BakeApplyReport {\n return {\n generation,\n applied: [],\n unmatched: [],\n unbaked: [],\n skipped: [],\n probed: [],\n standIns: [],\n replaced: [],\n shadow: false,\n };\n}\n\n/** The designed failure shape when there is one, the message otherwise. */\nfunction describe(error: unknown): string {\n if (error && typeof error === 'object' && 'toDisplayString' in error) {\n return (error as { toDisplayString(): string }).toDisplayString();\n }\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction disposedError(what: string): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `${what}() was called on a disposed bake session.`,\n why: 'dispose() reverts the scene and drops every texture, so there is nothing left to apply.',\n fix: 'Create a new session with createBakeSession({ scene }).',\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/bake/textures.ts","../src/bake/session.ts"],"names":["byUrl"],"mappings":"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","file":"chunk-3T3FJOSD.js","sourcesContent":["/**\n * A lightmap URI becomes a `THREE.Texture`, with the settings that make it\n * land the right way up on the right UV set.\n *\n * Orientation is a contract, not a guess: the render worker encodes the flip\n * at bake time, so the pixels and the UV values it ships are already correct\n * for `EXRLoader`'s defaults. This module changes nothing: `flipY = false` on\n * both the EXR and the PNG path, so an LDR fallback lands identically to the\n * HDR one.\n *\n * The bake's unwrap is a second UV set (your own `uv` still maps your\n * albedo). In three the second set is the `uv1` attribute, and\n * `texture.channel = 1` is how a map selects it, under WebGLRenderer and\n * WebGPURenderer alike.\n *\n * No mipmaps: a lightmap atlas is islands separated by a dilation margin, and\n * mipping it averages across island boundaries, which shows as light leaking\n * round the silhouette of every object at distance. Linear filtering with no\n * mips is the right trade for a map that is already low-frequency.\n */\n\nimport {\n ClampToEdgeWrapping,\n EquirectangularReflectionMapping,\n LinearFilter,\n LinearSRGBColorSpace,\n NoColorSpace,\n SRGBColorSpace,\n TextureLoader,\n type Texture,\n} from 'three';\nimport { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';\nimport { configureShadow } from './shadow.js';\nimport { Bakery3Error } from '../errors.js';\n\nexport type BakeTextureSource = {\n /** Already resolved against the bundle's own location. */\n url: string;\n format: 'exr' | 'png';\n /** For error messages: which object's lightmap this is. */\n objectId: string;\n size: number;\n /** What the texture is for. A lightmap (the default) is configured by\n * `configureLightmap`; the reflection probe by `configureProbe`. A factory\n * of your own may ignore this: the session applies the probe's mapping\n * itself either way. */\n role?: 'lightmap' | 'probe' | 'color' | 'normal' | 'billboard' | 'shadow';\n};\n\n/**\n * How a lightmap URI becomes a texture.\n *\n * Injectable for two reasons: a test wants a `DataTexture` and no\n * network, and an application that already has a loading manager, a CDN\n * rewrite or an auth header wants its own fetch in the loop.\n */\nexport type BakeTextureFactory = (\n source: BakeTextureSource,\n) => Promise<Texture>;\n\n/**\n * Apply the settings above to a texture from any source.\n *\n * Exported because a caller supplying their own `BakeTextureFactory` still\n * wants the channel, the color space and the filtering to be the ones the\n * bake was authored against: those are part of the format, not of the\n * loader.\n */\nexport function configureLightmap(\n texture: Texture,\n format: 'exr' | 'png',\n): Texture {\n texture.channel = 1;\n texture.flipY = false;\n // EXR is linear HDR irradiance and must not be decoded. A PNG lightmap is\n // the LDR fallback and is sRGB-encoded; three then decodes it to linear\n // before multiplying, which is what keeps the two formats interchangeable.\n texture.colorSpace = format === 'exr' ? LinearSRGBColorSpace : SRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The reflection probe as an environment map: three's equirect mapping, in\n * linear light, as the render worker wrote it (three's own equirect frame,\n * so no rotation). Everything else (the loader's flip, filtering, mips) is\n * left as `EXRLoader` sets it, which is what an HDRI loaded for\n * `scene.environment` gets.\n */\nexport function configureProbe(texture: Texture): Texture {\n texture.mapping = EquirectangularReflectionMapping;\n texture.colorSpace = LinearSRGBColorSpace;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * A stand-in's own maps (see proxies.ts and `BakedProxy`).\n *\n * `color` and `normal` are ordinary PNGs, the right way up for an ordinary\n * image loader, on the stand-in's first uv set; the color is sRGB and the\n * normals are data. They keep their mipmaps: a bookcase of spines shimmers\n * without them, and the unwrap's margin is what keeps a mip from reaching\n * across islands. `billboard` is linear radiance with alpha, left as\n * `EXRLoader` hands it over apart from the clamp.\n */\nexport function configureStandInMap(\n texture: Texture,\n role: 'color' | 'normal' | 'billboard',\n): Texture {\n texture.channel = 0;\n if (role === 'billboard') {\n texture.colorSpace = LinearSRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n } else {\n texture.flipY = true;\n texture.colorSpace = role === 'color' ? SRGBColorSpace : NoColorSpace;\n }\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The default loader: `EXRLoader` for HDR, `TextureLoader` for the PNG\n * fallback.\n *\n * A failure here is a designed error naming the object and the URL, because\n * \"the bake applied to 11 of 12 objects\" is a question the developer must be\n * able to answer without opening the network tab.\n */\nexport function defaultTextureFactory(): BakeTextureFactory {\n const exr = new EXRLoader();\n const png = new TextureLoader();\n // Both loaders are asked for cross-origin data by default; a bundle served\n // from a CDN on another origin is the normal case, not the exception.\n exr.setCrossOrigin('anonymous');\n png.setCrossOrigin('anonymous');\n\n return async (source) => {\n const loader = source.format === 'exr' ? exr : png;\n const texture = await new Promise<Texture>((resolve, reject) => {\n loader.load(\n source.url,\n (loaded) => resolve(loaded as Texture),\n undefined,\n () =>\n reject(\n new Bakery3Error({\n code: 'InvalidRequest',\n message:\n source.role === 'probe'\n ? 'Could not load the reflection probe.'\n : source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ? `Could not load the ${source.role} map of \"${source.objectId}\".`\n : `Could not load the lightmap for \"${source.objectId}\".`,\n why: `${source.url} did not load. A bundle's uris are relative to where the bundle came from, and the artifacts have to be reachable from the browser.`,\n fix: 'Pass { baseUrl } to addGeneration() if the bundle moved, and check the artifact server allows cross-origin reads.',\n }),\n ),\n );\n });\n if (source.role === 'probe') return configureProbe(texture);\n if (source.role === 'shadow') return configureShadow(texture);\n if (\n source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ) {\n return configureStandInMap(texture, source.role);\n }\n return configureLightmap(texture, source.format);\n };\n}\n\n/**\n * A bundle uri, resolved against where the bundle came from.\n *\n * A uri is left alone when it already names its own origin (`https:`,\n * `data:`, `blob:`, `//host`): a hosted bundle carries signed URLs. `baseUrl`\n * is for a bundle saved to disk and served from somewhere else later.\n */\nexport function resolveBundleUri(uri: string, baseUrl?: string): string {\n if (/^[a-z][a-z0-9+.-]*:/i.test(uri) || uri.startsWith('//')) return uri;\n if (!baseUrl) return uri;\n try {\n return new URL(uri, baseUrl).toString();\n } catch {\n // A baseUrl that is not a URL is a caller mistake, but failing the whole\n // apply over it would be worse than trying the raw uri.\n return uri;\n }\n}\n","/**\n * A bake session: generations of lighting you can step through, over one\n * live scene.\n *\n * The session is the thing a panel binds to. It owns three pieces of state\n * and nothing else: which bundles it knows about, which one is currently\n * applied (`-1` means \"your scene, untouched\"), and whether the realtime\n * lights are muted. Everything visible follows from those.\n *\n * Generations do not stack: `apply(i)` reverts to live first, every time.\n * Applying generation 2 over generation 1 would leave generation 1's cloned\n * materials and rebuilt geometries in the scene under generation 2's\n * textures, and the second revert would restore the first bake rather than\n * your scene.\n *\n * Generations are evicted: twelve objects at 2048² of half-float RGBA is\n * around 400 MB of VRAM per generation, so only the applied generation and\n * the most recent few keep their textures. The rest are disposed and\n * reloaded on demand.\n */\n\nimport { findPresetRooms, roomShownBaked } from '../presets/roomState.js';\nimport type { Light, Object3D, Scene, Texture } from 'three';\nimport type { BakeBundle, BakedObject } from '../protocol/index.js';\nimport { Bakery3Error } from '../errors.js';\nimport { bakeCandidates, type BakeCandidate } from './candidates.js';\nimport { buildPatch, type BakeApplySkip, type BakePatch } from './apply.js';\nimport { probeTargets } from './probe.js';\nimport type { ProxyTextures } from './proxies.js';\nimport { configureShadow } from './shadow.js';\nimport { presetBaseUrl } from '../presets/baseUrl.js';\nimport { prebakedRoomsUnder } from '../presets/roomPrebake.js';\nimport { PRESETS_VERSION } from '../presets/catalog.gen.js';\nimport type { BakeShading } from './shading.js';\nimport {\n configureProbe,\n defaultTextureFactory,\n resolveBundleUri,\n type BakeTextureFactory,\n} from './textures.js';\n\n/** Your own scene, untouched: always a generation you can go back to. */\n/** No generation applied: your scene, untouched. */\nexport const LIVE = -1;\n\nexport type BakeGeneration = {\n /** Stable index into `session.generations`; generations are append-only. */\n index: number;\n /** What the stepper shows: `1024 · standard` unless the host names it. */\n label: string;\n bundle: BakeBundle;\n baseUrl?: string;\n /** When `addGeneration` was called, for \"2m ago\". */\n createdAt: number;\n /** True while this generation's textures are resident. */\n loaded: boolean;\n};\n\n/**\n * What one `apply()` actually managed to do.\n *\n * Reported rather than thrown, because a generation that no longer perfectly\n * matches the scene is the normal case the moment you edit anything, and\n * \"applied 10 of 12, here are the other two\" is more useful than either a\n * failure or a lie.\n */\nexport type BakeApplyReport = {\n /** The generation this report is about, or -1 for your scene untouched. */\n generation: number;\n /** objectIds whose lightmap landed. */\n applied: string[];\n /** Baked objects with nothing in the scene answering to their id. */\n unmatched: string[];\n /** Bakeable meshes in the scene this generation has no lightmap for. */\n unbaked: string[];\n /** Objects the apply refused, each with a reason and a fix. */\n skipped: BakeApplySkip[];\n /** objectIds that received the bake's reflection probe as `envMap`: the\n * meshes the bake did not light (the product, the glass beside it). */\n probed: string[];\n /** Stand-ins that went into the scene, by their place in the request. */\n standIns: number[];\n /** objectIds out of sight because a stand-in took their place. */\n replaced: string[];\n /** Whether the bake's shadow plane is in the scene. */\n shadow: boolean;\n /**\n * The prebaked preset room applied under this generation, and how many of\n * its surfaces found a mesh. A bake in `room: 'preset'` mode covers only\n * the product; this is where the rest of the light came from.\n */\n room?: { name: string; lighting: string; applied: number; unmatched: number };\n /** Why the prebaked room is not on: it was wanted and did not load. The\n * product's own lightmaps applied regardless. */\n roomError?: string;\n /** Why the bundle's probe is on nothing: it was wanted and did not load.\n * The lightmaps applied regardless: a probe costs the product its\n * reflections of the room and nothing else. */\n probeError?: string;\n};\n\nexport type BakeSessionOptions = {\n scene: Scene | Object3D;\n /**\n * Where the preset library lives, for a bundle that stands its objects in\n * a prebaked room (`BakeBundle.room`). Defaults to the CDN the SDK ships\n * with; a test points it somewhere else.\n */\n presetBaseUrl?: string;\n /**\n * How a lightmap uri becomes a texture. Defaults to EXRLoader/TextureLoader\n * with the channel, color space and filtering the format requires.\n * Injected by tests, and by applications that need their own fetch.\n */\n textureFactory?: BakeTextureFactory;\n /** `lightMapIntensity` to write. Default 1: the bake is already in the\n * scene's own light units. */\n intensity?: number;\n /**\n * How the lightmap meets the lights that keep running. `'replace'` (the\n * default) makes it the only diffuse lighting while lamps and the\n * environment still supply specular, the combination that matches the\n * traced still. `'add'` is three's stock behavior, for a bake that\n * deliberately holds only part of the light. See shading.ts.\n */\n shading?: BakeShading;\n /**\n * Put the bake's reflection probe on the objects it did not light, as\n * `envMap`, so a product kept live in a baked room reflects that room\n * rather than the scene's own environment. Default `true`; `false` leaves\n * every material's environment as you set it. See probe.ts.\n */\n probe?: boolean;\n /** How many generations keep their textures. Default 3. */\n residentGenerations?: number;\n};\n\nexport type BakeSession = {\n readonly generations: readonly BakeGeneration[];\n /** Index of the applied generation, or -1 when none is (see `revert()`). */\n readonly current: number;\n /** The last apply's report, for the panel's \"what didn't match\" line. */\n readonly lastReport: BakeApplyReport | null;\n /** True while `compare(true)` is showing the live scene under an applied\n * generation: the applied state is still there, just switched off. */\n readonly comparing: boolean;\n readonly lightsMuted: boolean;\n /** Whether an applied bake puts its reflection probe on the objects it did\n * not light. The `probe` option, until `setProbe` changes it. */\n readonly probe: boolean;\n\n /** Which meshes could be baked, and why the others could not. */\n candidates(): BakeCandidate[];\n\n /** Remember a bundle. Textures are not fetched until it is applied. */\n addGeneration(\n bundle: BakeBundle,\n options?: { baseUrl?: string; label?: string },\n ): number;\n\n /** Revert to live, then apply generation `index`. `revert()` goes back to live. */\n apply(index: number): Promise<BakeApplyReport>;\n /** Back to your scene, exactly. */\n revert(): void;\n /** Hold-to-compare: `true` shows live, `false` puts the bake back. Neither\n * loses the applied patch, so both are instant and lossless. */\n compare(showLive: boolean): void;\n /**\n * The reflection probe on or off. With a generation applied this re-applies\n * it, so the change shows at once and the report says which objects carry\n * the probe; turning it on for the first time fetches the file.\n */\n setProbe(on: boolean): Promise<BakeApplyReport>;\n /**\n * Realtime lights to zero and back. Under the default `'replace'` shading\n * the lamps only add specular, so this shows the bake's diffuse on its own;\n * under `'add'` it is what stops the lamps being counted twice.\n */\n muteLights(on: boolean): void;\n\n on(event: 'change', listener: (session: BakeSession) => void): () => void;\n /** Revert, drop every texture, restore the lights. */\n dispose(): void;\n};\n\ntype LoadedGeneration = {\n textures: Map<string, Texture>;\n /** objectId → why its lightmap did not load. One unreachable artifact\n * costs one object, not the whole apply. */\n failures: Map<string, string>;\n /** Stand-in index → its maps. One that did not load is in `failures`\n * under `simplify[n]` and simply does not go in. */\n proxies: Map<number, ProxyTextures>;\n /** The shadow plane's ratio map. */\n shadow?: Texture;\n /** The prebaked room's own bundle and textures, fetched once. */\n room?: {\n bundle: BakeBundle;\n baseUrl: string;\n textures: Map<string, Texture>;\n };\n roomFailed?: string;\n /** For LRU eviction. */\n usedAt: number;\n /** The bundle's reflection probe, as an equirect environment map. */\n probe?: Texture;\n /** It was asked for and did not load; not asked for again. The reason,\n * for the report. */\n probeFailed?: string;\n};\n\nexport function createBakeSession(options: BakeSessionOptions): BakeSession {\n const scene = options.scene;\n const intensity = options.intensity ?? 1;\n const shading: BakeShading = options.shading ?? 'replace';\n const resident = Math.max(1, options.residentGenerations ?? 3);\n let useProbe = options.probe ?? true;\n const loadTexture = options.textureFactory ?? defaultTextureFactory();\n\n const generations: BakeGeneration[] = [];\n const loaded = new Map<number, LoadedGeneration>();\n const listeners = new Set<(session: BakeSession) => void>();\n\n let current = LIVE;\n let patch: BakePatch | null = null;\n let lastReport: BakeApplyReport | null = null;\n let comparing = false;\n let muted: Array<{ light: Light; intensity: number }> | null = null;\n let disposed = false;\n /** Guards against two applies racing over one scene: the later one wins and\n * the earlier one drops its result rather than half-applying under it. */\n let applyToken = 0;\n let clock = 0;\n /** Preset rooms lit by their own library lightmaps that the applied\n * generation lights over, switched off until it is released. */\n let suspendedRooms: Array<{ resume(): void }> = [];\n\n function emit() {\n for (const listener of listeners) listener(session);\n }\n\n function releasePatch() {\n patch?.dispose();\n patch = null;\n comparing = false;\n // After the patch is gone, so the room's own lightmaps go back on over\n // the materials they were first put on (see presets/roomPrebake.ts).\n for (const room of suspendedRooms) room.resume();\n suspendedRooms = [];\n }\n\n function disposeGeneration(index: number) {\n const entry = loaded.get(index);\n if (!entry) return;\n // Unique textures only: an atlas is one Texture shared by every object.\n for (const texture of new Set(entry.textures.values())) texture.dispose();\n for (const texture of new Set(entry.room?.textures.values() ?? []))\n texture.dispose();\n for (const maps of entry.proxies.values()) {\n if (maps.kind === 'billboard') maps.map.dispose();\n else if (maps.kind === 'decimated') maps.light.dispose();\n else\n for (const texture of [maps.color, maps.normal, maps.light])\n texture.dispose();\n }\n entry.probe?.dispose();\n entry.shadow?.dispose();\n loaded.delete(index);\n const generation = generations[index];\n if (generation) generation.loaded = false;\n }\n\n function evict(keep: number) {\n if (loaded.size <= resident) return;\n const ranked = [...loaded.entries()]\n .filter(([index]) => index !== keep)\n .sort((a, b) => a[1].usedAt - b[1].usedAt);\n while (loaded.size > resident && ranked.length) {\n disposeGeneration(ranked.shift()![0]);\n }\n }\n\n async function ensureLoaded(index: number): Promise<LoadedGeneration> {\n const existing = loaded.get(index);\n if (existing) {\n existing.usedAt = ++clock;\n return existing;\n }\n const generation = generations[index]!;\n const textures = new Map<string, Texture>();\n const failures = new Map<string, string>();\n // One texture per file: an atlas bundle names the same lightmap on every\n // object, and it must be fetched and decoded once and bound once, which\n // is the reason an atlas exists.\n const byUrl = new Map<string, Texture>();\n // Sequential rather than parallel: a twelve-object bundle at 2048² is a\n // lot of megabytes, and a browser that opens twelve HDR decodes at once\n // janks the frame you are watching.\n for (const baked of generation.bundle.objects) {\n try {\n const url = resolveBundleUri(baked.lightmap.uri, generation.baseUrl);\n let texture = byUrl.get(url);\n if (!texture) {\n texture = await loadTexture({\n url,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(url, texture);\n }\n textures.set(baked.objectId, texture);\n } catch (error) {\n // One unreachable artifact must not cost the other eleven objects\n // their lighting: it becomes a per-object skip with the reason\n // instead.\n failures.set(baked.objectId, describe(error));\n }\n }\n const proxies = new Map<number, ProxyTextures>();\n for (const proxy of generation.bundle.proxies ?? []) {\n const label = proxy.name ?? `stand-in ${proxy.index}`;\n const load = (\n uri: string,\n format: 'exr' | 'png',\n role: 'color' | 'normal' | 'billboard' | 'lightmap',\n size: number,\n ) =>\n loadTexture({\n url: resolveBundleUri(uri, generation.baseUrl),\n format,\n objectId: label,\n size,\n role,\n });\n try {\n if (proxy.kind === 'billboard') {\n proxies.set(proxy.index, {\n kind: 'billboard',\n map: await load(proxy.map.uri, 'exr', 'billboard', proxy.map.width),\n });\n } else if (proxy.kind === 'decimated') {\n proxies.set(proxy.index, {\n kind: 'decimated',\n light: await load(\n proxy.lightmap.uri,\n 'exr',\n 'lightmap',\n proxy.lightmap.size,\n ),\n });\n } else {\n const size = proxy.lightmap.size;\n proxies.set(proxy.index, {\n kind: 'mesh',\n color: await load(proxy.color.uri, 'png', 'color', size),\n normal: await load(proxy.normal.uri, 'png', 'normal', size),\n light: await load(proxy.lightmap.uri, 'exr', 'lightmap', size),\n });\n }\n } catch (error) {\n failures.set(`simplify[${proxy.index}]`, describe(error));\n }\n }\n let shadow: Texture | undefined;\n if (generation.bundle.shadow) {\n const shadowEntry = generation.bundle.shadow;\n try {\n shadow = configureShadow(\n await loadTexture({\n url: resolveBundleUri(shadowEntry.uri, generation.baseUrl),\n format: shadowEntry.format,\n objectId: 'shadow',\n size: shadowEntry.size,\n role: 'shadow',\n }),\n );\n } catch (error) {\n // A missing shadow costs the product its contact with the floor and\n // nothing else, so it is a note on the report, not a failed apply.\n failures.set('shadow', describe(error));\n }\n }\n // The prebaked room, when the bundle stands its objects in one. One\n // fetch for a library asset every page that shows this room shares, and\n // the reason a bundle of three objects can light a whole room.\n let room: LoadedGeneration['room'];\n let roomFailed: string | undefined;\n // A room the page shows BAKED is lit already: its own file carries the\n // light the library's lightmaps would bring, so there is nothing to fetch.\n const wantsRoom = findPresetRooms(scene).some(roomShownBaked)\n ? undefined\n : generation.bundle.room;\n if (wantsRoom) {\n const base = `${(options.presetBaseUrl ?? presetBaseUrl()).replace(/\\/$/, '')}/v${PRESETS_VERSION}/`;\n const url = new URL(wantsRoom.uri, base).toString();\n try {\n const response = await fetch(url);\n if (!response.ok)\n throw new Error(`${response.status} ${response.statusText}`);\n const bundle = (await response.json()) as BakeBundle;\n const roomTextures = new Map<string, Texture>();\n const byUrl = new Map<string, Texture>();\n for (const baked of bundle.objects) {\n const textureUrl = resolveBundleUri(baked.lightmap.uri, url);\n let texture = byUrl.get(textureUrl);\n if (!texture) {\n texture = await loadTexture({\n url: textureUrl,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(textureUrl, texture);\n }\n roomTextures.set(baked.objectId, texture);\n }\n room = { bundle, baseUrl: url, textures: roomTextures };\n } catch (error) {\n // The product's own lightmaps still apply. What is lost is the room\n // around them, which is worth saying and not worth failing over.\n roomFailed = describe(error);\n }\n }\n\n const entry: LoadedGeneration = {\n textures,\n failures,\n proxies,\n usedAt: ++clock,\n ...(shadow ? { shadow } : {}),\n ...(room ? { room } : {}),\n ...(roomFailed ? { roomFailed } : {}),\n };\n loaded.set(index, entry);\n generation.loaded = true;\n return entry;\n }\n\n /**\n * The reflection probe, fetched the first time it is wanted, so a session\n * created with `probe: false` never downloads it, and one that turns it on\n * later (`setProbe`) gets it then. A probe that does not load costs the\n * product its reflections of the room and nothing else, so the failure is\n * remembered and the apply goes on without it.\n */\n async function ensureProbe(\n index: number,\n entry: LoadedGeneration,\n ): Promise<Texture | undefined> {\n if (entry.probe || entry.probeFailed) return entry.probe;\n const generation = generations[index]!;\n const probeEntry = generation.bundle.probe;\n if (!probeEntry) return undefined;\n try {\n entry.probe = configureProbe(\n await loadTexture({\n url: resolveBundleUri(probeEntry.uri, generation.baseUrl),\n format: probeEntry.format,\n objectId: 'probe',\n size: probeEntry.width,\n role: 'probe',\n }),\n );\n } catch (error) {\n entry.probeFailed = describe(error);\n }\n return entry.probe;\n }\n\n const session: BakeSession = {\n get generations() {\n return generations;\n },\n get current() {\n return current;\n },\n get lastReport() {\n return lastReport;\n },\n get comparing() {\n return comparing;\n },\n get lightsMuted() {\n return muted !== null;\n },\n get probe() {\n return useProbe;\n },\n\n candidates() {\n return bakeCandidates({ scene });\n },\n\n addGeneration(bundle, addOptions = {}) {\n if (disposed) throw disposedError('addGeneration');\n const index = generations.length;\n generations.push({\n index,\n label:\n addOptions.label ??\n `${bundle.settings.textureSize} · ${bundle.settings.quality}`,\n bundle,\n ...(addOptions.baseUrl !== undefined\n ? { baseUrl: addOptions.baseUrl }\n : {}),\n createdAt: Date.now(),\n loaded: false,\n });\n emit();\n return index;\n },\n\n async apply(index) {\n if (disposed) throw disposedError('apply');\n if (index === LIVE) {\n session.revert();\n return lastReport!;\n }\n const generation = generations[index];\n if (!generation) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `There is no bake generation ${index}.`,\n why: `This session has ${generations.length} generation(s).`,\n fix: 'Call addGeneration(bundle) with a BakeBundle first, or revert() to go back to live.',\n });\n }\n\n const token = ++applyToken;\n const entry = await ensureLoaded(index);\n const probe = useProbe ? await ensureProbe(index, entry) : undefined;\n if (token !== applyToken || disposed)\n return lastReport ?? emptyReport(index);\n\n // Always revert first. See the file header.\n releasePatch();\n\n const objects: Array<{\n baked: (typeof generation.bundle.objects)[number];\n texture: Texture;\n }> = [];\n const missingTextures: BakeApplySkip[] = [];\n for (const baked of generation.bundle.objects) {\n const texture = entry.textures.get(baked.objectId);\n if (!texture) {\n missingTextures.push({\n objectId: baked.objectId,\n ...(baked.name ? { name: baked.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The lightmap for \"${baked.name ?? baked.objectId}\" did not load.`,\n why:\n entry.failures.get(baked.objectId) ??\n 'Its texture is missing from this generation, so there is nothing to apply.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again.',\n });\n continue;\n }\n objects.push({ baked, texture });\n }\n\n // The prebaked room's objects are baked too, just not by this bake.\n const roomObjects = (entry.room?.bundle.objects ?? []).flatMap(\n (baked) => {\n const texture = entry.room!.textures.get(baked.objectId);\n return texture ? [{ baked, texture }] : [];\n },\n );\n const litIds = new Set(\n generation.bundle.objects.map((object) => object.objectId),\n );\n for (const { baked } of roomObjects) litIds.add(baked.objectId);\n const standIns = (generation.bundle.proxies ?? []).flatMap((proxy) => {\n const textures = entry.proxies.get(proxy.index);\n if (textures) return [{ proxy, textures }];\n missingTextures.push({\n objectId: `simplify[${proxy.index}]`,\n ...(proxy.name ? { name: proxy.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The maps for the stand-in \"${proxy.name ?? proxy.index}\" did not load.`,\n why:\n entry.failures.get(`simplify[${proxy.index}]`) ??\n 'One of its textures is missing from this generation.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again. The objects it replaces are left as they were.',\n });\n return [];\n });\n // What a stand-in replaces is out of sight: it is neither unbaked nor\n // something to put the reflection probe on.\n for (const { proxy } of standIns)\n for (const id of proxy.replaces) litIds.add(id);\n // One entry per object. The room's lightmaps go in first and this\n // bake's overwrite them, because a stand the product sits on is in\n // both and only one of the two was traced with the product on it.\n // Applying an id twice would also make revert restore the wrong state:\n // the second touch records the first's edit as the value to put back.\n const byObjectId = new Map<\n string,\n { baked: BakedObject; texture: Texture }\n >();\n for (const entry_ of [...roomObjects, ...objects])\n byObjectId.set(entry_.baked.objectId, entry_);\n const winners = [...byObjectId.values()];\n\n // A preset room already lit by its own library lightmaps: when this\n // generation lights any of its objects, that patch comes off first, so\n // this one records the room's own materials as the thing to restore.\n // The room's session is scoped to its group, which is how it tells\n // itself apart from a session over the whole scene.\n const touched = new Set([\n ...byObjectId.keys(),\n ...standIns.flatMap(({ proxy }) => proxy.replaces),\n ]);\n for (const { group, handle } of prebakedRoomsUnder(scene)) {\n if (group === scene) continue;\n let lightsIt = false;\n group.traverse((node) => {\n if (touched.has(node.userData.bakery3Id as string)) lightsIt = true;\n });\n if (!lightsIt) continue;\n handle.suspend();\n suspendedRooms.push(handle);\n }\n\n const built = buildPatch({\n scene,\n objects: winners,\n intensity,\n shading,\n ...(probe\n ? {\n probe: {\n texture: probe,\n meshes: probeTargets(session.candidates(), litIds),\n },\n }\n : {}),\n ...(standIns.length ? { proxies: standIns } : {}),\n ...(generation.bundle.shadow && entry.shadow\n ? {\n shadow: {\n shadow: generation.bundle.shadow,\n texture: entry.shadow,\n },\n }\n : {}),\n });\n built.patch.on();\n patch = built.patch;\n current = index;\n\n const bakedIds = new Set(litIds);\n for (const skip of generation.bundle.skipped) bakedIds.add(skip.objectId);\n const unbaked = session\n .candidates()\n .filter(\n (candidate) =>\n candidate.bakeable &&\n candidate.defaultInclude &&\n !bakedIds.has(candidate.objectId),\n )\n .map((candidate) => candidate.objectId);\n\n lastReport = {\n generation: index,\n applied: built.applied,\n unmatched: built.unmatched,\n unbaked,\n skipped: [...missingTextures, ...built.skipped],\n probed: built.probed,\n standIns: built.standIns,\n replaced: built.replaced,\n shadow: built.shadow,\n ...(entry.room\n ? {\n room: {\n name: generation.bundle.room!.name,\n lighting: generation.bundle.room!.lighting,\n applied: roomObjects.filter(({ baked }) =>\n built.applied.includes(baked.objectId),\n ).length,\n unmatched: roomObjects.filter(({ baked }) =>\n built.unmatched.includes(baked.objectId),\n ).length,\n },\n }\n : {}),\n ...(entry.roomFailed ? { roomError: entry.roomFailed } : {}),\n ...(useProbe && entry.probeFailed\n ? { probeError: entry.probeFailed }\n : {}),\n };\n evict(index);\n emit();\n return lastReport;\n },\n\n revert() {\n releasePatch();\n current = LIVE;\n lastReport = emptyReport(LIVE);\n emit();\n },\n\n compare(showLive) {\n if (!patch) return;\n if (showLive) patch.off();\n else patch.on();\n comparing = showLive;\n emit();\n },\n\n async setProbe(on) {\n if (disposed) throw disposedError('setProbe');\n if (on === useProbe) return lastReport ?? emptyReport(current);\n useProbe = on;\n // The probe is part of the applied patch, so changing it is an apply:\n // revert, then the same generation with or without it.\n if (current === LIVE) {\n emit();\n return lastReport ?? emptyReport(LIVE);\n }\n return session.apply(current);\n },\n\n muteLights(on) {\n if (on === (muted !== null)) return;\n if (on) {\n const touched: Array<{ light: Light; intensity: number }> = [];\n scene.traverse((object) => {\n const light = object as Light;\n if (!light.isLight) return;\n touched.push({ light, intensity: light.intensity });\n light.intensity = 0;\n });\n muted = touched;\n } else {\n for (const entry of muted!) entry.light.intensity = entry.intensity;\n muted = null;\n }\n emit();\n },\n\n on(_event, listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n dispose() {\n if (disposed) return;\n disposed = true;\n releasePatch();\n if (muted) {\n for (const entry of muted) entry.light.intensity = entry.intensity;\n muted = null;\n }\n for (const index of [...loaded.keys()]) disposeGeneration(index);\n current = LIVE;\n listeners.clear();\n },\n };\n\n return session;\n}\n\nfunction emptyReport(generation: number): BakeApplyReport {\n return {\n generation,\n applied: [],\n unmatched: [],\n unbaked: [],\n skipped: [],\n probed: [],\n standIns: [],\n replaced: [],\n shadow: false,\n };\n}\n\n/** The designed failure shape when there is one, the message otherwise. */\nfunction describe(error: unknown): string {\n if (error && typeof error === 'object' && 'toDisplayString' in error) {\n return (error as { toDisplayString(): string }).toDisplayString();\n }\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction disposedError(what: string): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `${what}() was called on a disposed bake session.`,\n why: 'dispose() reverts the scene and drops every texture, so there is nothing left to apply.',\n fix: 'Create a new session with createBakeSession({ scene }).',\n });\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { record, defaultVariantId } from './chunk-XK35ANPJ.js';
|
|
2
|
-
import { Bakery3Client, Batch, quoteKey, sampleOf, testSettings, PollFailures } from './chunk-
|
|
2
|
+
import { Bakery3Client, Batch, quoteKey, sampleOf, testSettings, PollFailures } from './chunk-X6GW43EX.js';
|
|
3
3
|
import { RenderSet } from './chunk-ZEBVAIJJ.js';
|
|
4
|
-
import { captureScene, bindTimelineContext, createTimeline, prepareBake, bakeQuoteOf, quoteBake, analyzeScene, resolveOutput, sceneComplexity, tracedTriangles } from './chunk-
|
|
5
|
-
import { SDK_VERSION, protocolVersionFor } from './chunk-
|
|
6
|
-
import { shouldExclude, idOf, captureFog } from './chunk-
|
|
7
|
-
import { findPresetRooms } from './chunk-
|
|
4
|
+
import { captureScene, bindTimelineContext, createTimeline, prepareBake, bakeQuoteOf, quoteBake, analyzeScene, resolveOutput, sceneComplexity, tracedTriangles } from './chunk-WLEFNUOH.js';
|
|
5
|
+
import { SDK_VERSION, protocolVersionFor } from './chunk-R5IUPOWI.js';
|
|
6
|
+
import { shouldExclude, idOf, captureFog } from './chunk-NEK5TBEH.js';
|
|
7
|
+
import { findPresetRooms } from './chunk-EN4ROBYQ.js';
|
|
8
8
|
import { Bakery3Error, RenderBudgetExceeded } from './chunk-3G5QL4F4.js';
|
|
9
9
|
|
|
10
10
|
// src/protocol/job.ts
|
|
@@ -1153,5 +1153,5 @@ function inBrowser() {
|
|
|
1153
1153
|
}
|
|
1154
1154
|
|
|
1155
1155
|
export { BakeJob, RenderJob, createBakery3 };
|
|
1156
|
-
//# sourceMappingURL=chunk-
|
|
1157
|
-
//# sourceMappingURL=chunk-
|
|
1156
|
+
//# sourceMappingURL=chunk-6FAMQZXB.js.map
|
|
1157
|
+
//# sourceMappingURL=chunk-6FAMQZXB.js.map
|