@lingbi/studio 0.4.0 → 0.5.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.
Files changed (76) hide show
  1. package/Application.d.ts +69 -21
  2. package/DownloadSaveSink.d.ts +21 -0
  3. package/EditedArchiveResourceContext.d.ts +32 -0
  4. package/ImportPerformanceMode.d.ts +5 -0
  5. package/ModelDownloadController.d.ts +21 -0
  6. package/ModelExportContext.d.ts +20 -0
  7. package/ModelExportContextFactory.d.ts +21 -0
  8. package/StudioToolbarState.d.ts +20 -0
  9. package/StudioWorkspace.d.ts +27 -8
  10. package/archive/ArchiveImportCentralDirectoryValidator.d.ts +21 -0
  11. package/archive/ArchiveImportChunkAcknowledgement.d.ts +12 -0
  12. package/archive/ArchiveImportCrc32.d.ts +8 -0
  13. package/archive/ArchiveImportError.d.ts +9 -0
  14. package/archive/ArchiveImportFileResult.d.ts +7 -0
  15. package/archive/ArchiveImportJobRequest.d.ts +4 -0
  16. package/archive/ArchiveImportJobValidator.d.ts +8 -0
  17. package/archive/ArchiveImportModelFormat.d.ts +1 -0
  18. package/archive/ArchiveImportPathValidator.d.ts +22 -0
  19. package/archive/ArchiveImportResult.d.ts +6 -0
  20. package/archive/ArchiveImportResultAccumulator.d.ts +17 -0
  21. package/archive/ArchiveImportRole.d.ts +1 -0
  22. package/archive/ArchiveImportRoleResult.d.ts +6 -0
  23. package/archive/ArchiveImportSignatureValidator.d.ts +7 -0
  24. package/archive/ArchiveImportWorkerClient.d.ts +23 -0
  25. package/archive/ArchiveImportWorkerClientTask.d.ts +17 -0
  26. package/archive/ArchiveImportWorkerEndpoint.d.ts +13 -0
  27. package/archive/ArchiveImportWorkerEntry.d.ts +1 -0
  28. package/archive/ArchiveImportWorkerFactory.d.ts +4 -0
  29. package/archive/ArchiveImportWorkerMessage.d.ts +48 -0
  30. package/archive/ArchiveImportWorkerMessageParser.d.ts +16 -0
  31. package/archive/ArchiveImportWorkerPort.d.ts +5 -0
  32. package/archive/ArchiveImportWorkerRuntime.d.ts +47 -0
  33. package/archive/ArchiveImportWorkerTask.d.ts +38 -0
  34. package/archive/BrowserArchiveImportWorkerEndpoint.d.ts +15 -0
  35. package/archive/BrowserArchiveImportWorkerFactory.d.ts +5 -0
  36. package/archive/BrowserArchiveImportWorkerPort.d.ts +7 -0
  37. package/assets/ArchiveImportWorkerEntry-Dh4RZo22.js +1548 -0
  38. package/assets/ManifoldWorkerEntry-BulSBVFW.js +3028 -0
  39. package/assets/ModelExportWorkerEntry-DwhcdDU3.js +3457 -0
  40. package/export/BrowserExportWorkerPort.d.ts +7 -0
  41. package/export/BrowserModelExportWorkerEndpoint.d.ts +15 -0
  42. package/export/BrowserModelExportWorkerFactory.d.ts +6 -0
  43. package/export/ByteChunkWriter.d.ts +11 -0
  44. package/export/ExportChunkAcknowledgement.d.ts +13 -0
  45. package/export/ExportJobRequest.d.ts +6 -0
  46. package/export/ExportJobValidator.d.ts +17 -0
  47. package/export/ExportModelFormat.d.ts +1 -0
  48. package/export/ExportModelRole.d.ts +1 -0
  49. package/export/ExportResourceFile.d.ts +6 -0
  50. package/export/ExportRoleRequest.d.ts +25 -0
  51. package/export/ExportWorkerMessage.d.ts +41 -0
  52. package/export/ExportWorkerMessageParser.d.ts +29 -0
  53. package/export/ExportWorkerPort.d.ts +6 -0
  54. package/export/ExportWorkerTask.d.ts +15 -0
  55. package/export/GeneratedMtlWriter.d.ts +10 -0
  56. package/export/GeneratedObjModelBaker.d.ts +12 -0
  57. package/export/GeneratedTextChunkWriter.d.ts +10 -0
  58. package/export/MatrixTransformer.d.ts +21 -0
  59. package/export/ModelExportError.d.ts +14 -0
  60. package/export/ModelExportWorkerClient.d.ts +24 -0
  61. package/export/ModelExportWorkerClientListener.d.ts +5 -0
  62. package/export/ModelExportWorkerClientTask.d.ts +14 -0
  63. package/export/ModelExportWorkerEndpoint.d.ts +14 -0
  64. package/export/ModelExportWorkerEntry.d.ts +1 -0
  65. package/export/ModelExportWorkerFactory.d.ts +4 -0
  66. package/export/ModelExportWorkerRuntime.d.ts +47 -0
  67. package/export/ObjModelBaker.d.ts +27 -0
  68. package/export/PlyHeaderParser.d.ts +64 -0
  69. package/export/PlyModelBaker.d.ts +52 -0
  70. package/index.d.ts +1 -4
  71. package/index.js +11144 -6143
  72. package/package.json +1 -1
  73. package/ObjImportSource.d.ts +0 -7
  74. package/ObjResourceListSource.d.ts +0 -5
  75. package/ObjResourceSceneSource.d.ts +0 -14
  76. package/ObjSceneSource.d.ts +0 -14
