@sketch-hq/sketch-web-renderer 12.0.0 → 12.0.1

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.
@@ -0,0 +1,4742 @@
1
+ import React, { useRef, useLayoutEffect, useCallback, createContext, useContext, useReducer, useMemo, useEffect, useState } from 'react';
2
+
3
+ function _arrayLikeToArray(r, a) {
4
+ (null == a || a > r.length) && (a = r.length);
5
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
6
+ return n;
7
+ }
8
+ function _arrayWithHoles(r) {
9
+ if (Array.isArray(r)) return r;
10
+ }
11
+ function _assertThisInitialized(e) {
12
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
13
+ return e;
14
+ }
15
+ function _callSuper(t, o, e) {
16
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
17
+ }
18
+ function _classCallCheck(a, n) {
19
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
20
+ }
21
+ function _construct(t, e, r) {
22
+ if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
23
+ var o = [null];
24
+ o.push.apply(o, e);
25
+ var p = new (t.bind.apply(t, o))();
26
+ return r && _setPrototypeOf(p, r.prototype), p;
27
+ }
28
+ function _defineProperties(e, r) {
29
+ for (var t = 0; t < r.length; t++) {
30
+ var o = r[t];
31
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
32
+ }
33
+ }
34
+ function _createClass(e, r, t) {
35
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
36
+ writable: !1
37
+ }), e;
38
+ }
39
+ function _createForOfIteratorHelper(r, e) {
40
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
41
+ if (!t) {
42
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
43
+ t && (r = t);
44
+ var n = 0,
45
+ F = function () {};
46
+ return {
47
+ s: F,
48
+ n: function () {
49
+ return n >= r.length ? {
50
+ done: !0
51
+ } : {
52
+ done: !1,
53
+ value: r[n++]
54
+ };
55
+ },
56
+ e: function (r) {
57
+ throw r;
58
+ },
59
+ f: F
60
+ };
61
+ }
62
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
63
+ }
64
+ var o,
65
+ a = !0,
66
+ u = !1;
67
+ return {
68
+ s: function () {
69
+ t = t.call(r);
70
+ },
71
+ n: function () {
72
+ var r = t.next();
73
+ return a = r.done, r;
74
+ },
75
+ e: function (r) {
76
+ u = !0, o = r;
77
+ },
78
+ f: function () {
79
+ try {
80
+ a || null == t.return || t.return();
81
+ } finally {
82
+ if (u) throw o;
83
+ }
84
+ }
85
+ };
86
+ }
87
+ function _getPrototypeOf(t) {
88
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
89
+ return t.__proto__ || Object.getPrototypeOf(t);
90
+ }, _getPrototypeOf(t);
91
+ }
92
+ function _inherits(t, e) {
93
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
94
+ t.prototype = Object.create(e && e.prototype, {
95
+ constructor: {
96
+ value: t,
97
+ writable: !0,
98
+ configurable: !0
99
+ }
100
+ }), Object.defineProperty(t, "prototype", {
101
+ writable: !1
102
+ }), e && _setPrototypeOf(t, e);
103
+ }
104
+ function _isNativeFunction(t) {
105
+ try {
106
+ return -1 !== Function.toString.call(t).indexOf("[native code]");
107
+ } catch (n) {
108
+ return "function" == typeof t;
109
+ }
110
+ }
111
+ function _isNativeReflectConstruct() {
112
+ try {
113
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
114
+ } catch (t) {}
115
+ return (_isNativeReflectConstruct = function () {
116
+ return !!t;
117
+ })();
118
+ }
119
+ function _iterableToArrayLimit(r, l) {
120
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
121
+ if (null != t) {
122
+ var e,
123
+ n,
124
+ i,
125
+ u,
126
+ a = [],
127
+ f = !0,
128
+ o = !1;
129
+ try {
130
+ if (i = (t = t.call(r)).next, 0 === l) {
131
+ if (Object(t) !== t) return;
132
+ f = !1;
133
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
134
+ } catch (r) {
135
+ o = !0, n = r;
136
+ } finally {
137
+ try {
138
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
139
+ } finally {
140
+ if (o) throw n;
141
+ }
142
+ }
143
+ return a;
144
+ }
145
+ }
146
+ function _nonIterableRest() {
147
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
148
+ }
149
+ function _possibleConstructorReturn(t, e) {
150
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
151
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
152
+ return _assertThisInitialized(t);
153
+ }
154
+ function _regeneratorRuntime() {
155
+ _regeneratorRuntime = function () {
156
+ return e;
157
+ };
158
+ var t,
159
+ e = {},
160
+ r = Object.prototype,
161
+ n = r.hasOwnProperty,
162
+ o = Object.defineProperty || function (t, e, r) {
163
+ t[e] = r.value;
164
+ },
165
+ i = "function" == typeof Symbol ? Symbol : {},
166
+ a = i.iterator || "@@iterator",
167
+ c = i.asyncIterator || "@@asyncIterator",
168
+ u = i.toStringTag || "@@toStringTag";
169
+ function define(t, e, r) {
170
+ return Object.defineProperty(t, e, {
171
+ value: r,
172
+ enumerable: !0,
173
+ configurable: !0,
174
+ writable: !0
175
+ }), t[e];
176
+ }
177
+ try {
178
+ define({}, "");
179
+ } catch (t) {
180
+ define = function (t, e, r) {
181
+ return t[e] = r;
182
+ };
183
+ }
184
+ function wrap(t, e, r, n) {
185
+ var i = e && e.prototype instanceof Generator ? e : Generator,
186
+ a = Object.create(i.prototype),
187
+ c = new Context(n || []);
188
+ return o(a, "_invoke", {
189
+ value: makeInvokeMethod(t, r, c)
190
+ }), a;
191
+ }
192
+ function tryCatch(t, e, r) {
193
+ try {
194
+ return {
195
+ type: "normal",
196
+ arg: t.call(e, r)
197
+ };
198
+ } catch (t) {
199
+ return {
200
+ type: "throw",
201
+ arg: t
202
+ };
203
+ }
204
+ }
205
+ e.wrap = wrap;
206
+ var h = "suspendedStart",
207
+ l = "suspendedYield",
208
+ f = "executing",
209
+ s = "completed",
210
+ y = {};
211
+ function Generator() {}
212
+ function GeneratorFunction() {}
213
+ function GeneratorFunctionPrototype() {}
214
+ var p = {};
215
+ define(p, a, function () {
216
+ return this;
217
+ });
218
+ var d = Object.getPrototypeOf,
219
+ v = d && d(d(values([])));
220
+ v && v !== r && n.call(v, a) && (p = v);
221
+ var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
222
+ function defineIteratorMethods(t) {
223
+ ["next", "throw", "return"].forEach(function (e) {
224
+ define(t, e, function (t) {
225
+ return this._invoke(e, t);
226
+ });
227
+ });
228
+ }
229
+ function AsyncIterator(t, e) {
230
+ function invoke(r, o, i, a) {
231
+ var c = tryCatch(t[r], t, o);
232
+ if ("throw" !== c.type) {
233
+ var u = c.arg,
234
+ h = u.value;
235
+ return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
236
+ invoke("next", t, i, a);
237
+ }, function (t) {
238
+ invoke("throw", t, i, a);
239
+ }) : e.resolve(h).then(function (t) {
240
+ u.value = t, i(u);
241
+ }, function (t) {
242
+ return invoke("throw", t, i, a);
243
+ });
244
+ }
245
+ a(c.arg);
246
+ }
247
+ var r;
248
+ o(this, "_invoke", {
249
+ value: function (t, n) {
250
+ function callInvokeWithMethodAndArg() {
251
+ return new e(function (e, r) {
252
+ invoke(t, n, e, r);
253
+ });
254
+ }
255
+ return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
256
+ }
257
+ });
258
+ }
259
+ function makeInvokeMethod(e, r, n) {
260
+ var o = h;
261
+ return function (i, a) {
262
+ if (o === f) throw Error("Generator is already running");
263
+ if (o === s) {
264
+ if ("throw" === i) throw a;
265
+ return {
266
+ value: t,
267
+ done: !0
268
+ };
269
+ }
270
+ for (n.method = i, n.arg = a;;) {
271
+ var c = n.delegate;
272
+ if (c) {
273
+ var u = maybeInvokeDelegate(c, n);
274
+ if (u) {
275
+ if (u === y) continue;
276
+ return u;
277
+ }
278
+ }
279
+ if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
280
+ if (o === h) throw o = s, n.arg;
281
+ n.dispatchException(n.arg);
282
+ } else "return" === n.method && n.abrupt("return", n.arg);
283
+ o = f;
284
+ var p = tryCatch(e, r, n);
285
+ if ("normal" === p.type) {
286
+ if (o = n.done ? s : l, p.arg === y) continue;
287
+ return {
288
+ value: p.arg,
289
+ done: n.done
290
+ };
291
+ }
292
+ "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
293
+ }
294
+ };
295
+ }
296
+ function maybeInvokeDelegate(e, r) {
297
+ var n = r.method,
298
+ o = e.iterator[n];
299
+ if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y;
300
+ var i = tryCatch(o, e.iterator, r.arg);
301
+ if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
302
+ var a = i.arg;
303
+ return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y);
304
+ }
305
+ function pushTryEntry(t) {
306
+ var e = {
307
+ tryLoc: t[0]
308
+ };
309
+ 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
310
+ }
311
+ function resetTryEntry(t) {
312
+ var e = t.completion || {};
313
+ e.type = "normal", delete e.arg, t.completion = e;
314
+ }
315
+ function Context(t) {
316
+ this.tryEntries = [{
317
+ tryLoc: "root"
318
+ }], t.forEach(pushTryEntry, this), this.reset(!0);
319
+ }
320
+ function values(e) {
321
+ if (e || "" === e) {
322
+ var r = e[a];
323
+ if (r) return r.call(e);
324
+ if ("function" == typeof e.next) return e;
325
+ if (!isNaN(e.length)) {
326
+ var o = -1,
327
+ i = function next() {
328
+ for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
329
+ return next.value = t, next.done = !0, next;
330
+ };
331
+ return i.next = i;
332
+ }
333
+ }
334
+ throw new TypeError(typeof e + " is not iterable");
335
+ }
336
+ return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
337
+ value: GeneratorFunctionPrototype,
338
+ configurable: !0
339
+ }), o(GeneratorFunctionPrototype, "constructor", {
340
+ value: GeneratorFunction,
341
+ configurable: !0
342
+ }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
343
+ var e = "function" == typeof t && t.constructor;
344
+ return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
345
+ }, e.mark = function (t) {
346
+ return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
347
+ }, e.awrap = function (t) {
348
+ return {
349
+ __await: t
350
+ };
351
+ }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
352
+ return this;
353
+ }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
354
+ void 0 === i && (i = Promise);
355
+ var a = new AsyncIterator(wrap(t, r, n, o), i);
356
+ return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
357
+ return t.done ? t.value : a.next();
358
+ });
359
+ }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
360
+ return this;
361
+ }), define(g, "toString", function () {
362
+ return "[object Generator]";
363
+ }), e.keys = function (t) {
364
+ var e = Object(t),
365
+ r = [];
366
+ for (var n in e) r.push(n);
367
+ return r.reverse(), function next() {
368
+ for (; r.length;) {
369
+ var t = r.pop();
370
+ if (t in e) return next.value = t, next.done = !1, next;
371
+ }
372
+ return next.done = !0, next;
373
+ };
374
+ }, e.values = values, Context.prototype = {
375
+ constructor: Context,
376
+ reset: function (e) {
377
+ if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t);
378
+ },
379
+ stop: function () {
380
+ this.done = !0;
381
+ var t = this.tryEntries[0].completion;
382
+ if ("throw" === t.type) throw t.arg;
383
+ return this.rval;
384
+ },
385
+ dispatchException: function (e) {
386
+ if (this.done) throw e;
387
+ var r = this;
388
+ function handle(n, o) {
389
+ return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
390
+ }
391
+ for (var o = this.tryEntries.length - 1; o >= 0; --o) {
392
+ var i = this.tryEntries[o],
393
+ a = i.completion;
394
+ if ("root" === i.tryLoc) return handle("end");
395
+ if (i.tryLoc <= this.prev) {
396
+ var c = n.call(i, "catchLoc"),
397
+ u = n.call(i, "finallyLoc");
398
+ if (c && u) {
399
+ if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
400
+ if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
401
+ } else if (c) {
402
+ if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
403
+ } else {
404
+ if (!u) throw Error("try statement without catch or finally");
405
+ if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
406
+ }
407
+ }
408
+ }
409
+ },
410
+ abrupt: function (t, e) {
411
+ for (var r = this.tryEntries.length - 1; r >= 0; --r) {
412
+ var o = this.tryEntries[r];
413
+ if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
414
+ var i = o;
415
+ break;
416
+ }
417
+ }
418
+ i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
419
+ var a = i ? i.completion : {};
420
+ return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
421
+ },
422
+ complete: function (t, e) {
423
+ if ("throw" === t.type) throw t.arg;
424
+ return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y;
425
+ },
426
+ finish: function (t) {
427
+ for (var e = this.tryEntries.length - 1; e >= 0; --e) {
428
+ var r = this.tryEntries[e];
429
+ if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
430
+ }
431
+ },
432
+ catch: function (t) {
433
+ for (var e = this.tryEntries.length - 1; e >= 0; --e) {
434
+ var r = this.tryEntries[e];
435
+ if (r.tryLoc === t) {
436
+ var n = r.completion;
437
+ if ("throw" === n.type) {
438
+ var o = n.arg;
439
+ resetTryEntry(r);
440
+ }
441
+ return o;
442
+ }
443
+ }
444
+ throw Error("illegal catch attempt");
445
+ },
446
+ delegateYield: function (e, r, n) {
447
+ return this.delegate = {
448
+ iterator: values(e),
449
+ resultName: r,
450
+ nextLoc: n
451
+ }, "next" === this.method && (this.arg = t), y;
452
+ }
453
+ }, e;
454
+ }
455
+ function _setPrototypeOf(t, e) {
456
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
457
+ return t.__proto__ = e, t;
458
+ }, _setPrototypeOf(t, e);
459
+ }
460
+ function _slicedToArray(r, e) {
461
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
462
+ }
463
+ function _toPrimitive(t, r) {
464
+ if ("object" != typeof t || !t) return t;
465
+ var e = t[Symbol.toPrimitive];
466
+ if (void 0 !== e) {
467
+ var i = e.call(t, r || "default");
468
+ if ("object" != typeof i) return i;
469
+ throw new TypeError("@@toPrimitive must return a primitive value.");
470
+ }
471
+ return ("string" === r ? String : Number)(t);
472
+ }
473
+ function _toPropertyKey(t) {
474
+ var i = _toPrimitive(t, "string");
475
+ return "symbol" == typeof i ? i : i + "";
476
+ }
477
+ function _typeof(o) {
478
+ "@babel/helpers - typeof";
479
+
480
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
481
+ return typeof o;
482
+ } : function (o) {
483
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
484
+ }, _typeof(o);
485
+ }
486
+ function _unsupportedIterableToArray(r, a) {
487
+ if (r) {
488
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
489
+ var t = {}.toString.call(r).slice(8, -1);
490
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
491
+ }
492
+ }
493
+ function _wrapNativeSuper(t) {
494
+ var r = "function" == typeof Map ? new Map() : void 0;
495
+ return _wrapNativeSuper = function (t) {
496
+ if (null === t || !_isNativeFunction(t)) return t;
497
+ if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function");
498
+ if (void 0 !== r) {
499
+ if (r.has(t)) return r.get(t);
500
+ r.set(t, Wrapper);
501
+ }
502
+ function Wrapper() {
503
+ return _construct(t, arguments, _getPrototypeOf(this).constructor);
504
+ }
505
+ return Wrapper.prototype = Object.create(t.prototype, {
506
+ constructor: {
507
+ value: Wrapper,
508
+ enumerable: !1,
509
+ writable: !0,
510
+ configurable: !0
511
+ }
512
+ }), _setPrototypeOf(Wrapper, t);
513
+ }, _wrapNativeSuper(t);
514
+ }
515
+
516
+ /******************************************************************************
517
+ Copyright (c) Microsoft Corporation.
518
+
519
+ Permission to use, copy, modify, and/or distribute this software for any
520
+ purpose with or without fee is hereby granted.
521
+
522
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
523
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
524
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
525
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
526
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
527
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
528
+ PERFORMANCE OF THIS SOFTWARE.
529
+ ***************************************************************************** */
530
+ /* global Reflect, Promise */
531
+
532
+ var _extendStatics = function extendStatics(d, b) {
533
+ _extendStatics = Object.setPrototypeOf || {
534
+ __proto__: []
535
+ } instanceof Array && function (d, b) {
536
+ d.__proto__ = b;
537
+ } || function (d, b) {
538
+ for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
539
+ };
540
+ return _extendStatics(d, b);
541
+ };
542
+ function __extends(d, b) {
543
+ if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
544
+ _extendStatics(d, b);
545
+ function __() {
546
+ this.constructor = d;
547
+ }
548
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
549
+ }
550
+ var _assign = function __assign() {
551
+ _assign = Object.assign || function __assign(t) {
552
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
553
+ s = arguments[i];
554
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
555
+ }
556
+ return t;
557
+ };
558
+ return _assign.apply(this, arguments);
559
+ };
560
+ function __awaiter(thisArg, _arguments, P, generator) {
561
+ function adopt(value) {
562
+ return value instanceof P ? value : new P(function (resolve) {
563
+ resolve(value);
564
+ });
565
+ }
566
+ return new (P || (P = Promise))(function (resolve, reject) {
567
+ function fulfilled(value) {
568
+ try {
569
+ step(generator.next(value));
570
+ } catch (e) {
571
+ reject(e);
572
+ }
573
+ }
574
+ function rejected(value) {
575
+ try {
576
+ step(generator["throw"](value));
577
+ } catch (e) {
578
+ reject(e);
579
+ }
580
+ }
581
+ function step(result) {
582
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
583
+ }
584
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
585
+ });
586
+ }
587
+ function __generator(thisArg, body) {
588
+ var _ = {
589
+ label: 0,
590
+ sent: function sent() {
591
+ if (t[0] & 1) throw t[1];
592
+ return t[1];
593
+ },
594
+ trys: [],
595
+ ops: []
596
+ },
597
+ f,
598
+ y,
599
+ t,
600
+ g;
601
+ return g = {
602
+ next: verb(0),
603
+ "throw": verb(1),
604
+ "return": verb(2)
605
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
606
+ return this;
607
+ }), g;
608
+ function verb(n) {
609
+ return function (v) {
610
+ return step([n, v]);
611
+ };
612
+ }
613
+ function step(op) {
614
+ if (f) throw new TypeError("Generator is already executing.");
615
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
616
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
617
+ if (y = 0, t) op = [op[0] & 2, t.value];
618
+ switch (op[0]) {
619
+ case 0:
620
+ case 1:
621
+ t = op;
622
+ break;
623
+ case 4:
624
+ _.label++;
625
+ return {
626
+ value: op[1],
627
+ done: false
628
+ };
629
+ case 5:
630
+ _.label++;
631
+ y = op[1];
632
+ op = [0];
633
+ continue;
634
+ case 7:
635
+ op = _.ops.pop();
636
+ _.trys.pop();
637
+ continue;
638
+ default:
639
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
640
+ _ = 0;
641
+ continue;
642
+ }
643
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
644
+ _.label = op[1];
645
+ break;
646
+ }
647
+ if (op[0] === 6 && _.label < t[1]) {
648
+ _.label = t[1];
649
+ t = op;
650
+ break;
651
+ }
652
+ if (t && _.label < t[2]) {
653
+ _.label = t[2];
654
+ _.ops.push(op);
655
+ break;
656
+ }
657
+ if (t[2]) _.ops.pop();
658
+ _.trys.pop();
659
+ continue;
660
+ }
661
+ op = body.call(thisArg, _);
662
+ } catch (e) {
663
+ op = [6, e];
664
+ y = 0;
665
+ } finally {
666
+ f = t = 0;
667
+ }
668
+ if (op[0] & 5) throw op[1];
669
+ return {
670
+ value: op[0] ? op[1] : void 0,
671
+ done: true
672
+ };
673
+ }
674
+ }
675
+ function __spreadArray(to, from, pack) {
676
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
677
+ if (ar || !(i in from)) {
678
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
679
+ ar[i] = from[i];
680
+ }
681
+ }
682
+ return to.concat(ar || Array.prototype.slice.call(from));
683
+ }
684
+
685
+ function e(e, t, n, r) {
686
+ return new (n || (n = Promise))(function (o, a) {
687
+ function i(e) {
688
+ try {
689
+ d(r.next(e));
690
+ } catch (e) {
691
+ a(e);
692
+ }
693
+ }
694
+ function c(e) {
695
+ try {
696
+ d(r["throw"](e));
697
+ } catch (e) {
698
+ a(e);
699
+ }
700
+ }
701
+ function d(e) {
702
+ var t;
703
+ e.done ? o(e.value) : (t = e.value, t instanceof n ? t : new n(function (e) {
704
+ e(t);
705
+ })).then(i, c);
706
+ }
707
+ d((r = r.apply(e, t || [])).next());
708
+ });
709
+ }
710
+ var t = ["geforce 320m", "geforce 8600", "geforce 8600m gt", "geforce 8800 gs", "geforce 8800 gt", "geforce 9400", "geforce 9400m g", "geforce 9400m", "geforce 9600m gt", "geforce 9600m", "geforce fx go5200", "geforce gt 120", "geforce gt 130", "geforce gt 330m", "geforce gtx 285", "google swiftshader", "intel g41", "intel g45", "intel gma 4500mhd", "intel gma x3100", "intel hd 3000", "intel q45", "legacy", "mali-2", "mali-3", "mali-4", "quadro fx 1500", "quadro fx 4", "quadro fx 5", "radeon hd 2400", "radeon hd 2600", "radeon hd 4670", "radeon hd 4850", "radeon hd 4870", "radeon hd 5670", "radeon hd 5750", "radeon hd 6290", "radeon hd 6300", "radeon hd 6310", "radeon hd 6320", "radeon hd 6490m", "radeon hd 6630m", "radeon hd 6750m", "radeon hd 6770m", "radeon hd 6970m", "sgx 543", "sgx543"];
711
+ function n(e) {
712
+ return e = e.toLowerCase().replace(/.*angle ?\((.+)\)(?: on vulkan [0-9.]+)?$/i, "$1").replace(/\s(\d{1,2}gb|direct3d.+$)|\(r\)| \([^)]+\)$/g, "").replace(/(?:vulkan|opengl) \d+\.\d+(?:\.\d+)?(?: \((.*)\))?/, "$1");
713
+ }
714
+ var r = "undefined" == typeof window,
715
+ o = function () {
716
+ if (r) return;
717
+ var _window$navigator = window.navigator,
718
+ e = _window$navigator.userAgent,
719
+ t = _window$navigator.platform,
720
+ n = _window$navigator.maxTouchPoints,
721
+ o = /(iphone|ipod|ipad)/i.test(e),
722
+ a = "iPad" === t || "MacIntel" === t && n > 0 && !window.MSStream;
723
+ return {
724
+ isIpad: a,
725
+ isMobile: /android/i.test(e) || o || a,
726
+ isSafari12: /Version\/12.+Safari/.test(e)
727
+ };
728
+ }();
729
+ function a(e, t, n) {
730
+ if (!n) return [t];
731
+ var r = function (e) {
732
+ var t = "\n precision highp float;\n attribute vec3 aPosition;\n varying float vvv;\n void main() {\n vvv = 0.31622776601683794;\n gl_Position = vec4(aPosition, 1.0);\n }\n ",
733
+ n = "\n precision highp float;\n varying float vvv;\n void main() {\n vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * vvv;\n enc = fract(enc);\n enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n gl_FragColor = enc;\n }\n ",
734
+ r = e.createShader(35633),
735
+ o = e.createShader(35632),
736
+ a = e.createProgram();
737
+ if (!(o && r && a)) return;
738
+ e.shaderSource(r, t), e.shaderSource(o, n), e.compileShader(r), e.compileShader(o), e.attachShader(a, r), e.attachShader(a, o), e.linkProgram(a), e.detachShader(a, r), e.detachShader(a, o), e.deleteShader(r), e.deleteShader(o), e.useProgram(a);
739
+ var i = e.createBuffer();
740
+ e.bindBuffer(34962, i), e.bufferData(34962, new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]), 35044);
741
+ var c = e.getAttribLocation(a, "aPosition");
742
+ e.vertexAttribPointer(c, 3, 5126, !1, 0, 0), e.enableVertexAttribArray(c), e.clearColor(1, 1, 1, 1), e.clear(16384), e.viewport(0, 0, 1, 1), e.drawArrays(4, 0, 3);
743
+ var d = new Uint8Array(4);
744
+ return e.readPixels(0, 0, 1, 1, 6408, 5121, d), e.deleteProgram(a), e.deleteBuffer(i), d.join("");
745
+ }(e),
746
+ a = "801621810",
747
+ i = "8016218135",
748
+ c = "80162181161",
749
+ d = (null == o ? void 0 : o.isIpad) ? [["a7", c, 12], ["a8", i, 15], ["a8x", i, 15], ["a9", i, 15], ["a9x", i, 15], ["a10", i, 15], ["a10x", i, 15], ["a12", a, 15], ["a12x", a, 15], ["a12z", a, 15], ["a14", a, 15], ["m1", a, 15]] : [["a7", c, 12], ["a8", i, 12], ["a9", i, 15], ["a10", i, 15], ["a11", a, 15], ["a12", a, 15], ["a13", a, 15], ["a14", a, 15]];
750
+ var l;
751
+ "80162181255" === r ? l = d.filter(function (_ref) {
752
+ var _ref2 = _slicedToArray(_ref, 3),
753
+ e = _ref2[2];
754
+ return e >= 14;
755
+ }) : (l = d.filter(function (_ref3) {
756
+ var _ref4 = _slicedToArray(_ref3, 2),
757
+ e = _ref4[1];
758
+ return e === r;
759
+ }), l.length || (l = d));
760
+ return l.map(function (_ref5) {
761
+ var _ref6 = _slicedToArray(_ref5, 1),
762
+ e = _ref6[0];
763
+ return "apple ".concat(e, " gpu");
764
+ });
765
+ }
766
+ var i = /*#__PURE__*/function (_Error) {
767
+ function i(e) {
768
+ var _this;
769
+ _classCallCheck(this, i);
770
+ _this = _callSuper(this, i, [e]), Object.setPrototypeOf(_assertThisInitialized(_this), (this instanceof i ? this.constructor : void 0).prototype);
771
+ return _this;
772
+ }
773
+ _inherits(i, _Error);
774
+ return _createClass(i);
775
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
776
+ var c = [],
777
+ d = [];
778
+ function l(e, t) {
779
+ if (e === t) return 0;
780
+ var n = e;
781
+ e.length > t.length && (e = t, t = n);
782
+ var r = e.length,
783
+ o = t.length;
784
+ for (; r > 0 && e.charCodeAt(~-r) === t.charCodeAt(~-o);) r--, o--;
785
+ var a,
786
+ i = 0;
787
+ for (; i < r && e.charCodeAt(i) === t.charCodeAt(i);) i++;
788
+ if (r -= i, o -= i, 0 === r) return o;
789
+ var l,
790
+ s,
791
+ f = 0,
792
+ u = 0,
793
+ h = 0;
794
+ for (; u < r;) d[u] = e.charCodeAt(i + u), c[u] = ++u;
795
+ for (; h < o;) for (a = t.charCodeAt(i + h), l = h++, f = h, u = 0; u < r; u++) s = a === d[u] ? l : l + 1, l = c[u], f = c[u] = l > f ? s > f ? f + 1 : s : s > l ? l + 1 : s;
796
+ return f;
797
+ }
798
+ function s(e) {
799
+ return null != e;
800
+ }
801
+ var f = function f() {
802
+ var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
803
+ _ref7$mobileTiers = _ref7.mobileTiers,
804
+ c = _ref7$mobileTiers === void 0 ? [0, 15, 30, 60] : _ref7$mobileTiers,
805
+ _ref7$desktopTiers = _ref7.desktopTiers,
806
+ d = _ref7$desktopTiers === void 0 ? [0, 15, 30, 60] : _ref7$desktopTiers,
807
+ _ref7$override = _ref7.override,
808
+ f = _ref7$override === void 0 ? {} : _ref7$override,
809
+ u = _ref7.glContext,
810
+ _ref7$failIfMajorPerf = _ref7.failIfMajorPerformanceCaveat,
811
+ h = _ref7$failIfMajorPerf === void 0 ? !1 : _ref7$failIfMajorPerf,
812
+ _ref7$benchmarksURL = _ref7.benchmarksURL,
813
+ g = _ref7$benchmarksURL === void 0 ? "https://unpkg.com/detect-gpu@5.0.25/dist/benchmarks" : _ref7$benchmarksURL;
814
+ return e(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
815
+ var p, _f$isIpad, m, _f$isMobile, v, _f$screenSize, w, _f$loadBenchmarks, x, A, P, b, S, _e, _t, y, _e4, _y$, C, E, L, M, $, _e5;
816
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
817
+ while (1) switch (_context3.prev = _context3.next) {
818
+ case 0:
819
+ p = {};
820
+ if (!r) {
821
+ _context3.next = 3;
822
+ break;
823
+ }
824
+ return _context3.abrupt("return", {
825
+ tier: 0,
826
+ type: "SSR"
827
+ });
828
+ case 3:
829
+ _f$isIpad = f.isIpad, m = _f$isIpad === void 0 ? !!(null == o ? void 0 : o.isIpad) : _f$isIpad, _f$isMobile = f.isMobile, v = _f$isMobile === void 0 ? !!(null == o ? void 0 : o.isMobile) : _f$isMobile, _f$screenSize = f.screenSize, w = _f$screenSize === void 0 ? window.screen : _f$screenSize, _f$loadBenchmarks = f.loadBenchmarks, x = _f$loadBenchmarks === void 0 ? function (t) {
830
+ return e(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
831
+ var e;
832
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
833
+ while (1) switch (_context.prev = _context.next) {
834
+ case 0:
835
+ _context.next = 2;
836
+ return fetch("".concat(g, "/").concat(t)).then(function (e) {
837
+ return e.json();
838
+ });
839
+ case 2:
840
+ e = _context.sent;
841
+ if (!(parseInt(e.shift().split(".")[0], 10) < 4)) {
842
+ _context.next = 5;
843
+ break;
844
+ }
845
+ throw new i("Detect GPU benchmark data is out of date. Please update to version 4x");
846
+ case 5:
847
+ return _context.abrupt("return", e);
848
+ case 6:
849
+ case "end":
850
+ return _context.stop();
851
+ }
852
+ }, _callee);
853
+ }));
854
+ } : _f$loadBenchmarks;
855
+ A = f.renderer;
856
+ P = function P(e, t, n, r, o) {
857
+ return {
858
+ device: o,
859
+ fps: r,
860
+ gpu: n,
861
+ isMobile: v,
862
+ tier: e,
863
+ type: t
864
+ };
865
+ };
866
+ S = "";
867
+ if (!A) {
868
+ _context3.next = 11;
869
+ break;
870
+ }
871
+ A = n(A), b = [A];
872
+ _context3.next = 18;
873
+ break;
874
+ case 11:
875
+ _e = u || function (e) {
876
+ var t = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : !1;
877
+ var n = {
878
+ alpha: !1,
879
+ antialias: !1,
880
+ depth: !1,
881
+ failIfMajorPerformanceCaveat: t,
882
+ powerPreference: "high-performance",
883
+ stencil: !1
884
+ };
885
+ e && delete n.powerPreference;
886
+ var r = window.document.createElement("canvas"),
887
+ o = r.getContext("webgl", n) || r.getContext("experimental-webgl", n);
888
+ return null != o ? o : void 0;
889
+ }(null == o ? void 0 : o.isSafari12, h);
890
+ if (_e) {
891
+ _context3.next = 14;
892
+ break;
893
+ }
894
+ return _context3.abrupt("return", P(0, "WEBGL_UNSUPPORTED"));
895
+ case 14:
896
+ _t = _e.getExtension("WEBGL_debug_renderer_info");
897
+ if (!(_t && (A = _e.getParameter(_t.UNMASKED_RENDERER_WEBGL)), !A)) {
898
+ _context3.next = 17;
899
+ break;
900
+ }
901
+ return _context3.abrupt("return", P(1, "FALLBACK"));
902
+ case 17:
903
+ S = A, A = n(A), b = function (e, t, n) {
904
+ return "apple gpu" === t ? a(e, t, n) : [t];
905
+ }(_e, A, v);
906
+ case 18:
907
+ _context3.next = 20;
908
+ return Promise.all(b.map(function (t) {
909
+ var n;
910
+ return e(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
911
+ var e, r, o, a, c, d, s, f, u, _ref12, _ref13, h, g, A, _window, P, b, _iterator, _step, _e2, _e3, _t3, _n2, _r, _o, _u, _u2, S, y;
912
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
913
+ while (1) switch (_context2.prev = _context2.next) {
914
+ case 0:
915
+ e = function (e) {
916
+ var t = v ? ["adreno", "apple", "mali-t", "mali", "nvidia", "powervr", "samsung"] : ["intel", "apple", "amd", "radeon", "nvidia", "geforce"];
917
+ for (var _i = 0, _t2 = t; _i < _t2.length; _i++) {
918
+ var _n = _t2[_i];
919
+ if (e.includes(_n)) return _n;
920
+ }
921
+ }(t);
922
+ if (e) {
923
+ _context2.next = 3;
924
+ break;
925
+ }
926
+ return _context2.abrupt("return");
927
+ case 3:
928
+ r = "".concat(v ? "m" : "d", "-").concat(e).concat(m ? "-ipad" : "", ".json"), o = p[r] = null !== (n = p[r]) && void 0 !== n ? n : x(r);
929
+ _context2.prev = 4;
930
+ _context2.next = 7;
931
+ return o;
932
+ case 7:
933
+ a = _context2.sent;
934
+ _context2.next = 15;
935
+ break;
936
+ case 10:
937
+ _context2.prev = 10;
938
+ _context2.t0 = _context2["catch"](4);
939
+ if (!(_context2.t0 instanceof i)) {
940
+ _context2.next = 14;
941
+ break;
942
+ }
943
+ throw _context2.t0;
944
+ case 14:
945
+ return _context2.abrupt("return");
946
+ case 15:
947
+ c = function (e) {
948
+ var t;
949
+ var n = (e = e.replace(/\([^)]+\)/, "")).match(/\d+/) || e.match(/(\W|^)([A-Za-z]{1,3})(\W|$)/g);
950
+ return null !== (t = null == n ? void 0 : n.join("").replace(/\W|amd/g, "")) && void 0 !== t ? t : "";
951
+ }(t);
952
+ d = a.filter(function (_ref8) {
953
+ var _ref9 = _slicedToArray(_ref8, 2),
954
+ e = _ref9[1];
955
+ return e === c;
956
+ });
957
+ d.length || (d = a.filter(function (_ref10) {
958
+ var _ref11 = _slicedToArray(_ref10, 1),
959
+ e = _ref11[0];
960
+ return e.includes(t);
961
+ }));
962
+ s = d.length;
963
+ if (!(0 === s)) {
964
+ _context2.next = 21;
965
+ break;
966
+ }
967
+ return _context2.abrupt("return");
968
+ case 21:
969
+ f = t.split(/[.,()\[\]/\s]/g).sort().filter(function (e, t, n) {
970
+ return 0 === t || e !== n[t - 1];
971
+ }).join(" ");
972
+ _ref12 = s > 1 ? d.map(function (e) {
973
+ return [e, l(f, e[2])];
974
+ }).sort(function (_ref14, _ref15) {
975
+ var _ref16 = _slicedToArray(_ref14, 2),
976
+ e = _ref16[1];
977
+ var _ref17 = _slicedToArray(_ref15, 2),
978
+ t = _ref17[1];
979
+ return e - t;
980
+ })[0][0] : d[0], _ref13 = _slicedToArray(_ref12, 5), h = _ref13[0], g = _ref13[4], A = Number.MAX_VALUE;
981
+ _window = window, P = _window.devicePixelRatio, b = w.width * P * w.height * P;
982
+ _iterator = _createForOfIteratorHelper(g);
983
+ try {
984
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
985
+ _e2 = _step.value;
986
+ _e3 = _slicedToArray(_e2, 2), _t3 = _e3[0], _n2 = _e3[1], _r = _t3 * _n2, _o = Math.abs(b - _r);
987
+ _o < A && (A = _o, u = _e2);
988
+ }
989
+ } catch (err) {
990
+ _iterator.e(err);
991
+ } finally {
992
+ _iterator.f();
993
+ }
994
+ if (u) {
995
+ _context2.next = 28;
996
+ break;
997
+ }
998
+ return _context2.abrupt("return");
999
+ case 28:
1000
+ _u = u, _u2 = _slicedToArray(_u, 4), S = _u2[2], y = _u2[3];
1001
+ return _context2.abrupt("return", [A, S, h, y]);
1002
+ case 30:
1003
+ case "end":
1004
+ return _context2.stop();
1005
+ }
1006
+ }, _callee2, null, [[4, 10]]);
1007
+ }));
1008
+ }));
1009
+ case 20:
1010
+ y = _context3.sent.filter(s).sort(function (_ref18, _ref19) {
1011
+ var _ref20 = _slicedToArray(_ref18, 2),
1012
+ _ref20$ = _ref20[0],
1013
+ e = _ref20$ === void 0 ? Number.MAX_VALUE : _ref20$,
1014
+ t = _ref20[1];
1015
+ var _ref21 = _slicedToArray(_ref19, 2),
1016
+ _ref21$ = _ref21[0],
1017
+ n = _ref21$ === void 0 ? Number.MAX_VALUE : _ref21$,
1018
+ r = _ref21[1];
1019
+ return e === n ? t - r : e - n;
1020
+ });
1021
+ if (y.length) {
1022
+ _context3.next = 24;
1023
+ break;
1024
+ }
1025
+ _e4 = t.find(function (e) {
1026
+ return A.includes(e);
1027
+ });
1028
+ return _context3.abrupt("return", _e4 ? P(0, "BLOCKLISTED", _e4) : P(1, "FALLBACK", "".concat(A, " (").concat(S, ")")));
1029
+ case 24:
1030
+ _y$ = _slicedToArray(y[0], 4), C = _y$[1], E = _y$[2], L = _y$[3];
1031
+ if (!(-1 === C)) {
1032
+ _context3.next = 27;
1033
+ break;
1034
+ }
1035
+ return _context3.abrupt("return", P(0, "BLOCKLISTED", E, C, L));
1036
+ case 27:
1037
+ M = v ? c : d;
1038
+ $ = 0;
1039
+ for (_e5 = 0; _e5 < M.length; _e5++) C >= M[_e5] && ($ = _e5);
1040
+ return _context3.abrupt("return", P($, "BENCHMARK", E, C, L));
1041
+ case 31:
1042
+ case "end":
1043
+ return _context3.stop();
1044
+ }
1045
+ }, _callee3);
1046
+ }));
1047
+ };
1048
+
1049
+ var WebRendererError = /** @class */ (function (_super) {
1050
+ __extends(WebRendererError, _super);
1051
+ function WebRendererError(code, message, cause) {
1052
+ var _newTarget = this.constructor;
1053
+ var _this = _super.call(this, "(".concat(code, ") ").concat(message)) || this;
1054
+ _this.code = code;
1055
+ _this.cause = cause;
1056
+ _this.name = WebRendererError.name;
1057
+ Object.setPrototypeOf(_this, _newTarget.prototype);
1058
+ return _this;
1059
+ }
1060
+ return WebRendererError;
1061
+ }(Error));
1062
+
1063
+ var WebRendererMode;
1064
+ (function (WebRendererMode) {
1065
+ WebRendererMode["debug"] = "debug";
1066
+ WebRendererMode["release"] = "release";
1067
+ })(WebRendererMode || (WebRendererMode = {}));
1068
+
1069
+ function isDefinedPresentationManifestArtboard(value) {
1070
+ return typeof value !== 'undefined';
1071
+ }
1072
+
1073
+ var PrototypeResizeMode;
1074
+ (function (PrototypeResizeMode) {
1075
+ PrototypeResizeMode["Fit"] = "Fit";
1076
+ PrototypeResizeMode["FillWidth"] = "FillWidth";
1077
+ PrototypeResizeMode["ActualSize"] = "ActualSize";
1078
+ })(PrototypeResizeMode || (PrototypeResizeMode = {}));
1079
+
1080
+ /**
1081
+ * Very simple event emitter that can be extended from any class
1082
+ */
1083
+ var EventEmitter = /** @class */ (function () {
1084
+ function EventEmitter() {
1085
+ this.listeners = {};
1086
+ }
1087
+ EventEmitter.prototype.on = function (event, callback) {
1088
+ var _a, _b;
1089
+ this.listeners[event] = (_a = this.listeners[event]) !== null && _a !== void 0 ? _a : new Set();
1090
+ (_b = this.listeners[event]) === null || _b === void 0 ? void 0 : _b.add(callback);
1091
+ };
1092
+ EventEmitter.prototype.off = function (event, callback) {
1093
+ var _a;
1094
+ (_a = this.listeners[event]) === null || _a === void 0 ? void 0 : _a.delete(callback);
1095
+ };
1096
+ /**
1097
+ * Forward a specific event to the given target
1098
+ */
1099
+ EventEmitter.prototype.forwardEvent = function (target, event) {
1100
+ var callback = function () {
1101
+ var args = [];
1102
+ for (var _i = 0; _i < arguments.length; _i++) {
1103
+ args[_i] = arguments[_i];
1104
+ }
1105
+ target.emit.apply(target, __spreadArray([event], args, false));
1106
+ };
1107
+ this.on(event, callback);
1108
+ };
1109
+ EventEmitter.prototype.emit = function (event) {
1110
+ var args = [];
1111
+ for (var _i = 1; _i < arguments.length; _i++) {
1112
+ args[_i - 1] = arguments[_i];
1113
+ }
1114
+ var listeners = this.listeners[event];
1115
+ if (listeners === null || listeners === void 0 ? void 0 : listeners.size) {
1116
+ listeners.forEach(function (listener) {
1117
+ // Invoke listeners on next tick. This helps avoid tricky situations
1118
+ // where handlers potentially syncronously dispose the renderer or
1119
+ // trigger other large internal state changes in the same call stack as
1120
+ // emit(...) is invoked.
1121
+ Promise.resolve().then(function () {
1122
+ listener.apply(void 0, args);
1123
+ });
1124
+ });
1125
+ }
1126
+ };
1127
+ EventEmitter.prototype.detachAllListeners = function () {
1128
+ this.listeners = {};
1129
+ };
1130
+ return EventEmitter;
1131
+ }());
1132
+
1133
+ /**
1134
+ * ListenersCollector
1135
+ * It's a wrapper around addEventListener, which collects
1136
+ * all the callbacks, and provides a way to remove all of them
1137
+ */
1138
+ var ListenersCollector = /** @class */ (function () {
1139
+ function ListenersCollector(disabled) {
1140
+ if (disabled === void 0) { disabled = false; }
1141
+ this.removeListenerCallbacks = [];
1142
+ this.disabled = disabled;
1143
+ }
1144
+ ListenersCollector.prototype.add = function (scope, event, callback, options) {
1145
+ var _this = this;
1146
+ var safeguardedCallback = function () {
1147
+ var args = [];
1148
+ for (var _i = 0; _i < arguments.length; _i++) {
1149
+ args[_i] = arguments[_i];
1150
+ }
1151
+ if (_this.disabled) {
1152
+ return;
1153
+ }
1154
+ callback.apply(void 0, args);
1155
+ };
1156
+ scope.addEventListener(event, safeguardedCallback, options);
1157
+ var remove = function () {
1158
+ scope.removeEventListener(event, safeguardedCallback, options);
1159
+ };
1160
+ this.removeListenerCallbacks.push(remove);
1161
+ // Returns the function to remove the event
1162
+ return remove;
1163
+ };
1164
+ ListenersCollector.prototype.dispose = function () {
1165
+ this.removeListenerCallbacks.forEach(function (remove) { return remove(); });
1166
+ };
1167
+ ListenersCollector.prototype.setDisabled = function (disabled) {
1168
+ this.disabled = disabled;
1169
+ };
1170
+ return ListenersCollector;
1171
+ }());
1172
+
1173
+ /**
1174
+ * Initial dummy structure for feature flags
1175
+ */
1176
+ var DefaultFeatureFlags = {
1177
+ delayedDraw: true,
1178
+ offscreenCanvas: false,
1179
+ useDirtyRectsRendering: true,
1180
+ safariWebGL2: false,
1181
+ // When this is true, the canvas won't allow to pan/zoom outside the page boundaries
1182
+ pageBoundariesLimit: false,
1183
+ // When this is true, the canvas will send user events through the rendering scene.
1184
+ // This is useful to check which layer was clicked/hovered, etc.
1185
+ canvasLayersEvents: false,
1186
+ };
1187
+
1188
+ // Taken from https://gist.github.com/Craga89/2829457
1189
+ var getiOSVersion = function (userAgent) {
1190
+ return parseFloat(('' +
1191
+ (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(userAgent) || [0, ''])[1])
1192
+ .replace('undefined', '3_2')
1193
+ .replace('_', '.')
1194
+ .replace('_', '')) || false;
1195
+ };
1196
+ var SAFARI_USER_AGENT_REGEX = /(iPhone|Macintosh|iPad)(.*)(Version)\/(0|[1-9]\d*)\.(0|[1-9]\d*)\.?(0|[1-9]\d*)?/;
1197
+ /**
1198
+ * Parses a Safari user agent string into structured data. If the user agent string
1199
+ * isn't for a Safari browser, null is returned.
1200
+ *
1201
+ * User Agent parsing is generally discouraged and can never be 100% reliable. So favour
1202
+ * feature detection when possible, and do not use this method for critical functionality.
1203
+ */
1204
+ var parseSafariUserAgent = function (userAgent) {
1205
+ if (userAgent === void 0) { userAgent = window.navigator.userAgent; }
1206
+ if (userAgent.includes('Chrome/') ||
1207
+ userAgent.includes('Chromium/') ||
1208
+ userAgent.includes('Opera/') ||
1209
+ userAgent.includes('Firefox/'))
1210
+ return null;
1211
+ var match = userAgent.match(SAFARI_USER_AGENT_REGEX);
1212
+ if (!match)
1213
+ return null;
1214
+ var hardware = match[1];
1215
+ if (hardware !== 'Macintosh' && hardware !== 'iPad' && hardware !== 'iPhone')
1216
+ return null;
1217
+ return {
1218
+ hardware: hardware,
1219
+ version: {
1220
+ major: parseInt(match[4]) || 0,
1221
+ minor: parseInt(match[5]) || 0,
1222
+ patch: parseInt(match[6]) || 0,
1223
+ },
1224
+ };
1225
+ };
1226
+
1227
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1228
+ function debounce(callback, delayMs) {
1229
+ var timeoutId;
1230
+ function debouncedCallback() {
1231
+ var args = [];
1232
+ for (var _i = 0; _i < arguments.length; _i++) {
1233
+ args[_i] = arguments[_i];
1234
+ }
1235
+ clearTimeout(timeoutId);
1236
+ timeoutId = setTimeout(function () {
1237
+ callback.apply(void 0, args);
1238
+ }, delayMs);
1239
+ }
1240
+ /**
1241
+ * Cancel the potentially scheduled execution.
1242
+ * Call this function to clean things up properly.
1243
+ */
1244
+ debouncedCallback.cancel = function () {
1245
+ if (timeoutId) {
1246
+ clearTimeout(timeoutId);
1247
+ }
1248
+ };
1249
+ return debouncedCallback;
1250
+ }
1251
+ /**
1252
+ * Extract the correct mouse position
1253
+ * @param e: The type can be MouseEvent or TouchEvent or GestureEvent, but we are using any because for some reason the pageX/Y is not included inside the TouchEvent type definition.
1254
+ */
1255
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1256
+ function extractPointer(e) {
1257
+ var _a, _b, _c, _d, _e;
1258
+ // If the touches array is empty, but the changedTouches is not, it means that all the fingers were lifted from the screen,
1259
+ // and the changed touches contains the position of the last finger that was lifted.
1260
+ // The changed touches might contain more fingers, in case multiple fingers were lifted at the same time,
1261
+ // in that case we would need to find the mid point, but we don't really need to handle that, because no user interaction depends on that
1262
+ var touch = (_b = (_a = e.touches) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : (_c = e.changedTouches) === null || _c === void 0 ? void 0 : _c[0];
1263
+ return {
1264
+ x: (_d = touch === null || touch === void 0 ? void 0 : touch.clientX) !== null && _d !== void 0 ? _d : e.clientX,
1265
+ y: (_e = touch === null || touch === void 0 ? void 0 : touch.clientY) !== null && _e !== void 0 ? _e : e.clientY,
1266
+ };
1267
+ }
1268
+ function clamp(value, min, max) {
1269
+ return Math.max(min, Math.min(max, value));
1270
+ }
1271
+ function getSupportedWebGLVersion(deviceInfo) {
1272
+ // We are forcing WebGL 1 on AMD Radeon Pro 5xxx series
1273
+ // On macs with this GPU, Chrome scrambles the vertices of the triangles sent to the gpu
1274
+ // causing incorrect renderings. See https://bugs.chromium.org/p/chromium/issues/detail?id=1301748&q=webgl&can=2
1275
+ // GH ticket: https://github.com/sketch-hq/Cloud/issues/17439
1276
+ var amdRadeonRegex = /amd\sradeon\s(pro|rx)\s5\d\d\d/gi;
1277
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1278
+ var isChrome = Boolean(window.chrome);
1279
+ if (isChrome && deviceInfo.gpu && amdRadeonRegex.test(deviceInfo.gpu)) {
1280
+ return 1;
1281
+ }
1282
+ // Safari 15 has support for WebGL 2, but their implementation
1283
+ // is still slow and filled with bugs, so we are forcing WebGL 1
1284
+ // until we see that WebGL 2 starts working correctly on Safari
1285
+ if (parseSafariUserAgent() && !DefaultFeatureFlags.safariWebGL2)
1286
+ return 1;
1287
+ if (typeof WebGL2RenderingContext !== 'undefined')
1288
+ return 2;
1289
+ return 1;
1290
+ }
1291
+ function convertEmbindVectorToArray(vector) {
1292
+ if (!vector)
1293
+ return [];
1294
+ var result = [];
1295
+ for (var i = 0; i < vector.size(); i++) {
1296
+ result.push(vector.get(i));
1297
+ }
1298
+ return result;
1299
+ }
1300
+ /**
1301
+ * Keep in mind that this check is not entirely accurate on Windows machines.
1302
+ * On Safari for MacOS, it's fairly accurate. That's where we use it.
1303
+ * @see: https://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript
1304
+ */
1305
+ function isTouchDevice() {
1306
+ return ('ontouchstart' in window ||
1307
+ navigator.maxTouchPoints > 0 ||
1308
+ navigator.msMaxTouchPoints > 0);
1309
+ }
1310
+ /**
1311
+ * Remove all the keys that have an undefined value.
1312
+ * The function doesn't edit the given object directly, but it creates and returns a copy
1313
+ */
1314
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1315
+ function removeUndefinedKeys(targetObject) {
1316
+ var copiedObject = _assign({}, targetObject);
1317
+ Object.keys(copiedObject).forEach(function (key) {
1318
+ if (typeof copiedObject[key] !== 'undefined')
1319
+ return;
1320
+ delete copiedObject[key];
1321
+ });
1322
+ return copiedObject;
1323
+ }
1324
+ /**
1325
+ * Prevent to bind both onClick and touchEnd events by only binding the required event based on the device.
1326
+ * The function is designed to be used with React.
1327
+ *
1328
+ * How to use:
1329
+ *
1330
+ * <div {...touchableClick(myCallback) />
1331
+ */
1332
+ function touchableClick(callback) {
1333
+ return isTouchDevice() ? { onTouchEnd: callback } : { onClick: callback };
1334
+ }
1335
+ var safePtrAccess = function (embindPtr) {
1336
+ /**
1337
+ * We are preventing JS to throw an error when accessing
1338
+ * the internal methods of a pointer when it is deleted.
1339
+ *
1340
+ * Given "$$.count.value" are internal properties of emscripten
1341
+ * we re-type prFile as any
1342
+ */
1343
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1344
+ if ((embindPtr === null || embindPtr === void 0 ? void 0 : embindPtr.$$.count.value) === 0) {
1345
+ return null;
1346
+ }
1347
+ return embindPtr;
1348
+ };
1349
+
1350
+ var GestureManager = /** @class */ (function (_super) {
1351
+ __extends(GestureManager, _super);
1352
+ function GestureManager(target, disabled) {
1353
+ if (disabled === void 0) { disabled = false; }
1354
+ var _this = _super.call(this) || this;
1355
+ _this.state = {
1356
+ // The distance between the 2 fingers used to pinch to zoom
1357
+ pinchToZoomLastDistance: 0,
1358
+ lastGestureScale: 1,
1359
+ isCtrlPressed: false,
1360
+ };
1361
+ _this.handleGestureStart = function (e) {
1362
+ e.preventDefault();
1363
+ _this.state.lastGestureScale = e.scale;
1364
+ };
1365
+ _this.handleGestureChange = function (e) {
1366
+ e.preventDefault();
1367
+ var delta = e.scale / _this.state.lastGestureScale;
1368
+ _this.state.lastGestureScale = e.scale;
1369
+ var center = _this.getCorrectPointerPosition(e);
1370
+ _this.emitZoomEvent(delta, center);
1371
+ };
1372
+ _this.handleGestureEnd = function (e) {
1373
+ e.preventDefault();
1374
+ };
1375
+ /**
1376
+ * Update the mouse position and emit the mousemove event
1377
+ */
1378
+ _this.updateMousePosition = function (e) {
1379
+ _this.emit('pointermove', {
1380
+ type: 'mouse',
1381
+ position: _this.getCorrectPointerPosition(e),
1382
+ button: e.button,
1383
+ touchesCount: 0,
1384
+ });
1385
+ };
1386
+ _this.updateGlobalMousePosition = function (e) {
1387
+ _this.emit('globalpointermove', {
1388
+ type: 'mouse',
1389
+ position: _this.getCorrectPointerPosition(e),
1390
+ button: e.button,
1391
+ touchesCount: 0,
1392
+ });
1393
+ };
1394
+ _this.handleTouchStart = function (e) {
1395
+ e.preventDefault();
1396
+ _this.handleTouchPinchToZoomStart(e);
1397
+ _this.emit('pointerdown', {
1398
+ type: 'touch',
1399
+ position: _this.getCorrectPointerPosition(e),
1400
+ button: 0,
1401
+ touchesCount: e.touches.length,
1402
+ });
1403
+ };
1404
+ _this.handleMouseDown = function (e) {
1405
+ // Preventing dragging while keeping the CTRL key pressed.
1406
+ // When holding the CTRL key the user is expected to zoom, so it might cause conflicts with the pan.
1407
+ // But also, on macOS left-clicking while holding the CTRL key opens the context menu,
1408
+ // and when the context menu is open, no mouseup event is triggered after releasing the left click.
1409
+ // We would also need to track the context menu event and treat it as a mouseup, bringing more complexity,
1410
+ // for our own sanity, let's just prevent dragging when this key is pressed
1411
+ if (e.ctrlKey)
1412
+ return;
1413
+ e.preventDefault();
1414
+ _this.emit('pointerdown', {
1415
+ type: 'mouse',
1416
+ position: _this.getCorrectPointerPosition(e),
1417
+ button: e.button,
1418
+ touchesCount: 0,
1419
+ });
1420
+ };
1421
+ _this.handleTouchMove = function (e) {
1422
+ _this.handleTouchPinchToZoomChange(e);
1423
+ _this.emit('pointermove', {
1424
+ type: 'touch',
1425
+ position: _this.getCorrectPointerPosition(e),
1426
+ button: 0,
1427
+ touchesCount: e.touches.length,
1428
+ });
1429
+ };
1430
+ _this.handleMouseMove = function (e) {
1431
+ _this.updateMousePosition(e);
1432
+ };
1433
+ _this.handleGlobalTouchMove = function (e) {
1434
+ _this.emit('globalpointermove', {
1435
+ type: 'touch',
1436
+ position: _this.getCorrectPointerPosition(e),
1437
+ button: 0,
1438
+ touchesCount: e.touches.length,
1439
+ });
1440
+ };
1441
+ _this.handleGlobalMouseMove = function (e) {
1442
+ _this.updateGlobalMousePosition(e);
1443
+ };
1444
+ _this.handleTouchPinchToZoomStart = function (e) {
1445
+ var _a;
1446
+ if (!e.touches || ((_a = e.touches) === null || _a === void 0 ? void 0 : _a.length) < 2)
1447
+ return;
1448
+ _this.state.pinchToZoomLastDistance = _this.calculateDistanceBetweenTouches(e.touches[0], e.touches[1]);
1449
+ };
1450
+ /**
1451
+ * Handle the pinch to zoom scale calculation on touch devices, using the distance
1452
+ * between the first 2 fingers on screen and the middle point between them as zoom center
1453
+ */
1454
+ _this.handleTouchPinchToZoomChange = function (e) {
1455
+ var _a;
1456
+ if (!e.touches || ((_a = e.touches) === null || _a === void 0 ? void 0 : _a.length) < 2)
1457
+ return;
1458
+ var distance = _this.calculateDistanceBetweenTouches(e.touches[0], e.touches[1]);
1459
+ var middlePoint = _this.getCorrectPointerPosition(e);
1460
+ var distanceDelta = distance - _this.state.pinchToZoomLastDistance;
1461
+ var normalisedDelta = 1 + distanceDelta * 0.004;
1462
+ _this.state.pinchToZoomLastDistance = distance;
1463
+ // The pinch to zoom is triggered by the touchstart/touchmove/touched events, and the start/end events are emitted by the touchstart/end.
1464
+ _this.emitZoomEvent(normalisedDelta, middlePoint);
1465
+ };
1466
+ _this.handleTouchEnd = function (e) {
1467
+ var position = _this.getCorrectPointerPosition(e);
1468
+ _this.emit('pointerup', {
1469
+ position: position,
1470
+ type: 'touch',
1471
+ button: 0,
1472
+ touchesCount: e.touches.length,
1473
+ });
1474
+ };
1475
+ _this.handleMouseUp = function (e) {
1476
+ _this.emit('pointerup', {
1477
+ type: 'mouse',
1478
+ position: _this.getCorrectPointerPosition(e),
1479
+ button: e.button,
1480
+ touchesCount: 0,
1481
+ });
1482
+ };
1483
+ _this.debouncedUpdateMousePosition = debounce(_this.updateMousePosition, 40);
1484
+ _this.debouncedUpdateGlobalMousePosition = debounce(_this.updateGlobalMousePosition, 40);
1485
+ _this.handleMouseWheel = function (e) {
1486
+ // Preventing the mousewheel by default when in the canvas,
1487
+ // so we don't get unwanted scrolls, bounces, etc
1488
+ e.preventDefault();
1489
+ // crtlKey is true when the user is using pinch to zoom
1490
+ // not very intuitive, but that's how chrome and firefox work.
1491
+ // BUT, the keydown event for the ctrlKey won't be triggered when
1492
+ // pinching to zoom, so we can track the key pressed and understand
1493
+ // if the user is really pressing the key or pinching to zoom
1494
+ var isPinchToZoom = e.ctrlKey && !_this.state.isCtrlPressed;
1495
+ var isZooming = e.metaKey || isPinchToZoom || _this.state.isCtrlPressed;
1496
+ // The mouse wheel event can be triggered only by a mouse like device,
1497
+ // so we update only the mouse position, we ignore the touch.
1498
+ // The emitted event is debounced, so we don't keep emitting mouse events at a high rate while scrolling.
1499
+ // But also, it's common UX in apps/browsers that while the user scrolls, events are not triggered
1500
+ _this.debouncedUpdateMousePosition(e);
1501
+ _this.debouncedUpdateGlobalMousePosition(e);
1502
+ if (isZooming) {
1503
+ // When the user is pinching to zoom, the deltaY is inverted
1504
+ var invert = isPinchToZoom ? -1 : 1;
1505
+ var center = _this.getCorrectPointerPosition(e);
1506
+ var zoomDelta = 1 + e.deltaY * 0.005 * invert;
1507
+ _this.emitZoomEvent(zoomDelta, center);
1508
+ }
1509
+ else {
1510
+ _this.emit('wheel',
1511
+ /* delta */ {
1512
+ x: -e.deltaX,
1513
+ y: -e.deltaY,
1514
+ },
1515
+ /* pointerInfo */ {
1516
+ type: 'mouse',
1517
+ position: _this.getCorrectPointerPosition(e),
1518
+ button: e.button,
1519
+ touchesCount: 0,
1520
+ });
1521
+ }
1522
+ };
1523
+ _this.target = target;
1524
+ _this.targetBounds = target.getBoundingClientRect();
1525
+ _this.listenersCollector = new ListenersCollector(disabled);
1526
+ _this.addListeners();
1527
+ _this.targetResizeObserver = new ResizeObserver(_this.updateTargetBounds.bind(_this));
1528
+ _this.targetResizeObserver.observe(_this.target);
1529
+ return _this;
1530
+ }
1531
+ GestureManager.prototype.updateTargetBounds = function () {
1532
+ this.targetBounds = this.target.getBoundingClientRect();
1533
+ };
1534
+ GestureManager.prototype.addListeners = function () {
1535
+ this.addTouchEventListeners();
1536
+ this.addMouseEventListeners();
1537
+ this.addKeyboardEventListeners();
1538
+ this.addSafariGesturesEventListeners();
1539
+ };
1540
+ GestureManager.prototype.addKeyboardEventListeners = function () {
1541
+ var _this = this;
1542
+ this.listenersCollector.add(document, 'keydown', function (e) {
1543
+ // Tracking the CTRL key, so we can understand when it's really pressed or not.
1544
+ // Chrome and firefox sets the Event.ctrlKey boolean to true when pinching to zoom, even if that's not true.
1545
+ if (e.key === 'Control')
1546
+ _this.state.isCtrlPressed = true;
1547
+ });
1548
+ this.listenersCollector.add(document, 'keyup', function (e) {
1549
+ if (e.key === 'Control')
1550
+ _this.state.isCtrlPressed = false;
1551
+ });
1552
+ this.listenersCollector.add(document, 'contextmenu', function (e) {
1553
+ // On macOS, if the context menu was opened by using: CTRL + left click, the keyup event wouldn't be triggered
1554
+ if (e.ctrlKey) {
1555
+ _this.state.isCtrlPressed = false;
1556
+ }
1557
+ });
1558
+ };
1559
+ GestureManager.prototype.addMouseEventListeners = function () {
1560
+ this.listenersCollector.add(this.target, 'mousedown', this.handleMouseDown);
1561
+ this.listenersCollector.add(this.target, 'mousemove', this.handleMouseMove);
1562
+ this.listenersCollector.add(document, 'mousemove', this.handleGlobalMouseMove);
1563
+ // Attaching the mouseup listener to the document itself, so we never miss a mouseup event to invalidate a dragging session
1564
+ this.listenersCollector.add(document, 'mouseup', this.handleMouseUp);
1565
+ this.listenersCollector.add(this.target, 'wheel', this.handleMouseWheel);
1566
+ };
1567
+ GestureManager.prototype.addTouchEventListeners = function () {
1568
+ this.listenersCollector.add(this.target, 'touchstart', this.handleTouchStart);
1569
+ this.listenersCollector.add(document, 'touchmove', this.handleGlobalTouchMove, {
1570
+ passive: true,
1571
+ capture: true,
1572
+ });
1573
+ this.listenersCollector.add(this.target, 'touchmove', this.handleTouchMove, { passive: true, capture: true });
1574
+ // Attaching to the document to never miss a touchcancel or touchend event
1575
+ this.listenersCollector.add(document, 'touchcancel', this.handleTouchEnd);
1576
+ this.listenersCollector.add(document, 'touchend', this.handleTouchEnd);
1577
+ };
1578
+ GestureManager.prototype.addSafariGesturesEventListeners = function () {
1579
+ // Add the gesture listeners only for Safari Desktop
1580
+ // These listeners are used for the pinch to zoom gesture
1581
+ // and on touch devices, we use the touch events instead
1582
+ if (isTouchDevice())
1583
+ return;
1584
+ this.listenersCollector.add(this.target, 'gesturestart', this.handleGestureStart, { capture: true });
1585
+ this.listenersCollector.add(this.target, 'gesturechange', this.handleGestureChange, { capture: true });
1586
+ this.listenersCollector.add(this.target, 'gestureend', this.handleGestureEnd, { capture: true });
1587
+ };
1588
+ GestureManager.prototype.clampPointerToTargetBounds = function (pointer) {
1589
+ return {
1590
+ x: pointer.x - this.targetBounds.x,
1591
+ y: pointer.y - this.targetBounds.y,
1592
+ };
1593
+ };
1594
+ /**
1595
+ * Extract the pointer position from the event
1596
+ * and makes sure that the pointer position is correct even if the target has margins
1597
+ */
1598
+ GestureManager.prototype.getCorrectPointerPosition = function (e) {
1599
+ var _a;
1600
+ var pointer = { x: 0, y: 0 };
1601
+ // If there are multiple touches on the screen, we use the middle
1602
+ // point between the first two touches as the pointer position,
1603
+ // so panning while pinching to zoom works correctly, by using the point between the 2 fingers
1604
+ if (((_a = e.touches) === null || _a === void 0 ? void 0 : _a.length) > 1) {
1605
+ var touchEv = e;
1606
+ var firstTouch = touchEv.touches[0];
1607
+ var secTouch = touchEv.touches[1];
1608
+ // Finding the middle point
1609
+ pointer = {
1610
+ x: (firstTouch.clientX + secTouch.clientX) / 2,
1611
+ y: (firstTouch.clientY + secTouch.clientY) / 2,
1612
+ };
1613
+ }
1614
+ else {
1615
+ pointer = extractPointer(e);
1616
+ }
1617
+ return this.clampPointerToTargetBounds(pointer);
1618
+ };
1619
+ GestureManager.prototype.calculateDistanceBetweenTouches = function (firstTouch, secTouch) {
1620
+ return Math.hypot(firstTouch.clientX - secTouch.clientX, firstTouch.clientY - secTouch.clientY);
1621
+ };
1622
+ GestureManager.prototype.emitZoomEvent = function (zoomDelta, zoomCenter) {
1623
+ this.emit('pinchToZoom', zoomDelta, zoomCenter);
1624
+ };
1625
+ GestureManager.prototype.dispose = function () {
1626
+ this.listenersCollector.dispose();
1627
+ this.targetResizeObserver.disconnect();
1628
+ };
1629
+ GestureManager.prototype.setDisable = function (disable) {
1630
+ this.listenersCollector.setDisabled(disable);
1631
+ };
1632
+ return GestureManager;
1633
+ }(EventEmitter));
1634
+
1635
+ /**
1636
+ * A class to manage all kinds of keyboard events
1637
+ * The class exposes a .dispose function that can be invoked when all the listeners should be detached
1638
+ */
1639
+ var KeyboardManager = /** @class */ (function (_super) {
1640
+ __extends(KeyboardManager, _super);
1641
+ function KeyboardManager(target) {
1642
+ var _this = _super.call(this) || this;
1643
+ _this.listenersCollector = new ListenersCollector();
1644
+ _this.handleKeyUp = function (e) {
1645
+ _this.emit('keyUp', e.code);
1646
+ };
1647
+ _this.target = target;
1648
+ _this.addListeners();
1649
+ return _this;
1650
+ }
1651
+ KeyboardManager.prototype.addListeners = function () {
1652
+ this.listenersCollector.add(this.target, 'keyup', this.handleKeyUp);
1653
+ };
1654
+ KeyboardManager.prototype.dispose = function () {
1655
+ this.listenersCollector.dispose();
1656
+ };
1657
+ return KeyboardManager;
1658
+ }(EventEmitter));
1659
+
1660
+ var Performance = /** @class */ (function () {
1661
+ function Performance(label) {
1662
+ this.label = label;
1663
+ this.startTime = performance.now();
1664
+ this.startTimestamp = Date.now();
1665
+ }
1666
+ Performance.prototype.measure = function () {
1667
+ var duration = performance.now() - this.startTime;
1668
+ return {
1669
+ duration: duration,
1670
+ end: Date.now(),
1671
+ start: this.startTimestamp,
1672
+ id: this.label,
1673
+ };
1674
+ };
1675
+ Performance.prototype.printMeasurement = function () {
1676
+ var duration = this.measure().duration;
1677
+ if (duration < 1000) {
1678
+ var formatted = duration.toFixed(2);
1679
+ return "[Performance] ".concat(this.label, " -> ").concat(formatted, " ms");
1680
+ }
1681
+ else {
1682
+ var seconds = (duration / 1000).toFixed(2);
1683
+ return "[Performance] ".concat(this.label, " -> ").concat(seconds, " s");
1684
+ }
1685
+ };
1686
+ return Performance;
1687
+ }());
1688
+
1689
+ /**
1690
+ * Invoke the callback in the next event loop
1691
+ *
1692
+ * Note:
1693
+ * This nextTick works differently from the nodejs process.nextTick
1694
+ * - process.nextTick invokes the callback at the beginning of the next event loop
1695
+ * - setTimeout invokes the callback at the end of the next event loop
1696
+ */
1697
+ function nextTick(callback) {
1698
+ setTimeout(function () {
1699
+ callback();
1700
+ }, 0);
1701
+ }
1702
+
1703
+ var Logger = /** @class */ (function (_super) {
1704
+ __extends(Logger, _super);
1705
+ function Logger() {
1706
+ return _super !== null && _super.apply(this, arguments) || this;
1707
+ }
1708
+ Logger.prototype.logDebug = function () {
1709
+ var args = [];
1710
+ for (var _i = 0; _i < arguments.length; _i++) {
1711
+ args[_i] = arguments[_i];
1712
+ }
1713
+ this.emit.apply(this, __spreadArray(['log', 'debug'], args, false));
1714
+ };
1715
+ Logger.prototype.logWarning = function () {
1716
+ var args = [];
1717
+ for (var _i = 0; _i < arguments.length; _i++) {
1718
+ args[_i] = arguments[_i];
1719
+ }
1720
+ this.emit.apply(this, __spreadArray(['log', 'warn'], args, false));
1721
+ };
1722
+ Logger.prototype.logError = function () {
1723
+ var args = [];
1724
+ for (var _i = 0; _i < arguments.length; _i++) {
1725
+ args[_i] = arguments[_i];
1726
+ }
1727
+ this.emit.apply(this, __spreadArray(['log', 'error'], args, false));
1728
+ };
1729
+ return Logger;
1730
+ }(EventEmitter));
1731
+ var logger = new Logger();
1732
+
1733
+ var useDebounceFunction = function (func, timeout) {
1734
+ /**
1735
+ * Cache the debounced function so we
1736
+ * always have the updated value when calling
1737
+ */
1738
+ var cacheFunction = useRef(func);
1739
+ cacheFunction.current = func;
1740
+ /**
1741
+ * Temporary set of the debouncedFunction as a empty function
1742
+ * to later be set by the layoutEffect
1743
+ */
1744
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1745
+ var debouncedFunction = useRef(function () { });
1746
+ useLayoutEffect(function () {
1747
+ var newDebouncedFunction = debounce(function () {
1748
+ cacheFunction.current();
1749
+ }, timeout);
1750
+ debouncedFunction.current = newDebouncedFunction;
1751
+ return function () {
1752
+ newDebouncedFunction.cancel();
1753
+ };
1754
+ }, [timeout]);
1755
+ /**
1756
+ * Make sure the debounced function is always stable
1757
+ */
1758
+ return useCallback(function () { return debouncedFunction.current(); }, []);
1759
+ };
1760
+
1761
+ /**
1762
+ * Utility class that accepts a container and a canvas,
1763
+ * and resizes the canvas based on the container, using a resize observer
1764
+ */
1765
+ var CanvasManager = /** @class */ (function (_super) {
1766
+ __extends(CanvasManager, _super);
1767
+ function CanvasManager(settings) {
1768
+ var _this = this;
1769
+ var _a;
1770
+ _this = _super.call(this) || this;
1771
+ _this.listenersCollector = new ListenersCollector();
1772
+ _this.size = { width: 0, height: 0 };
1773
+ _this.pixelRatio = 1;
1774
+ _this.maxPixelRatio = 2;
1775
+ _this.handleCanvasResizeObserver = function (entries) {
1776
+ _this.resizeCanvas(entries[0].contentRect);
1777
+ };
1778
+ _this.resizeCanvas = function (_a) {
1779
+ var width = _a.width, height = _a.height;
1780
+ window.requestAnimationFrame(function () {
1781
+ _this.setSize(width, height);
1782
+ _this.emit('resize', width, height, _this.getDevicePixelRatio());
1783
+ });
1784
+ };
1785
+ _this.getCanvasCenterPoint = function () {
1786
+ var bounds = _this.getBoundingClientRect();
1787
+ return {
1788
+ // Calculating the canvas relative to the target position
1789
+ // we don't want the window center, but the center of the target element
1790
+ x: bounds.width / 2 + bounds.x,
1791
+ y: bounds.height / 2 + bounds.y,
1792
+ };
1793
+ };
1794
+ _this.container = settings.container;
1795
+ _this.canvas = settings.canvas;
1796
+ _this.maxPixelRatio = (_a = settings.maxPixelRatio) !== null && _a !== void 0 ? _a : _this.maxPixelRatio;
1797
+ _this.canvasResizeObserver = new ResizeObserver(_this.handleCanvasResizeObserver);
1798
+ // Why listening for events on the container and not on the canvas itself?
1799
+ // That's because we don't want the browser to set the canvas size automatically,
1800
+ // but we want to update the size manually to make sure that the canvas size is
1801
+ // always the one expected by the web renderer. So, we listen for resize events
1802
+ // on the container wrapping the canvas, and then we update the canvas size
1803
+ // in sync with the web renderer size. The canvas element will always have 100%
1804
+ // of the size of the container
1805
+ _this.canvasResizeObserver.observe(_this.container);
1806
+ _this.listenersCollector.add(window, 'orientationchange', _this.handleDeviceOrientationChange);
1807
+ _this.setSize(_this.container.clientWidth, _this.container.clientHeight);
1808
+ return _this;
1809
+ }
1810
+ // Just update the CSS and the pixel size of the canvas
1811
+ CanvasManager.prototype.setSize = function (width, height) {
1812
+ this.pixelRatio = this.getDevicePixelRatio();
1813
+ this.canvas.style.width = "".concat(width, "px");
1814
+ this.canvas.style.height = "".concat(height, "px");
1815
+ this.size.width = width * this.pixelRatio;
1816
+ this.size.height = height * this.pixelRatio;
1817
+ this.canvas.width = this.size.width;
1818
+ this.canvas.height = this.size.height;
1819
+ };
1820
+ CanvasManager.prototype.handleDeviceOrientationChange = function () {
1821
+ this.resizeCanvas({
1822
+ width: this.container.clientWidth,
1823
+ height: this.container.clientHeight,
1824
+ });
1825
+ };
1826
+ CanvasManager.prototype.getDevicePixelRatio = function () {
1827
+ return clamp(window.devicePixelRatio, 1, this.maxPixelRatio);
1828
+ };
1829
+ CanvasManager.prototype.getBoundingClientRect = function () {
1830
+ return this.canvas.getBoundingClientRect();
1831
+ };
1832
+ CanvasManager.prototype.dispose = function () {
1833
+ this.detachAllListeners();
1834
+ this.canvasResizeObserver.disconnect();
1835
+ this.listenersCollector.dispose();
1836
+ };
1837
+ return CanvasManager;
1838
+ }(EventEmitter));
1839
+
1840
+ /**
1841
+ * This class responsibility is to initialise the WASM module created by emscripten,
1842
+ * and provide utility functions to access the objects exposed through Embind, which are attached to the main wasm module
1843
+ */
1844
+ var WasmModule = /** @class */ (function () {
1845
+ function WasmModule(settings) {
1846
+ this.settings = settings;
1847
+ }
1848
+ WasmModule.prototype.isReleaseMode = function () {
1849
+ return this.settings.mode === WebRendererMode.release;
1850
+ };
1851
+ WasmModule.prototype.init = function () {
1852
+ return __awaiter(this, void 0, void 0, function () {
1853
+ var emscriptenJsModule, factory, _a, error_1;
1854
+ var _b;
1855
+ var _this = this;
1856
+ return __generator(this, function (_c) {
1857
+ switch (_c.label) {
1858
+ case 0: return [4 /*yield*/, this.importModule()];
1859
+ case 1:
1860
+ emscriptenJsModule = _c.sent();
1861
+ factory = emscriptenJsModule.default;
1862
+ _c.label = 2;
1863
+ case 2:
1864
+ _c.trys.push([2, 4, , 5]);
1865
+ _a = this;
1866
+ return [4 /*yield*/, factory({
1867
+ FeatureFlags: this.settings.featureFlags,
1868
+ currentWebGLVersion: this.settings.webglVersion,
1869
+ bridge: this.settings.jsBridge,
1870
+ locateFile: function (file) {
1871
+ return _this.settings.locateFile.replace('{file}', file);
1872
+ },
1873
+ })];
1874
+ case 3:
1875
+ _a.instance = _c.sent();
1876
+ return [3 /*break*/, 5];
1877
+ case 4:
1878
+ error_1 = _c.sent();
1879
+ throw new WebRendererError('WASM_ERROR', 'An error occurred while trying to create the wasm module.', error_1);
1880
+ case 5:
1881
+ // Updating the pointer info map. We use it to convert Js pointer types to WASM
1882
+ this.pointerTypeToWASMMap = {
1883
+ unset: this.instance.PRUserPointerTypeEnum.Unset,
1884
+ mouse: this.instance.PRUserPointerTypeEnum.Mouse,
1885
+ touch: this.instance.PRUserPointerTypeEnum.Touch,
1886
+ };
1887
+ // Mapping the PRCursorType to the TS Enum
1888
+ this.prCursorTypeToCSSCursorMap = (_b = {},
1889
+ _b[this.instance.PRCursorTypeEnum.Auto.value] = "auto" /* CSSCursor.Auto */,
1890
+ _b[this.instance.PRCursorTypeEnum.Default.value] = "default" /* CSSCursor.Default */,
1891
+ _b[this.instance.PRCursorTypeEnum.Pointer.value] = "pointer" /* CSSCursor.Pointer */,
1892
+ _b[this.instance.PRCursorTypeEnum.Grab.value] = "grab" /* CSSCursor.Grab */,
1893
+ _b[this.instance.PRCursorTypeEnum.Grabbing.value] = "grabbing" /* CSSCursor.Grabbing */,
1894
+ _b);
1895
+ this.prototypeResizeModeToWASMMap = {
1896
+ Fit: this.instance.PrototypeResizeModeWasmEnum.Fit,
1897
+ FillWidth: this.instance.PrototypeResizeModeWasmEnum.FillWidth,
1898
+ ActualSize: this.instance.PrototypeResizeModeWasmEnum.ActualSize,
1899
+ };
1900
+ return [2 /*return*/];
1901
+ }
1902
+ });
1903
+ });
1904
+ };
1905
+ WasmModule.prototype.makeWebGLContext = function (canvas, webGLContextAttributes) {
1906
+ var _a;
1907
+ if (webGLContextAttributes === void 0) { webGLContextAttributes = {}; }
1908
+ var ctxSettings = _assign({ antialias: false, alpha: false, stencil: false, depth: false, powerPreference: 'high-performance', preserveDrawingBuffer: false, desynchronized: true }, webGLContextAttributes);
1909
+ var ctxHandle = this.instance.GL.createContext(canvas, ctxSettings);
1910
+ if (!ctxHandle) {
1911
+ throw new WebRendererError('WEBGL_ERROR', 'Unable to create WebGL context. WebGL might be unsupported, disabled, or this device is not able to run WebGL correctly.');
1912
+ }
1913
+ var gl = (_a = this.instance.GL.getContext(ctxHandle)) === null || _a === void 0 ? void 0 : _a.GLctx;
1914
+ if (gl) {
1915
+ // Enabling the WEBGL_debug_renderer_info extension if available
1916
+ // so that we can retrieve debug info about the GPU
1917
+ // We do that using the detect-gpu npm package
1918
+ gl.getExtension('WEBGL_debug_renderer_info');
1919
+ }
1920
+ return ctxHandle;
1921
+ };
1922
+ WasmModule.prototype.createWebGLTextureFromImage = function (image, webGLCtxHandle) {
1923
+ var GL = this.instance.GL;
1924
+ var ctxHandle = GL.getContext(webGLCtxHandle);
1925
+ if (!ctxHandle) {
1926
+ throw new Error('Unable to retrieve emscripten WebGL context from handle');
1927
+ }
1928
+ var ctx = ctxHandle.GLctx;
1929
+ if (!ctx) {
1930
+ throw new Error('WebGL context is null');
1931
+ }
1932
+ // First, create a WebGL texture
1933
+ var texture = ctx.createTexture();
1934
+ ctx.bindTexture(ctx.TEXTURE_2D, texture);
1935
+ ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
1936
+ // Now we generate a texture id using emscripten
1937
+ var textureHandle = GL.getNewId(GL.textures);
1938
+ // Adding the texture into the correct slot
1939
+ GL.textures[textureHandle] = texture;
1940
+ // And finally, we upload the image to the texture
1941
+ ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
1942
+ // Unbinding the current texture, so that we don't accidentally modify it
1943
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
1944
+ return textureHandle;
1945
+ };
1946
+ /**
1947
+ * Forcefully releasing the WebGL context
1948
+ */
1949
+ WasmModule.prototype.destroyWebGLContext = function (webGLCtxHandle) {
1950
+ var _a;
1951
+ logger.logDebug('Destroying WebGL context');
1952
+ var ctx = (_a = this.instance) === null || _a === void 0 ? void 0 : _a.GL.getContext(webGLCtxHandle);
1953
+ if (!ctx) {
1954
+ logger.logError('WebGL context not found while trying to destroy it');
1955
+ return;
1956
+ }
1957
+ this.instance.GL.deleteContext(webGLCtxHandle);
1958
+ var loseContextExt = ctx.GLctx.getExtension('WEBGL_lose_context');
1959
+ if (!loseContextExt) {
1960
+ logger.logError('WEBGL_lose_context not available. Not possible to destroy WebGL context manually.');
1961
+ return;
1962
+ }
1963
+ loseContextExt.loseContext();
1964
+ logger.logDebug('WebGL destroyed');
1965
+ return true;
1966
+ };
1967
+ /**
1968
+ * Imports the emscripten generated JavaScript using a dynamic import. By using
1969
+ * a dynamic import the user only has to download the JS needed for their use
1970
+ * case (debug or release), and not both. How the dynamic import is handled
1971
+ * during the build is the responsibility of our bundler Rollup - the result is
1972
+ * a bundle employing code splitting and dynamic chunk loading. As such there
1973
+ * are implications for downstream build tools too, for example Webpack in
1974
+ * cloud-frontend.
1975
+ */
1976
+ WasmModule.prototype.importModule = function () {
1977
+ var emscriptenJsModule;
1978
+ // For the "production" package release to npm we want to use the UMD emscripten
1979
+ // output to maximise downstream compatibility (output files ending in .js).
1980
+ // For local development workflows in the Vite Viewer the ESM output works
1981
+ // much better (output files ending in .mjs).
1982
+ //
1983
+ // Rollup dead code elimation will take care of deleting the appropriate
1984
+ // section below depending on the NODE_ENV.
1985
+ //
1986
+ // Note that isReleaseMode() refers to the debug vs. release flavours of the
1987
+ // cpp build, and we want to be able to use those interchangably depending
1988
+ // on runtime settings, whether we're working locally or via the released
1989
+ // npm package.
1990
+ {
1991
+ emscriptenJsModule = this.isReleaseMode()
1992
+ ? import('./web-renderer-release-60255953.js')
1993
+ : import('./web-renderer-debug-bbc5d18c.js');
1994
+ }
1995
+ return emscriptenJsModule;
1996
+ };
1997
+ WasmModule.prototype.mapToCSSCursor = function (prCursorType) {
1998
+ return this.prCursorTypeToCSSCursorMap[prCursorType.value];
1999
+ };
2000
+ WasmModule.prototype.mapToPRPointerType = function (pointerType) {
2001
+ var _a;
2002
+ return ((_a = this.pointerTypeToWASMMap[pointerType]) !== null && _a !== void 0 ? _a : this.instance.PRUserPointerTypeEnum.Unset);
2003
+ };
2004
+ WasmModule.prototype.mapPointerInfo = function (pointerInfo) {
2005
+ return _assign(_assign({}, pointerInfo), { type: this.mapToPRPointerType(pointerInfo.type) });
2006
+ };
2007
+ WasmModule.prototype.mapResizeMode = function (resizeMode) {
2008
+ return this.prototypeResizeModeToWASMMap[resizeMode];
2009
+ };
2010
+ return WasmModule;
2011
+ }());
2012
+
2013
+ function loadImage(src) {
2014
+ return new Promise(function (resolve, reject) {
2015
+ var image = new Image();
2016
+ image.onload = function () {
2017
+ resolve(image);
2018
+ };
2019
+ image.onerror = function (e) {
2020
+ reject(e);
2021
+ };
2022
+ image.src = src;
2023
+ });
2024
+ }
2025
+
2026
+ /**
2027
+ * Container for Canvas settings. All properties are marked as required to
2028
+ * force either initizalization or assignment in the constructor.
2029
+ */
2030
+ var CanvasSettingsContainer = /** @class */ (function () {
2031
+ function CanvasSettingsContainer(canvas, container, filePath) {
2032
+ this.canvas = canvas;
2033
+ this.container = container;
2034
+ this.filePath = filePath;
2035
+ this.locateFile = '/{file}';
2036
+ this.imagesURLFormat = '';
2037
+ this.imagesURLMap = {};
2038
+ this.fragmentsURLFormat = '';
2039
+ this.fragmentsURLMap = {};
2040
+ this.backgroundColor = { r: 1, g: 1, b: 1, a: 1 };
2041
+ this.mode = WebRendererMode.release;
2042
+ this.showTilesBorders = false;
2043
+ this.minimumZoomLevel = 5;
2044
+ this.maximumZoomLevel = 0.01;
2045
+ this.preserveDrawingBuffer = false;
2046
+ this.featureFlags = DefaultFeatureFlags;
2047
+ this.manualInitialization = false;
2048
+ this.panBoundariesPadding = 0;
2049
+ this.selectedArtboard = null;
2050
+ this.initialZoom = null;
2051
+ this.initialPan = null;
2052
+ }
2053
+ CanvasSettingsContainer.FromSettings = function (settings) {
2054
+ return Object.assign(new CanvasSettingsContainer(settings.canvas, settings.container, settings.filePath), Object.fromEntries(Object.entries(settings).filter(function (_a) {
2055
+ var value = _a[1];
2056
+ return value !== undefined;
2057
+ })));
2058
+ };
2059
+ return CanvasSettingsContainer;
2060
+ }());
2061
+
2062
+ var MIME_TYPE = {
2063
+ png: 'image/png',
2064
+ jpg: 'image/jpeg',
2065
+ webp: 'image/webp',
2066
+ svg: 'image/svg+xml',
2067
+ pdf: 'application/pdf',
2068
+ };
2069
+
2070
+ /* Auto-generated by web-renderer.mts build script */
2071
+ var PRMarinaVisibleScaleType;
2072
+ (function (PRMarinaVisibleScaleType) {
2073
+ PRMarinaVisibleScaleType[PRMarinaVisibleScaleType["None"] = 0] = "None";
2074
+ PRMarinaVisibleScaleType[PRMarinaVisibleScaleType["Scale"] = 1] = "Scale";
2075
+ PRMarinaVisibleScaleType[PRMarinaVisibleScaleType["Width"] = 2] = "Width";
2076
+ PRMarinaVisibleScaleType[PRMarinaVisibleScaleType["Height"] = 3] = "Height";
2077
+ })(PRMarinaVisibleScaleType || (PRMarinaVisibleScaleType = {}));
2078
+ var PRMarinaExportFormatType;
2079
+ (function (PRMarinaExportFormatType) {
2080
+ PRMarinaExportFormatType[PRMarinaExportFormatType["None"] = 0] = "None";
2081
+ PRMarinaExportFormatType[PRMarinaExportFormatType["PNG"] = 1] = "PNG";
2082
+ PRMarinaExportFormatType[PRMarinaExportFormatType["JPG"] = 2] = "JPG";
2083
+ PRMarinaExportFormatType[PRMarinaExportFormatType["TIFF"] = 3] = "TIFF";
2084
+ PRMarinaExportFormatType[PRMarinaExportFormatType["WEBP"] = 4] = "WEBP";
2085
+ PRMarinaExportFormatType[PRMarinaExportFormatType["PDF"] = 5] = "PDF";
2086
+ PRMarinaExportFormatType[PRMarinaExportFormatType["EPS"] = 6] = "EPS";
2087
+ PRMarinaExportFormatType[PRMarinaExportFormatType["SVG"] = 7] = "SVG";
2088
+ PRMarinaExportFormatType[PRMarinaExportFormatType["HEIC"] = 8] = "HEIC";
2089
+ })(PRMarinaExportFormatType || (PRMarinaExportFormatType = {}));
2090
+ var PRMarinaLayerFillType;
2091
+ (function (PRMarinaLayerFillType) {
2092
+ PRMarinaLayerFillType[PRMarinaLayerFillType["Color"] = 0] = "Color";
2093
+ PRMarinaLayerFillType[PRMarinaLayerFillType["Gradient"] = 1] = "Gradient";
2094
+ PRMarinaLayerFillType[PRMarinaLayerFillType["Pattern"] = 2] = "Pattern";
2095
+ })(PRMarinaLayerFillType || (PRMarinaLayerFillType = {}));
2096
+ var PRMarinaLayerImageFillType;
2097
+ (function (PRMarinaLayerImageFillType) {
2098
+ PRMarinaLayerImageFillType[PRMarinaLayerImageFillType["Fit"] = 0] = "Fit";
2099
+ PRMarinaLayerImageFillType[PRMarinaLayerImageFillType["Fill"] = 1] = "Fill";
2100
+ PRMarinaLayerImageFillType[PRMarinaLayerImageFillType["Stretch"] = 2] = "Stretch";
2101
+ PRMarinaLayerImageFillType[PRMarinaLayerImageFillType["Tile"] = 3] = "Tile";
2102
+ })(PRMarinaLayerImageFillType || (PRMarinaLayerImageFillType = {}));
2103
+ var PRMarinaLayerGradientType;
2104
+ (function (PRMarinaLayerGradientType) {
2105
+ PRMarinaLayerGradientType[PRMarinaLayerGradientType["Linear"] = 0] = "Linear";
2106
+ PRMarinaLayerGradientType[PRMarinaLayerGradientType["Radial"] = 1] = "Radial";
2107
+ PRMarinaLayerGradientType[PRMarinaLayerGradientType["Angular"] = 2] = "Angular";
2108
+ })(PRMarinaLayerGradientType || (PRMarinaLayerGradientType = {}));
2109
+ var PRMarinaLayerBorderPosition;
2110
+ (function (PRMarinaLayerBorderPosition) {
2111
+ PRMarinaLayerBorderPosition[PRMarinaLayerBorderPosition["Center"] = 0] = "Center";
2112
+ PRMarinaLayerBorderPosition[PRMarinaLayerBorderPosition["Inside"] = 1] = "Inside";
2113
+ PRMarinaLayerBorderPosition[PRMarinaLayerBorderPosition["Outside"] = 2] = "Outside";
2114
+ })(PRMarinaLayerBorderPosition || (PRMarinaLayerBorderPosition = {}));
2115
+ var PRMarinaLayerLineCap;
2116
+ (function (PRMarinaLayerLineCap) {
2117
+ PRMarinaLayerLineCap[PRMarinaLayerLineCap["Butt"] = 0] = "Butt";
2118
+ PRMarinaLayerLineCap[PRMarinaLayerLineCap["Round"] = 1] = "Round";
2119
+ PRMarinaLayerLineCap[PRMarinaLayerLineCap["Square"] = 2] = "Square";
2120
+ })(PRMarinaLayerLineCap || (PRMarinaLayerLineCap = {}));
2121
+ var PRMarinaLayerLineJoin;
2122
+ (function (PRMarinaLayerLineJoin) {
2123
+ PRMarinaLayerLineJoin[PRMarinaLayerLineJoin["Miter"] = 0] = "Miter";
2124
+ PRMarinaLayerLineJoin[PRMarinaLayerLineJoin["Round"] = 1] = "Round";
2125
+ PRMarinaLayerLineJoin[PRMarinaLayerLineJoin["Bevel"] = 2] = "Bevel";
2126
+ })(PRMarinaLayerLineJoin || (PRMarinaLayerLineJoin = {}));
2127
+ var PRMarinaLayerBlurType;
2128
+ (function (PRMarinaLayerBlurType) {
2129
+ PRMarinaLayerBlurType[PRMarinaLayerBlurType["Motion"] = 0] = "Motion";
2130
+ PRMarinaLayerBlurType[PRMarinaLayerBlurType["Zoom"] = 1] = "Zoom";
2131
+ PRMarinaLayerBlurType[PRMarinaLayerBlurType["Background"] = 2] = "Background";
2132
+ PRMarinaLayerBlurType[PRMarinaLayerBlurType["Gaussian"] = 3] = "Gaussian";
2133
+ })(PRMarinaLayerBlurType || (PRMarinaLayerBlurType = {}));
2134
+ var PRMarinaBlendMode;
2135
+ (function (PRMarinaBlendMode) {
2136
+ PRMarinaBlendMode[PRMarinaBlendMode["Normal"] = 0] = "Normal";
2137
+ PRMarinaBlendMode[PRMarinaBlendMode["DestAtop"] = 1] = "DestAtop";
2138
+ PRMarinaBlendMode[PRMarinaBlendMode["Clear"] = 2] = "Clear";
2139
+ PRMarinaBlendMode[PRMarinaBlendMode["Source"] = 3] = "Source";
2140
+ PRMarinaBlendMode[PRMarinaBlendMode["Darken"] = 4] = "Darken";
2141
+ PRMarinaBlendMode[PRMarinaBlendMode["Multiply"] = 5] = "Multiply";
2142
+ PRMarinaBlendMode[PRMarinaBlendMode["ColorBurn"] = 6] = "ColorBurn";
2143
+ PRMarinaBlendMode[PRMarinaBlendMode["Lighten"] = 7] = "Lighten";
2144
+ PRMarinaBlendMode[PRMarinaBlendMode["Screen"] = 8] = "Screen";
2145
+ PRMarinaBlendMode[PRMarinaBlendMode["ColorDodge"] = 9] = "ColorDodge";
2146
+ PRMarinaBlendMode[PRMarinaBlendMode["Overlay"] = 10] = "Overlay";
2147
+ PRMarinaBlendMode[PRMarinaBlendMode["SoftLight"] = 11] = "SoftLight";
2148
+ PRMarinaBlendMode[PRMarinaBlendMode["HardLight"] = 12] = "HardLight";
2149
+ PRMarinaBlendMode[PRMarinaBlendMode["Difference"] = 13] = "Difference";
2150
+ PRMarinaBlendMode[PRMarinaBlendMode["Exclusion"] = 14] = "Exclusion";
2151
+ PRMarinaBlendMode[PRMarinaBlendMode["Hue"] = 15] = "Hue";
2152
+ PRMarinaBlendMode[PRMarinaBlendMode["Saturation"] = 16] = "Saturation";
2153
+ PRMarinaBlendMode[PRMarinaBlendMode["Color"] = 17] = "Color";
2154
+ PRMarinaBlendMode[PRMarinaBlendMode["Luminosity"] = 18] = "Luminosity";
2155
+ PRMarinaBlendMode[PRMarinaBlendMode["PlusLighter"] = 19] = "PlusLighter";
2156
+ PRMarinaBlendMode[PRMarinaBlendMode["PlusDarker"] = 20] = "PlusDarker";
2157
+ })(PRMarinaBlendMode || (PRMarinaBlendMode = {}));
2158
+ var PRMarinaLayerType;
2159
+ (function (PRMarinaLayerType) {
2160
+ PRMarinaLayerType[PRMarinaLayerType["Artboard"] = 0] = "Artboard";
2161
+ PRMarinaLayerType[PRMarinaLayerType["SymbolMaster"] = 1] = "SymbolMaster";
2162
+ PRMarinaLayerType[PRMarinaLayerType["SymbolInstance"] = 2] = "SymbolInstance";
2163
+ PRMarinaLayerType[PRMarinaLayerType["Hotspot"] = 3] = "Hotspot";
2164
+ PRMarinaLayerType[PRMarinaLayerType["Bitmap"] = 4] = "Bitmap";
2165
+ PRMarinaLayerType[PRMarinaLayerType["Group"] = 5] = "Group";
2166
+ PRMarinaLayerType[PRMarinaLayerType["Oval"] = 6] = "Oval";
2167
+ PRMarinaLayerType[PRMarinaLayerType["Polygon"] = 7] = "Polygon";
2168
+ PRMarinaLayerType[PRMarinaLayerType["Rectangle"] = 8] = "Rectangle";
2169
+ PRMarinaLayerType[PRMarinaLayerType["ShapeGroup"] = 9] = "ShapeGroup";
2170
+ PRMarinaLayerType[PRMarinaLayerType["ShapePath"] = 10] = "ShapePath";
2171
+ PRMarinaLayerType[PRMarinaLayerType["Star"] = 11] = "Star";
2172
+ PRMarinaLayerType[PRMarinaLayerType["Text"] = 12] = "Text";
2173
+ PRMarinaLayerType[PRMarinaLayerType["Triangle"] = 13] = "Triangle";
2174
+ PRMarinaLayerType[PRMarinaLayerType["Slice"] = 14] = "Slice";
2175
+ })(PRMarinaLayerType || (PRMarinaLayerType = {}));
2176
+ var PRMarinaLayerCornerStyle;
2177
+ (function (PRMarinaLayerCornerStyle) {
2178
+ PRMarinaLayerCornerStyle[PRMarinaLayerCornerStyle["Angled"] = 2] = "Angled";
2179
+ PRMarinaLayerCornerStyle[PRMarinaLayerCornerStyle["InsideArc"] = 4] = "InsideArc";
2180
+ PRMarinaLayerCornerStyle[PRMarinaLayerCornerStyle["InsideSquare"] = 3] = "InsideSquare";
2181
+ PRMarinaLayerCornerStyle[PRMarinaLayerCornerStyle["Rounded"] = 0] = "Rounded";
2182
+ PRMarinaLayerCornerStyle[PRMarinaLayerCornerStyle["Smooth"] = 1] = "Smooth";
2183
+ })(PRMarinaLayerCornerStyle || (PRMarinaLayerCornerStyle = {}));
2184
+ var PRMarinaLayerTextTransform;
2185
+ (function (PRMarinaLayerTextTransform) {
2186
+ PRMarinaLayerTextTransform[PRMarinaLayerTextTransform["Lowercase"] = 2] = "Lowercase";
2187
+ PRMarinaLayerTextTransform[PRMarinaLayerTextTransform["None"] = 0] = "None";
2188
+ PRMarinaLayerTextTransform[PRMarinaLayerTextTransform["Uppercase"] = 1] = "Uppercase";
2189
+ })(PRMarinaLayerTextTransform || (PRMarinaLayerTextTransform = {}));
2190
+ var PRMarinaLayerHorizontalTextAlignment;
2191
+ (function (PRMarinaLayerHorizontalTextAlignment) {
2192
+ PRMarinaLayerHorizontalTextAlignment[PRMarinaLayerHorizontalTextAlignment["Center"] = 1] = "Center";
2193
+ PRMarinaLayerHorizontalTextAlignment[PRMarinaLayerHorizontalTextAlignment["Justified"] = 3] = "Justified";
2194
+ PRMarinaLayerHorizontalTextAlignment[PRMarinaLayerHorizontalTextAlignment["Left"] = 0] = "Left";
2195
+ PRMarinaLayerHorizontalTextAlignment[PRMarinaLayerHorizontalTextAlignment["Right"] = 2] = "Right";
2196
+ })(PRMarinaLayerHorizontalTextAlignment || (PRMarinaLayerHorizontalTextAlignment = {}));
2197
+ var PRMarinaLayerVerticalTextAlignment;
2198
+ (function (PRMarinaLayerVerticalTextAlignment) {
2199
+ PRMarinaLayerVerticalTextAlignment[PRMarinaLayerVerticalTextAlignment["Top"] = 0] = "Top";
2200
+ PRMarinaLayerVerticalTextAlignment[PRMarinaLayerVerticalTextAlignment["Middle"] = 1] = "Middle";
2201
+ PRMarinaLayerVerticalTextAlignment[PRMarinaLayerVerticalTextAlignment["Bottom"] = 2] = "Bottom";
2202
+ })(PRMarinaLayerVerticalTextAlignment || (PRMarinaLayerVerticalTextAlignment = {}));
2203
+ var PRMarinaLayerTextDecoration;
2204
+ (function (PRMarinaLayerTextDecoration) {
2205
+ PRMarinaLayerTextDecoration[PRMarinaLayerTextDecoration["LineThrough"] = 2] = "LineThrough";
2206
+ PRMarinaLayerTextDecoration[PRMarinaLayerTextDecoration["Underline"] = 1] = "Underline";
2207
+ PRMarinaLayerTextDecoration[PRMarinaLayerTextDecoration["None"] = 0] = "None";
2208
+ })(PRMarinaLayerTextDecoration || (PRMarinaLayerTextDecoration = {}));
2209
+ var PRUserPointerType;
2210
+ (function (PRUserPointerType) {
2211
+ PRUserPointerType[PRUserPointerType["Unset"] = 0] = "Unset";
2212
+ PRUserPointerType[PRUserPointerType["Mouse"] = 1] = "Mouse";
2213
+ PRUserPointerType[PRUserPointerType["Touch"] = 2] = "Touch";
2214
+ })(PRUserPointerType || (PRUserPointerType = {}));
2215
+ var PRCursorType;
2216
+ (function (PRCursorType) {
2217
+ PRCursorType[PRCursorType["Auto"] = 0] = "Auto";
2218
+ PRCursorType[PRCursorType["Default"] = 1] = "Default";
2219
+ PRCursorType[PRCursorType["Pointer"] = 2] = "Pointer";
2220
+ PRCursorType[PRCursorType["Grab"] = 3] = "Grab";
2221
+ PRCursorType[PRCursorType["Grabbing"] = 4] = "Grabbing";
2222
+ })(PRCursorType || (PRCursorType = {}));
2223
+ var PRNodeExportFormat;
2224
+ (function (PRNodeExportFormat) {
2225
+ PRNodeExportFormat[PRNodeExportFormat["PNG"] = 0] = "PNG";
2226
+ PRNodeExportFormat[PRNodeExportFormat["JPG"] = 1] = "JPG";
2227
+ PRNodeExportFormat[PRNodeExportFormat["WEBP"] = 2] = "WEBP";
2228
+ PRNodeExportFormat[PRNodeExportFormat["PDF"] = 4] = "PDF";
2229
+ PRNodeExportFormat[PRNodeExportFormat["SVG"] = 3] = "SVG";
2230
+ })(PRNodeExportFormat || (PRNodeExportFormat = {}));
2231
+ var PrototypeStructureFlowType;
2232
+ (function (PrototypeStructureFlowType) {
2233
+ PrototypeStructureFlowType[PrototypeStructureFlowType["Screen"] = 0] = "Screen";
2234
+ PrototypeStructureFlowType[PrototypeStructureFlowType["Overlay"] = 1] = "Overlay";
2235
+ })(PrototypeStructureFlowType || (PrototypeStructureFlowType = {}));
2236
+ var PrototypeResizeModeWasm;
2237
+ (function (PrototypeResizeModeWasm) {
2238
+ PrototypeResizeModeWasm[PrototypeResizeModeWasm["Fit"] = 0] = "Fit";
2239
+ PrototypeResizeModeWasm[PrototypeResizeModeWasm["FillWidth"] = 1] = "FillWidth";
2240
+ PrototypeResizeModeWasm[PrototypeResizeModeWasm["ActualSize"] = 2] = "ActualSize";
2241
+ })(PrototypeResizeModeWasm || (PrototypeResizeModeWasm = {}));
2242
+
2243
+ var CanvasRenderer = /** @class */ (function (_super) {
2244
+ __extends(CanvasRenderer, _super);
2245
+ function CanvasRenderer(settings) {
2246
+ var _this = _super.call(this) || this;
2247
+ _this.status = { type: 'IDLE' };
2248
+ // Track if the renderer has been disposed
2249
+ _this.disposed = false;
2250
+ _this.handleCanvasResize = function (width, height, pixelRatio) {
2251
+ var _a;
2252
+ (_a = _this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.resize(width, height, pixelRatio);
2253
+ };
2254
+ _this.handleWebGLContextLost = function () {
2255
+ _this.setStatus({ type: 'WEBGL_CONTEXT_LOST' });
2256
+ };
2257
+ _this.handlePinchToZoomEvent = function (scaleDelta, center) {
2258
+ var _a;
2259
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchPinchToZoomEvent(scaleDelta, center.x, center.y);
2260
+ };
2261
+ _this.handleWheelEvent = function (delta, pointerInfo) {
2262
+ var _a;
2263
+ if (!_this.wasmModule)
2264
+ return;
2265
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchWheelEvent(delta.x, delta.y, _this.wasmModule.mapPointerInfo(pointerInfo));
2266
+ };
2267
+ _this.handlePointerDownEvent = function (pointerInfo) {
2268
+ var _a;
2269
+ if (!_this.wasmModule)
2270
+ return;
2271
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchPointerDownEvent(_this.wasmModule.mapPointerInfo(pointerInfo));
2272
+ };
2273
+ _this.handlePointerMoveEvent = function (pointerInfo) {
2274
+ var _a;
2275
+ if (!_this.wasmModule)
2276
+ return;
2277
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchPointerMoveEvent(_this.wasmModule.mapPointerInfo(pointerInfo));
2278
+ };
2279
+ _this.handleGlobalPointerMoveEvent = function (pointerInfo) {
2280
+ var _a;
2281
+ if (!_this.wasmModule)
2282
+ return;
2283
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchGlobalPointerMoveEvent(_this.wasmModule.mapPointerInfo(pointerInfo));
2284
+ };
2285
+ _this.handlePointerUpEvent = function (pointerInfo) {
2286
+ var _a;
2287
+ if (!_this.wasmModule)
2288
+ return;
2289
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchPointerUpEvent(_this.wasmModule.mapPointerInfo(pointerInfo));
2290
+ };
2291
+ _this.settings = CanvasSettingsContainer.FromSettings(settings);
2292
+ logger.logDebug('CanvasRenderer JS constructed with settings:', _this.settings);
2293
+ _this.gestureManager = new GestureManager(_this.settings.container);
2294
+ _this.canvasManager = new CanvasManager({
2295
+ container: _this.settings.container,
2296
+ canvas: _this.settings.canvas,
2297
+ });
2298
+ _this.fetchWorker = new Worker(
2299
+ // It's important to use the locateFile path here.
2300
+ // The consumer might use a custom path for the web renderer file
2301
+ _this.settings.locateFile.replace('{file}', 'fetch-worker.js'));
2302
+ _this.exporterFetchWorker = new Worker(
2303
+ // It's important to use the locateFile path here.
2304
+ // The consumer might use a custom path for the web renderer file
2305
+ _this.settings.locateFile.replace('{file}', 'fetch-worker.js'));
2306
+ if (!_this.settings.manualInitialization) {
2307
+ _this.init();
2308
+ }
2309
+ return _this;
2310
+ }
2311
+ CanvasRenderer.prototype.addListeners = function () {
2312
+ this.canvasManager.on('resize', this.handleCanvasResize);
2313
+ this.gestureManager.on('wheel', this.handleWheelEvent);
2314
+ this.gestureManager.on('pointerup', this.handlePointerUpEvent);
2315
+ this.gestureManager.on('pointermove', this.handlePointerMoveEvent);
2316
+ this.gestureManager.on('globalpointermove', this.handleGlobalPointerMoveEvent);
2317
+ this.gestureManager.on('pointerdown', this.handlePointerDownEvent);
2318
+ this.gestureManager.on('pinchToZoom', this.handlePinchToZoomEvent);
2319
+ this.settings.canvas.addEventListener('webglcontextlost', this.handleWebGLContextLost);
2320
+ };
2321
+ CanvasRenderer.prototype.collectAndEmitDeviceInfo = function () {
2322
+ return __awaiter(this, void 0, void 0, function () {
2323
+ var gpuTier;
2324
+ return __generator(this, function (_a) {
2325
+ switch (_a.label) {
2326
+ case 0: return [4 /*yield*/, f()];
2327
+ case 1:
2328
+ gpuTier = _a.sent();
2329
+ this.deviceInfo = _assign(_assign({}, gpuTier), { hardwareConcurrency: navigator.hardwareConcurrency });
2330
+ this.emit('deviceInfo', this.deviceInfo);
2331
+ return [2 /*return*/];
2332
+ }
2333
+ });
2334
+ });
2335
+ };
2336
+ CanvasRenderer.prototype.detectWebGLVersion = function () {
2337
+ this.webglVersion = getSupportedWebGLVersion(this.deviceInfo);
2338
+ logger.logDebug("Using WebGL ".concat(this.webglVersion));
2339
+ };
2340
+ // Keeping the real init into a separate function
2341
+ // so the outer app can wait for the init to finish
2342
+ // because we can't use async/await with constructors
2343
+ CanvasRenderer.prototype.init = function () {
2344
+ return __awaiter(this, void 0, void 0, function () {
2345
+ var error_1;
2346
+ return __generator(this, function (_a) {
2347
+ switch (_a.label) {
2348
+ case 0:
2349
+ this.traceFirstPaint = new Performance('FirstPaint');
2350
+ this.setStatus({ type: 'INITIALIZING' });
2351
+ return [4 /*yield*/, this.collectAndEmitDeviceInfo()];
2352
+ case 1:
2353
+ _a.sent();
2354
+ this.detectWebGLVersion();
2355
+ _a.label = 2;
2356
+ case 2:
2357
+ _a.trys.push([2, 6, , 7]);
2358
+ return [4 /*yield*/, this.initWasmModule()];
2359
+ case 3:
2360
+ _a.sent();
2361
+ return [4 /*yield*/, this.initCanvasRendererWasm()];
2362
+ case 4:
2363
+ _a.sent();
2364
+ return [4 /*yield*/, this.setFile(this.settings.filePath)];
2365
+ case 5:
2366
+ _a.sent();
2367
+ if (this.settings.selectedArtboard) {
2368
+ this.selectArtboard(this.settings.selectedArtboard);
2369
+ }
2370
+ return [3 /*break*/, 7];
2371
+ case 6:
2372
+ error_1 = _a.sent();
2373
+ return [2 /*return*/, this.fail(error_1 instanceof WebRendererError
2374
+ ? error_1
2375
+ : new WebRendererError('ERROR', 'Unexpected exception initializing the web renderer', error_1))];
2376
+ case 7:
2377
+ this.setInitialCameraState();
2378
+ this.startRendering();
2379
+ this.addListeners();
2380
+ return [2 /*return*/];
2381
+ }
2382
+ });
2383
+ });
2384
+ };
2385
+ CanvasRenderer.prototype.setInitialCameraState = function () {
2386
+ var _a, _b, _c;
2387
+ var hasZoom = this.settings.initialZoom !== null;
2388
+ var hasPan = this.settings.initialPan !== null;
2389
+ if (hasZoom || hasPan) {
2390
+ // Setting the zoom before the pan is important.
2391
+ // That's because the pan values are multiplied by the zoom value
2392
+ if (hasZoom) {
2393
+ // For some reason TS can't narrow the types propery here via the
2394
+ // helper booleans
2395
+ this.setZoom(this.settings.initialZoom || 1);
2396
+ }
2397
+ if (hasPan) {
2398
+ this.setPan(((_a = this.settings.initialPan) === null || _a === void 0 ? void 0 : _a.x) || 0, ((_b = this.settings.initialPan) === null || _b === void 0 ? void 0 : _b.y) || 0, (_c = this.settings.initialPan) === null || _c === void 0 ? void 0 : _c.centerPointInViewport);
2399
+ }
2400
+ }
2401
+ else {
2402
+ this.zoomToFit();
2403
+ }
2404
+ };
2405
+ CanvasRenderer.prototype.startRendering = function () {
2406
+ var _a;
2407
+ this.traceInitialRender = new Performance('InitialRender');
2408
+ this.setStatus({ type: 'DRAWING_FILE' });
2409
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.startRenderLoop();
2410
+ };
2411
+ CanvasRenderer.prototype.createJSBridge = function () {
2412
+ var _this = this;
2413
+ return {
2414
+ logDebug: function (msg) {
2415
+ logger.logDebug("[C++] ".concat(msg));
2416
+ },
2417
+ logWarning: function (msg) {
2418
+ logger.logWarning("[C++] ".concat(msg));
2419
+ },
2420
+ logError: function (msg) {
2421
+ logger.logError("[C++] ".concat(msg));
2422
+ },
2423
+ emitMetric: function (id, start, end, duration) {
2424
+ _this.emit('metric', { id: id, start: start, end: end, duration: duration });
2425
+ },
2426
+ // Having the image url resolver in JS gives
2427
+ // us more flexibility, especially when the images
2428
+ // have blob url coming from a zip file, and it's not
2429
+ // possible to create the url using a specific format
2430
+ resolveImageUrl: function (imageId, format) {
2431
+ if (_this.settings.imagesURLMap && _this.settings.imagesURLMap[imageId]) {
2432
+ return _this.settings.imagesURLMap[imageId].replace(':format', format);
2433
+ }
2434
+ if (_this.settings.imagesURLFormat) {
2435
+ return _this.settings.imagesURLFormat
2436
+ .replace(':imageId', imageId)
2437
+ .replace(':format', format);
2438
+ }
2439
+ logger.logWarning("Not able to resolve the url for the image with UUID: ".concat(imageId));
2440
+ // returning a string, because web assembly expect
2441
+ // a string return type, otherwise it will throw an error
2442
+ return '';
2443
+ },
2444
+ resolveFragmentUrl: function (fragmentId) {
2445
+ if (_this.settings.fragmentsURLMap &&
2446
+ _this.settings.fragmentsURLMap[fragmentId]) {
2447
+ return _this.settings.fragmentsURLMap[fragmentId];
2448
+ }
2449
+ if (_this.settings.fragmentsURLFormat) {
2450
+ return _this.settings.fragmentsURLFormat.replace(':fragmentId', fragmentId);
2451
+ }
2452
+ logger.logWarning("Not able to resolve the url for the fragment with UUID: ".concat(fragmentId));
2453
+ // returning a string, because web assembly expect
2454
+ // a string return type, otherwise it will throw an error
2455
+ return '';
2456
+ },
2457
+ onDrawComplete: this.handleDrawComplete.bind(this),
2458
+ onAllImagesReady: function () {
2459
+ _this.emit('allImagesReady');
2460
+ },
2461
+ onCameraMoveStart: function () {
2462
+ _this.emit('cameraMoveStart');
2463
+ },
2464
+ onCameraMoveEnd: function () {
2465
+ _this.emit('cameraMoveEnd');
2466
+ },
2467
+ onCameraZoomStart: function () {
2468
+ _this.emit('cameraZoomStart');
2469
+ },
2470
+ onCameraZoomEnd: function () {
2471
+ _this.emit('cameraZoomEnd');
2472
+ },
2473
+ onCameraZoomChange: function (zoom) {
2474
+ _this.emit('cameraZoomChange', zoom);
2475
+ },
2476
+ onCameraPanChange: function () {
2477
+ var panRelativeToPageOrigin = _this.getPan();
2478
+ _this.emit('cameraPanChange', (panRelativeToPageOrigin === null || panRelativeToPageOrigin === void 0 ? void 0 : panRelativeToPageOrigin.x) || 0, (panRelativeToPageOrigin === null || panRelativeToPageOrigin === void 0 ? void 0 : panRelativeToPageOrigin.y) || 0);
2479
+ },
2480
+ onCursorChange: function (cursor) {
2481
+ var _a;
2482
+ var mappedCSSCursor = (_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapToCSSCursor(cursor);
2483
+ if (mappedCSSCursor) {
2484
+ _this.emit('cursorChange', mappedCSSCursor);
2485
+ }
2486
+ },
2487
+ fetch: this.handleJSBridgeFetch.bind(this),
2488
+ exporterFetch: this.handleJSBridgeExporterFetch.bind(this),
2489
+ abortFetch: this.handleJSBridgeAbortFetch.bind(this),
2490
+ onLayerClick: function (id) {
2491
+ _this.emit('layerClick', id);
2492
+ },
2493
+ onLayerMouseHoverChange: function (id) {
2494
+ _this.emit('layerMouseHoverChange', id);
2495
+ },
2496
+ onSceneChange: function () {
2497
+ _this.emit('sceneChange');
2498
+ },
2499
+ onFragmentLoad: function (id) {
2500
+ _this.emit('fragmentLoad', id);
2501
+ },
2502
+ };
2503
+ };
2504
+ /**
2505
+ * Temporary bridge function to fetch images for the exporter,
2506
+ * in which case we don't want to create WebGL textures for images.
2507
+ * Once the exporter is running in a web worker, we will be able to
2508
+ * remove this function.
2509
+ */
2510
+ CanvasRenderer.prototype.handleJSBridgeExporterFetch = function (url, callback) {
2511
+ var _this = this;
2512
+ // Cloning the callback for later reuse, because the C++ one will be deallocated when the function goes out of scope
2513
+ var onComplete = callback.clone();
2514
+ var onExporterFetchComplete = function (e) { return __awaiter(_this, void 0, void 0, function () {
2515
+ var response;
2516
+ var _a, _b, _c, _d, _e;
2517
+ return __generator(this, function (_f) {
2518
+ if (!this.wasmModule)
2519
+ return [2 /*return*/];
2520
+ if (this.disposed)
2521
+ return [2 /*return*/];
2522
+ if (e.data.url !== url) {
2523
+ return [2 /*return*/];
2524
+ }
2525
+ switch (e.data.type) {
2526
+ case 'success': {
2527
+ response = {
2528
+ statusCode: 200,
2529
+ statusText: 'OK',
2530
+ contentType: e.data.contentType,
2531
+ isWebGLTexture: false,
2532
+ emscriptenWebGLTextureHandle: -1,
2533
+ width: 0,
2534
+ height: 0,
2535
+ buffer: new Uint8Array(e.data.buffer),
2536
+ };
2537
+ onComplete.exec(response);
2538
+ break;
2539
+ }
2540
+ case 'error': {
2541
+ logger.logError("Error while fetching ".concat(url), e.data.error);
2542
+ onComplete.exec({
2543
+ buffer: new Uint8Array(0),
2544
+ statusCode: (_b = (_a = e.data.error) === null || _a === void 0 ? void 0 : _a.statusCode) !== null && _b !== void 0 ? _b : 500,
2545
+ statusText: (_d = (_c = e.data.error) === null || _c === void 0 ? void 0 : _c.statusText) !== null && _d !== void 0 ? _d : 'Unknown error',
2546
+ contentType: (_e = e.data.contentType) !== null && _e !== void 0 ? _e : '',
2547
+ isWebGLTexture: false,
2548
+ emscriptenWebGLTextureHandle: 0,
2549
+ width: 0,
2550
+ height: 0,
2551
+ });
2552
+ break;
2553
+ }
2554
+ }
2555
+ this.exporterFetchWorker.removeEventListener('message', onExporterFetchComplete);
2556
+ return [2 /*return*/];
2557
+ });
2558
+ }); };
2559
+ this.exporterFetchWorker.addEventListener('message', onExporterFetchComplete);
2560
+ // Fetch using a separate fetch worker to avoid mixing the two requests.
2561
+ this.exporterFetchWorker.postMessage({
2562
+ type: 'fetch',
2563
+ url: url,
2564
+ });
2565
+ };
2566
+ CanvasRenderer.prototype.handleJSBridgeFetch = function (url, callback) {
2567
+ var _this = this;
2568
+ // Cloning the callback for later reuse, because the C++ one will be deallocated when the function goes out of scope
2569
+ var onComplete = callback.clone();
2570
+ var onFetchComplete = function (e) { return __awaiter(_this, void 0, void 0, function () {
2571
+ var _a, response, blob, image, textureHandle;
2572
+ var _b, _c, _d, _e, _f;
2573
+ return __generator(this, function (_g) {
2574
+ switch (_g.label) {
2575
+ case 0:
2576
+ if (!this.wasmModule)
2577
+ return [2 /*return*/];
2578
+ if (this.disposed)
2579
+ return [2 /*return*/];
2580
+ if (e.data.url !== url) {
2581
+ return [2 /*return*/];
2582
+ }
2583
+ _a = e.data.type;
2584
+ switch (_a) {
2585
+ case 'success': return [3 /*break*/, 1];
2586
+ case 'error': return [3 /*break*/, 5];
2587
+ }
2588
+ return [3 /*break*/, 6];
2589
+ case 1:
2590
+ response = {
2591
+ statusCode: 200,
2592
+ statusText: 'OK',
2593
+ contentType: e.data.contentType,
2594
+ isWebGLTexture: false,
2595
+ emscriptenWebGLTextureHandle: -1,
2596
+ width: 0,
2597
+ height: 0,
2598
+ };
2599
+ if (!/image/.test(e.data.contentType)) return [3 /*break*/, 3];
2600
+ blob = new Blob([e.data.buffer]);
2601
+ return [4 /*yield*/, loadImage(URL.createObjectURL(blob))
2602
+ // The image is loaded asynchronously, so we need to check again if the wasmModule wasn't disposed in the meantime
2603
+ ];
2604
+ case 2:
2605
+ image = _g.sent();
2606
+ // The image is loaded asynchronously, so we need to check again if the wasmModule wasn't disposed in the meantime
2607
+ if (!this.wasmModule)
2608
+ return [2 /*return*/];
2609
+ textureHandle = this.wasmModule.createWebGLTextureFromImage(image, this.webglCtxHandle);
2610
+ response.buffer = new Uint8Array(0);
2611
+ response.isWebGLTexture = true;
2612
+ response.emscriptenWebGLTextureHandle = textureHandle;
2613
+ response.width = image.width;
2614
+ response.height = image.height;
2615
+ return [3 /*break*/, 4];
2616
+ case 3:
2617
+ response.buffer = new Uint8Array(e.data.buffer);
2618
+ _g.label = 4;
2619
+ case 4:
2620
+ onComplete.exec(response);
2621
+ return [3 /*break*/, 7];
2622
+ case 5:
2623
+ {
2624
+ logger.logError("Error while fetching ".concat(url), e.data.error);
2625
+ onComplete.exec({
2626
+ buffer: new Uint8Array(0),
2627
+ statusCode: (_c = (_b = e.data.error) === null || _b === void 0 ? void 0 : _b.statusCode) !== null && _c !== void 0 ? _c : 500,
2628
+ statusText: (_e = (_d = e.data.error) === null || _d === void 0 ? void 0 : _d.statusText) !== null && _e !== void 0 ? _e : 'Unknown error',
2629
+ contentType: (_f = e.data.contentType) !== null && _f !== void 0 ? _f : '',
2630
+ isWebGLTexture: false,
2631
+ emscriptenWebGLTextureHandle: 0,
2632
+ width: 0,
2633
+ height: 0,
2634
+ });
2635
+ return [3 /*break*/, 7];
2636
+ }
2637
+ case 6: return [3 /*break*/, 7];
2638
+ case 7:
2639
+ this.fetchWorker.removeEventListener('message', onFetchComplete);
2640
+ return [2 /*return*/];
2641
+ }
2642
+ });
2643
+ }); };
2644
+ this.fetchWorker.addEventListener('message', onFetchComplete);
2645
+ this.fetchWorker.postMessage({
2646
+ type: 'fetch',
2647
+ url: url,
2648
+ });
2649
+ };
2650
+ CanvasRenderer.prototype.handleJSBridgeAbortFetch = function (url) {
2651
+ this.fetchWorker.postMessage({
2652
+ type: 'abort',
2653
+ url: url,
2654
+ });
2655
+ };
2656
+ CanvasRenderer.prototype.initWasmModule = function () {
2657
+ var _a;
2658
+ return __awaiter(this, void 0, void 0, function () {
2659
+ var traceWasmModule;
2660
+ return __generator(this, function (_b) {
2661
+ switch (_b.label) {
2662
+ case 0:
2663
+ if (this.disposed)
2664
+ return [2 /*return*/];
2665
+ traceWasmModule = new Performance('WasmModuleDownload');
2666
+ this.wasmModule = new WasmModule({
2667
+ mode: this.settings.mode,
2668
+ locateFile: this.settings.locateFile,
2669
+ jsBridge: this.createJSBridge(),
2670
+ featureFlags: this.settings.featureFlags,
2671
+ webglVersion: this.webglVersion,
2672
+ });
2673
+ return [4 /*yield*/, ((_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.init())];
2674
+ case 1:
2675
+ _b.sent();
2676
+ logger.logDebug(traceWasmModule.printMeasurement());
2677
+ this.emit('metric', traceWasmModule.measure());
2678
+ return [2 /*return*/];
2679
+ }
2680
+ });
2681
+ });
2682
+ };
2683
+ CanvasRenderer.prototype.initCanvasRendererWasm = function () {
2684
+ return __awaiter(this, void 0, void 0, function () {
2685
+ var userEventsCollectorWasm;
2686
+ return __generator(this, function (_a) {
2687
+ if (this.disposed)
2688
+ return [2 /*return*/];
2689
+ try {
2690
+ if (!this.wasmModule)
2691
+ throw Error('WASM module not initialized');
2692
+ this.webglCtxHandle = this.wasmModule.makeWebGLContext(this.settings.canvas, {
2693
+ preserveDrawingBuffer: this.settings.preserveDrawingBuffer,
2694
+ majorVersion: this.webglVersion,
2695
+ });
2696
+ this.renderTarget = this.wasmModule.instance.RenderTarget.MakeWebGL(this.webglCtxHandle, this.canvasManager.size.width, this.canvasManager.size.height, this.canvasManager.pixelRatio);
2697
+ this.pageCanvasWasm = new this.wasmModule.instance.CanvasRendererWasm(this.renderTarget, {
2698
+ showTilesBorders: this.settings.showTilesBorders,
2699
+ });
2700
+ }
2701
+ catch (error) {
2702
+ throw new WebRendererError('WASM_ERROR', 'An error occurred while trying to create the wasm object.', error);
2703
+ }
2704
+ // This should never happen, but otherwise Typescript complains, because
2705
+ // it doesn't take into account that the thrown error will stop the execution
2706
+ if (!this.pageCanvasWasm)
2707
+ return [2 /*return*/];
2708
+ userEventsCollectorWasm = this.pageCanvasWasm.getUserEventsCollector();
2709
+ if (!userEventsCollectorWasm) {
2710
+ throw new WebRendererError('WASM_ERROR', 'An error occurred while trying to create the user events collector');
2711
+ }
2712
+ this.userEventsCollectorWasm = userEventsCollectorWasm;
2713
+ this.pageCanvasWasm.setBackgroundColor(this.settings.backgroundColor.r, this.settings.backgroundColor.g, this.settings.backgroundColor.b, this.settings.backgroundColor.a);
2714
+ this.pageCanvasWasm.setZoomLevels(this.settings.minimumZoomLevel, this.settings.maximumZoomLevel);
2715
+ this.pageCanvasWasm.setPanBoundariesPadding(this.settings.panBoundariesPadding);
2716
+ return [2 /*return*/];
2717
+ });
2718
+ });
2719
+ };
2720
+ CanvasRenderer.prototype.setIsCameraLocked = function (isLocked) {
2721
+ var _a;
2722
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.setIsCameraLocked(isLocked);
2723
+ };
2724
+ CanvasRenderer.prototype.setBackgroundColor = function (color) {
2725
+ var _a;
2726
+ if (color.r === this.settings.backgroundColor.r &&
2727
+ color.g === this.settings.backgroundColor.g &&
2728
+ color.b === this.settings.backgroundColor.b &&
2729
+ color.a === this.settings.backgroundColor.a)
2730
+ return;
2731
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.setBackgroundColor(color.r, color.g, color.b, color.a);
2732
+ this.settings.backgroundColor = color;
2733
+ };
2734
+ CanvasRenderer.prototype.handleDrawComplete = function () {
2735
+ if (this.status.type === 'DRAWING_FILE') {
2736
+ // Draw complete is called repeatedly, but here we just want to perform
2737
+ // some actions after the initial draw is complete (when the status is DRAWING_FILE)
2738
+ // @TODO Look into ways of formalizing these status transitions
2739
+ logger.logDebug(this.traceInitialRender.printMeasurement());
2740
+ this.emit('metric', this.traceInitialRender.measure());
2741
+ logger.logDebug(this.traceFirstPaint.printMeasurement());
2742
+ this.emit('metric', this.traceFirstPaint.measure());
2743
+ this.setStatus({ type: 'READY' });
2744
+ }
2745
+ };
2746
+ /**
2747
+ * Forcefully releasing the WebGL context
2748
+ */
2749
+ CanvasRenderer.prototype.looseWebGLContext = function () {
2750
+ var _a;
2751
+ var result = (_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.destroyWebGLContext(this.webglCtxHandle);
2752
+ if (!result) {
2753
+ logger.logWarning('Failed to loose WebGL context');
2754
+ }
2755
+ this.webglCtxHandle = -1;
2756
+ };
2757
+ /**
2758
+ * Scale the document to fit the surface size
2759
+ * @returns {number} the appropriate zoom level to fit the document
2760
+ */
2761
+ CanvasRenderer.prototype.zoomToFit = function () {
2762
+ var _a;
2763
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.scaleDocumentToFit();
2764
+ };
2765
+ /** Load the presentation file at the given URL into the renderer */
2766
+ CanvasRenderer.prototype.setFile = function (fileURL) {
2767
+ return __awaiter(this, void 0, void 0, function () {
2768
+ var _this = this;
2769
+ return __generator(this, function (_a) {
2770
+ if (this.disposed)
2771
+ return [2 /*return*/];
2772
+ this.setStatus({ type: 'LOADING_FILE' });
2773
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2774
+ var _a;
2775
+ var onFailure = function () {
2776
+ return reject(new WebRendererError('FILE_ERROR', 'Error encountered while fetching and parsing the file'));
2777
+ };
2778
+ var onSuccess = function (fileIdentifier, prFileWeightInBytes, imagesCount) {
2779
+ _this.setStatus({ type: 'FILE_READY' });
2780
+ var fileIdentifierAndVersion = "".concat(fileIdentifier, "-v").concat("12.0.1");
2781
+ _this.emit('fileReady', fileIdentifierAndVersion, prFileWeightInBytes, imagesCount);
2782
+ resolve();
2783
+ };
2784
+ (_a = _this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.setFile(fileURL, onSuccess, onFailure);
2785
+ })];
2786
+ });
2787
+ });
2788
+ };
2789
+ CanvasRenderer.prototype.fail = function (error) {
2790
+ this.setStatus({
2791
+ type: 'FAILURE',
2792
+ code: error.code,
2793
+ message: "".concat(error.toString()).concat(error.cause ? "\nWrapped Error: ".concat(error.cause.toString()) : ''),
2794
+ });
2795
+ logger.logError(error);
2796
+ error.cause && logger.logError(error.cause);
2797
+ };
2798
+ CanvasRenderer.prototype.setStatus = function (status) {
2799
+ // When the status is failure, prevent other status changes
2800
+ // otherwise the failure will be overwritten
2801
+ if (this.status.type === 'FAILURE')
2802
+ return;
2803
+ logger.logDebug("Status transition ".concat(this.status.type, " => ").concat(status.type));
2804
+ this.status = status;
2805
+ this.emit('status', status);
2806
+ };
2807
+ CanvasRenderer.prototype.getPRFileCachedData = function () {
2808
+ var _a;
2809
+ if (!this.pageCanvasWasm)
2810
+ return null;
2811
+ // Caching the PRFileHandle for later use
2812
+ if (((_a = this.prFileHandle) === null || _a === void 0 ? void 0 : _a.filePath) !== this.settings.filePath) {
2813
+ var prFile = this.pageCanvasWasm.getPRFile();
2814
+ this.prFileHandle = {
2815
+ handle: prFile,
2816
+ filePath: this.settings.filePath,
2817
+ artboards: convertEmbindVectorToArray(prFile.getArtboards()),
2818
+ };
2819
+ }
2820
+ return this.prFileHandle;
2821
+ };
2822
+ CanvasRenderer.prototype.getPRFile = function () {
2823
+ var _a;
2824
+ return (_a = this.getPRFileCachedData()) === null || _a === void 0 ? void 0 : _a.handle;
2825
+ };
2826
+ CanvasRenderer.prototype.releasePRFileHandle = function () {
2827
+ var _a, _b;
2828
+ (_b = (_a = this.prFileHandle) === null || _a === void 0 ? void 0 : _a.handle) === null || _b === void 0 ? void 0 : _b.delete();
2829
+ this.prFileHandle = undefined;
2830
+ };
2831
+ CanvasRenderer.prototype.getRootNodeExtent = function () {
2832
+ var _a, _b, _c;
2833
+ return (_c = (_b = (_a = this.getPRFile()) === null || _a === void 0 ? void 0 : _a.getRootNode()) === null || _b === void 0 ? void 0 : _b.getAbsoluteExtent()) !== null && _c !== void 0 ? _c : null;
2834
+ };
2835
+ CanvasRenderer.prototype.getPRFileArtboards = function () {
2836
+ var _a, _b;
2837
+ return (_b = (_a = this.getPRFileCachedData()) === null || _a === void 0 ? void 0 : _a.artboards) !== null && _b !== void 0 ? _b : [];
2838
+ };
2839
+ /**
2840
+ * Returns the PRMarinaNode of the Artboard at position x,y relative to the canvas
2841
+ * element origin in the browser, or null if there is no Artboard at that
2842
+ * position.
2843
+ */
2844
+ CanvasRenderer.prototype.getArtboardAtPosition = function (x, y) {
2845
+ if (!this.pageCanvasWasm)
2846
+ return null;
2847
+ var artboards = this.getPRFileArtboards();
2848
+ var pan = this.pageCanvasWasm.getPan();
2849
+ var zoom = this.pageCanvasWasm.getZoom();
2850
+ var mouse = {
2851
+ x: (x - pan.x) / zoom,
2852
+ y: (y - pan.y) / zoom,
2853
+ };
2854
+ for (var _i = 0, artboards_1 = artboards; _i < artboards_1.length; _i++) {
2855
+ var artboard = artboards_1[_i];
2856
+ var maxX = artboard.bounds.x + artboard.bounds.width;
2857
+ var maxY = artboard.bounds.y + artboard.bounds.height;
2858
+ if (mouse.x >= artboard.bounds.x &&
2859
+ mouse.y >= artboard.bounds.y &&
2860
+ mouse.x <= maxX &&
2861
+ mouse.y <= maxY) {
2862
+ return artboard.getNode();
2863
+ }
2864
+ }
2865
+ return null;
2866
+ };
2867
+ CanvasRenderer.prototype.mapRelativePositionToCameraPosition = function (x, y) {
2868
+ var _a;
2869
+ var cameraPosition = (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.mapRelativePositionToCameraPosition(x, y);
2870
+ return cameraPosition;
2871
+ };
2872
+ /**
2873
+ * Get the current pan value for a given point relative to the viewport
2874
+ * Use case: when the user clicks on the canvas, we want to know what's
2875
+ * the corresponding pan value at a given mouse position, so that we can restore the pan value later
2876
+ */
2877
+ CanvasRenderer.prototype.getPanAtPosition = function (x, y) {
2878
+ var pan = this.getPan();
2879
+ var zoom = Math.max(this.getZoom(), Number.EPSILON);
2880
+ // The x and y are relative to the viewport, and not affected by the zoom
2881
+ // so, firstly we need to multiply them by the current zoom
2882
+ // then, we only need to add them to the current pan value
2883
+ var offsetX = x / zoom;
2884
+ var offsetY = y / zoom;
2885
+ return { x: pan.x - offsetX, y: pan.y - offsetY };
2886
+ };
2887
+ CanvasRenderer.prototype.getStatus = function () {
2888
+ return this.status;
2889
+ };
2890
+ CanvasRenderer.prototype.setZoom = function (delta, center) {
2891
+ var _a;
2892
+ var correctedCenter = center !== null && center !== void 0 ? center : this.canvasManager.getCanvasCenterPoint();
2893
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.setZoom(delta, correctedCenter.x, correctedCenter.y);
2894
+ };
2895
+ CanvasRenderer.prototype.getPan = function () {
2896
+ var _a, _b;
2897
+ var extent = this.getRootNodeExtent();
2898
+ if (!extent)
2899
+ return { x: 0, y: 0 };
2900
+ var pan = (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.getPan();
2901
+ // Making sure that the pan values are relative to the document
2902
+ // and take into consideration the zoom level
2903
+ var zoom = (_b = this.pageCanvasWasm) === null || _b === void 0 ? void 0 : _b.getZoom();
2904
+ if (!pan || !zoom) {
2905
+ return { x: 0, y: 0 };
2906
+ }
2907
+ return { x: pan.x / zoom + extent.x, y: pan.y / zoom + extent.y };
2908
+ };
2909
+ CanvasRenderer.prototype.getZoom = function () {
2910
+ var _a;
2911
+ var zoom = (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.getZoom();
2912
+ return zoom || 0;
2913
+ };
2914
+ CanvasRenderer.prototype.setPan = function (x, y, centerPointInViewport) {
2915
+ var _a;
2916
+ if (centerPointInViewport === void 0) { centerPointInViewport = false; }
2917
+ var extent = this.getRootNodeExtent();
2918
+ if (!extent)
2919
+ return;
2920
+ // The consumer is expected to set the pan values relative to 0,0, because it doesn't know the
2921
+ // document origin. Also, the values are independent from the zoom level, that's an
2922
+ // implementation detail that we take care of.
2923
+ var newPanX = x;
2924
+ var newPanY = y;
2925
+ var zoom = this.getZoom();
2926
+ if (centerPointInViewport) {
2927
+ // Use half of the viewport and make sure to take into consideration the zoom and pixelRatio
2928
+ var factor = Math.max(2 * zoom * this.canvasManager.pixelRatio, Number.EPSILON); // preventing divisions by zero
2929
+ newPanX += this.canvasManager.size.width / factor;
2930
+ newPanY += this.canvasManager.size.height / factor;
2931
+ }
2932
+ var cleanX = (newPanX - extent.x) * zoom;
2933
+ var cleanY = (newPanY - extent.y) * zoom;
2934
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.setPan(cleanX, cleanY);
2935
+ };
2936
+ CanvasRenderer.prototype.selectArtboard = function (artboardId) {
2937
+ var _a;
2938
+ if (!this.pageCanvasWasm)
2939
+ return;
2940
+ this.settings.selectedArtboard = artboardId;
2941
+ // An empty string will deselect the current artboard
2942
+ (_a = this.pageCanvasWasm) === null || _a === void 0 ? void 0 : _a.selectArtboard(artboardId !== null && artboardId !== void 0 ? artboardId : '');
2943
+ };
2944
+ CanvasRenderer.prototype.disposeFetchWorker = function () {
2945
+ this.fetchWorker.postMessage({ type: 'abort-all' });
2946
+ this.fetchWorker.terminate();
2947
+ };
2948
+ CanvasRenderer.prototype.exportNode = function (nodeId, exportSettings) {
2949
+ return __awaiter(this, void 0, void 0, function () {
2950
+ var _this = this;
2951
+ return __generator(this, function (_a) {
2952
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2953
+ if (!_this.wasmModule || !_this.pageCanvasWasm) {
2954
+ reject('Wasm module is not ready or was disposed.');
2955
+ return;
2956
+ }
2957
+ var exportKey = exportSettings.format.toUpperCase();
2958
+ var format = PRNodeExportFormat[exportKey];
2959
+ if (!format) {
2960
+ reject("Unsupported export format: ".concat(exportSettings.format));
2961
+ return;
2962
+ }
2963
+ var wasmSettings = {
2964
+ format: { value: format },
2965
+ backingScale: exportSettings.backingScale,
2966
+ };
2967
+ var handleExportDone = function (data) {
2968
+ if (data === null) {
2969
+ reject('Export failed');
2970
+ return;
2971
+ }
2972
+ var mimeType = MIME_TYPE[exportSettings.format];
2973
+ var blob = new Blob([data.buffer], {
2974
+ type: mimeType,
2975
+ });
2976
+ resolve(blob);
2977
+ };
2978
+ _this.pageCanvasWasm.exportNode(nodeId, wasmSettings, handleExportDone);
2979
+ })];
2980
+ });
2981
+ });
2982
+ };
2983
+ CanvasRenderer.prototype.dispose = function () {
2984
+ var _a, _b, _c, _d;
2985
+ try {
2986
+ this.disposeFetchWorker();
2987
+ this.disposed = true;
2988
+ this.detachAllListeners();
2989
+ this.releasePRFileHandle();
2990
+ (_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.destroyWebGLContext(this.webglCtxHandle);
2991
+ this.canvasManager.dispose();
2992
+ this.gestureManager.dispose();
2993
+ (_b = this.pageCanvasWasm) === null || _b === void 0 ? void 0 : _b.stopRenderLoop();
2994
+ (_c = this.pageCanvasWasm) === null || _c === void 0 ? void 0 : _c.delete(); // This will call the destructor in C++
2995
+ (_d = this.renderTarget) === null || _d === void 0 ? void 0 : _d.delete();
2996
+ this.pageCanvasWasm = undefined;
2997
+ this.wasmModule = undefined;
2998
+ }
2999
+ catch (error) {
3000
+ this.fail(new WebRendererError('ERROR', 'Unexpected exception while disposing the wasm object', error));
3001
+ }
3002
+ };
3003
+ return CanvasRenderer;
3004
+ }(EventEmitter));
3005
+
3006
+ /**
3007
+ * Context for the renderer `status` value.
3008
+ */
3009
+ var StatusContext$1 = createContext(undefined);
3010
+ /**
3011
+ * Context for the renderer `zoom` value.
3012
+ */
3013
+ var ZoomContext$1 = createContext(undefined);
3014
+ /**
3015
+ * Context for track if the camera is being zoomed
3016
+ */
3017
+ var CameraZoomingContext = createContext(undefined);
3018
+ /**
3019
+ * Context for track if the camera is moving (both panning and zooming)
3020
+ */
3021
+ var CameraMoveContext = createContext(undefined);
3022
+ /**
3023
+ * Context for the renderer `pan` value.
3024
+ */
3025
+ var PanContext$1 = createContext(undefined);
3026
+ /**
3027
+ * Context for the renderer `cursor` value.
3028
+ */
3029
+ var CursorContext$1 = createContext("auto" /* CSSCursor.Auto */);
3030
+
3031
+ /**
3032
+ * The internal context contains private methods and is used exclusively within
3033
+ * the package. The members of this module are not exported from the package
3034
+ * entrypoint.
3035
+ */
3036
+ var InternalContext$1 = createContext(undefined);
3037
+ /**
3038
+ * Access the internal context values.
3039
+ */
3040
+ var useInternalContext$1 = function () {
3041
+ var internal = useContext(InternalContext$1);
3042
+ if (internal === undefined) {
3043
+ throw Error('useInternalContext must be used within a provider');
3044
+ }
3045
+ return internal;
3046
+ };
3047
+
3048
+ /**
3049
+ * The reducer acts as the source of truth for the renderer state, at least
3050
+ * from the point of view of the React app consuming the package. We mirror
3051
+ * renderer state here, and keep it up to date via events emitted from
3052
+ * the renderer.
3053
+ *
3054
+ * Some state values are "derived", in that they don't have a direct counterpart
3055
+ * in the renderer, but we update them over time as events are emitted - for
3056
+ * example the "cursor" value which models the canvas pointer typoe.
3057
+ *
3058
+ * This state is accessed via the hooks in the hooks/state folder, which will
3059
+ * typically expose small slices of the state or single values from dedicated
3060
+ * contexts to avoid render thrashing.
3061
+ */
3062
+ var reducer$1 = function (state, action) {
3063
+ switch (action.type) {
3064
+ case 'on-status': {
3065
+ return _assign(_assign({}, state), { status: action.status });
3066
+ }
3067
+ case 'on-zoom': {
3068
+ return _assign(_assign({}, state), { zoom: action.zoom });
3069
+ }
3070
+ case 'on-pan': {
3071
+ return _assign(_assign({}, state), { pan: action.pan });
3072
+ }
3073
+ case 'dispose': {
3074
+ return _assign(_assign({}, state), { status: { type: 'DISPOSED' }, zoom: null, pan: null, cursor: "auto" /* CSSCursor.Auto */ });
3075
+ }
3076
+ case 'on-camera-zoom-start': {
3077
+ return _assign(_assign({}, state), { isCameraZooming: true });
3078
+ }
3079
+ case 'on-camera-zoom-end': {
3080
+ return _assign(_assign({}, state), { isCameraZooming: false });
3081
+ }
3082
+ case 'on-camera-move-start': {
3083
+ return _assign(_assign({}, state), { isCameraMoving: true });
3084
+ }
3085
+ case 'on-camera-move-end': {
3086
+ return _assign(_assign({}, state), { isCameraMoving: false });
3087
+ }
3088
+ case 'on-cursor-change': {
3089
+ return _assign(_assign({}, state), { cursor: action.cursor });
3090
+ }
3091
+ default: {
3092
+ return state;
3093
+ }
3094
+ }
3095
+ };
3096
+
3097
+ /**
3098
+ * Manages the renderer class instance, and handles the Providers that must
3099
+ * be rendered as parents to CanvasRendererReact.
3100
+ *
3101
+ * By managing the class instance lifecycle logic in one place, and maintaining
3102
+ * a single source of truth for its state via a reducer we can provide a consistent
3103
+ * and globally accessible view on the instance state, manage state transitions
3104
+ * and handle dervied state easily.
3105
+ *
3106
+ * Note that currently we are exposing this API via multiple different nested
3107
+ * contexts. The idea here is that we insulate components in the outer app from
3108
+ * re-rendering everytime any piece of state changes. They can instead just
3109
+ * subscribe to small slices of state and values from the individual contexts
3110
+ * and only re-render when necessary. This approach is under review and subject
3111
+ * to change if it starts to feel unscalable.
3112
+ */
3113
+ var CanvasRendererProvider = function (props) {
3114
+ var instanceRef = useRef(null);
3115
+ var settingsRef = useRef(null);
3116
+ var _a = useReducer(reducer$1, {
3117
+ pan: null,
3118
+ zoom: null,
3119
+ status: { type: 'IDLE' },
3120
+ isCameraZooming: false,
3121
+ isCameraMoving: false,
3122
+ cursor: "auto" /* CSSCursor.Auto */,
3123
+ }), _b = _a[0], status = _b.status, zoom = _b.zoom, pan = _b.pan, isCameraZooming = _b.isCameraZooming, isCameraMoving = _b.isCameraMoving, cursor = _b.cursor, dispatch = _a[1];
3124
+ var onZoom = useCallback(function (zoom) { return dispatch({ type: 'on-zoom', zoom: zoom }); }, []);
3125
+ var onPan = useCallback(function (x, y) { return dispatch({ type: 'on-pan', pan: { x: x, y: y } }); }, []);
3126
+ var onStatus = useCallback(function (status) {
3127
+ dispatch({ type: 'on-status', status: status });
3128
+ }, []);
3129
+ var onCameraZoomStart = useCallback(function () { return dispatch({ type: 'on-camera-zoom-start' }); }, []);
3130
+ var onCameraZoomEnd = useCallback(function () { return dispatch({ type: 'on-camera-zoom-end' }); }, []);
3131
+ var onCameraMoveStart = useCallback(function () { return dispatch({ type: 'on-camera-move-start' }); }, []);
3132
+ var onCameraMoveEnd = useCallback(function () { return dispatch({ type: 'on-camera-move-end' }); }, []);
3133
+ var onCursorChange = useCallback(function (cursor) {
3134
+ return dispatch({
3135
+ type: 'on-cursor-change',
3136
+ cursor: cursor,
3137
+ });
3138
+ }, []);
3139
+ var onSceneChange = useCallback(function () {
3140
+ if (!instanceRef.current)
3141
+ return;
3142
+ // Scene changes can implicitly change the pan, in case the root
3143
+ // extent has changed, so update it here
3144
+ var pan = instanceRef.current.getPan();
3145
+ dispatch({ type: 'on-pan', pan: pan });
3146
+ }, []);
3147
+ var dispose = useCallback(function () {
3148
+ var currentManager = instanceRef.current;
3149
+ if (!currentManager)
3150
+ return;
3151
+ logger.logDebug('Provider dispose');
3152
+ currentManager.off('status', onStatus);
3153
+ currentManager.off('cameraZoomChange', onZoom);
3154
+ currentManager.off('cameraPanChange', onPan);
3155
+ currentManager.off('cameraZoomStart', onCameraZoomStart);
3156
+ currentManager.off('cameraZoomEnd', onCameraZoomEnd);
3157
+ currentManager.off('cameraMoveStart', onCameraMoveStart);
3158
+ currentManager.off('cameraMoveEnd', onCameraMoveEnd);
3159
+ currentManager.off('cursorChange', onCursorChange);
3160
+ currentManager.off('sceneChange', onSceneChange);
3161
+ currentManager.dispose();
3162
+ instanceRef.current = null;
3163
+ dispatch({ type: 'dispose' });
3164
+ }, [
3165
+ onStatus,
3166
+ onPan,
3167
+ onZoom,
3168
+ onCameraZoomStart,
3169
+ onCameraZoomEnd,
3170
+ onCameraMoveStart,
3171
+ onCameraMoveEnd,
3172
+ onCursorChange,
3173
+ onSceneChange,
3174
+ ]);
3175
+ var init = useCallback(function (filePath, canvas, container) {
3176
+ if (filePath === '')
3177
+ return;
3178
+ if (!canvas || !container)
3179
+ return;
3180
+ if (!settingsRef.current)
3181
+ return;
3182
+ logger.logDebug('Provider init');
3183
+ var nextInstance = new CanvasRenderer(_assign(_assign({}, settingsRef.current), { filePath: filePath, container: container, canvas: canvas, manualInitialization: true }));
3184
+ nextInstance.on('status', onStatus);
3185
+ nextInstance.on('cameraZoomChange', onZoom);
3186
+ nextInstance.on('cameraPanChange', onPan);
3187
+ nextInstance.on('cameraZoomStart', onCameraZoomStart);
3188
+ nextInstance.on('cameraZoomEnd', onCameraZoomEnd);
3189
+ nextInstance.on('cameraMoveStart', onCameraMoveStart);
3190
+ nextInstance.on('cameraMoveEnd', onCameraMoveEnd);
3191
+ nextInstance.on('cursorChange', onCursorChange);
3192
+ nextInstance.on('sceneChange', onSceneChange);
3193
+ instanceRef.current = nextInstance;
3194
+ nextInstance.init();
3195
+ }, [
3196
+ onStatus,
3197
+ onZoom,
3198
+ onPan,
3199
+ onCameraZoomStart,
3200
+ onCameraZoomEnd,
3201
+ onCameraMoveStart,
3202
+ onCameraMoveEnd,
3203
+ onCursorChange,
3204
+ onSceneChange,
3205
+ ]);
3206
+ var setSettings = useCallback(function (settings) {
3207
+ var _a, _b;
3208
+ logger.logDebug('Provider setSettings');
3209
+ // @TODO We are kind of piggy backing on setSettings to propagate incoming
3210
+ // props changes on the component into the renderer instance. Maybe would
3211
+ // be nice to handle this more explicitly
3212
+ if (settings.backgroundColor) {
3213
+ (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.setBackgroundColor(settings.backgroundColor);
3214
+ }
3215
+ (_b = instanceRef.current) === null || _b === void 0 ? void 0 : _b.selectArtboard(settings.selectedArtboard || null);
3216
+ settingsRef.current = settings;
3217
+ }, []);
3218
+ var getInstance = useCallback(function () {
3219
+ return instanceRef.current;
3220
+ }, []);
3221
+ var internal = useMemo(function () {
3222
+ return {
3223
+ dispose: dispose,
3224
+ init: init,
3225
+ setSettings: setSettings,
3226
+ getInstance: getInstance,
3227
+ dispatch: dispatch,
3228
+ };
3229
+ }, [dispose, init, setSettings, getInstance]);
3230
+ return (React.createElement(InternalContext$1.Provider, { value: internal },
3231
+ React.createElement(StatusContext$1.Provider, { value: status },
3232
+ React.createElement(ZoomContext$1.Provider, { value: zoom },
3233
+ React.createElement(PanContext$1.Provider, { value: pan },
3234
+ React.createElement(CameraZoomingContext.Provider, { value: isCameraZooming },
3235
+ React.createElement(CameraMoveContext.Provider, { value: isCameraMoving },
3236
+ React.createElement(CursorContext$1.Provider, { value: cursor }, props.children))))))));
3237
+ };
3238
+
3239
+ /**
3240
+ * Subscribe to any renderer event type. Prefer passing memoized function
3241
+ * references from useCallback to this hook to avoid calling `on`/`off` every
3242
+ * render.
3243
+ */
3244
+ var useEvent = function (event, callback) {
3245
+ var getInstance = useInternalContext$1().getInstance;
3246
+ var instance = getInstance();
3247
+ useEffect(function () {
3248
+ instance === null || instance === void 0 ? void 0 : instance.on(event, callback);
3249
+ return function () {
3250
+ instance === null || instance === void 0 ? void 0 : instance.off(event, callback);
3251
+ };
3252
+ }, [event, instance, callback]);
3253
+ };
3254
+
3255
+ /**
3256
+ * Access the renderer `status` value.
3257
+ */
3258
+ var useStatus = function () {
3259
+ var status = useContext(StatusContext$1);
3260
+ if (status === undefined) {
3261
+ throw Error('useStatus must be used within a provider');
3262
+ }
3263
+ return status;
3264
+ };
3265
+ /**
3266
+ * Access the renderer `zoom` value.
3267
+ */
3268
+ var useZoom = function () {
3269
+ var zoom = useContext(ZoomContext$1);
3270
+ if (zoom === undefined) {
3271
+ throw Error('useZoom must be used within a provider');
3272
+ }
3273
+ return zoom;
3274
+ };
3275
+ /**
3276
+ * Access the renderer `pan` value.
3277
+ */
3278
+ var usePan = function () {
3279
+ var pan = useContext(PanContext$1);
3280
+ if (pan === undefined) {
3281
+ throw Error('usePan must be used within a provider');
3282
+ }
3283
+ return pan;
3284
+ };
3285
+ /**
3286
+ * Access the renderer `cursor` value.
3287
+ */
3288
+ var useCursor = function () {
3289
+ var cursor = useContext(CursorContext$1);
3290
+ if (cursor === undefined) {
3291
+ throw Error('useCursor must be used within a provider');
3292
+ }
3293
+ return cursor;
3294
+ };
3295
+ /**
3296
+ * Access the renderer `isCameraMoving` value.
3297
+ */
3298
+ var useIsCameraZooming = function () {
3299
+ var isZooming = useContext(CameraZoomingContext);
3300
+ if (status === undefined) {
3301
+ throw Error('useIsCameraZooming must be used within a provider');
3302
+ }
3303
+ return isZooming;
3304
+ };
3305
+ /**
3306
+ * Access the renderer `isCameraMoving` value.
3307
+ */
3308
+ var useIsCameraMoving = function () {
3309
+ var isMoving = useContext(CameraMoveContext);
3310
+ if (status === undefined) {
3311
+ throw Error('useIsCameraMoving must be used within a provider');
3312
+ }
3313
+ return isMoving;
3314
+ };
3315
+ /**
3316
+ * Returns the PRFile data structure
3317
+ */
3318
+ var usePRFile = function () {
3319
+ var getInstance = useInternalContext$1().getInstance;
3320
+ var instance = getInstance();
3321
+ var status = useStatus();
3322
+ return useMemo(function () {
3323
+ if (!instance || status.type !== 'READY')
3324
+ return null;
3325
+ return instance.getPRFile();
3326
+ }, [instance, status]);
3327
+ };
3328
+ /**
3329
+ * Returns the PRFile data structure
3330
+ */
3331
+ var usePRFileArtboards = function () {
3332
+ var getInstance = useInternalContext$1().getInstance;
3333
+ var instance = getInstance();
3334
+ var status = useStatus();
3335
+ return useMemo(function () {
3336
+ if (!instance || status.type !== 'READY')
3337
+ return null;
3338
+ return instance.getPRFileArtboards();
3339
+ }, [instance, status]);
3340
+ };
3341
+ /**
3342
+ * Returns the root node absolute extent. Importantly the root node extent
3343
+ * is updated if the canvas renderer scene changes. This can be useful for code
3344
+ * that uses the root node extent for layout calculations.
3345
+ */
3346
+ var useRootNodeAbsoluteExtent = function () {
3347
+ var _a, _b, _c, _d;
3348
+ var prFile = usePRFile();
3349
+ var _e = useState(null), extent = _e[0], setExtent = _e[1];
3350
+ var extentUpdate = useDebounceFunction(function () {
3351
+ setExtent(function (prev) {
3352
+ var _a, _b, _c;
3353
+ var newExtend = (_c = (_b = (_a = safePtrAccess(prFile)) === null || _a === void 0 ? void 0 : _a.getRootNode()) === null || _b === void 0 ? void 0 : _b.getAbsoluteExtent()) !== null && _c !== void 0 ? _c : null;
3354
+ if ((prev === null || prev === void 0 ? void 0 : prev.width) === (newExtend === null || newExtend === void 0 ? void 0 : newExtend.width) &&
3355
+ (prev === null || prev === void 0 ? void 0 : prev.height) === (newExtend === null || newExtend === void 0 ? void 0 : newExtend.height) &&
3356
+ (prev === null || prev === void 0 ? void 0 : prev.x) === (newExtend === null || newExtend === void 0 ? void 0 : newExtend.x) &&
3357
+ (prev === null || prev === void 0 ? void 0 : prev.y) === (newExtend === null || newExtend === void 0 ? void 0 : newExtend.y)) {
3358
+ return prev;
3359
+ }
3360
+ return newExtend;
3361
+ });
3362
+ }, 16);
3363
+ useEvent('sceneChange', extentUpdate);
3364
+ useEffect(function () {
3365
+ extentUpdate();
3366
+ }, [extentUpdate]);
3367
+ var x = (_a = extent === null || extent === void 0 ? void 0 : extent.x) !== null && _a !== void 0 ? _a : 0;
3368
+ var y = (_b = extent === null || extent === void 0 ? void 0 : extent.y) !== null && _b !== void 0 ? _b : 0;
3369
+ var width = (_c = extent === null || extent === void 0 ? void 0 : extent.width) !== null && _c !== void 0 ? _c : 0;
3370
+ var height = (_d = extent === null || extent === void 0 ? void 0 : extent.height) !== null && _d !== void 0 ? _d : 0;
3371
+ return useMemo(function () { return ({ x: x, y: y, width: width, height: height }); }, [x, y, width, height]);
3372
+ };
3373
+
3374
+ /**
3375
+ * Returns a function that imperatively sets the renderer's `zoom` value.
3376
+ */
3377
+ var useSetZoom = function () {
3378
+ var getInstance = useInternalContext$1().getInstance;
3379
+ var instance = getInstance();
3380
+ return useCallback(function (zoom) {
3381
+ instance === null || instance === void 0 ? void 0 : instance.setZoom(zoom);
3382
+ }, [instance]);
3383
+ };
3384
+ /**
3385
+ * Returns a function that imperatively increments the `zoom` value one step.
3386
+ * This behaviour matches the Mac app.
3387
+ */
3388
+ var useIncrementZoom = function () {
3389
+ var setZoom = useSetZoom();
3390
+ var zoom = useZoom();
3391
+ return useCallback(function () {
3392
+ if (typeof zoom !== 'number')
3393
+ return;
3394
+ var nextZoom;
3395
+ if (zoom >= 1.0) {
3396
+ nextZoom = Math.round(zoom * 2);
3397
+ }
3398
+ else if (zoom > 0.5) {
3399
+ nextZoom = 1;
3400
+ }
3401
+ else {
3402
+ nextZoom = zoom * 2;
3403
+ }
3404
+ setZoom(nextZoom);
3405
+ }, [setZoom, zoom]);
3406
+ };
3407
+ /**
3408
+ * Returns a function that imperatively decrements the `zoom` value one step.
3409
+ * This behaviour matches the Mac app.
3410
+ */
3411
+ var useDecrementZoom = function () {
3412
+ var setZoom = useSetZoom();
3413
+ var zoom = useZoom();
3414
+ return useCallback(function () {
3415
+ if (typeof zoom !== 'number')
3416
+ return;
3417
+ setZoom(zoom / 2);
3418
+ }, [setZoom, zoom]);
3419
+ };
3420
+ /**
3421
+ * Returns a function that imperatively sets the renderer's `pan` value.
3422
+ */
3423
+ var useSetPan = function () {
3424
+ var getInstance = useInternalContext$1().getInstance;
3425
+ var instance = getInstance();
3426
+ return useCallback(function (_a) {
3427
+ var x = _a.x, y = _a.y, centerPointInViewport = _a.centerPointInViewport;
3428
+ instance === null || instance === void 0 ? void 0 : instance.setPan(x, y, centerPointInViewport);
3429
+ }, [instance]);
3430
+ };
3431
+ /**
3432
+ * Returns a function that imperatively causes the renderer to zoom/pan to
3433
+ * fit the current page content in the canvas.
3434
+ */
3435
+ var useZoomToFit = function () {
3436
+ var getInstance = useInternalContext$1().getInstance;
3437
+ var instance = getInstance();
3438
+ return useCallback(function () {
3439
+ instance === null || instance === void 0 ? void 0 : instance.zoomToFit();
3440
+ }, [instance]);
3441
+ };
3442
+ /**
3443
+ * Returns a function that imperatively causes the renderer to loose its
3444
+ * WebGL context. Useful for debugging this behaviour.
3445
+ */
3446
+ var useLooseWebGLContext = function () {
3447
+ var getInstance = useInternalContext$1().getInstance;
3448
+ var instance = getInstance();
3449
+ return useCallback(function () {
3450
+ instance === null || instance === void 0 ? void 0 : instance.looseWebGLContext();
3451
+ }, [instance]);
3452
+ };
3453
+ /**
3454
+ * Returns a function that can be used to find out if an Artboard exists below
3455
+ * specific mouse coordinates relative to the canvas origin.
3456
+ */
3457
+ var useGetArtboardAtPosition = function () {
3458
+ var getInstance = useInternalContext$1().getInstance;
3459
+ var instance = getInstance();
3460
+ return useCallback(function (x, y) { return __awaiter(void 0, void 0, void 0, function () {
3461
+ var uuid;
3462
+ return __generator(this, function (_a) {
3463
+ switch (_a.label) {
3464
+ case 0: return [4 /*yield*/, (instance === null || instance === void 0 ? void 0 : instance.getArtboardAtPosition(x, y))];
3465
+ case 1:
3466
+ uuid = _a.sent();
3467
+ return [2 /*return*/, uuid || null];
3468
+ }
3469
+ });
3470
+ }); }, [instance]);
3471
+ };
3472
+ /**
3473
+ * Returns a function that can be used to find out the equivalent pan position
3474
+ * at specific mouse coordinates relative to the canvas origin.
3475
+ */
3476
+ var useGetPanAtPosition = function () {
3477
+ var getInstance = useInternalContext$1().getInstance;
3478
+ var instance = getInstance();
3479
+ return useCallback(function (x, y) { return __awaiter(void 0, void 0, void 0, function () {
3480
+ var pan;
3481
+ return __generator(this, function (_a) {
3482
+ switch (_a.label) {
3483
+ case 0: return [4 /*yield*/, (instance === null || instance === void 0 ? void 0 : instance.getPanAtPosition(x, y))];
3484
+ case 1:
3485
+ pan = _a.sent();
3486
+ return [2 /*return*/, pan || null];
3487
+ }
3488
+ });
3489
+ }); }, [instance]);
3490
+ };
3491
+ /**
3492
+ * Disable user interaction like panning and zooming. This is useful when
3493
+ * showing the context menu and we don't want users to mess with its position
3494
+ * related to the canvas.
3495
+ */
3496
+ var useLockCamera = function () {
3497
+ var getInstance = useInternalContext$1().getInstance;
3498
+ var instance = getInstance();
3499
+ return useCallback(function (locked) {
3500
+ instance === null || instance === void 0 ? void 0 : instance.setIsCameraLocked(locked);
3501
+ }, [instance]);
3502
+ };
3503
+ var useMapRelativePositionToCameraPosition = function () {
3504
+ var getInstance = useInternalContext$1().getInstance;
3505
+ var instance = getInstance();
3506
+ return useCallback(function (x, y) {
3507
+ if (!instance)
3508
+ return null;
3509
+ var cameraPos = instance.mapRelativePositionToCameraPosition(x, y);
3510
+ return cameraPos !== null && cameraPos !== void 0 ? cameraPos : null;
3511
+ }, [instance]);
3512
+ };
3513
+ var useExportNode = function () {
3514
+ var getInstance = useInternalContext$1().getInstance;
3515
+ var instance = getInstance();
3516
+ var prFile = usePRFile();
3517
+ return useCallback(function (nodeId, settings) {
3518
+ if (!instance || !prFile)
3519
+ return Promise.reject('WebRenderer instance not ready');
3520
+ return instance.exportNode(nodeId, settings);
3521
+ }, [instance, prFile]);
3522
+ };
3523
+
3524
+ function useLogEvent(cb) {
3525
+ var cbRef = useRef(cb);
3526
+ cbRef.current = cb;
3527
+ var onLog = useCallback(function (level) {
3528
+ var args = [];
3529
+ for (var _i = 1; _i < arguments.length; _i++) {
3530
+ args[_i - 1] = arguments[_i];
3531
+ }
3532
+ cbRef.current.apply(cbRef, __spreadArray([level], args, false));
3533
+ }, []);
3534
+ useEffect(function () {
3535
+ logger.on('log', onLog);
3536
+ return function () {
3537
+ logger.off('log', onLog);
3538
+ };
3539
+ }, [onLog]);
3540
+ }
3541
+
3542
+ var CONTAINER_STYLES$1 = {
3543
+ position: 'relative',
3544
+ width: '100%',
3545
+ height: '100%',
3546
+ // Removes the 300ms tap delay, prevents double-tap zoom and allows smoother panning on Safari iOS
3547
+ // The property is automatically applied to all its children. We need it on the container
3548
+ // because some events are not listened directly on the canvas
3549
+ touchAction: 'manipulation',
3550
+ };
3551
+ var CANVAS_STYLES$1 = {
3552
+ position: 'absolute',
3553
+ top: 0,
3554
+ left: 0,
3555
+ };
3556
+ /**
3557
+ * The CanvasRendererReact component renders a canvas element, and connects it to the
3558
+ * Manager instance wrapped by CanvasRendererProvider. The props passed to this
3559
+ * component mostly match the static settings passed to the Manager.
3560
+ *
3561
+ * Rendering the CanvasRendererReact component has no side effects initially aside
3562
+ * from establishing the canvas element in the DOM. However, when the `filePath`
3563
+ * prop is defined the renderer will begin to init and eventually draw to the
3564
+ * canvas. If `filePath` is changed then the renderer will dispose and re-init
3565
+ * to begin rendering the new file.
3566
+ *
3567
+ * Currently `filePath` is the only "reactive" prop, all the other settings
3568
+ * props can be changed, but they will only take effect the next time `filePath`
3569
+ * changes and the renderer (re)inits.
3570
+ *
3571
+ * To interact with the renderer use the various hooks exposed by the package,
3572
+ * these can be used to access state values, listen to events and perform
3573
+ * actions.
3574
+ */
3575
+ var CanvasRendererReact = function (props) {
3576
+ var filePath = props.filePath, locateFile = props.locateFile, imagesURLFormat = props.imagesURLFormat, imagesURLMap = props.imagesURLMap, fragmentsURLFormat = props.fragmentsURLFormat, fragmentsURLMap = props.fragmentsURLMap, backgroundColor = props.backgroundColor, mode = props.mode, showTilesBorders = props.showTilesBorders, minimumZoomLevel = props.minimumZoomLevel, maximumZoomLevel = props.maximumZoomLevel, preserveDrawingBuffer = props.preserveDrawingBuffer, panBoundariesPadding = props.panBoundariesPadding, initialPan = props.initialPan, initialZoom = props.initialZoom, children = props.children, containerProps = props.containerProps, canvasProps = props.canvasProps, featureFlags = props.featureFlags, selectedArtboard = props.selectedArtboard;
3577
+ var canvas = useRef(null);
3578
+ var container = useRef(null);
3579
+ var _a = useState(false), allImagesReady = _a[0], setAllImagesReady = _a[1];
3580
+ var onAllImagesReady = useCallback(function () { return setAllImagesReady(true); }, []);
3581
+ var _b = useInternalContext$1(), dispose = _b.dispose, init = _b.init, setSettings = _b.setSettings;
3582
+ var contextCursor = useCursor();
3583
+ var status = useStatus();
3584
+ useEvent('allImagesReady', onAllImagesReady);
3585
+ useEffect(function () {
3586
+ logger.logDebug('CanvasRenderer mounted');
3587
+ return function () { return logger.logDebug('CanvasRenderer unmounted'); };
3588
+ }, []);
3589
+ useEffect(function () {
3590
+ setSettings({
3591
+ locateFile: locateFile,
3592
+ imagesURLFormat: imagesURLFormat,
3593
+ imagesURLMap: imagesURLMap,
3594
+ fragmentsURLFormat: fragmentsURLFormat,
3595
+ fragmentsURLMap: fragmentsURLMap,
3596
+ backgroundColor: backgroundColor,
3597
+ mode: mode,
3598
+ showTilesBorders: showTilesBorders,
3599
+ minimumZoomLevel: minimumZoomLevel,
3600
+ maximumZoomLevel: maximumZoomLevel,
3601
+ preserveDrawingBuffer: preserveDrawingBuffer,
3602
+ panBoundariesPadding: panBoundariesPadding,
3603
+ initialPan: initialPan,
3604
+ initialZoom: initialZoom,
3605
+ featureFlags: featureFlags,
3606
+ selectedArtboard: selectedArtboard,
3607
+ });
3608
+ }, [
3609
+ setSettings,
3610
+ locateFile,
3611
+ imagesURLFormat,
3612
+ imagesURLMap,
3613
+ fragmentsURLFormat,
3614
+ fragmentsURLMap,
3615
+ backgroundColor,
3616
+ mode,
3617
+ showTilesBorders,
3618
+ minimumZoomLevel,
3619
+ maximumZoomLevel,
3620
+ preserveDrawingBuffer,
3621
+ panBoundariesPadding,
3622
+ initialPan,
3623
+ initialZoom,
3624
+ featureFlags,
3625
+ selectedArtboard,
3626
+ ]);
3627
+ useEffect(function () {
3628
+ if (!filePath)
3629
+ return;
3630
+ init(filePath, canvas.current, container.current);
3631
+ return function () {
3632
+ dispose();
3633
+ };
3634
+ }, [dispose, init, filePath]);
3635
+ var currentCursor = useMemo(function () {
3636
+ var _a;
3637
+ return (_a = props.cursor) !== null && _a !== void 0 ? _a : contextCursor;
3638
+ }, [props.cursor, contextCursor]);
3639
+ var containerStyles = useMemo(function () {
3640
+ return _assign(_assign({}, CONTAINER_STYLES$1), { cursor: currentCursor });
3641
+ }, [currentCursor]);
3642
+ return (React.createElement("div", _assign({}, containerProps, { ref: container, style: containerStyles }),
3643
+ filePath && (React.createElement("canvas", _assign({}, canvasProps, {
3644
+ // The key in the canvas is necessary, to be sure that we don't reuse the canvas element.
3645
+ // Reusing the canvas element is not entirely safe, because the browser might decide to keep
3646
+ // in memory resources that we don't actually need anymore and could cause a memory leak
3647
+ key: filePath, ref: canvas, "data-sketchweb-all-images-ready": allImagesReady, "data-testid": "sketchweb-canvas", "data-sketchweb-status": "sketchweb-status-".concat((status === null || status === void 0 ? void 0 : status.type.toLowerCase()) || 'null'), style: CANVAS_STYLES$1 }))),
3648
+ (status === null || status === void 0 ? void 0 : status.type) === 'READY' && children));
3649
+ };
3650
+
3651
+ /**
3652
+ * Container for Prototype settings. All properties are marked as required to
3653
+ * force either initizalization or assignment in the constructor.
3654
+ */
3655
+ var PrototypeSettingsContainer = /** @class */ (function () {
3656
+ function PrototypeSettingsContainer(prototypeStructure, startArtboardUUID, canvas, container) {
3657
+ this.prototypeStructure = prototypeStructure;
3658
+ this.startArtboardUUID = startArtboardUUID;
3659
+ this.canvas = canvas;
3660
+ this.container = container;
3661
+ this.locateFile = '/{file}';
3662
+ this.imagesURLFormat = '';
3663
+ this.imagesURLMap = {};
3664
+ this.fragmentsURLFormat = '';
3665
+ this.fragmentsURLMap = {};
3666
+ this.backgroundColor = { r: 0, g: 0, b: 0, a: 1 };
3667
+ this.mode = WebRendererMode.release;
3668
+ this.showTilesBorders = false;
3669
+ this.minimumZoomLevel = 5;
3670
+ this.maximumZoomLevel = 0.01;
3671
+ this.preserveDrawingBuffer = false;
3672
+ this.featureFlags = DefaultFeatureFlags;
3673
+ this.manualInitialization = false;
3674
+ this.highlightHotspots = true;
3675
+ this.resizeMode = PrototypeResizeMode.Fit;
3676
+ this.assetsManagerLimits = {
3677
+ maxDepthForBackgroundRequests: 1,
3678
+ maxArtboardsForBackgroundRequests: 5,
3679
+ maxInitialLoadingDepth: 2,
3680
+ maxInitialArtboardToLoad: 10,
3681
+ };
3682
+ this.disableInteraction = false;
3683
+ }
3684
+ PrototypeSettingsContainer.FromSettings = function (settings) {
3685
+ return Object.assign(new PrototypeSettingsContainer(settings.prototypeStructure, settings.startArtboardUUID, settings.canvas, settings.container), Object.fromEntries(Object.entries(settings).filter(function (_a) {
3686
+ var value = _a[1];
3687
+ return value !== undefined;
3688
+ })));
3689
+ };
3690
+ return PrototypeSettingsContainer;
3691
+ }());
3692
+
3693
+ var PrototypeRenderer = /** @class */ (function (_super) {
3694
+ __extends(PrototypeRenderer, _super);
3695
+ function PrototypeRenderer(settings) {
3696
+ var _this = _super.call(this) || this;
3697
+ _this.status = { type: 'IDLE' };
3698
+ _this.disposed = false;
3699
+ _this.handleCanvasResize = function (width, height, pixelRatio) {
3700
+ var _a;
3701
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.resize(width, height, pixelRatio);
3702
+ };
3703
+ _this.handleWebGLContextLost = function () {
3704
+ _this.setStatus({ type: 'WEBGL_CONTEXT_LOST' });
3705
+ };
3706
+ _this.handlePinchToZoomEvent = function (scaleDelta, center) {
3707
+ var _a;
3708
+ (_a = _this.userEventsCollectorWasm) === null || _a === void 0 ? void 0 : _a.dispatchPinchToZoomEvent(scaleDelta, center.x, center.y);
3709
+ };
3710
+ _this.handleWheelEvent = function (delta, pointerInfo) {
3711
+ var _a;
3712
+ if (!_this.wasmModule)
3713
+ return;
3714
+ _this.userEventsCollectorWasm.dispatchWheelEvent(delta.x, delta.y, (_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapPointerInfo(pointerInfo));
3715
+ };
3716
+ _this.handlePointerDownEvent = function (pointerInfo) {
3717
+ var _a;
3718
+ if (!_this.wasmModule)
3719
+ return;
3720
+ _this.userEventsCollectorWasm.dispatchPointerDownEvent((_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapPointerInfo(pointerInfo));
3721
+ };
3722
+ _this.handlePointerMoveEvent = function (pointerInfo) {
3723
+ var _a;
3724
+ if (!_this.wasmModule)
3725
+ return;
3726
+ _this.userEventsCollectorWasm.dispatchPointerMoveEvent((_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapPointerInfo(pointerInfo));
3727
+ };
3728
+ _this.handleGlobalPointerMoveEvent = function (pointerInfo) {
3729
+ var _a;
3730
+ if (!_this.wasmModule)
3731
+ return;
3732
+ _this.userEventsCollectorWasm.dispatchGlobalPointerMoveEvent((_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapPointerInfo(pointerInfo));
3733
+ };
3734
+ _this.handlePointerUpEvent = function (pointerInfo) {
3735
+ var _a;
3736
+ if (!_this.wasmModule)
3737
+ return;
3738
+ _this.userEventsCollectorWasm.dispatchPointerUpEvent((_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapPointerInfo(pointerInfo));
3739
+ };
3740
+ _this.restartPrototype = function (artboardUUID) {
3741
+ var _a;
3742
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.restartPrototype(artboardUUID);
3743
+ };
3744
+ _this.navigateToFirstFlow = function () {
3745
+ var _a;
3746
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.navigateToFirstFlow();
3747
+ };
3748
+ _this.goBack = function () {
3749
+ var _a;
3750
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.goBack();
3751
+ };
3752
+ _this.goForwards = function () {
3753
+ var _a;
3754
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.goForwards();
3755
+ };
3756
+ _this.setResizeMode = function (resizeMode) {
3757
+ var _a;
3758
+ if (!_this.wasmModule)
3759
+ return;
3760
+ var wasmResizeMode = _this.wasmModule.mapResizeMode(resizeMode);
3761
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.setResizeMode(wasmResizeMode);
3762
+ };
3763
+ _this.getScreen = function (includeHotspots) {
3764
+ var _a;
3765
+ if (includeHotspots === void 0) { includeHotspots = true; }
3766
+ var jsScreen = (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.getJSScreen(includeHotspots);
3767
+ if (!jsScreen) {
3768
+ return { layers: [] };
3769
+ }
3770
+ return {
3771
+ layers: convertEmbindVectorToArray(jsScreen.layers),
3772
+ };
3773
+ };
3774
+ _this.settings = PrototypeSettingsContainer.FromSettings(settings);
3775
+ logger.logDebug('PrototypeRenderer JS constructed with settings:', _this.settings);
3776
+ _this.gestureManager = new GestureManager(_this.settings.container, _this.settings.disableInteraction);
3777
+ _this.canvasManager = new CanvasManager({
3778
+ container: _this.settings.container,
3779
+ canvas: _this.settings.canvas,
3780
+ maxPixelRatio: 3, // Recent iPhones have a pixel ratio of 3
3781
+ });
3782
+ _this.fetchWorker = new Worker(
3783
+ // It's important to use the locateFile path here.
3784
+ // The consumer might use a custom path for the web renderer file
3785
+ _this.settings.locateFile.replace('{file}', 'fetch-worker.js'));
3786
+ if (!_this.settings.manualInitialization) {
3787
+ _this.init();
3788
+ }
3789
+ return _this;
3790
+ }
3791
+ PrototypeRenderer.prototype.addListeners = function () {
3792
+ this.canvasManager.on('resize', this.handleCanvasResize);
3793
+ this.gestureManager.on('wheel', this.handleWheelEvent);
3794
+ this.gestureManager.on('pointerup', this.handlePointerUpEvent);
3795
+ this.gestureManager.on('pointermove', this.handlePointerMoveEvent);
3796
+ this.gestureManager.on('globalpointermove', this.handleGlobalPointerMoveEvent);
3797
+ this.gestureManager.on('pointerdown', this.handlePointerDownEvent);
3798
+ this.gestureManager.on('pinchToZoom', this.handlePinchToZoomEvent);
3799
+ this.settings.canvas.addEventListener('webglcontextlost', this.handleWebGLContextLost);
3800
+ };
3801
+ PrototypeRenderer.prototype.collectAndEmitDeviceInfo = function () {
3802
+ return __awaiter(this, void 0, void 0, function () {
3803
+ var gpuTier;
3804
+ return __generator(this, function (_a) {
3805
+ switch (_a.label) {
3806
+ case 0: return [4 /*yield*/, f()];
3807
+ case 1:
3808
+ gpuTier = _a.sent();
3809
+ this.deviceInfo = _assign(_assign({}, gpuTier), { hardwareConcurrency: navigator.hardwareConcurrency });
3810
+ this.emit('deviceInfo', this.deviceInfo);
3811
+ return [2 /*return*/];
3812
+ }
3813
+ });
3814
+ });
3815
+ };
3816
+ PrototypeRenderer.prototype.detectWebGLVersion = function () {
3817
+ this.webglVersion = getSupportedWebGLVersion(this.deviceInfo);
3818
+ logger.logDebug("Using WebGL ".concat(this.webglVersion));
3819
+ };
3820
+ // Keeping the real init into a separate function
3821
+ // so the outer app can wait for the init to finish
3822
+ // because we can't use async/await with constructors
3823
+ PrototypeRenderer.prototype.init = function () {
3824
+ return __awaiter(this, void 0, void 0, function () {
3825
+ var error_1;
3826
+ return __generator(this, function (_a) {
3827
+ switch (_a.label) {
3828
+ case 0:
3829
+ this.traceFirstPaint = new Performance('FirstPaint');
3830
+ this.setStatus({ type: 'INITIALIZING' });
3831
+ return [4 /*yield*/, this.collectAndEmitDeviceInfo()];
3832
+ case 1:
3833
+ _a.sent();
3834
+ this.detectWebGLVersion();
3835
+ _a.label = 2;
3836
+ case 2:
3837
+ _a.trys.push([2, 6, , 7]);
3838
+ return [4 /*yield*/, this.initWasmModule()];
3839
+ case 3:
3840
+ _a.sent();
3841
+ return [4 /*yield*/, this.initPlayerWasm()];
3842
+ case 4:
3843
+ _a.sent();
3844
+ return [4 /*yield*/, this.startDownload()];
3845
+ case 5:
3846
+ _a.sent();
3847
+ return [3 /*break*/, 7];
3848
+ case 6:
3849
+ error_1 = _a.sent();
3850
+ return [2 /*return*/, this.fail(error_1 instanceof WebRendererError
3851
+ ? error_1
3852
+ : new WebRendererError('ERROR', 'Unexpected exception initializing the web renderer', error_1))];
3853
+ case 7:
3854
+ this.startRendering();
3855
+ this.addListeners();
3856
+ return [2 /*return*/];
3857
+ }
3858
+ });
3859
+ });
3860
+ };
3861
+ PrototypeRenderer.prototype.initWasmModule = function () {
3862
+ var _a;
3863
+ return __awaiter(this, void 0, void 0, function () {
3864
+ var traceWasmModule;
3865
+ return __generator(this, function (_b) {
3866
+ switch (_b.label) {
3867
+ case 0:
3868
+ if (this.disposed)
3869
+ return [2 /*return*/];
3870
+ traceWasmModule = new Performance('WasmModuleDownload');
3871
+ this.wasmModule = new WasmModule({
3872
+ mode: this.settings.mode,
3873
+ locateFile: this.settings.locateFile,
3874
+ jsBridge: this.createJSBridge(),
3875
+ featureFlags: this.settings.featureFlags,
3876
+ webglVersion: this.webglVersion,
3877
+ });
3878
+ return [4 /*yield*/, ((_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.init())];
3879
+ case 1:
3880
+ _b.sent();
3881
+ traceWasmModule.printMeasurement();
3882
+ this.emit('metric', traceWasmModule.measure());
3883
+ return [2 /*return*/];
3884
+ }
3885
+ });
3886
+ });
3887
+ };
3888
+ PrototypeRenderer.prototype.startDownload = function () {
3889
+ var _this = this;
3890
+ this.setStatus({ type: 'LOADING_FILE' });
3891
+ return new Promise(function (resolve) {
3892
+ var _a;
3893
+ var onSuccess = function () {
3894
+ resolve();
3895
+ };
3896
+ (_a = _this.playerWasm) === null || _a === void 0 ? void 0 : _a.startDownload(onSuccess);
3897
+ });
3898
+ };
3899
+ PrototypeRenderer.prototype.startRendering = function () {
3900
+ var _a;
3901
+ this.traceInitialRender = new Performance('InitialRender');
3902
+ this.setStatus({ type: 'DRAWING_FILE' });
3903
+ (_a = this.playerWasm) === null || _a === void 0 ? void 0 : _a.startRenderLoop();
3904
+ };
3905
+ PrototypeRenderer.prototype.createJSBridge = function () {
3906
+ var _this = this;
3907
+ return {
3908
+ logDebug: function (msg) {
3909
+ logger.logDebug("[C++] ".concat(msg));
3910
+ },
3911
+ logWarning: function (msg) {
3912
+ logger.logWarning("[C++] ".concat(msg));
3913
+ },
3914
+ logError: function (msg) {
3915
+ logger.logError("[C++] ".concat(msg));
3916
+ },
3917
+ emitMetric: function (id, start, end, duration) {
3918
+ _this.emit('metric', { id: id, start: start, end: end, duration: duration });
3919
+ },
3920
+ // Having the image url resolver in JS gives
3921
+ // us more flexibility, especially when the images
3922
+ // have blob url coming from a zip file, and it's not
3923
+ // possible to create the url using a specific format
3924
+ resolveImageUrl: function (imageId, format) {
3925
+ if (_this.settings.imagesURLMap && _this.settings.imagesURLMap[imageId]) {
3926
+ return _this.settings.imagesURLMap[imageId].replace(':format', format);
3927
+ }
3928
+ if (_this.settings.imagesURLFormat) {
3929
+ return _this.settings.imagesURLFormat
3930
+ .replace(':imageId', imageId)
3931
+ .replace(':format', format);
3932
+ }
3933
+ logger.logWarning("Not able to resolve the url for the image with UUID: ".concat(imageId));
3934
+ // returning a string, because web assembly expect
3935
+ // a string return type, otherwise it will throw an error
3936
+ return '';
3937
+ },
3938
+ resolveFragmentUrl: function (fragmentId) {
3939
+ if (_this.settings.fragmentsURLMap &&
3940
+ _this.settings.fragmentsURLMap[fragmentId]) {
3941
+ return _this.settings.fragmentsURLMap[fragmentId];
3942
+ }
3943
+ if (_this.settings.fragmentsURLFormat) {
3944
+ return _this.settings.fragmentsURLFormat.replace(':fragmentId', fragmentId);
3945
+ }
3946
+ logger.logWarning("Not able to resolve the url for the fragment with UUID: ".concat(fragmentId));
3947
+ // returning a string, because web assembly expect
3948
+ // a string return type, otherwise it will throw an error
3949
+ return '';
3950
+ },
3951
+ onDrawComplete: this.handleDrawComplete.bind(this),
3952
+ onAllImagesReady: function () {
3953
+ _this.emit('allImagesReady');
3954
+ },
3955
+ onCameraMoveStart: function () {
3956
+ _this.emit('cameraMoveStart');
3957
+ },
3958
+ onCameraMoveEnd: function () {
3959
+ _this.emit('cameraMoveEnd');
3960
+ },
3961
+ onCameraZoomStart: function () {
3962
+ _this.emit('cameraZoomStart');
3963
+ },
3964
+ onCameraZoomEnd: function () {
3965
+ _this.emit('cameraZoomEnd');
3966
+ },
3967
+ onCameraZoomChange: function (zoom) {
3968
+ _this.emit('cameraZoomChange', zoom);
3969
+ },
3970
+ onCameraPanChange: function (x, y) {
3971
+ _this.emit('cameraPanChange', x, y);
3972
+ },
3973
+ onCursorChange: function (cursor) {
3974
+ var _a;
3975
+ var mappedCSSCursor = (_a = _this.wasmModule) === null || _a === void 0 ? void 0 : _a.mapToCSSCursor(cursor);
3976
+ if (mappedCSSCursor)
3977
+ _this.emit('cursorChange', mappedCSSCursor);
3978
+ },
3979
+ onPrototypeStateWillChange: function (currentArtboardId, canGoBack, canGoForwards) {
3980
+ _this.emit('prototypeStateWillChange', {
3981
+ currentArtboardId: currentArtboardId,
3982
+ canGoBack: canGoBack,
3983
+ canGoForwards: canGoForwards,
3984
+ });
3985
+ },
3986
+ onPrototypeStateChange: function (currentArtboardId, canGoBack, canGoForwards) {
3987
+ _this.emit('prototypeStateChange', {
3988
+ currentArtboardId: currentArtboardId,
3989
+ canGoBack: canGoBack,
3990
+ canGoForwards: canGoForwards,
3991
+ });
3992
+ },
3993
+ fetch: this.handleJSBridgeFetch.bind(this),
3994
+ abortFetch: this.handleJSBridgeAbortFetch.bind(this),
3995
+ onPrototypeUnhandledPointerUp: function () {
3996
+ _this.emit('prototypeUnhandledPointerUp');
3997
+ },
3998
+ onSceneChange: function () {
3999
+ _this.emit('sceneChange');
4000
+ },
4001
+ };
4002
+ };
4003
+ PrototypeRenderer.prototype.handleJSBridgeFetch = function (url, callback) {
4004
+ var _this = this;
4005
+ // Cloning the callback for later reuse, because the C++ one will be deallocated when the function goes out of scope
4006
+ var onComplete = callback.clone();
4007
+ var onFetchComplete = function (e) { return __awaiter(_this, void 0, void 0, function () {
4008
+ var _a, response, blob, image, textureHandle;
4009
+ var _b, _c, _d, _e, _f;
4010
+ return __generator(this, function (_g) {
4011
+ switch (_g.label) {
4012
+ case 0:
4013
+ if (this.disposed || !this.wasmModule)
4014
+ return [2 /*return*/];
4015
+ if (e.data.url !== url) {
4016
+ return [2 /*return*/];
4017
+ }
4018
+ _a = e.data.type;
4019
+ switch (_a) {
4020
+ case 'success': return [3 /*break*/, 1];
4021
+ case 'error': return [3 /*break*/, 5];
4022
+ }
4023
+ return [3 /*break*/, 6];
4024
+ case 1:
4025
+ response = {
4026
+ statusCode: 200,
4027
+ statusText: 'OK',
4028
+ contentType: e.data.contentType,
4029
+ isWebGLTexture: false,
4030
+ emscriptenWebGLTextureHandle: -1,
4031
+ width: 0,
4032
+ height: 0,
4033
+ };
4034
+ if (!/image/.test(e.data.contentType)) return [3 /*break*/, 3];
4035
+ blob = new Blob([e.data.buffer]);
4036
+ return [4 /*yield*/, loadImage(URL.createObjectURL(blob))
4037
+ // The image is loaded asynchronously, so we need to check again if the wasmModule wasn't disposed in the meantime
4038
+ ];
4039
+ case 2:
4040
+ image = _g.sent();
4041
+ // The image is loaded asynchronously, so we need to check again if the wasmModule wasn't disposed in the meantime
4042
+ if (!this.wasmModule)
4043
+ return [2 /*return*/];
4044
+ textureHandle = this.wasmModule.createWebGLTextureFromImage(image, this.webglCtxHandle);
4045
+ response.buffer = new Uint8Array(0);
4046
+ response.isWebGLTexture = true;
4047
+ response.emscriptenWebGLTextureHandle = textureHandle;
4048
+ response.width = image.width;
4049
+ response.height = image.height;
4050
+ return [3 /*break*/, 4];
4051
+ case 3:
4052
+ response.buffer = new Uint8Array(e.data.buffer);
4053
+ _g.label = 4;
4054
+ case 4:
4055
+ onComplete.exec(response);
4056
+ return [3 /*break*/, 7];
4057
+ case 5:
4058
+ {
4059
+ logger.logError("Error while fetching ".concat(url), e.data.error);
4060
+ onComplete.exec({
4061
+ buffer: new Uint8Array(0),
4062
+ statusCode: (_c = (_b = e.data.error) === null || _b === void 0 ? void 0 : _b.statusCode) !== null && _c !== void 0 ? _c : 500,
4063
+ statusText: (_e = (_d = e.data.error) === null || _d === void 0 ? void 0 : _d.statusText) !== null && _e !== void 0 ? _e : 'Unknown error',
4064
+ contentType: (_f = e.data.contentType) !== null && _f !== void 0 ? _f : '',
4065
+ isWebGLTexture: false,
4066
+ emscriptenWebGLTextureHandle: -1,
4067
+ width: 0,
4068
+ height: 0,
4069
+ });
4070
+ return [3 /*break*/, 7];
4071
+ }
4072
+ case 6: return [3 /*break*/, 7];
4073
+ case 7:
4074
+ this.fetchWorker.removeEventListener('message', onFetchComplete);
4075
+ return [2 /*return*/];
4076
+ }
4077
+ });
4078
+ }); };
4079
+ this.fetchWorker.addEventListener('message', onFetchComplete);
4080
+ this.fetchWorker.postMessage({
4081
+ type: 'fetch',
4082
+ url: url,
4083
+ });
4084
+ };
4085
+ PrototypeRenderer.prototype.handleJSBridgeAbortFetch = function (url) {
4086
+ this.fetchWorker.postMessage({
4087
+ type: 'abort',
4088
+ url: url,
4089
+ });
4090
+ };
4091
+ PrototypeRenderer.prototype.initPlayerWasm = function () {
4092
+ var _a, _b;
4093
+ return __awaiter(this, void 0, void 0, function () {
4094
+ var _c, RenderTarget, PrototypeRendererWasm, PrototypeStructureArtboardVector, PrototypeStructureFlowVector, PrototypeStructureAssetVector, PrototypeStructureFlowTypeEnum, prototypeStructure, flowTypesMap, _i, _d, artboard, flows, _e, _f, flow, assets, _g, _h, asset, userEventsCollectorWasm;
4095
+ return __generator(this, function (_j) {
4096
+ try {
4097
+ if (!this.wasmModule)
4098
+ throw Error('WASM module not initialized');
4099
+ this.webglCtxHandle = this.wasmModule.makeWebGLContext(this.settings.canvas, {
4100
+ preserveDrawingBuffer: this.settings.preserveDrawingBuffer,
4101
+ majorVersion: this.webglVersion,
4102
+ });
4103
+ _c = this.wasmModule.instance, RenderTarget = _c.RenderTarget, PrototypeRendererWasm = _c.PrototypeRendererWasm, PrototypeStructureArtboardVector = _c.PrototypeStructureArtboardVector, PrototypeStructureFlowVector = _c.PrototypeStructureFlowVector, PrototypeStructureAssetVector = _c.PrototypeStructureAssetVector, PrototypeStructureFlowTypeEnum = _c.PrototypeStructureFlowTypeEnum;
4104
+ this.renderTarget = RenderTarget.MakeWebGL(this.webglCtxHandle, this.canvasManager.size.width, this.canvasManager.size.height, this.canvasManager.pixelRatio);
4105
+ prototypeStructure = {
4106
+ artboards: new PrototypeStructureArtboardVector(),
4107
+ };
4108
+ flowTypesMap = {
4109
+ Overlay: PrototypeStructureFlowTypeEnum.Overlay,
4110
+ Screen: PrototypeStructureFlowTypeEnum.Screen,
4111
+ };
4112
+ for (_i = 0, _d = this.settings.prototypeStructure.artboards; _i < _d.length; _i++) {
4113
+ artboard = _d[_i];
4114
+ flows = new PrototypeStructureFlowVector();
4115
+ for (_e = 0, _f = (_a = artboard.flows) !== null && _a !== void 0 ? _a : []; _e < _f.length; _e++) {
4116
+ flow = _f[_e];
4117
+ flows.push_back(_assign(_assign({}, flow), { type: flowTypesMap[flow.type] }));
4118
+ }
4119
+ assets = new PrototypeStructureAssetVector();
4120
+ for (_g = 0, _h = (_b = artboard.assets) !== null && _b !== void 0 ? _b : []; _g < _h.length; _g++) {
4121
+ asset = _h[_g];
4122
+ assets.push_back(asset);
4123
+ }
4124
+ prototypeStructure.artboards.push_back(_assign(_assign({}, artboard), { flows: flows, assets: assets }));
4125
+ }
4126
+ this.playerWasm = new PrototypeRendererWasm(this.renderTarget, {
4127
+ showTilesBorders: this.settings.showTilesBorders,
4128
+ }, this.settings.startArtboardUUID, prototypeStructure, this.settings.highlightHotspots, this.settings.assetsManagerLimits);
4129
+ }
4130
+ catch (error) {
4131
+ throw new WebRendererError('WASM_ERROR', 'An error occurred while trying to create the PrototypeRenderer WASM object.', error);
4132
+ }
4133
+ userEventsCollectorWasm = this.playerWasm.getUserEventsCollector();
4134
+ if (!userEventsCollectorWasm) {
4135
+ throw new WebRendererError('WASM_ERROR', 'An error occurred while trying to create the user events collector');
4136
+ }
4137
+ this.userEventsCollectorWasm = userEventsCollectorWasm;
4138
+ this.playerWasm.setBackgroundColor(this.settings.backgroundColor.r, this.settings.backgroundColor.g, this.settings.backgroundColor.b, this.settings.backgroundColor.a);
4139
+ this.playerWasm.setZoomLevels(this.settings.minimumZoomLevel, this.settings.maximumZoomLevel);
4140
+ this.setResizeMode(this.settings.resizeMode);
4141
+ return [2 /*return*/];
4142
+ });
4143
+ });
4144
+ };
4145
+ PrototypeRenderer.prototype.setIsCameraLocked = function (isLocked) {
4146
+ var _a;
4147
+ (_a = this.playerWasm) === null || _a === void 0 ? void 0 : _a.setIsCameraLocked(isLocked);
4148
+ };
4149
+ PrototypeRenderer.prototype.setBackgroundColor = function (color) {
4150
+ var _a;
4151
+ if (color.r === this.settings.backgroundColor.r &&
4152
+ color.g === this.settings.backgroundColor.g &&
4153
+ color.b === this.settings.backgroundColor.b &&
4154
+ color.a === this.settings.backgroundColor.a)
4155
+ return;
4156
+ (_a = this.playerWasm) === null || _a === void 0 ? void 0 : _a.setBackgroundColor(color.r, color.g, color.b, color.a);
4157
+ this.settings.backgroundColor = color;
4158
+ };
4159
+ PrototypeRenderer.prototype.handleDrawComplete = function () {
4160
+ if (this.status.type === 'DRAWING_FILE') {
4161
+ // Draw complete is called repeatedly, but here we just want to perform
4162
+ // some actions after the initial draw is complete (when the status is DRAWING_FILE)
4163
+ // @TODO Look into ways of formalizing these status transitions
4164
+ this.traceInitialRender.printMeasurement();
4165
+ this.emit('metric', this.traceInitialRender.measure());
4166
+ this.traceFirstPaint.printMeasurement();
4167
+ this.emit('metric', this.traceFirstPaint.measure());
4168
+ this.setStatus({ type: 'READY' });
4169
+ }
4170
+ };
4171
+ /**
4172
+ * Forcefully releasing the WebGL context
4173
+ */
4174
+ PrototypeRenderer.prototype.looseWebGLContext = function () {
4175
+ var _a;
4176
+ (_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.destroyWebGLContext(this.webglCtxHandle);
4177
+ this.webglCtxHandle = -1;
4178
+ };
4179
+ PrototypeRenderer.prototype.fail = function (error) {
4180
+ this.setStatus({
4181
+ type: 'FAILURE',
4182
+ code: error.code,
4183
+ message: "".concat(error.toString()).concat(error.cause ? "\nWrapped Error: ".concat(error.cause.toString()) : ''),
4184
+ });
4185
+ logger.logError(error);
4186
+ error.cause && logger.logError(error.cause);
4187
+ };
4188
+ PrototypeRenderer.prototype.setStatus = function (status) {
4189
+ // When the status is failure, prevent other status changes
4190
+ // otherwise the failure will be overwritten
4191
+ if (this.status.type === 'FAILURE')
4192
+ return;
4193
+ logger.logDebug("Status transition ".concat(this.status.type, " => ").concat(status.type));
4194
+ this.status = status;
4195
+ this.emit('status', status);
4196
+ };
4197
+ PrototypeRenderer.prototype.getStatus = function () {
4198
+ return this.status;
4199
+ };
4200
+ PrototypeRenderer.prototype.getArtboardAtPosition = function (x, y) {
4201
+ var playerWasm = this.playerWasm;
4202
+ if (!playerWasm)
4203
+ return null;
4204
+ var jsScreen = playerWasm.getJSScreen(false);
4205
+ var pan = playerWasm.getPan();
4206
+ var zoom = playerWasm.getZoom();
4207
+ var mouse = {
4208
+ x: (x - pan.x) / zoom,
4209
+ y: (y - pan.y) / zoom,
4210
+ };
4211
+ for (var i = jsScreen.layers.size() - 1; i >= 0; i -= 1) {
4212
+ var artboard = jsScreen.layers.get(i);
4213
+ if (!artboard)
4214
+ continue;
4215
+ if (artboard.type !== 'artboard')
4216
+ continue;
4217
+ var maxX = artboard.bounds.x + artboard.bounds.width;
4218
+ var maxY = artboard.bounds.y + artboard.bounds.height;
4219
+ if (mouse.x >= artboard.bounds.x &&
4220
+ mouse.y >= artboard.bounds.y &&
4221
+ mouse.x <= maxX &&
4222
+ mouse.y <= maxY) {
4223
+ return artboard.getNode();
4224
+ }
4225
+ }
4226
+ return null;
4227
+ };
4228
+ PrototypeRenderer.prototype.disposeFetchWorker = function () {
4229
+ this.fetchWorker.postMessage({ type: 'abort-all' });
4230
+ this.fetchWorker.terminate();
4231
+ };
4232
+ PrototypeRenderer.prototype.dispose = function () {
4233
+ var _a, _b, _c;
4234
+ try {
4235
+ this.disposeFetchWorker();
4236
+ this.detachAllListeners();
4237
+ (_a = this.wasmModule) === null || _a === void 0 ? void 0 : _a.destroyWebGLContext(this.webglCtxHandle);
4238
+ this.canvasManager.dispose();
4239
+ this.gestureManager.dispose();
4240
+ (_b = this.playerWasm) === null || _b === void 0 ? void 0 : _b.stopRenderLoop();
4241
+ (_c = this.playerWasm) === null || _c === void 0 ? void 0 : _c.delete(); // This will call the destructor in C++
4242
+ this.renderTarget.delete();
4243
+ this.playerWasm = undefined;
4244
+ this.wasmModule = undefined;
4245
+ this.disposed = true;
4246
+ }
4247
+ catch (error) {
4248
+ this.fail(new WebRendererError('ERROR', 'Unexpected exception while disposing the WebRendererWasm object', error));
4249
+ }
4250
+ };
4251
+ PrototypeRenderer.prototype.mapRelativePositionToCameraPosition = function (x, y) {
4252
+ var playerWasm = this.playerWasm;
4253
+ if (!playerWasm)
4254
+ return null;
4255
+ var cameraPosition = playerWasm.mapRelativePositionToCameraPosition(x, y);
4256
+ return cameraPosition;
4257
+ };
4258
+ PrototypeRenderer.prototype.updateHighlightHotspotsSetting = function (highlightHotspots) {
4259
+ var playerWasm = this.playerWasm;
4260
+ if (!playerWasm)
4261
+ return null;
4262
+ playerWasm.updateHighlightHotspotsSetting(highlightHotspots);
4263
+ };
4264
+ return PrototypeRenderer;
4265
+ }(EventEmitter));
4266
+
4267
+ /**
4268
+ * Context for the renderer `status` value.
4269
+ */
4270
+ var StatusContext = createContext(undefined);
4271
+ /**
4272
+ * Context for the renderer `cursor` value.
4273
+ */
4274
+ var CursorContext = createContext("auto" /* CSSCursor.Auto */);
4275
+ /**
4276
+ * Context that describes the current prototype state.
4277
+ */
4278
+ var PrototypeStateContext = createContext(undefined);
4279
+ /**
4280
+ * Context that describes the current prototype zoom/scale value.
4281
+ */
4282
+ var ZoomContext = createContext(undefined);
4283
+ /**
4284
+ * Context that describes the current prototype pan value.
4285
+ */
4286
+ var PanContext = createContext(undefined);
4287
+
4288
+ /**
4289
+ * The internal context contains private methods and is used exclusively within
4290
+ * the package. The members of this module are not exported from the package
4291
+ * entrypoint.
4292
+ */
4293
+ var InternalContext = createContext(undefined);
4294
+ /**
4295
+ * Access the internal context values.
4296
+ */
4297
+ var useInternalContext = function () {
4298
+ var internal = useContext(InternalContext);
4299
+ if (internal === undefined) {
4300
+ throw Error('useInternalContext must be used within a provider');
4301
+ }
4302
+ return internal;
4303
+ };
4304
+
4305
+ /**
4306
+ * The reducer acts as the source of truth for the renderer state, at least
4307
+ * from the point of view of the React app consuming the package. We mirror
4308
+ * renderer state here, and keep it up to date via events emitted from
4309
+ * the renderer.
4310
+ *
4311
+ * Some state values are "derived", in that they don't have a direct counterpart
4312
+ * in the renderer, but we update them over time as events are emitted - for
4313
+ * example the "cursor" value which models the canvas pointer typoe.
4314
+ *
4315
+ * This state is accessed via the hooks in the hooks/state folder, which will
4316
+ * typically expose small slices of the state or single values from dedicated
4317
+ * contexts to avoid render thrashing.
4318
+ */
4319
+ var reducer = function (state, action) {
4320
+ switch (action.type) {
4321
+ case 'on-status': {
4322
+ return _assign(_assign({}, state), { status: action.status });
4323
+ }
4324
+ case 'dispose': {
4325
+ return _assign(_assign({}, state), { status: { type: 'DISPOSED' }, cursor: "auto" /* CSSCursor.Auto */ });
4326
+ }
4327
+ case 'on-cursor-change': {
4328
+ return _assign(_assign({}, state), { cursor: action.cursor });
4329
+ }
4330
+ case 'on-prototype-state-will-change': {
4331
+ return _assign(_assign({}, state), { prototypeState: _assign(_assign({}, state.prototypeState), { isChanging: true }) });
4332
+ }
4333
+ case 'on-prototype-state-change': {
4334
+ return _assign(_assign({}, state), { prototypeState: _assign(_assign(_assign({}, state.prototypeState), action.prototypeState), { isChanging: false }) });
4335
+ }
4336
+ case 'on-zoom': {
4337
+ return _assign(_assign({}, state), { zoom: action.zoom });
4338
+ }
4339
+ case 'on-pan': {
4340
+ return _assign(_assign({}, state), { pan: {
4341
+ x: action.pan.x,
4342
+ y: action.pan.y,
4343
+ } });
4344
+ }
4345
+ default: {
4346
+ return state;
4347
+ }
4348
+ }
4349
+ };
4350
+
4351
+ /**
4352
+ * Manages the renderer class instance, and handles the Providers that must
4353
+ * be rendered as parents to PrototypeRendererReact.
4354
+ *
4355
+ * By managing the class instance lifecycle logic in one place, and maintaining
4356
+ * a single source of truth for its state via a reducer we can provide a consistent
4357
+ * and globally accessible view on the instance state, manage state transitions
4358
+ * and handle dervied state easily.
4359
+ *
4360
+ * Note that currently we are exposing this API via multiple different nested
4361
+ * contexts. The idea here is that we insulate components in the outer app from
4362
+ * re-rendering everytime any piece of state changes. They can instead just
4363
+ * subscribe to small slices of state and values from the individual contexts
4364
+ * and only re-render when necessary. This approach is under review and subject
4365
+ * to change if it starts to feel unscalable.
4366
+ */
4367
+ var PrototypeRendererProvider = function (props) {
4368
+ var instanceRef = useRef(null);
4369
+ var settingsRef = useRef(null);
4370
+ var _a = useReducer(reducer, {
4371
+ status: { type: 'IDLE' },
4372
+ cursor: "auto" /* CSSCursor.Auto */,
4373
+ prototypeState: {
4374
+ currentArtboardId: '',
4375
+ canGoBack: false,
4376
+ canGoForwards: false,
4377
+ isChanging: false,
4378
+ },
4379
+ zoom: 1,
4380
+ pan: { x: 0, y: 0 },
4381
+ }), _b = _a[0], status = _b.status, cursor = _b.cursor, prototypeState = _b.prototypeState, zoom = _b.zoom, pan = _b.pan, dispatch = _a[1];
4382
+ var onStatus = useCallback(function (status) {
4383
+ dispatch({ type: 'on-status', status: status });
4384
+ }, []);
4385
+ var onZoom = useCallback(function (zoom) { return dispatch({ type: 'on-zoom', zoom: zoom }); }, []);
4386
+ var onPan = useCallback(function (x, y) { return dispatch({ type: 'on-pan', pan: { x: x, y: y } }); }, []);
4387
+ var onCursorChange = useCallback(function (cursor) {
4388
+ return dispatch({
4389
+ type: 'on-cursor-change',
4390
+ cursor: cursor,
4391
+ });
4392
+ }, []);
4393
+ var onPrototypeStateWillChange = useCallback(function () { return dispatch({ type: 'on-prototype-state-will-change' }); }, []);
4394
+ var onPrototypeStateChange = useCallback(function (prototypeState) {
4395
+ return dispatch({ type: 'on-prototype-state-change', prototypeState: prototypeState });
4396
+ }, []);
4397
+ var dispose = useCallback(function () {
4398
+ var currentManager = instanceRef.current;
4399
+ if (!currentManager)
4400
+ return;
4401
+ logger.logDebug('Provider dispose');
4402
+ currentManager.off('status', onStatus);
4403
+ currentManager.off('cursorChange', onCursorChange);
4404
+ currentManager.off('prototypeStateWillChange', onPrototypeStateWillChange);
4405
+ currentManager.off('prototypeStateChange', onPrototypeStateChange);
4406
+ currentManager.off('cameraZoomChange', onZoom);
4407
+ currentManager.off('cameraPanChange', onPan);
4408
+ currentManager.dispose();
4409
+ instanceRef.current = null;
4410
+ dispatch({ type: 'dispose' });
4411
+ }, [
4412
+ onStatus,
4413
+ onCursorChange,
4414
+ onPrototypeStateWillChange,
4415
+ onPrototypeStateChange,
4416
+ onPan,
4417
+ onZoom,
4418
+ ]);
4419
+ var init = useCallback(function (canvas, container) {
4420
+ if (!canvas || !container)
4421
+ return;
4422
+ if (!settingsRef.current)
4423
+ return;
4424
+ logger.logDebug('Provider init');
4425
+ var nextInstance = new PrototypeRenderer(_assign(_assign({}, settingsRef.current), { container: container, canvas: canvas, manualInitialization: true }));
4426
+ nextInstance.on('status', onStatus);
4427
+ nextInstance.on('cursorChange', onCursorChange);
4428
+ nextInstance.on('prototypeStateWillChange', onPrototypeStateWillChange);
4429
+ nextInstance.on('prototypeStateChange', onPrototypeStateChange);
4430
+ nextInstance.on('cameraZoomChange', onZoom);
4431
+ nextInstance.on('cameraPanChange', onPan);
4432
+ instanceRef.current = nextInstance;
4433
+ nextInstance.init();
4434
+ }, [
4435
+ onStatus,
4436
+ onCursorChange,
4437
+ onPrototypeStateWillChange,
4438
+ onPrototypeStateChange,
4439
+ onPan,
4440
+ onZoom,
4441
+ ]);
4442
+ var setSettings = useCallback(function (settings) {
4443
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4444
+ logger.logDebug('Provider setSettings');
4445
+ if (settings.backgroundColor &&
4446
+ settings.backgroundColor != ((_a = settingsRef.current) === null || _a === void 0 ? void 0 : _a.backgroundColor)) {
4447
+ (_b = instanceRef.current) === null || _b === void 0 ? void 0 : _b.setBackgroundColor(settings.backgroundColor);
4448
+ }
4449
+ if (((_c = settingsRef.current) === null || _c === void 0 ? void 0 : _c.resizeMode) != settings.resizeMode) {
4450
+ (_d = instanceRef.current) === null || _d === void 0 ? void 0 : _d.setResizeMode(settings.resizeMode || PrototypeResizeMode.Fit);
4451
+ }
4452
+ if (settings.highlightHotspots !== undefined &&
4453
+ ((_e = settingsRef.current) === null || _e === void 0 ? void 0 : _e.highlightHotspots) !== settings.highlightHotspots) {
4454
+ (_f = instanceRef.current) === null || _f === void 0 ? void 0 : _f.updateHighlightHotspotsSetting(settings.highlightHotspots);
4455
+ }
4456
+ if (settings.disableInteraction !== ((_g = settingsRef.current) === null || _g === void 0 ? void 0 : _g.disableInteraction)) {
4457
+ (_h = instanceRef.current) === null || _h === void 0 ? void 0 : _h.gestureManager.setDisable(settings.disableInteraction || false);
4458
+ }
4459
+ settingsRef.current = settings;
4460
+ }, []);
4461
+ var getInstance = useCallback(function () {
4462
+ return instanceRef.current;
4463
+ }, []);
4464
+ var internal = useMemo(function () {
4465
+ return {
4466
+ dispose: dispose,
4467
+ init: init,
4468
+ setSettings: setSettings,
4469
+ getInstance: getInstance,
4470
+ dispatch: dispatch,
4471
+ };
4472
+ }, [dispose, init, setSettings, getInstance]);
4473
+ return (React.createElement(InternalContext.Provider, { value: internal },
4474
+ React.createElement(StatusContext.Provider, { value: status },
4475
+ React.createElement(CursorContext.Provider, { value: cursor },
4476
+ React.createElement(PrototypeStateContext.Provider, { value: prototypeState },
4477
+ React.createElement(ZoomContext.Provider, { value: zoom },
4478
+ React.createElement(PanContext.Provider, { value: pan }, props.children)))))));
4479
+ };
4480
+
4481
+ /**
4482
+ * Returns a function that resets/restarts the prototype to the supplied
4483
+ * Artboard id.
4484
+ */
4485
+ var useRestartPrototype = function () {
4486
+ var getInstance = useInternalContext().getInstance;
4487
+ var instance = getInstance();
4488
+ return useCallback(function (artboardUUID) {
4489
+ instance === null || instance === void 0 ? void 0 : instance.restartPrototype(artboardUUID);
4490
+ }, [instance]);
4491
+ };
4492
+ /**
4493
+ * Returns a function that naviagtes to the first flow found on the current
4494
+ * Screen, or noops if there isn't one.
4495
+ */
4496
+ var useNavigateToFirstFlow = function () {
4497
+ var getInstance = useInternalContext().getInstance;
4498
+ var instance = getInstance();
4499
+ return useCallback(function () {
4500
+ instance === null || instance === void 0 ? void 0 : instance.navigateToFirstFlow();
4501
+ }, [instance]);
4502
+ };
4503
+ /**
4504
+ * Navigate the prototype stack backwards.
4505
+ */
4506
+ var useGoBack = function () {
4507
+ var getInstance = useInternalContext().getInstance;
4508
+ var instance = getInstance();
4509
+ return useCallback(function () {
4510
+ instance === null || instance === void 0 ? void 0 : instance.goBack();
4511
+ }, [instance]);
4512
+ };
4513
+ /**
4514
+ * Navigate the prototype stack forwards.
4515
+ */
4516
+ var useGoForwards = function () {
4517
+ var getInstance = useInternalContext().getInstance;
4518
+ var instance = getInstance();
4519
+ return useCallback(function () {
4520
+ instance === null || instance === void 0 ? void 0 : instance.goForwards();
4521
+ }, [instance]);
4522
+ };
4523
+ /**
4524
+ * Returns a function that can be used to find out if an Artboard exists below
4525
+ * specific mouse coordinates relative to the canvas origin.
4526
+ */
4527
+ var usePrototypeGetArtboardAtPosition = function () {
4528
+ var getInstance = useInternalContext().getInstance;
4529
+ var instance = getInstance();
4530
+ return useCallback(function (x, y) { return __awaiter(void 0, void 0, void 0, function () {
4531
+ return __generator(this, function (_a) {
4532
+ return [2 /*return*/, instance === null || instance === void 0 ? void 0 : instance.getArtboardAtPosition(x, y)];
4533
+ });
4534
+ }); }, [instance]);
4535
+ };
4536
+ var usePrototypeMapRelativePositionToCameraPosition = function () {
4537
+ var getInstance = useInternalContext().getInstance;
4538
+ var instance = getInstance();
4539
+ return useCallback(function (x, y) {
4540
+ if (!instance)
4541
+ return null;
4542
+ var cameraPos = instance.mapRelativePositionToCameraPosition(x, y);
4543
+ return cameraPos !== null && cameraPos !== void 0 ? cameraPos : null;
4544
+ }, [instance]);
4545
+ };
4546
+
4547
+ /**
4548
+ * Access the renderer `status` value.
4549
+ */
4550
+ var usePrototypeStatus = function () {
4551
+ var status = useContext(StatusContext);
4552
+ if (status === undefined) {
4553
+ throw Error('usePrototypeStatus must be used within a provider');
4554
+ }
4555
+ return status;
4556
+ };
4557
+ /**
4558
+ * Access the renderer `cursor` value.
4559
+ */
4560
+ var usePrototypeCursor = function () {
4561
+ var cursor = useContext(CursorContext);
4562
+ if (cursor === undefined) {
4563
+ throw Error('usePrototypeCursor must be used within a provider');
4564
+ }
4565
+ return cursor;
4566
+ };
4567
+ var usePrototypeState = function () {
4568
+ var nav = useContext(PrototypeStateContext);
4569
+ if (nav === undefined) {
4570
+ throw Error('usePrototypeState must be used within a provider');
4571
+ }
4572
+ return nav;
4573
+ };
4574
+ var usePrototypeZoom = function () {
4575
+ var zoom = useContext(ZoomContext);
4576
+ if (zoom === undefined) {
4577
+ throw Error('usePrototypeZoom must be used within a provider');
4578
+ }
4579
+ return zoom;
4580
+ };
4581
+ var usePrototypePan = function () {
4582
+ var pan = useContext(PanContext);
4583
+ if (pan === undefined) {
4584
+ throw Error('usePrototypePan must be used within a provider');
4585
+ }
4586
+ return pan;
4587
+ };
4588
+
4589
+ /**
4590
+ * Subscribe to any renderer event type. Prefer passing memoized function
4591
+ * references from useCallback to this hook to avoid calling `on`/`off` every
4592
+ * render.
4593
+ */
4594
+ var usePrototypeEvent = function (event, callback) {
4595
+ var getInstance = useInternalContext().getInstance;
4596
+ var instance = getInstance();
4597
+ useEffect(function () {
4598
+ instance === null || instance === void 0 ? void 0 : instance.on(event, callback);
4599
+ return function () {
4600
+ instance === null || instance === void 0 ? void 0 : instance.off(event, callback);
4601
+ };
4602
+ }, [event, instance, callback]);
4603
+ };
4604
+
4605
+ function useGetScreen() {
4606
+ var getInstance = useInternalContext().getInstance;
4607
+ var instance = getInstance();
4608
+ return useCallback(function (includeHotspots) {
4609
+ if (includeHotspots === void 0) { includeHotspots = true; }
4610
+ return instance === null || instance === void 0 ? void 0 : instance.getScreen(includeHotspots);
4611
+ }, [instance]);
4612
+ }
4613
+
4614
+ var CONTAINER_STYLES = {
4615
+ position: 'relative',
4616
+ width: '100%',
4617
+ height: '100%',
4618
+ // Removes the 300ms tap delay, prevents double-tap zoom and allows smoother panning on Safari iOS
4619
+ // The property is automatically applied to all its children. We need it on the container
4620
+ // because some events are not listened directly on the canvas
4621
+ touchAction: 'manipulation',
4622
+ };
4623
+ var CANVAS_STYLES = {
4624
+ position: 'absolute',
4625
+ top: 0,
4626
+ left: 0,
4627
+ };
4628
+ var PrototypeRendererReact = function (props) {
4629
+ var locateFile = props.locateFile, imagesURLFormat = props.imagesURLFormat, imagesURLMap = props.imagesURLMap, backgroundColor = props.backgroundColor, mode = props.mode, showTilesBorders = props.showTilesBorders, minimumZoomLevel = props.minimumZoomLevel, maximumZoomLevel = props.maximumZoomLevel, preserveDrawingBuffer = props.preserveDrawingBuffer, children = props.children, containerProps = props.containerProps, canvasProps = props.canvasProps, featureFlags = props.featureFlags, startArtboardUUID = props.startArtboardUUID, prototypeStructure = props.prototypeStructure, fragmentsURLFormat = props.fragmentsURLFormat, fragmentsURLMap = props.fragmentsURLMap, highlightHotspots = props.highlightHotspots, resizeMode = props.resizeMode, assetsManagerLimits = props.assetsManagerLimits, externalCursor = props.cursor, disableInteraction = props.disableInteraction;
4630
+ var canvas = useRef(null);
4631
+ var container = useRef(null);
4632
+ var _a = useInternalContext(), dispose = _a.dispose, init = _a.init, setSettings = _a.setSettings;
4633
+ var status = usePrototypeStatus();
4634
+ var prototypeCursor = usePrototypeCursor();
4635
+ var externalCursorComputed = typeof externalCursor === 'function'
4636
+ ? externalCursor(prototypeCursor)
4637
+ : externalCursor;
4638
+ var cursor = externalCursorComputed || prototypeCursor;
4639
+ useEffect(function () {
4640
+ logger.logDebug('PrototypeRenderer mounted');
4641
+ return function () { return logger.logDebug('PrototypeRenderer unmounted'); };
4642
+ }, []);
4643
+ useEffect(function () {
4644
+ setSettings({
4645
+ locateFile: locateFile,
4646
+ imagesURLFormat: imagesURLFormat,
4647
+ imagesURLMap: imagesURLMap,
4648
+ backgroundColor: backgroundColor,
4649
+ mode: mode,
4650
+ showTilesBorders: showTilesBorders,
4651
+ minimumZoomLevel: minimumZoomLevel,
4652
+ maximumZoomLevel: maximumZoomLevel,
4653
+ preserveDrawingBuffer: preserveDrawingBuffer,
4654
+ featureFlags: featureFlags,
4655
+ startArtboardUUID: startArtboardUUID,
4656
+ prototypeStructure: prototypeStructure,
4657
+ fragmentsURLFormat: fragmentsURLFormat,
4658
+ fragmentsURLMap: fragmentsURLMap,
4659
+ highlightHotspots: highlightHotspots,
4660
+ resizeMode: resizeMode,
4661
+ assetsManagerLimits: assetsManagerLimits,
4662
+ disableInteraction: disableInteraction,
4663
+ });
4664
+ }, [
4665
+ setSettings,
4666
+ locateFile,
4667
+ imagesURLFormat,
4668
+ imagesURLMap,
4669
+ backgroundColor,
4670
+ mode,
4671
+ showTilesBorders,
4672
+ minimumZoomLevel,
4673
+ maximumZoomLevel,
4674
+ preserveDrawingBuffer,
4675
+ featureFlags,
4676
+ startArtboardUUID,
4677
+ highlightHotspots,
4678
+ resizeMode,
4679
+ fragmentsURLFormat,
4680
+ fragmentsURLMap,
4681
+ prototypeStructure,
4682
+ assetsManagerLimits,
4683
+ disableInteraction,
4684
+ ]);
4685
+ useEffect(function () {
4686
+ init(canvas.current, container.current);
4687
+ return function () {
4688
+ dispose();
4689
+ };
4690
+ }, [dispose, init]);
4691
+ var containerStyles = useMemo(function () {
4692
+ return _assign(_assign({}, CONTAINER_STYLES), { cursor: cursor });
4693
+ }, [cursor]);
4694
+ return (React.createElement("div", _assign({}, containerProps, { ref: container, style: containerStyles }),
4695
+ React.createElement("canvas", _assign({}, canvasProps, { ref: canvas, "data-testid": "prototype-canvas", "data-prototype-status": "prototype-status-".concat((status === null || status === void 0 ? void 0 : status.type.toLowerCase()) || 'null'), style: CANVAS_STYLES })),
4696
+ (status === null || status === void 0 ? void 0 : status.type) === 'READY' && children));
4697
+ };
4698
+
4699
+ var WRAPPER_STYLE = {
4700
+ position: 'absolute',
4701
+ inset: 0,
4702
+ pointerEvents: 'none',
4703
+ };
4704
+ /**
4705
+ * Renders an HTML overlay that can be placed over the Prototype canvas
4706
+ * to make hotspots clickable and selectable in tools like Cypress and Playwright.
4707
+ */
4708
+ function PrototypeTestOverlay(props) {
4709
+ var _a = props.visualize, visualize = _a === void 0 ? false : _a;
4710
+ var getScreen = useGetScreen();
4711
+ var _b = useState(function () {
4712
+ return getScreen() || null;
4713
+ }), screen = _b[0], setScreen = _b[1];
4714
+ var onSceneChange = useCallback(function () {
4715
+ setScreen(getScreen() || null);
4716
+ }, [getScreen]);
4717
+ usePrototypeEvent('sceneChange', onSceneChange);
4718
+ var wrapperStyle = useMemo(function () {
4719
+ return _assign(_assign({}, WRAPPER_STYLE), { opacity: visualize ? 1 : 0 });
4720
+ }, [visualize]);
4721
+ if (!screen)
4722
+ return null;
4723
+ return (React.createElement("div", { style: wrapperStyle }, screen.layers.map(function (layer, i) { return (React.createElement(Element, { key: "".concat(i, "/").concat(layer.id), bounds: layer.bounds, id: layer.id, name: layer.name, type: layer.type })); })));
4724
+ }
4725
+ function Element(props) {
4726
+ var bounds = props.bounds, name = props.name, id = props.id, type = props.type;
4727
+ var zoom = usePrototypeZoom();
4728
+ var _a = usePrototypePan() || { x: 0, y: 0 }, panX = _a.x, panY = _a.y;
4729
+ var style = useMemo(function () {
4730
+ return _assign({ position: 'absolute', left: panX / window.devicePixelRatio + bounds.x * zoom, top: panY / window.devicePixelRatio + bounds.y * zoom, width: bounds.width * zoom, height: bounds.height * zoom, backgroundColor: 'rgba(0, 255, 255, 0.2)', border: '2px dotted white' }, (type === 'hotspot'
4731
+ ? { cursor: 'pointer', pointerEvents: 'auto' }
4732
+ : {}));
4733
+ }, [bounds.x, bounds.y, bounds.width, bounds.height, panX, panY, zoom, type]);
4734
+ return (React.createElement("div", { style: style, "data-testid": "".concat(type, "-").concat(kebabCase(name), "-").concat(id), "data-entity-name": name, "data-entity-id": id, "data-entity-bounds-x": bounds.x, "data-entity-bounds-y": bounds.x, "data-entity-bounds-width": bounds.width, "data-entity-bounds-height": bounds.height }));
4735
+ }
4736
+ function kebabCase(s) {
4737
+ var _a, _b;
4738
+ return ((_b = (_a = s
4739
+ .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)) === null || _a === void 0 ? void 0 : _a.join('-').toLowerCase()) !== null && _b !== void 0 ? _b : '');
4740
+ }
4741
+
4742
+ export { usePrototypePan as $, useCursor as A, useIsCameraZooming as B, CanvasRenderer as C, useIsCameraMoving as D, usePRFile as E, usePRFileArtboards as F, useRootNodeAbsoluteExtent as G, useEvent as H, useLogEvent as I, reducer$1 as J, PrototypeRenderer as K, PrototypeRendererProvider as L, PrototypeRendererReact as M, useRestartPrototype as N, useNavigateToFirstFlow as O, PanContext$1 as P, useGoBack as Q, useGoForwards as R, StatusContext$1 as S, usePrototypeGetArtboardAtPosition as T, usePrototypeMapRelativePositionToCameraPosition as U, usePrototypeStatus as V, usePrototypeCursor as W, usePrototypeState as X, usePrototypeZoom as Y, ZoomContext$1 as Z, _inherits as _, _createClass as a, usePrototypeEvent as a0, useGetScreen as a1, PrototypeTestOverlay as a2, WebRendererError as a3, WebRendererMode as a4, isDefinedPresentationManifestArtboard as a5, PrototypeResizeMode as a6, EventEmitter as a7, GestureManager as a8, KeyboardManager as a9, PRMarinaBlendMode as aA, PRMarinaLayerType as aB, PRMarinaLayerCornerStyle as aC, PRMarinaLayerTextTransform as aD, PRMarinaLayerHorizontalTextAlignment as aE, PRMarinaLayerVerticalTextAlignment as aF, PRMarinaLayerTextDecoration as aG, PRUserPointerType as aH, PRCursorType as aI, PRNodeExportFormat as aJ, PrototypeStructureFlowType as aK, PrototypeResizeModeWasm as aL, ListenersCollector as aa, Performance as ab, DefaultFeatureFlags as ac, debounce as ad, extractPointer as ae, clamp as af, getSupportedWebGLVersion as ag, convertEmbindVectorToArray as ah, isTouchDevice as ai, removeUndefinedKeys as aj, touchableClick as ak, safePtrAccess as al, nextTick as am, getiOSVersion as an, parseSafariUserAgent as ao, logger as ap, useDebounceFunction as aq, PRMarinaVisibleScaleType as ar, PRMarinaExportFormatType as as, PRMarinaLayerFillType as at, PRMarinaLayerImageFillType as au, PRMarinaLayerGradientType as av, PRMarinaLayerBorderPosition as aw, PRMarinaLayerLineCap as ax, PRMarinaLayerLineJoin as ay, PRMarinaLayerBlurType as az, _typeof as b, _wrapNativeSuper as c, _classCallCheck as d, _callSuper as e, _createForOfIteratorHelper as f, _slicedToArray as g, CanvasRendererProvider as h, CanvasRendererReact as i, CameraZoomingContext as j, CameraMoveContext as k, CursorContext$1 as l, useIncrementZoom as m, useDecrementZoom as n, useSetPan as o, useZoomToFit as p, useLooseWebGLContext as q, useGetArtboardAtPosition as r, useGetPanAtPosition as s, useLockCamera as t, useSetZoom as u, useMapRelativePositionToCameraPosition as v, useExportNode as w, useStatus as x, useZoom as y, usePan as z };