@@ -0,0 +1,1548 @@
1
+ (function() {
2
+ "use strict";
3
+ var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
4
+ var fleb = new u8([
5
+ 0,
6
+ 0,
7
+ 0,
8
+ 0,
9
+ 0,
10
+ 0,
11
+ 0,
12
+ 0,
13
+ 1,
14
+ 1,
15
+ 1,
16
+ 1,
17
+ 2,
18
+ 2,
19
+ 2,
20
+ 2,
21
+ 3,
22
+ 3,
23
+ 3,
24
+ 3,
25
+ 4,
26
+ 4,
27
+ 4,
28
+ 4,
29
+ 5,
30
+ 5,
31
+ 5,
32
+ 5,
33
+ 0,
34
+ /* unused */
35
+ 0,
36
+ 0,
37
+ /* impossible */
38
+ 0
39
+ ]);
40
+ var fdeb = new u8([
41
+ 0,
42
+ 0,
43
+ 0,
44
+ 0,
45
+ 1,
46
+ 1,
47
+ 2,
48
+ 2,
49
+ 3,
50
+ 3,
51
+ 4,
52
+ 4,
53
+ 5,
54
+ 5,
55
+ 6,
56
+ 6,
57
+ 7,
58
+ 7,
59
+ 8,
60
+ 8,
61
+ 9,
62
+ 9,
63
+ 10,
64
+ 10,
65
+ 11,
66
+ 11,
67
+ 12,
68
+ 12,
69
+ 13,
70
+ 13,
71
+ /* unused */
72
+ 0,
73
+ 0
74
+ ]);
75
+ var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
76
+ var freb = function(eb, start) {
77
+ var b = new u16(31);
78
+ for (var i2 = 0; i2 < 31; ++i2) {
79
+ b[i2] = start += 1 << eb[i2 - 1];
80
+ }
81
+ var r = new i32(b[30]);
82
+ for (var i2 = 1; i2 < 30; ++i2) {
83
+ for (var j = b[i2]; j < b[i2 + 1]; ++j) {
84
+ r[j] = j - b[i2] << 5 | i2;
85
+ }
86
+ }
87
+ return { b, r };
88
+ };
89
+ var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
90
+ fl[28] = 258, revfl[258] = 28;
91
+ var _b = freb(fdeb, 0), fd = _b.b;
92
+ var rev = new u16(32768);
93
+ for (var i = 0; i < 32768; ++i) {
94
+ var x = (i & 43690) >> 1 | (i & 21845) << 1;
95
+ x = (x & 52428) >> 2 | (x & 13107) << 2;
96
+ x = (x & 61680) >> 4 | (x & 3855) << 4;
97
+ rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
98
+ }
99
+ var hMap = (function(cd, mb, r) {
100
+ var s = cd.length;
101
+ var i2 = 0;
102
+ var l = new u16(mb);
103
+ for (; i2 < s; ++i2) {
104
+ if (cd[i2])
105
+ ++l[cd[i2] - 1];
106
+ }
107
+ var le = new u16(mb);
108
+ for (i2 = 1; i2 < mb; ++i2) {
109
+ le[i2] = le[i2 - 1] + l[i2 - 1] << 1;
110
+ }
111
+ var co;
112
+ if (r) {
113
+ co = new u16(1 << mb);
114
+ var rvb = 15 - mb;
115
+ for (i2 = 0; i2 < s; ++i2) {
116
+ if (cd[i2]) {
117
+ var sv = i2 << 4 | cd[i2];
118
+ var r_1 = mb - cd[i2];
119
+ var v = le[cd[i2] - 1]++ << r_1;
120
+ for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
121
+ co[rev[v] >> rvb] = sv;
122
+ }
123
+ }
124
+ }
125
+ } else {
126
+ co = new u16(s);
127
+ for (i2 = 0; i2 < s; ++i2) {
128
+ if (cd[i2]) {
129
+ co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
130
+ }
131
+ }
132
+ }
133
+ return co;
134
+ });
135
+ var flt = new u8(288);
136
+ for (var i = 0; i < 144; ++i)
137
+ flt[i] = 8;
138
+ for (var i = 144; i < 256; ++i)
139
+ flt[i] = 9;
140
+ for (var i = 256; i < 280; ++i)
141
+ flt[i] = 7;
142
+ for (var i = 280; i < 288; ++i)
143
+ flt[i] = 8;
144
+ var fdt = new u8(32);
145
+ for (var i = 0; i < 32; ++i)
146
+ fdt[i] = 5;
147
+ var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
148
+ var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
149
+ var max = function(a) {
150
+ var m = a[0];
151
+ for (var i2 = 1; i2 < a.length; ++i2) {
152
+ if (a[i2] > m)
153
+ m = a[i2];
154
+ }
155
+ return m;
156
+ };
157
+ var bits = function(d, p, m) {
158
+ var o = p / 8 | 0;
159
+ return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
160
+ };
161
+ var bits16 = function(d, p) {
162
+ var o = p / 8 | 0;
163
+ return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
164
+ };
165
+ var shft = function(p) {
166
+ return (p + 7) / 8 | 0;
167
+ };
168
+ var slc = function(v, s, e) {
169
+ if (s == null || s < 0)
170
+ s = 0;
171
+ if (e == null || e > v.length)
172
+ e = v.length;
173
+ return new u8(v.subarray(s, e));
174
+ };
175
+ var ec = [
176
+ "unexpected EOF",
177
+ "invalid block type",
178
+ "invalid length/literal",
179
+ "invalid distance",
180
+ "stream finished",
181
+ "no stream handler",
182
+ ,
183
+ // determined by compression function
184
+ "no callback",
185
+ "invalid UTF-8 data",
186
+ "extra field too long",
187
+ "date not in range 1980-2099",
188
+ "filename too long",
189
+ "stream finishing",
190
+ "invalid zip data"
191
+ // determined by unknown compression method
192
+ ];
193
+ var err = function(ind, msg, nt) {
194
+ var e = new Error(msg || ec[ind]);
195
+ e.code = ind;
196
+ if (Error.captureStackTrace)
197
+ Error.captureStackTrace(e, err);
198
+ if (!nt)
199
+ throw e;
200
+ return e;
201
+ };
202
+ var inflt = function(dat, st, buf, dict) {
203
+ var sl = dat.length, dl = 0;
204
+ if (!sl || st.f && !st.l)
205
+ return buf || new u8(0);
206
+ var noBuf = !buf;
207
+ var resize = noBuf || st.i != 2;
208
+ var noSt = st.i;
209
+ if (noBuf)
210
+ buf = new u8(sl * 3);
211
+ var cbuf = function(l2) {
212
+ var bl = buf.length;
213
+ if (l2 > bl) {
214
+ var nbuf = new u8(Math.max(bl * 2, l2));
215
+ nbuf.set(buf);
216
+ buf = nbuf;
217
+ }
218
+ };
219
+ var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
220
+ var tbts = sl * 8;
221
+ do {
222
+ if (!lm) {
223
+ final = bits(dat, pos, 1);
224
+ var type = bits(dat, pos + 1, 3);
225
+ pos += 3;
226
+ if (!type) {
227
+ var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
228
+ if (t > sl) {
229
+ if (noSt)
230
+ err(0);
231
+ break;
232
+ }
233
+ if (resize)
234
+ cbuf(bt + l);
235
+ buf.set(dat.subarray(s, t), bt);
236
+ st.b = bt += l, st.p = pos = t * 8, st.f = final;
237
+ continue;
238
+ } else if (type == 1)
239
+ lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
240
+ else if (type == 2) {
241
+ var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
242
+ var tl = hLit + bits(dat, pos + 5, 31) + 1;
243
+ pos += 14;
244
+ var ldt = new u8(tl);
245
+ var clt = new u8(19);
246
+ for (var i2 = 0; i2 < hcLen; ++i2) {
247
+ clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
248
+ }
249
+ pos += hcLen * 3;
250
+ var clb = max(clt), clbmsk = (1 << clb) - 1;
251
+ var clm = hMap(clt, clb, 1);
252
+ for (var i2 = 0; i2 < tl; ) {
253
+ var r = clm[bits(dat, pos, clbmsk)];
254
+ pos += r & 15;
255
+ var s = r >> 4;
256
+ if (s < 16) {
257
+ ldt[i2++] = s;
258
+ } else {
259
+ var c = 0, n = 0;
260
+ if (s == 16)
261
+ n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
262
+ else if (s == 17)
263
+ n = 3 + bits(dat, pos, 7), pos += 3;
264
+ else if (s == 18)
265
+ n = 11 + bits(dat, pos, 127), pos += 7;
266
+ while (n--)
267
+ ldt[i2++] = c;
268
+ }
269
+ }
270
+ var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
271
+ lbt = max(lt);
272
+ dbt = max(dt);
273
+ lm = hMap(lt, lbt, 1);
274
+ dm = hMap(dt, dbt, 1);
275
+ } else
276
+ err(1);
277
+ if (pos > tbts) {
278
+ if (noSt)
279
+ err(0);
280
+ break;
281
+ }
282
+ }
283
+ if (resize)
284
+ cbuf(bt + 131072);
285
+ var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
286
+ var lpos = pos;
287
+ for (; ; lpos = pos) {
288
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
289
+ pos += c & 15;
290
+ if (pos > tbts) {
291
+ if (noSt)
292
+ err(0);
293
+ break;
294
+ }
295
+ if (!c)
296
+ err(2);
297
+ if (sym < 256)
298
+ buf[bt++] = sym;
299
+ else if (sym == 256) {
300
+ lpos = pos, lm = null;
301
+ break;
302
+ } else {
303
+ var add = sym - 254;
304
+ if (sym > 264) {
305
+ var i2 = sym - 257, b = fleb[i2];
306
+ add = bits(dat, pos, (1 << b) - 1) + fl[i2];
307
+ pos += b;
308
+ }
309
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
310
+ if (!d)
311
+ err(3);
312
+ pos += d & 15;
313
+ var dt = fd[dsym];
314
+ if (dsym > 3) {
315
+ var b = fdeb[dsym];
316
+ dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
317
+ }
318
+ if (pos > tbts) {
319
+ if (noSt)
320
+ err(0);
321
+ break;
322
+ }
323
+ if (resize)
324
+ cbuf(bt + 131072);
325
+ var end = bt + add;
326
+ if (bt < dt) {
327
+ var shift = dl - dt, dend = Math.min(dt, end);
328
+ if (shift + bt < 0)
329
+ err(3);
330
+ for (; bt < dend; ++bt)
331
+ buf[bt] = dict[shift + bt];
332
+ }
333
+ for (; bt < end; ++bt)
334
+ buf[bt] = buf[bt - dt];
335
+ }
336
+ }
337
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
338
+ if (lm)
339
+ final = 1, st.m = lbt, st.d = dm, st.n = dbt;
340
+ } while (!final);
341
+ return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
342
+ };
343
+ var et = /* @__PURE__ */ new u8(0);
344
+ var b2 = function(d, b) {
345
+ return d[b] | d[b + 1] << 8;
346
+ };
347
+ var b4 = function(d, b) {
348
+ return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
349
+ };
350
+ var b8 = function(d, b) {
351
+ return b4(d, b) + b4(d, b + 4) * 4294967296;
352
+ };
353
+ var Inflate = /* @__PURE__ */ (function() {
354
+ function Inflate2(opts, cb) {
355
+ if (typeof opts == "function")
356
+ cb = opts, opts = {};
357
+ this.ondata = cb;
358
+ var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);
359
+ this.s = { i: 0, b: dict ? dict.length : 0 };
360
+ this.o = new u8(32768);
361
+ this.p = new u8(0);
362
+ if (dict)
363
+ this.o.set(dict);
364
+ }
365
+ Inflate2.prototype.e = function(c) {
366
+ if (!this.ondata)
367
+ err(5);
368
+ if (this.d)
369
+ err(4);
370
+ if (!this.p.length)
371
+ this.p = c;
372
+ else if (c.length) {
373
+ var n = new u8(this.p.length + c.length);
374
+ n.set(this.p), n.set(c, this.p.length), this.p = n;
375
+ }
376
+ };
377
+ Inflate2.prototype.c = function(final) {
378
+ this.s.i = +(this.d = final || false);
379
+ var bts = this.s.b;
380
+ var dt = inflt(this.p, this.s, this.o);
381
+ this.ondata(slc(dt, bts, this.s.b), this.d);
382
+ this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;
383
+ this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
384
+ };
385
+ Inflate2.prototype.push = function(chunk, final) {
386
+ this.e(chunk), this.c(final);
387
+ };
388
+ return Inflate2;
389
+ })();
390
+ var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
391
+ var tds = 0;
392
+ try {
393
+ td.decode(et, { stream: true });
394
+ tds = 1;
395
+ } catch (e) {
396
+ }
397
+ var dutf8 = function(d) {
398
+ for (var r = "", i2 = 0; ; ) {
399
+ var c = d[i2++];
400
+ var eb = (c > 127) + (c > 223) + (c > 239);
401
+ if (i2 + eb > d.length)
402
+ return { s: r, r: slc(d, i2 - 1) };
403
+ if (!eb)
404
+ r += String.fromCharCode(c);
405
+ else if (eb == 3) {
406
+ c = ((c & 15) << 18 | (d[i2++] & 63) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
407
+ } else if (eb & 1)
408
+ r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);
409
+ else
410
+ r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);
411
+ }
412
+ };
413
+ function strFromU8(dat, latin1) {
414
+ if (latin1) {
415
+ var r = "";
416
+ for (var i2 = 0; i2 < dat.length; i2 += 16384)
417
+ r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));
418
+ return r;
419
+ } else if (td) {
420
+ return td.decode(dat);
421
+ } else {
422
+ var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;
423
+ if (r.length)
424
+ err(8);
425
+ return s;
426
+ }
427
+ }
428
+ var z64hs = function(d, b, l, z, sc, su, off) {
429
+ var nsc = sc == 4294967295, nsu = su == 4294967295, noff = off == 4294967295, e = b + l;
430
+ var nf = nsc + nsu + noff;
431
+ if (nf) {
432
+ for (; b + 4 < e; b += 4 + b2(d, b + 2)) {
433
+ if (b2(d, b) == 1) {
434
+ return [
435
+ nsc ? b8(d, b + 4 + 8 * nsu) : sc,
436
+ nsu ? b8(d, b + 4) : su,
437
+ off,
438
+ 1
439
+ ];
440
+ }
441
+ }
442
+ }
443
+ return [sc, su, off, 0];
444
+ };
445
+ var UnzipPassThrough = /* @__PURE__ */ (function() {
446
+ function UnzipPassThrough2() {
447
+ }
448
+ UnzipPassThrough2.prototype.push = function(chunk, final) {
449
+ this.ondata(null, chunk, final);
450
+ };
451
+ UnzipPassThrough2.compression = 0;
452
+ return UnzipPassThrough2;
453
+ })();
454
+ var UnzipInflate = /* @__PURE__ */ (function() {
455
+ function UnzipInflate2() {
456
+ var _this = this;
457
+ this.i = new Inflate(function(dat, final) {
458
+ _this.ondata(null, dat, final);
459
+ });
460
+ }
461
+ UnzipInflate2.prototype.push = function(chunk, final) {
462
+ try {
463
+ this.i.push(chunk, final);
464
+ } catch (e) {
465
+ this.ondata(e, null, final);
466
+ }
467
+ };
468
+ UnzipInflate2.compression = 8;
469
+ return UnzipInflate2;
470
+ })();
471
+ var Unzip = /* @__PURE__ */ (function() {
472
+ function Unzip2(cb) {
473
+ this.onfile = cb;
474
+ this.k = [];
475
+ this.o = {
476
+ 0: UnzipPassThrough
477
+ };
478
+ this.p = et;
479
+ }
480
+ Unzip2.prototype.push = function(chunk, final) {
481
+ var _this = this;
482
+ if (!this.onfile)
483
+ err(5);
484
+ if (!this.p)
485
+ err(4);
486
+ if (this.c > 0) {
487
+ var len = Math.min(this.c, chunk.length);
488
+ var toAdd = chunk.subarray(0, len);
489
+ this.c -= len;
490
+ if (this.d)
491
+ this.d.push(toAdd, !this.c);
492
+ else
493
+ this.k[0].push(toAdd);
494
+ chunk = chunk.subarray(len);
495
+ if (chunk.length)
496
+ return this.push(chunk, final);
497
+ } else {
498
+ var f = 0, i2 = 0, is = void 0, buf = void 0;
499
+ if (!this.p.length)
500
+ buf = chunk;
501
+ else if (!chunk.length)
502
+ buf = this.p;
503
+ else {
504
+ buf = new u8(this.p.length + chunk.length);
505
+ buf.set(this.p), buf.set(chunk, this.p.length);
506
+ }
507
+ var l = buf.length, oc = this.c, add = oc && this.d;
508
+ var _loop_2 = function() {
509
+ var sig = b4(buf, i2);
510
+ if (sig == 67324752) {
511
+ f = 1, is = i2;
512
+ this_1.d = null;
513
+ this_1.c = 0;
514
+ var bf = b2(buf, i2 + 6), cmp_1 = b2(buf, i2 + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i2 + 26), es = b2(buf, i2 + 28);
515
+ if (l > i2 + 30 + fnl + es) {
516
+ var chks_3 = [];
517
+ this_1.k.unshift(chks_3);
518
+ f = 2;
519
+ var lsc = b4(buf, i2 + 18), lsu = b4(buf, i2 + 22);
520
+ var fn_1 = strFromU8(buf.subarray(i2 + 30, i2 += 30 + fnl), !u);
521
+ var _a2 = z64hs(buf, i2, es, 2, lsc, lsu, 0), sc_1 = _a2[0], su_1 = _a2[1], z64 = _a2[3];
522
+ if (dd)
523
+ sc_1 = -1 - z64;
524
+ i2 += es;
525
+ this_1.c = sc_1;
526
+ var d_1;
527
+ var file_1 = {
528
+ name: fn_1,
529
+ compression: cmp_1,
530
+ start: function() {
531
+ if (!file_1.ondata)
532
+ err(5);
533
+ if (!sc_1)
534
+ file_1.ondata(null, et, true);
535
+ else {
536
+ var ctr = _this.o[cmp_1];
537
+ if (!ctr)
538
+ file_1.ondata(err(14, "unknown compression type " + cmp_1, 1), null, false);
539
+ d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);
540
+ d_1.ondata = function(err2, dat3, final2) {
541
+ file_1.ondata(err2, dat3, final2);
542
+ };
543
+ for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {
544
+ var dat2 = chks_4[_i];
545
+ d_1.push(dat2, false);
546
+ }
547
+ if (_this.k[0] == chks_3 && _this.c)
548
+ _this.d = d_1;
549
+ else
550
+ d_1.push(et, true);
551
+ }
552
+ },
553
+ terminate: function() {
554
+ if (d_1 && d_1.terminate)
555
+ d_1.terminate();
556
+ }
557
+ };
558
+ if (sc_1 >= 0)
559
+ file_1.size = sc_1, file_1.originalSize = su_1;
560
+ this_1.onfile(file_1);
561
+ }
562
+ return "break";
563
+ } else if (oc) {
564
+ if (sig == 134695760) {
565
+ is = i2 += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;
566
+ return "break";
567
+ } else if (sig == 33639248) {
568
+ is = i2 -= 4, f = 3, this_1.c = 0;
569
+ return "break";
570
+ }
571
+ }
572
+ };
573
+ var this_1 = this;
574
+ for (; i2 < l - 4; ++i2) {
575
+ var state_1 = _loop_2();
576
+ if (state_1 === "break")
577
+ break;
578
+ }
579
+ this.p = et;
580
+ if (oc < 0) {
581
+ var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 134695760 && 4)) : buf.subarray(0, i2);
582
+ if (add)
583
+ add.push(dat, !!f);
584
+ else
585
+ this.k[+(f == 2)].push(dat);
586
+ }
587
+ if (f & 2)
588
+ return this.push(buf.subarray(i2), final);
589
+ this.p = buf.subarray(i2);
590
+ }
591
+ if (final) {
592
+ if (this.c)
593
+ err(13);
594
+ this.p = null;
595
+ }
596
+ };
597
+ Unzip2.prototype.register = function(decoder) {
598
+ this.o[decoder.compression] = decoder;
599
+ };
600
+ return Unzip2;
601
+ })();
602
+ var ArchiveImportErrorCode = /* @__PURE__ */ ((ArchiveImportErrorCode2) => {
603
+ ArchiveImportErrorCode2["Cancelled"] = "cancelled";
604
+ ArchiveImportErrorCode2["InvalidSource"] = "invalid-source";
605
+ ArchiveImportErrorCode2["Protocol"] = "protocol";
606
+ return ArchiveImportErrorCode2;
607
+ })(ArchiveImportErrorCode || {});
608
+ class ArchiveImportError extends Error {
609
+ code;
610
+ constructor(code, message) {
611
+ super(message);
612
+ this.code = code;
613
+ this.name = "ArchiveImportError";
614
+ }
615
+ }
616
+ class ArchiveImportPathValidator {
617
+ parse(path) {
618
+ if (path.length === 0 || path.includes("\\") || path.startsWith("/") || this.isDrivePath(path)) {
619
+ throw this.invalidPath(path);
620
+ }
621
+ if (this.hasControlCharacter(path)) {
622
+ throw this.invalidPath(path);
623
+ }
624
+ const parts = path.split("/");
625
+ const firstPart = parts[0];
626
+ const secondPart = parts[1];
627
+ if (parts.length === 2 && firstPart !== void 0 && secondPart === "") {
628
+ return this.parseDirectory(firstPart, path);
629
+ }
630
+ if (parts.length !== 2 || firstPart === void 0 || secondPart === void 0 || firstPart === "" || secondPart === "") {
631
+ throw this.invalidPath(path);
632
+ }
633
+ const role = this.parseRole(firstPart, path);
634
+ const fileName = secondPart;
635
+ if (fileName === "." || fileName === "..") {
636
+ throw this.invalidPath(path);
637
+ }
638
+ const format = this.getModelFormat(fileName);
639
+ return format === void 0 ? { fileName, isModel: false, kind: "file", role } : { fileName, format, isModel: true, kind: "file", role };
640
+ }
641
+ getModelFormat(fileName) {
642
+ const lowerName = fileName.toLowerCase();
643
+ if (lowerName.endsWith(".obj")) {
644
+ return "obj";
645
+ }
646
+ return lowerName.endsWith(".ply") ? "ply" : void 0;
647
+ }
648
+ hasControlCharacter(path) {
649
+ for (const character of path) {
650
+ const code = character.codePointAt(0);
651
+ if (code !== void 0 && (code < 32 || code === 127)) {
652
+ return true;
653
+ }
654
+ }
655
+ return false;
656
+ }
657
+ invalidPath(path) {
658
+ return new ArchiveImportError(
659
+ ArchiveImportErrorCode.InvalidSource,
660
+ `The archive path "${path}" is not allowed.`
661
+ );
662
+ }
663
+ isDrivePath(path) {
664
+ return path.length >= 2 && path.charCodeAt(1) === 58;
665
+ }
666
+ parseDirectory(roleName, path) {
667
+ const role = this.parseRole(roleName, path);
668
+ return { kind: "directory", role };
669
+ }
670
+ parseRole(roleName, path) {
671
+ if (roleName === "stone" || roleName === "base") {
672
+ return roleName;
673
+ }
674
+ throw this.invalidPath(path);
675
+ }
676
+ }
677
+ class ArchiveImportCentralDirectoryValidator {
678
+ pathValidator = new ArchiveImportPathValidator();
679
+ async validate(file, entries, signal) {
680
+ try {
681
+ this.throwIfAborted(signal);
682
+ const endRecord = await this.readEndRecord(file, signal);
683
+ const centralDirectory = await this.readCentralDirectory(file, endRecord, signal);
684
+ this.throwIfAborted(signal);
685
+ this.validateRecords(centralDirectory, endRecord.totalEntries, entries);
686
+ } catch (error) {
687
+ if (error instanceof ArchiveImportError) {
688
+ throw error;
689
+ }
690
+ throw new ArchiveImportError(
691
+ ArchiveImportErrorCode.InvalidSource,
692
+ "The selected archive has an invalid central directory."
693
+ );
694
+ }
695
+ }
696
+ decodeName(bytes, flags) {
697
+ try {
698
+ return strFromU8(bytes, (flags & 2048) === 0);
699
+ } catch {
700
+ throw this.invalidArchive();
701
+ }
702
+ }
703
+ findEndRecord(tail) {
704
+ for (let index = tail.length - 22; index >= 0; index -= 1) {
705
+ if (this.readUint32(tail, index) !== 101010256) {
706
+ continue;
707
+ }
708
+ const commentLength = this.readUint16(tail, index + 20);
709
+ if (index + 22 + commentLength !== tail.length) {
710
+ continue;
711
+ }
712
+ const totalEntries = this.readUint16(tail, index + 10);
713
+ const entriesOnDisk = this.readUint16(tail, index + 8);
714
+ const centralDirectorySize = this.readUint32(tail, index + 12);
715
+ const centralDirectoryOffset = this.readUint32(tail, index + 16);
716
+ if (entriesOnDisk !== totalEntries || totalEntries === 65535 || centralDirectorySize === 4294967295 || centralDirectoryOffset === 4294967295) {
717
+ throw this.invalidArchive("ZIP64 archives are not supported.");
718
+ }
719
+ if (this.readUint16(tail, index + 4) !== 0 || this.readUint16(tail, index + 6) !== 0) {
720
+ throw this.invalidArchive("Multi-disk ZIP archives are not supported.");
721
+ }
722
+ return {
723
+ centralDirectoryOffset,
724
+ centralDirectorySize,
725
+ commentLength,
726
+ offsetInTail: index,
727
+ totalEntries
728
+ };
729
+ }
730
+ throw this.invalidArchive();
731
+ }
732
+ invalidArchive(message = "The selected archive is invalid or corrupted.") {
733
+ return new ArchiveImportError(ArchiveImportErrorCode.InvalidSource, message);
734
+ }
735
+ parseCentralRecord(data, offset) {
736
+ if (this.readUint32(data, offset) !== 33639248 || offset + 46 > data.length) {
737
+ throw this.invalidArchive();
738
+ }
739
+ const flags = this.readUint16(data, offset + 8);
740
+ const crc32 = this.readUint32(data, offset + 16);
741
+ const byteLength = this.readUint32(data, offset + 24);
742
+ const fileNameLength = this.readUint16(data, offset + 28);
743
+ const extraLength = this.readUint16(data, offset + 30);
744
+ const commentLength = this.readUint16(data, offset + 32);
745
+ const nextOffset = offset + 46 + fileNameLength + extraLength + commentLength;
746
+ if (nextOffset > data.length) {
747
+ throw this.invalidArchive();
748
+ }
749
+ const nameStart = offset + 46;
750
+ const path = this.decodeName(data.subarray(nameStart, nameStart + fileNameLength), flags);
751
+ return { byteLength, crc32, nextOffset, path };
752
+ }
753
+ async readCentralDirectory(file, endRecord, signal) {
754
+ this.throwIfAborted(signal);
755
+ const end = endRecord.centralDirectoryOffset + endRecord.centralDirectorySize;
756
+ if (!Number.isSafeInteger(end) || end > file.size) {
757
+ throw this.invalidArchive();
758
+ }
759
+ const tailStart = file.size - Math.min(file.size, 65557);
760
+ const tail = new Uint8Array(await file.slice(tailStart, file.size).arrayBuffer());
761
+ this.throwIfAborted(signal);
762
+ if (endRecord.centralDirectoryOffset >= tailStart && end <= file.size && end <= tailStart + tail.byteLength) {
763
+ const startInTail = endRecord.centralDirectoryOffset - tailStart;
764
+ return tail.slice(startInTail, startInTail + endRecord.centralDirectorySize);
765
+ }
766
+ const directory = new Uint8Array(
767
+ await file.slice(endRecord.centralDirectoryOffset, end).arrayBuffer()
768
+ );
769
+ this.throwIfAborted(signal);
770
+ return directory;
771
+ }
772
+ async readEndRecord(file, signal) {
773
+ this.throwIfAborted(signal);
774
+ const tailStart = Math.max(0, file.size - 65557);
775
+ const tail = new Uint8Array(await file.slice(tailStart, file.size).arrayBuffer());
776
+ this.throwIfAborted(signal);
777
+ const endRecord = this.findEndRecord(tail);
778
+ const endOffset = tailStart + endRecord.offsetInTail + 22 + endRecord.commentLength;
779
+ const centralDirectoryEnd = endRecord.centralDirectoryOffset + endRecord.centralDirectorySize;
780
+ if (endOffset !== file.size) {
781
+ throw this.invalidArchive("The archive contains trailing data.");
782
+ }
783
+ if (centralDirectoryEnd !== tailStart + endRecord.offsetInTail) {
784
+ throw this.invalidArchive("The central directory position is invalid.");
785
+ }
786
+ return endRecord;
787
+ }
788
+ validatePath(path) {
789
+ return this.pathValidator.parse(path);
790
+ }
791
+ validateRecords(data, totalEntries, entries) {
792
+ const seenPaths = /* @__PURE__ */ new Set();
793
+ const expectedEntries = /* @__PURE__ */ new Map();
794
+ let offset = 0;
795
+ let fileCount = 0;
796
+ for (const entry of entries) {
797
+ if (expectedEntries.has(entry.path)) {
798
+ throw this.invalidArchive("The archive contains a duplicate file.");
799
+ }
800
+ expectedEntries.set(entry.path, entry);
801
+ }
802
+ let lastRoleIndex = -1;
803
+ for (let index = 0; index < totalEntries; index += 1) {
804
+ const record = this.parseCentralRecord(data, offset);
805
+ const path = this.validatePath(record.path);
806
+ const roleIndex = path.role === "stone" ? 0 : 1;
807
+ if (roleIndex < lastRoleIndex) {
808
+ throw this.invalidArchive("The archive roles are out of order.");
809
+ }
810
+ lastRoleIndex = roleIndex;
811
+ if (path.kind === "file") {
812
+ fileCount += 1;
813
+ if (seenPaths.has(record.path)) {
814
+ throw this.invalidArchive("The central directory contains a duplicate file.");
815
+ }
816
+ seenPaths.add(record.path);
817
+ const expected = expectedEntries.get(record.path);
818
+ if (expected === void 0) {
819
+ throw this.invalidArchive("The archive entry checksum or size is invalid.");
820
+ }
821
+ if (expected.byteLength !== record.byteLength || expected.crc32 !== record.crc32) {
822
+ throw this.invalidArchive("The archive entry checksum or size is invalid.");
823
+ }
824
+ } else if (record.byteLength !== 0 || record.crc32 !== 0) {
825
+ throw this.invalidArchive("The archive directory entry is not empty.");
826
+ }
827
+ offset = record.nextOffset;
828
+ }
829
+ if (offset !== data.length || fileCount !== entries.length) {
830
+ throw this.invalidArchive("The central directory does not match the archive entries.");
831
+ }
832
+ }
833
+ readUint16(data, offset) {
834
+ const first = data[offset];
835
+ const second = data[offset + 1];
836
+ if (first === void 0 || second === void 0) {
837
+ throw this.invalidArchive();
838
+ }
839
+ return first | second << 8;
840
+ }
841
+ readUint32(data, offset) {
842
+ const first = data[offset];
843
+ const second = data[offset + 1];
844
+ const third = data[offset + 2];
845
+ const fourth = data[offset + 3];
846
+ if (first === void 0 || second === void 0 || third === void 0 || fourth === void 0) {
847
+ throw this.invalidArchive();
848
+ }
849
+ return (first | second << 8 | third << 16 | fourth << 24) >>> 0;
850
+ }
851
+ throwIfAborted(signal) {
852
+ if (signal?.aborted) {
853
+ throw new ArchiveImportError(
854
+ ArchiveImportErrorCode.Cancelled,
855
+ "The archive import was cancelled."
856
+ );
857
+ }
858
+ }
859
+ }
860
+ class ArchiveImportChunkAcknowledgement {
861
+ chunkId;
862
+ promise;
863
+ taskId;
864
+ rejectPromise;
865
+ resolvePromise;
866
+ settled = false;
867
+ constructor(taskId, chunkId) {
868
+ this.chunkId = chunkId;
869
+ this.promise = new Promise(this.initializePromise.bind(this));
870
+ this.taskId = taskId;
871
+ }
872
+ acknowledge() {
873
+ if (this.settled) {
874
+ return;
875
+ }
876
+ this.settled = true;
877
+ this.resolvePromise?.();
878
+ }
879
+ cancel() {
880
+ if (this.settled) {
881
+ return;
882
+ }
883
+ this.settled = true;
884
+ this.rejectPromise?.(
885
+ new ArchiveImportError(
886
+ ArchiveImportErrorCode.Cancelled,
887
+ "The archive import was cancelled."
888
+ )
889
+ );
890
+ }
891
+ initializePromise(resolve, reject) {
892
+ this.resolvePromise = resolve;
893
+ this.rejectPromise = reject;
894
+ }
895
+ }
896
+ class ArchiveImportCrc32 {
897
+ table;
898
+ value = 4294967295;
899
+ constructor() {
900
+ const table = [];
901
+ for (let index = 0; index < 256; index += 1) {
902
+ let value = index;
903
+ for (let bit = 0; bit < 8; bit += 1) {
904
+ value = (value & 1) === 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
905
+ }
906
+ table.push(value >>> 0);
907
+ }
908
+ this.table = table;
909
+ }
910
+ digest() {
911
+ return (this.value ^ 4294967295) >>> 0;
912
+ }
913
+ update(data) {
914
+ for (const byte of data) {
915
+ const tableIndex = (this.value ^ byte) & 255;
916
+ const tableValue = this.table[tableIndex];
917
+ if (tableValue === void 0) {
918
+ throw new Error("The CRC-32 table is incomplete.");
919
+ }
920
+ this.value = tableValue ^ this.value >>> 8;
921
+ }
922
+ }
923
+ }
924
+ class ArchiveImportJobValidator {
925
+ validate(job) {
926
+ if (!Number.isSafeInteger(job.taskId) || job.taskId <= 0) {
927
+ throw new ArchiveImportError(
928
+ ArchiveImportErrorCode.Protocol,
929
+ "The archive import task id must be a positive safe integer."
930
+ );
931
+ }
932
+ const file = job.file;
933
+ if (!this.isReadableFile(file)) {
934
+ throw new ArchiveImportError(
935
+ ArchiveImportErrorCode.InvalidSource,
936
+ "The selected archive could not be read."
937
+ );
938
+ }
939
+ }
940
+ isReadableFile(value) {
941
+ const record = this.getRecord(value);
942
+ if (record === void 0) {
943
+ return false;
944
+ }
945
+ return typeof record["size"] === "number" && Number.isSafeInteger(record["size"]) && record["size"] > 0 && typeof record["stream"] === "function" && typeof record["slice"] === "function" && typeof record["arrayBuffer"] === "function";
946
+ }
947
+ getRecord(value) {
948
+ return this.isRecord(value) ? value : void 0;
949
+ }
950
+ isRecord(value) {
951
+ return typeof value === "object" && value !== null && !Array.isArray(value);
952
+ }
953
+ }
954
+ class ArchiveImportSignatureValidator {
955
+ prefix = [];
956
+ finish() {
957
+ if (this.prefix.length < 4 || !this.hasLocalFileSignature()) {
958
+ throw new ArchiveImportError(
959
+ ArchiveImportErrorCode.InvalidSource,
960
+ "The selected file is not a supported ZIP archive."
961
+ );
962
+ }
963
+ }
964
+ push(chunk) {
965
+ for (let index = 0; index < chunk.length && this.prefix.length < 4; index += 1) {
966
+ const value = chunk[index];
967
+ if (value !== void 0) {
968
+ this.prefix.push(value);
969
+ }
970
+ }
971
+ if (this.prefix.length === 4 && !this.hasLocalFileSignature()) {
972
+ throw new ArchiveImportError(
973
+ ArchiveImportErrorCode.InvalidSource,
974
+ "The selected file is not a supported ZIP archive."
975
+ );
976
+ }
977
+ }
978
+ hasLocalFileSignature() {
979
+ return this.prefix[0] === 80 && this.prefix[1] === 75 && this.prefix[2] === 3 && this.prefix[3] === 4;
980
+ }
981
+ }
982
+ class ArchiveImportWorkerMessageParser {
983
+ parseInbound(value) {
984
+ const record = this.getRecord(value);
985
+ if (record === void 0) {
986
+ return void 0;
987
+ }
988
+ switch (record["type"]) {
989
+ case "acknowledge-chunk":
990
+ return this.parseAcknowledgement(record);
991
+ case "cancel":
992
+ return this.parseCancellation(record);
993
+ case "start":
994
+ return this.parseStart(record);
995
+ default:
996
+ return void 0;
997
+ }
998
+ }
999
+ parseOutbound(value) {
1000
+ const record = this.getRecord(value);
1001
+ const taskId = record?.["taskId"];
1002
+ if (record === void 0 || !this.isPositiveSafeInteger(taskId)) {
1003
+ return void 0;
1004
+ }
1005
+ switch (record["type"]) {
1006
+ case "cancelled":
1007
+ return { taskId, type: "cancelled" };
1008
+ case "complete":
1009
+ return { taskId, type: "complete" };
1010
+ case "entry-chunk":
1011
+ return this.parseEntryChunk(record, taskId);
1012
+ case "entry-start":
1013
+ return this.parseEntryStart(record, taskId);
1014
+ case "error":
1015
+ return typeof record["message"] === "string" ? { message: record["message"], taskId, type: "error" } : void 0;
1016
+ default:
1017
+ return void 0;
1018
+ }
1019
+ }
1020
+ getRecord(value) {
1021
+ return this.isRecord(value) ? value : void 0;
1022
+ }
1023
+ isFileLike(value) {
1024
+ const record = this.getRecord(value);
1025
+ return record !== void 0 && typeof record["name"] === "string" && typeof record["size"] === "number" && Number.isSafeInteger(record["size"]) && typeof record["stream"] === "function" && typeof record["slice"] === "function" && typeof record["arrayBuffer"] === "function";
1026
+ }
1027
+ isFormat(value) {
1028
+ return value === "obj" || value === "ply";
1029
+ }
1030
+ isPositiveSafeInteger(value) {
1031
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
1032
+ }
1033
+ isRecord(value) {
1034
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1035
+ }
1036
+ parseAcknowledgement(record) {
1037
+ const chunkId = record["chunkId"];
1038
+ const taskId = record["taskId"];
1039
+ if (!this.isPositiveSafeInteger(chunkId) || !this.isPositiveSafeInteger(taskId)) {
1040
+ return void 0;
1041
+ }
1042
+ return { chunkId, taskId, type: "acknowledge-chunk" };
1043
+ }
1044
+ parseCancellation(record) {
1045
+ const taskId = record["taskId"];
1046
+ return this.isPositiveSafeInteger(taskId) ? { taskId, type: "cancel" } : void 0;
1047
+ }
1048
+ parseEntryChunk(record, taskId) {
1049
+ const chunk = record["chunk"];
1050
+ const chunkId = record["chunkId"];
1051
+ const entryId = record["entryId"];
1052
+ const final = record["final"];
1053
+ if (!(chunk instanceof ArrayBuffer) || !this.isPositiveSafeInteger(chunkId) || !this.isPositiveSafeInteger(entryId) || typeof final !== "boolean") {
1054
+ return void 0;
1055
+ }
1056
+ return {
1057
+ chunk,
1058
+ chunkId,
1059
+ entryId,
1060
+ final,
1061
+ taskId,
1062
+ type: "entry-chunk"
1063
+ };
1064
+ }
1065
+ parseEntryStart(record, taskId) {
1066
+ const entryId = record["entryId"];
1067
+ const fileName = record["fileName"];
1068
+ const format = record["format"];
1069
+ const isModel = record["isModel"];
1070
+ const role = record["role"];
1071
+ if (!this.isPositiveSafeInteger(entryId) || typeof fileName !== "string" || typeof isModel !== "boolean" || role !== "stone" && role !== "base" || format !== void 0 && !this.isFormat(format)) {
1072
+ return void 0;
1073
+ }
1074
+ return format === void 0 ? { entryId, fileName, isModel, role, taskId, type: "entry-start" } : { entryId, fileName, format, isModel, role, taskId, type: "entry-start" };
1075
+ }
1076
+ parseStart(record) {
1077
+ const file = record["file"];
1078
+ const taskId = record["taskId"];
1079
+ if (!this.isPositiveSafeInteger(taskId) || !this.isFileLike(file)) {
1080
+ return void 0;
1081
+ }
1082
+ return { file, taskId, type: "start" };
1083
+ }
1084
+ }
1085
+ class ArchiveImportWorkerTask {
1086
+ abortController = new AbortController();
1087
+ awaitingAcknowledgement;
1088
+ activeEntryId;
1089
+ cancelled = false;
1090
+ entryByteCounts = /* @__PURE__ */ new Map();
1091
+ entryChecksums = /* @__PURE__ */ new Map();
1092
+ entries = [];
1093
+ queuedMessages = [];
1094
+ request;
1095
+ roleModelCounts = /* @__PURE__ */ new Map();
1096
+ rolesSeen = /* @__PURE__ */ new Set();
1097
+ seenFileNames = /* @__PURE__ */ new Set();
1098
+ nextChunkId = 1;
1099
+ nextEntryId = 1;
1100
+ lastRoleIndex = -1;
1101
+ constructor(request) {
1102
+ this.request = request;
1103
+ }
1104
+ cancel() {
1105
+ if (this.cancelled) {
1106
+ return;
1107
+ }
1108
+ this.cancelled = true;
1109
+ this.abortController.abort();
1110
+ this.awaitingAcknowledgement?.cancel();
1111
+ this.queuedMessages.length = 0;
1112
+ }
1113
+ }
1114
+ class ArchiveImportWorkerRuntime {
1115
+ inputChunkSize = 64 * 1024;
1116
+ activeTask;
1117
+ jobValidator = new ArchiveImportJobValidator();
1118
+ latestStartedTaskId = 0;
1119
+ centralDirectoryValidator = new ArchiveImportCentralDirectoryValidator();
1120
+ messageParser = new ArchiveImportWorkerMessageParser();
1121
+ pathValidator = new ArchiveImportPathValidator();
1122
+ port;
1123
+ constructor(port) {
1124
+ this.port = port;
1125
+ }
1126
+ attach() {
1127
+ this.port.addEventListener("message", this.handleMessage.bind(this));
1128
+ }
1129
+ acknowledgeChunk(task, chunkId) {
1130
+ const acknowledgement = task.awaitingAcknowledgement;
1131
+ if (acknowledgement?.chunkId === chunkId) {
1132
+ acknowledgement.acknowledge();
1133
+ }
1134
+ }
1135
+ cancelTask(task) {
1136
+ task.cancel();
1137
+ }
1138
+ copyChunk(data) {
1139
+ const copy = new Uint8Array(data.byteLength);
1140
+ copy.set(data);
1141
+ return copy.buffer;
1142
+ }
1143
+ createUnzip(task) {
1144
+ const unzip = new Unzip(this.handleFile.bind(this, task));
1145
+ unzip.register(UnzipInflate);
1146
+ return unzip;
1147
+ }
1148
+ async drainMessages(task) {
1149
+ while (task.queuedMessages.length > 0) {
1150
+ this.throwIfCancelled(task);
1151
+ const queued = task.queuedMessages.shift();
1152
+ if (queued === void 0) {
1153
+ throw new ArchiveImportError(
1154
+ ArchiveImportErrorCode.Protocol,
1155
+ "The archive import output queue was unexpectedly empty."
1156
+ );
1157
+ }
1158
+ await this.sendQueuedMessage(task, queued);
1159
+ }
1160
+ }
1161
+ async handleArchiveStream(task) {
1162
+ let reader;
1163
+ try {
1164
+ const stream = task.request.file.stream();
1165
+ reader = stream.getReader();
1166
+ } catch {
1167
+ throw new ArchiveImportError(
1168
+ ArchiveImportErrorCode.InvalidSource,
1169
+ "The selected archive could not be read."
1170
+ );
1171
+ }
1172
+ const unzip = this.createUnzip(task);
1173
+ const signature = new ArchiveImportSignatureValidator();
1174
+ try {
1175
+ for (; ; ) {
1176
+ this.throwIfCancelled(task);
1177
+ const result = await reader.read();
1178
+ if (result.done) {
1179
+ break;
1180
+ }
1181
+ await this.processInputChunk(task, unzip, signature, result.value);
1182
+ }
1183
+ signature.finish();
1184
+ this.pushToUnzip(task, unzip, new Uint8Array(0), true);
1185
+ await this.drainMessages(task);
1186
+ this.validateArchive(task);
1187
+ await this.validateChecksums(task);
1188
+ } finally {
1189
+ await this.cancelReader(reader);
1190
+ reader.releaseLock();
1191
+ }
1192
+ }
1193
+ handleDirectoryData(error, data) {
1194
+ if (error !== null || data === null || data.byteLength > 0) {
1195
+ throw new ArchiveImportError(
1196
+ ArchiveImportErrorCode.InvalidSource,
1197
+ "The archive contains an invalid directory entry."
1198
+ );
1199
+ }
1200
+ }
1201
+ handleEntryData(task, entry, error, data, final) {
1202
+ if (error !== null) {
1203
+ throw new ArchiveImportError(
1204
+ ArchiveImportErrorCode.InvalidSource,
1205
+ `The archive entry ${entry.metadata.fileName} could not be decompressed.`
1206
+ );
1207
+ }
1208
+ if (data === null) {
1209
+ throw new ArchiveImportError(
1210
+ ArchiveImportErrorCode.InvalidSource,
1211
+ `The archive entry ${entry.metadata.fileName} has no decompressed data.`
1212
+ );
1213
+ }
1214
+ this.throwIfCancelled(task);
1215
+ const checksum = task.entryChecksums.get(entry.metadata.entryId);
1216
+ const byteCount = task.entryByteCounts.get(entry.metadata.entryId);
1217
+ if (checksum === void 0 || byteCount === void 0) {
1218
+ throw new ArchiveImportError(
1219
+ ArchiveImportErrorCode.Protocol,
1220
+ "The archive decoder returned an unknown entry."
1221
+ );
1222
+ }
1223
+ checksum.update(data);
1224
+ task.entryByteCounts.set(entry.metadata.entryId, byteCount + data.byteLength);
1225
+ if (task.activeEntryId !== entry.metadata.entryId) {
1226
+ throw new ArchiveImportError(
1227
+ ArchiveImportErrorCode.Protocol,
1228
+ "The archive decoder changed entries unexpectedly."
1229
+ );
1230
+ }
1231
+ if (data.byteLength > 0 || final) {
1232
+ this.queueEntryChunk(task, entry.metadata, data, final);
1233
+ }
1234
+ if (final) {
1235
+ task.activeEntryId = void 0;
1236
+ }
1237
+ }
1238
+ handleFile(task, file) {
1239
+ this.throwIfCancelled(task);
1240
+ const path = this.pathValidator.parse(file.name);
1241
+ if (path.kind === "directory") {
1242
+ this.handleDirectory(task, file, path);
1243
+ return;
1244
+ }
1245
+ const entry = this.registerEntry(task, path);
1246
+ task.activeEntryId = entry.metadata.entryId;
1247
+ file.ondata = this.handleEntryData.bind(this, task, entry);
1248
+ file.start();
1249
+ }
1250
+ handleInboundMessage(message) {
1251
+ switch (message.type) {
1252
+ case "acknowledge-chunk":
1253
+ this.handleChunkAcknowledgement(message.taskId, message.chunkId);
1254
+ return;
1255
+ case "cancel":
1256
+ this.handleCancellation(message.taskId);
1257
+ return;
1258
+ case "start":
1259
+ this.handleStart(message);
1260
+ }
1261
+ }
1262
+ handleCancellation(taskId) {
1263
+ const task = this.activeTask;
1264
+ if (task?.request.taskId === taskId) {
1265
+ this.cancelTask(task);
1266
+ }
1267
+ }
1268
+ handleChunkAcknowledgement(taskId, chunkId) {
1269
+ const task = this.activeTask;
1270
+ if (task?.request.taskId === taskId) {
1271
+ this.acknowledgeChunk(task, chunkId);
1272
+ }
1273
+ }
1274
+ handleDirectory(task, file, path) {
1275
+ this.assertRoleOrder(task, path.role);
1276
+ task.rolesSeen.add(path.role);
1277
+ file.ondata = this.handleDirectoryData.bind(this);
1278
+ file.start();
1279
+ }
1280
+ handleMessage(event) {
1281
+ const message = this.messageParser.parseInbound(event.data);
1282
+ if (message !== void 0) {
1283
+ this.handleInboundMessage(message);
1284
+ }
1285
+ }
1286
+ handleStart(message) {
1287
+ const request = {
1288
+ file: message.file,
1289
+ taskId: message.taskId
1290
+ };
1291
+ try {
1292
+ this.jobValidator.validate(request);
1293
+ } catch (error) {
1294
+ this.postError(message.taskId, error);
1295
+ return;
1296
+ }
1297
+ if (request.taskId <= this.latestStartedTaskId) {
1298
+ this.postError(
1299
+ request.taskId,
1300
+ new ArchiveImportError(
1301
+ ArchiveImportErrorCode.Protocol,
1302
+ "Each archive import must use a newer task id."
1303
+ )
1304
+ );
1305
+ return;
1306
+ }
1307
+ this.activeTask?.cancel();
1308
+ const task = new ArchiveImportWorkerTask(request);
1309
+ this.activeTask = task;
1310
+ this.latestStartedTaskId = request.taskId;
1311
+ void this.runTask(task);
1312
+ }
1313
+ isCurrentTask(task) {
1314
+ return this.activeTask === task;
1315
+ }
1316
+ postCancelled(task) {
1317
+ this.port.postMessage({ taskId: task.request.taskId, type: "cancelled" });
1318
+ }
1319
+ postComplete(task) {
1320
+ this.port.postMessage({ taskId: task.request.taskId, type: "complete" });
1321
+ }
1322
+ postError(taskId, error) {
1323
+ this.port.postMessage({
1324
+ message: this.getErrorMessage(error),
1325
+ taskId,
1326
+ type: "error"
1327
+ });
1328
+ }
1329
+ async processInputChunk(task, unzip, signature, chunk) {
1330
+ for (let offset = 0; offset < chunk.byteLength; offset += this.inputChunkSize) {
1331
+ const part = chunk.subarray(offset, offset + this.inputChunkSize);
1332
+ signature.push(part);
1333
+ this.pushToUnzip(task, unzip, part, false);
1334
+ await this.drainMessages(task);
1335
+ }
1336
+ }
1337
+ pushToUnzip(task, unzip, chunk, final) {
1338
+ this.throwIfCancelled(task);
1339
+ try {
1340
+ unzip.push(chunk, final);
1341
+ } catch (error) {
1342
+ if (error instanceof ArchiveImportError) {
1343
+ throw error;
1344
+ }
1345
+ throw new ArchiveImportError(
1346
+ ArchiveImportErrorCode.InvalidSource,
1347
+ "The selected archive is invalid or corrupted."
1348
+ );
1349
+ }
1350
+ }
1351
+ queueEntryChunk(task, metadata, data, final) {
1352
+ const chunkId = task.nextChunkId;
1353
+ if (!Number.isSafeInteger(chunkId)) {
1354
+ throw new ArchiveImportError(
1355
+ ArchiveImportErrorCode.Protocol,
1356
+ "The archive import chunk id overflowed."
1357
+ );
1358
+ }
1359
+ task.nextChunkId += 1;
1360
+ const message = {
1361
+ chunk: this.copyChunk(data),
1362
+ chunkId,
1363
+ entryId: metadata.entryId,
1364
+ final,
1365
+ taskId: task.request.taskId,
1366
+ type: "entry-chunk"
1367
+ };
1368
+ task.queuedMessages.push({ kind: "entry-chunk", message });
1369
+ }
1370
+ queueEntryStart(task, metadata) {
1371
+ const message = metadata.format === void 0 ? {
1372
+ entryId: metadata.entryId,
1373
+ fileName: metadata.fileName,
1374
+ isModel: metadata.isModel,
1375
+ role: metadata.role,
1376
+ taskId: task.request.taskId,
1377
+ type: "entry-start"
1378
+ } : {
1379
+ entryId: metadata.entryId,
1380
+ fileName: metadata.fileName,
1381
+ format: metadata.format,
1382
+ isModel: metadata.isModel,
1383
+ role: metadata.role,
1384
+ taskId: task.request.taskId,
1385
+ type: "entry-start"
1386
+ };
1387
+ task.queuedMessages.push({ kind: "entry-start", message });
1388
+ }
1389
+ registerEntry(task, path) {
1390
+ this.assertRoleOrder(task, path.role);
1391
+ task.rolesSeen.add(path.role);
1392
+ const duplicateKey = `${path.role}/${path.fileName}`;
1393
+ if (task.seenFileNames.has(duplicateKey)) {
1394
+ throw new ArchiveImportError(
1395
+ ArchiveImportErrorCode.InvalidSource,
1396
+ `The archive contains a duplicate file named ${duplicateKey}.`
1397
+ );
1398
+ }
1399
+ task.seenFileNames.add(duplicateKey);
1400
+ const entryId = task.nextEntryId;
1401
+ if (!Number.isSafeInteger(entryId)) {
1402
+ throw new ArchiveImportError(
1403
+ ArchiveImportErrorCode.Protocol,
1404
+ "The archive import entry id overflowed."
1405
+ );
1406
+ }
1407
+ task.nextEntryId += 1;
1408
+ const metadata = path.format === void 0 ? {
1409
+ entryId,
1410
+ fileName: path.fileName,
1411
+ isModel: path.isModel,
1412
+ role: path.role
1413
+ } : {
1414
+ entryId,
1415
+ fileName: path.fileName,
1416
+ format: path.format,
1417
+ isModel: path.isModel,
1418
+ role: path.role
1419
+ };
1420
+ task.entries.push(metadata);
1421
+ task.entryChecksums.set(entryId, new ArchiveImportCrc32());
1422
+ task.entryByteCounts.set(entryId, 0);
1423
+ if (metadata.isModel) {
1424
+ const modelCount = task.roleModelCounts.get(metadata.role) ?? 0;
1425
+ task.roleModelCounts.set(metadata.role, modelCount + 1);
1426
+ if (modelCount >= 1) {
1427
+ throw new ArchiveImportError(
1428
+ ArchiveImportErrorCode.InvalidSource,
1429
+ `The ${metadata.role} directory must contain exactly one OBJ or PLY model.`
1430
+ );
1431
+ }
1432
+ }
1433
+ this.queueEntryStart(task, metadata);
1434
+ return { metadata };
1435
+ }
1436
+ async runTask(task) {
1437
+ try {
1438
+ await this.handleArchiveStream(task);
1439
+ this.throwIfCancelled(task);
1440
+ if (this.isCurrentTask(task)) {
1441
+ this.postComplete(task);
1442
+ }
1443
+ } catch (error) {
1444
+ if (!this.isCurrentTask(task)) {
1445
+ return;
1446
+ }
1447
+ if (task.cancelled || this.isCancelledError(error)) {
1448
+ this.postCancelled(task);
1449
+ } else {
1450
+ this.postError(task.request.taskId, error);
1451
+ }
1452
+ } finally {
1453
+ if (this.activeTask === task) {
1454
+ this.activeTask = void 0;
1455
+ }
1456
+ }
1457
+ }
1458
+ async sendQueuedMessage(task, queued) {
1459
+ if (queued.kind === "entry-start") {
1460
+ this.port.postMessage(queued.message);
1461
+ return;
1462
+ }
1463
+ const acknowledgement = new ArchiveImportChunkAcknowledgement(
1464
+ task.request.taskId,
1465
+ queued.message.chunkId
1466
+ );
1467
+ task.awaitingAcknowledgement = acknowledgement;
1468
+ this.port.postMessage(queued.message, [queued.message.chunk]);
1469
+ await acknowledgement.promise;
1470
+ if (task.awaitingAcknowledgement === acknowledgement) {
1471
+ task.awaitingAcknowledgement = void 0;
1472
+ }
1473
+ }
1474
+ throwIfCancelled(task) {
1475
+ if (task.cancelled || task.abortController.signal.aborted) {
1476
+ throw new ArchiveImportError(
1477
+ ArchiveImportErrorCode.Cancelled,
1478
+ "The archive import was cancelled."
1479
+ );
1480
+ }
1481
+ }
1482
+ assertRoleOrder(task, role) {
1483
+ const roleIndex = role === "stone" ? 0 : 1;
1484
+ if (roleIndex < task.lastRoleIndex) {
1485
+ throw new ArchiveImportError(
1486
+ ArchiveImportErrorCode.InvalidSource,
1487
+ "The archive roles are out of order."
1488
+ );
1489
+ }
1490
+ task.lastRoleIndex = roleIndex;
1491
+ }
1492
+ validateArchive(task) {
1493
+ for (const role of ["stone", "base"]) {
1494
+ if (!task.rolesSeen.has(role) || task.roleModelCounts.get(role) !== 1) {
1495
+ throw new ArchiveImportError(
1496
+ ArchiveImportErrorCode.InvalidSource,
1497
+ `The archive must contain exactly one ${role} OBJ or PLY model.`
1498
+ );
1499
+ }
1500
+ }
1501
+ }
1502
+ async validateChecksums(task) {
1503
+ const entries = [];
1504
+ for (const metadata of task.entries) {
1505
+ const checksum = task.entryChecksums.get(metadata.entryId);
1506
+ const byteLength = task.entryByteCounts.get(metadata.entryId);
1507
+ if (checksum === void 0 || byteLength === void 0) {
1508
+ throw new ArchiveImportError(
1509
+ ArchiveImportErrorCode.Protocol,
1510
+ "The archive checksum state is incomplete."
1511
+ );
1512
+ }
1513
+ entries.push({
1514
+ byteLength,
1515
+ crc32: checksum.digest(),
1516
+ path: `${metadata.role}/${metadata.fileName}`
1517
+ });
1518
+ }
1519
+ await this.centralDirectoryValidator.validate(
1520
+ task.request.file,
1521
+ entries,
1522
+ task.abortController.signal
1523
+ );
1524
+ }
1525
+ async cancelReader(reader) {
1526
+ try {
1527
+ await reader.cancel();
1528
+ } catch {
1529
+ }
1530
+ }
1531
+ getErrorMessage(error) {
1532
+ return error instanceof ArchiveImportError ? error.message : "The edited model archive could not be imported.";
1533
+ }
1534
+ isCancelledError(error) {
1535
+ return error instanceof ArchiveImportError && error.code === ArchiveImportErrorCode.Cancelled;
1536
+ }
1537
+ }
1538
+ class BrowserArchiveImportWorkerPort {
1539
+ addEventListener(type, listener) {
1540
+ globalThis.addEventListener(type, listener);
1541
+ }
1542
+ postMessage(message, transfer) {
1543
+ Reflect.apply(globalThis.postMessage, globalThis, [message, transfer]);
1544
+ }
1545
+ }
1546
+ const runtime = new ArchiveImportWorkerRuntime(new BrowserArchiveImportWorkerPort());
1547
+ runtime.attach();
1548
+ })();