@netless/window-manager 1.0.13 → 1.0.15

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,2892 @@
1
+ var styles = ".netless-app-docs-viewer-content{position:relative;height:100%;overflow:hidden}.netless-app-docs-viewer-preview-mask{display:none;position:absolute;z-index:200;top:0;left:0;width:100%;height:100%}.netless-app-docs-viewer-preview{display:flex;flex-direction:column;align-items:center;position:absolute;z-index:300;top:0;left:0;width:33%;max-width:200px;height:100%;padding-top:10px;transform:translate(-100%);background:rgba(237,237,240,.9);box-shadow:inset -1px 0 #0000001c;transition:transform .4s}.netless-app-docs-viewer-preview-active .netless-app-docs-viewer-preview-mask{display:block}.netless-app-docs-viewer-preview-active .netless-app-docs-viewer-preview{transform:translate(0)}.netless-app-docs-viewer-preview-page{position:relative;display:block;width:55%;margin-bottom:10px;font-size:0;color:transparent;outline:none;border:7px solid transparent;border-radius:4px;transition:border-color .3s;user-select:none}.netless-app-docs-viewer-preview-page:hover,.netless-app-docs-viewer-preview-page.netless-app-docs-viewer-preview-page-active{border-color:#444e601a}.netless-app-docs-viewer-preview-page>img{width:100%;height:auto;box-sizing:border-box;border:1px solid rgba(0,0,0,.5);border-radius:1px;background-color:#fff;box-shadow:0 2px 8px #0000004d}.netless-app-docs-viewer-preview-page-name{position:absolute;top:1px;left:-10px;transform:translate(-100%);text-align:right;font-size:12px;color:#5f5f5f;user-select:none}.netless-app-docs-viewer-footer{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;border-top:1px solid #eeeef7;color:#191919}.netless-app-docs-viewer-float-footer{width:100%;min-height:26px;position:absolute;left:0;bottom:0;z-index:2000;background:rgba(249,249,252,.9);transition:opacity .4s}.netless-app-docs-viewer-footer-btn{box-sizing:border-box;width:26px;height:26px;font-size:0;margin:0;padding:3px;border:none;border-radius:1px;outline:none;color:currentColor;background:transparent;transition:background .4s;cursor:pointer;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-docs-viewer-footer-btn:hover{background:rgba(237,237,240,.9)}@media (hover: none){.netless-app-docs-viewer-footer-btn:hover{background:transparent!important}}.netless-app-docs-viewer-footer-btn>svg{width:100%;height:100%}.netless-app-docs-viewer-footer-btn>svg:nth-of-type(2){display:none}.netless-app-docs-viewer-footer-btn.netless-app-docs-viewer-footer-btn-playing>svg:nth-of-type(1){display:none}.netless-app-docs-viewer-footer-btn.netless-app-docs-viewer-footer-btn-playing>svg:nth-of-type(2){display:initial}.netless-app-docs-viewer-footer-btn~.netless-app-docs-viewer-footer-btn{margin-left:15px}.netless-app-docs-viewer-page-jumps{flex:1;display:flex;justify-content:center;align-items:center}.netless-app-docs-viewer-page-number{margin-left:auto;font-size:13px;user-select:none;white-space:nowrap;word-break:keep-all}.netless-app-docs-viewer-page-number-input{border:none;outline:none;width:3em;margin:0;padding:0 2px;text-align:right;font-size:13px;line-height:1;font-weight:400;font-family:inherit;border-radius:2px;color:currentColor;background:transparent;transition:background .4s;user-select:text;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-docs-viewer-page-number-input:hover,.netless-app-docs-viewer-page-number-input:focus,.netless-app-docs-viewer-page-number-input:active{background:#fff;box-shadow:#63636333 0 2px 8px}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-footer-btn{cursor:not-allowed}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-footer-btn:hover{background:transparent}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-page-number-input{cursor:not-allowed}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-page-number-input:hover,.netless-app-docs-viewer-readonly .netless-app-docs-viewer-page-number-input:focus,.netless-app-docs-viewer-readonly .netless-app-docs-viewer-page-number-input:active{background:transparent;box-shadow:none}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-page-number-input:disabled{color:inherit}.netless-app-docs-viewer-readonly.netless-app-docs-viewer-float-footer{display:none}.telebox-color-scheme-dark .netless-app-docs-viewer-page-number-input{color:#a6a6a8}.telebox-color-scheme-dark .netless-app-docs-viewer-page-number-input:active,.telebox-color-scheme-dark .netless-app-docs-viewer-page-number-input:focus,.telebox-color-scheme-dark .netless-app-docs-viewer-page-number-input:hover{color:#222}.telebox-color-scheme-dark .netless-app-docs-viewer-footer{color:#a6a6a8;background:#2d2d33;border-top:none}.telebox-color-scheme-dark .netless-app-docs-viewer-footer-btn:hover{background:#212126}.telebox-color-scheme-dark .netless-app-docs-viewer-preview{background:rgba(50,50,50,.9)}.netless-app-docs-viewer-static-scrollbar{position:absolute;top:0;right:0;z-index:2147483647;width:8px;min-height:30px;margin:0;padding:0;border:none;outline:none;border-radius:4px;background:rgba(68,78,96,.4);box-shadow:1px 1px 8px #ffffffb3;opacity:0;transition:background .4s,opacity .4s 3s,transform .2s;user-select:none}.netless-app-docs-viewer-static-scrollbar.netless-app-docs-viewer-static-scrollbar-dragging{background:rgba(68,78,96,.6);opacity:1;transition:background .4s,opacity .4s 3s!important}.netless-app-docs-viewer-static-scrollbar:hover,.netless-app-docs-viewer-static-scrollbar:focus{background:rgba(68,78,96,.5)}.netless-app-docs-viewer-static-scrollbar:active{background:rgba(68,78,96,.6)}.netless-app-docs-viewer-content:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-static-scrollbar{display:none}.netless-app-docs-viewer-static-pages:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.page-renderer-pages-container{position:relative;overflow:hidden}.page-renderer-page{position:absolute;top:0;left:0;background-position:center;background-size:cover;background-repeat:no-repeat}.page-renderer-pages-container.is-hwa .page-renderer-page{will-change:transform}.page-renderer-page-img{display:block;width:100%;height:auto;user-select:none}.netless-app-docs-viewer-static-pages{overflow:hidden;position:relative;height:100%;user-select:none}.netless-app-docs-viewer-static-page{display:block;width:100%;height:auto;user-select:none}.netless-app-docs-viewer-static-wb-view,.netless-app-docs-viewer-dynamic-wb-view{position:absolute;top:0;left:0;width:100%;height:100%;z-index:100;overflow:hidden}.netless-app-docs-viewer-dynamic-wb-view .cursor-clicker .ppt-event-source{cursor:pointer}\n";
2
+ const copyProperty = (to, from, property, ignoreNonConfigurable) => {
3
+ if (property === "length" || property === "prototype") {
4
+ return;
5
+ }
6
+ if (property === "arguments" || property === "caller") {
7
+ return;
8
+ }
9
+ const toDescriptor = Object.getOwnPropertyDescriptor(to, property);
10
+ const fromDescriptor = Object.getOwnPropertyDescriptor(from, property);
11
+ if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) {
12
+ return;
13
+ }
14
+ Object.defineProperty(to, property, fromDescriptor);
15
+ };
16
+ const canCopyProperty = function(toDescriptor, fromDescriptor) {
17
+ return toDescriptor === void 0 || toDescriptor.configurable || toDescriptor.writable === fromDescriptor.writable && toDescriptor.enumerable === fromDescriptor.enumerable && toDescriptor.configurable === fromDescriptor.configurable && (toDescriptor.writable || toDescriptor.value === fromDescriptor.value);
18
+ };
19
+ const changePrototype = (to, from) => {
20
+ const fromPrototype = Object.getPrototypeOf(from);
21
+ if (fromPrototype === Object.getPrototypeOf(to)) {
22
+ return;
23
+ }
24
+ Object.setPrototypeOf(to, fromPrototype);
25
+ };
26
+ const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/
27
+ ${fromBody}`;
28
+ const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, "toString");
29
+ const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, "name");
30
+ const changeToString = (to, from, name) => {
31
+ const withName = name === "" ? "" : `with ${name.trim()}() `;
32
+ const newToString = wrappedToString.bind(null, withName, from.toString());
33
+ Object.defineProperty(newToString, "name", toStringName);
34
+ Object.defineProperty(to, "toString", { ...toStringDescriptor, value: newToString });
35
+ };
36
+ function mimicFunction(to, from, { ignoreNonConfigurable = false } = {}) {
37
+ const { name } = to;
38
+ for (const property of Reflect.ownKeys(from)) {
39
+ copyProperty(to, from, property, ignoreNonConfigurable);
40
+ }
41
+ changePrototype(to, from);
42
+ changeToString(to, from, name);
43
+ return to;
44
+ }
45
+ const debounceFn = (inputFunction, options = {}) => {
46
+ if (typeof inputFunction !== "function") {
47
+ throw new TypeError(`Expected the first argument to be a function, got \`${typeof inputFunction}\``);
48
+ }
49
+ const {
50
+ wait = 0,
51
+ maxWait = Number.POSITIVE_INFINITY,
52
+ before = false,
53
+ after = true
54
+ } = options;
55
+ if (!before && !after) {
56
+ throw new Error("Both `before` and `after` are false, function wouldn't be called.");
57
+ }
58
+ let timeout;
59
+ let maxTimeout;
60
+ let result;
61
+ const debouncedFunction = function(...arguments_) {
62
+ const context = this;
63
+ const later = () => {
64
+ timeout = void 0;
65
+ if (maxTimeout) {
66
+ clearTimeout(maxTimeout);
67
+ maxTimeout = void 0;
68
+ }
69
+ if (after) {
70
+ result = inputFunction.apply(context, arguments_);
71
+ }
72
+ };
73
+ const maxLater = () => {
74
+ maxTimeout = void 0;
75
+ if (timeout) {
76
+ clearTimeout(timeout);
77
+ timeout = void 0;
78
+ }
79
+ if (after) {
80
+ result = inputFunction.apply(context, arguments_);
81
+ }
82
+ };
83
+ const shouldCallNow = before && !timeout;
84
+ clearTimeout(timeout);
85
+ timeout = setTimeout(later, wait);
86
+ if (maxWait > 0 && maxWait !== Number.POSITIVE_INFINITY && !maxTimeout) {
87
+ maxTimeout = setTimeout(maxLater, maxWait);
88
+ }
89
+ if (shouldCallNow) {
90
+ result = inputFunction.apply(context, arguments_);
91
+ }
92
+ return result;
93
+ };
94
+ mimicFunction(debouncedFunction, inputFunction);
95
+ debouncedFunction.cancel = () => {
96
+ if (timeout) {
97
+ clearTimeout(timeout);
98
+ timeout = void 0;
99
+ }
100
+ if (maxTimeout) {
101
+ clearTimeout(maxTimeout);
102
+ maxTimeout = void 0;
103
+ }
104
+ };
105
+ return debouncedFunction;
106
+ };
107
+ var SOUP = "!#%()*+,-./:;=?@[]^_`{|}~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
108
+ var SOUP_LEN = 87;
109
+ var ID_LEN = 20;
110
+ var reusedIdCarrier = [];
111
+ var genUID = () => {
112
+ for (let i = 0; i < ID_LEN; i++) {
113
+ reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);
114
+ }
115
+ return reusedIdCarrier.join("");
116
+ };
117
+ function invoke(fn) {
118
+ try {
119
+ return fn();
120
+ } catch (e) {
121
+ console.error(e);
122
+ }
123
+ }
124
+ var SideEffectManager = class {
125
+ constructor() {
126
+ this.push = this.addDisposer;
127
+ this.disposers = /* @__PURE__ */ new Map();
128
+ }
129
+ addDisposer(disposer, disposerID = this.genUID()) {
130
+ this.flush(disposerID);
131
+ this.disposers.set(
132
+ disposerID,
133
+ Array.isArray(disposer) ? joinDisposers(disposer) : disposer
134
+ );
135
+ return disposerID;
136
+ }
137
+ add(executor, disposerID = this.genUID()) {
138
+ const disposers = executor();
139
+ return disposers ? this.addDisposer(disposers, disposerID) : disposerID;
140
+ }
141
+ addEventListener(el, type, listener, options, disposerID = this.genUID()) {
142
+ el.addEventListener(type, listener, options);
143
+ this.addDisposer(
144
+ () => el.removeEventListener(type, listener, options),
145
+ disposerID
146
+ );
147
+ return disposerID;
148
+ }
149
+ setTimeout(handler, timeout, disposerID = this.genUID()) {
150
+ const ticket = window.setTimeout(() => {
151
+ this.remove(disposerID);
152
+ handler();
153
+ }, timeout);
154
+ return this.addDisposer(() => window.clearTimeout(ticket), disposerID);
155
+ }
156
+ setInterval(handler, timeout, disposerID = this.genUID()) {
157
+ const ticket = window.setInterval(handler, timeout);
158
+ return this.addDisposer(() => window.clearInterval(ticket), disposerID);
159
+ }
160
+ remove(disposerID) {
161
+ const disposer = this.disposers.get(disposerID);
162
+ this.disposers.delete(disposerID);
163
+ return disposer;
164
+ }
165
+ flush(disposerID) {
166
+ const disposer = this.remove(disposerID);
167
+ if (disposer) {
168
+ disposer();
169
+ }
170
+ }
171
+ flushAll() {
172
+ this.disposers.forEach(invoke);
173
+ this.disposers.clear();
174
+ }
175
+ genUID() {
176
+ let uid;
177
+ do {
178
+ uid = genUID();
179
+ } while (this.disposers.has(uid));
180
+ return uid;
181
+ }
182
+ };
183
+ function joinDisposers(disposers) {
184
+ return () => disposers.forEach(invoke);
185
+ }
186
+ var resizeObservers = [];
187
+ var hasActiveObservations = function() {
188
+ return resizeObservers.some(function(ro) {
189
+ return ro.activeTargets.length > 0;
190
+ });
191
+ };
192
+ var hasSkippedObservations = function() {
193
+ return resizeObservers.some(function(ro) {
194
+ return ro.skippedTargets.length > 0;
195
+ });
196
+ };
197
+ var msg = "ResizeObserver loop completed with undelivered notifications.";
198
+ var deliverResizeLoopError = function() {
199
+ var event;
200
+ if (typeof ErrorEvent === "function") {
201
+ event = new ErrorEvent("error", {
202
+ message: msg
203
+ });
204
+ } else {
205
+ event = document.createEvent("Event");
206
+ event.initEvent("error", false, false);
207
+ event.message = msg;
208
+ }
209
+ window.dispatchEvent(event);
210
+ };
211
+ var ResizeObserverBoxOptions;
212
+ (function(ResizeObserverBoxOptions2) {
213
+ ResizeObserverBoxOptions2["BORDER_BOX"] = "border-box";
214
+ ResizeObserverBoxOptions2["CONTENT_BOX"] = "content-box";
215
+ ResizeObserverBoxOptions2["DEVICE_PIXEL_CONTENT_BOX"] = "device-pixel-content-box";
216
+ })(ResizeObserverBoxOptions || (ResizeObserverBoxOptions = {}));
217
+ var freeze = function(obj) {
218
+ return Object.freeze(obj);
219
+ };
220
+ var ResizeObserverSize = function() {
221
+ function ResizeObserverSize2(inlineSize, blockSize) {
222
+ this.inlineSize = inlineSize;
223
+ this.blockSize = blockSize;
224
+ freeze(this);
225
+ }
226
+ return ResizeObserverSize2;
227
+ }();
228
+ var DOMRectReadOnly = function() {
229
+ function DOMRectReadOnly2(x, y, width, height) {
230
+ this.x = x;
231
+ this.y = y;
232
+ this.width = width;
233
+ this.height = height;
234
+ this.top = this.y;
235
+ this.left = this.x;
236
+ this.bottom = this.top + this.height;
237
+ this.right = this.left + this.width;
238
+ return freeze(this);
239
+ }
240
+ DOMRectReadOnly2.prototype.toJSON = function() {
241
+ var _a = this, x = _a.x, y = _a.y, top = _a.top, right = _a.right, bottom = _a.bottom, left = _a.left, width = _a.width, height = _a.height;
242
+ return { x, y, top, right, bottom, left, width, height };
243
+ };
244
+ DOMRectReadOnly2.fromRect = function(rectangle) {
245
+ return new DOMRectReadOnly2(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
246
+ };
247
+ return DOMRectReadOnly2;
248
+ }();
249
+ var isSVG = function(target) {
250
+ return target instanceof SVGElement && "getBBox" in target;
251
+ };
252
+ var isHidden = function(target) {
253
+ if (isSVG(target)) {
254
+ var _a = target.getBBox(), width = _a.width, height = _a.height;
255
+ return !width && !height;
256
+ }
257
+ var _b = target, offsetWidth = _b.offsetWidth, offsetHeight = _b.offsetHeight;
258
+ return !(offsetWidth || offsetHeight || target.getClientRects().length);
259
+ };
260
+ var isElement = function(obj) {
261
+ var _a;
262
+ if (obj instanceof Element) {
263
+ return true;
264
+ }
265
+ var scope = (_a = obj === null || obj === void 0 ? void 0 : obj.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView;
266
+ return !!(scope && obj instanceof scope.Element);
267
+ };
268
+ var isReplacedElement = function(target) {
269
+ switch (target.tagName) {
270
+ case "INPUT":
271
+ if (target.type !== "image") {
272
+ break;
273
+ }
274
+ case "VIDEO":
275
+ case "AUDIO":
276
+ case "EMBED":
277
+ case "OBJECT":
278
+ case "CANVAS":
279
+ case "IFRAME":
280
+ case "IMG":
281
+ return true;
282
+ }
283
+ return false;
284
+ };
285
+ var global = typeof window !== "undefined" ? window : {};
286
+ var cache = /* @__PURE__ */ new WeakMap();
287
+ var scrollRegexp = /auto|scroll/;
288
+ var verticalRegexp = /^tb|vertical/;
289
+ var IE = /msie|trident/i.test(global.navigator && global.navigator.userAgent);
290
+ var parseDimension = function(pixel) {
291
+ return parseFloat(pixel || "0");
292
+ };
293
+ var size = function(inlineSize, blockSize, switchSizes) {
294
+ if (inlineSize === void 0) {
295
+ inlineSize = 0;
296
+ }
297
+ if (blockSize === void 0) {
298
+ blockSize = 0;
299
+ }
300
+ if (switchSizes === void 0) {
301
+ switchSizes = false;
302
+ }
303
+ return new ResizeObserverSize((switchSizes ? blockSize : inlineSize) || 0, (switchSizes ? inlineSize : blockSize) || 0);
304
+ };
305
+ var zeroBoxes = freeze({
306
+ devicePixelContentBoxSize: size(),
307
+ borderBoxSize: size(),
308
+ contentBoxSize: size(),
309
+ contentRect: new DOMRectReadOnly(0, 0, 0, 0)
310
+ });
311
+ var calculateBoxSizes = function(target, forceRecalculation) {
312
+ if (forceRecalculation === void 0) {
313
+ forceRecalculation = false;
314
+ }
315
+ if (cache.has(target) && !forceRecalculation) {
316
+ return cache.get(target);
317
+ }
318
+ if (isHidden(target)) {
319
+ cache.set(target, zeroBoxes);
320
+ return zeroBoxes;
321
+ }
322
+ var cs = getComputedStyle(target);
323
+ var svg = isSVG(target) && target.ownerSVGElement && target.getBBox();
324
+ var removePadding = !IE && cs.boxSizing === "border-box";
325
+ var switchSizes = verticalRegexp.test(cs.writingMode || "");
326
+ var canScrollVertically = !svg && scrollRegexp.test(cs.overflowY || "");
327
+ var canScrollHorizontally = !svg && scrollRegexp.test(cs.overflowX || "");
328
+ var paddingTop = svg ? 0 : parseDimension(cs.paddingTop);
329
+ var paddingRight = svg ? 0 : parseDimension(cs.paddingRight);
330
+ var paddingBottom = svg ? 0 : parseDimension(cs.paddingBottom);
331
+ var paddingLeft = svg ? 0 : parseDimension(cs.paddingLeft);
332
+ var borderTop = svg ? 0 : parseDimension(cs.borderTopWidth);
333
+ var borderRight = svg ? 0 : parseDimension(cs.borderRightWidth);
334
+ var borderBottom = svg ? 0 : parseDimension(cs.borderBottomWidth);
335
+ var borderLeft = svg ? 0 : parseDimension(cs.borderLeftWidth);
336
+ var horizontalPadding = paddingLeft + paddingRight;
337
+ var verticalPadding = paddingTop + paddingBottom;
338
+ var horizontalBorderArea = borderLeft + borderRight;
339
+ var verticalBorderArea = borderTop + borderBottom;
340
+ var horizontalScrollbarThickness = !canScrollHorizontally ? 0 : target.offsetHeight - verticalBorderArea - target.clientHeight;
341
+ var verticalScrollbarThickness = !canScrollVertically ? 0 : target.offsetWidth - horizontalBorderArea - target.clientWidth;
342
+ var widthReduction = removePadding ? horizontalPadding + horizontalBorderArea : 0;
343
+ var heightReduction = removePadding ? verticalPadding + verticalBorderArea : 0;
344
+ var contentWidth = svg ? svg.width : parseDimension(cs.width) - widthReduction - verticalScrollbarThickness;
345
+ var contentHeight = svg ? svg.height : parseDimension(cs.height) - heightReduction - horizontalScrollbarThickness;
346
+ var borderBoxWidth = contentWidth + horizontalPadding + verticalScrollbarThickness + horizontalBorderArea;
347
+ var borderBoxHeight = contentHeight + verticalPadding + horizontalScrollbarThickness + verticalBorderArea;
348
+ var boxes = freeze({
349
+ devicePixelContentBoxSize: size(Math.round(contentWidth * devicePixelRatio), Math.round(contentHeight * devicePixelRatio), switchSizes),
350
+ borderBoxSize: size(borderBoxWidth, borderBoxHeight, switchSizes),
351
+ contentBoxSize: size(contentWidth, contentHeight, switchSizes),
352
+ contentRect: new DOMRectReadOnly(paddingLeft, paddingTop, contentWidth, contentHeight)
353
+ });
354
+ cache.set(target, boxes);
355
+ return boxes;
356
+ };
357
+ var calculateBoxSize = function(target, observedBox, forceRecalculation) {
358
+ var _a = calculateBoxSizes(target, forceRecalculation), borderBoxSize = _a.borderBoxSize, contentBoxSize = _a.contentBoxSize, devicePixelContentBoxSize = _a.devicePixelContentBoxSize;
359
+ switch (observedBox) {
360
+ case ResizeObserverBoxOptions.DEVICE_PIXEL_CONTENT_BOX:
361
+ return devicePixelContentBoxSize;
362
+ case ResizeObserverBoxOptions.BORDER_BOX:
363
+ return borderBoxSize;
364
+ default:
365
+ return contentBoxSize;
366
+ }
367
+ };
368
+ var ResizeObserverEntry = function() {
369
+ function ResizeObserverEntry2(target) {
370
+ var boxes = calculateBoxSizes(target);
371
+ this.target = target;
372
+ this.contentRect = boxes.contentRect;
373
+ this.borderBoxSize = freeze([boxes.borderBoxSize]);
374
+ this.contentBoxSize = freeze([boxes.contentBoxSize]);
375
+ this.devicePixelContentBoxSize = freeze([boxes.devicePixelContentBoxSize]);
376
+ }
377
+ return ResizeObserverEntry2;
378
+ }();
379
+ var calculateDepthForNode = function(node) {
380
+ if (isHidden(node)) {
381
+ return Infinity;
382
+ }
383
+ var depth = 0;
384
+ var parent = node.parentNode;
385
+ while (parent) {
386
+ depth += 1;
387
+ parent = parent.parentNode;
388
+ }
389
+ return depth;
390
+ };
391
+ var broadcastActiveObservations = function() {
392
+ var shallowestDepth = Infinity;
393
+ var callbacks2 = [];
394
+ resizeObservers.forEach(function processObserver(ro) {
395
+ if (ro.activeTargets.length === 0) {
396
+ return;
397
+ }
398
+ var entries = [];
399
+ ro.activeTargets.forEach(function processTarget(ot) {
400
+ var entry = new ResizeObserverEntry(ot.target);
401
+ var targetDepth = calculateDepthForNode(ot.target);
402
+ entries.push(entry);
403
+ ot.lastReportedSize = calculateBoxSize(ot.target, ot.observedBox);
404
+ if (targetDepth < shallowestDepth) {
405
+ shallowestDepth = targetDepth;
406
+ }
407
+ });
408
+ callbacks2.push(function resizeObserverCallback() {
409
+ ro.callback.call(ro.observer, entries, ro.observer);
410
+ });
411
+ ro.activeTargets.splice(0, ro.activeTargets.length);
412
+ });
413
+ for (var _i = 0, callbacks_1 = callbacks2; _i < callbacks_1.length; _i++) {
414
+ var callback = callbacks_1[_i];
415
+ callback();
416
+ }
417
+ return shallowestDepth;
418
+ };
419
+ var gatherActiveObservationsAtDepth = function(depth) {
420
+ resizeObservers.forEach(function processObserver(ro) {
421
+ ro.activeTargets.splice(0, ro.activeTargets.length);
422
+ ro.skippedTargets.splice(0, ro.skippedTargets.length);
423
+ ro.observationTargets.forEach(function processTarget(ot) {
424
+ if (ot.isActive()) {
425
+ if (calculateDepthForNode(ot.target) > depth) {
426
+ ro.activeTargets.push(ot);
427
+ } else {
428
+ ro.skippedTargets.push(ot);
429
+ }
430
+ }
431
+ });
432
+ });
433
+ };
434
+ var process = function() {
435
+ var depth = 0;
436
+ gatherActiveObservationsAtDepth(depth);
437
+ while (hasActiveObservations()) {
438
+ depth = broadcastActiveObservations();
439
+ gatherActiveObservationsAtDepth(depth);
440
+ }
441
+ if (hasSkippedObservations()) {
442
+ deliverResizeLoopError();
443
+ }
444
+ return depth > 0;
445
+ };
446
+ var trigger;
447
+ var callbacks = [];
448
+ var notify = function() {
449
+ return callbacks.splice(0).forEach(function(cb) {
450
+ return cb();
451
+ });
452
+ };
453
+ var queueMicroTask = function(callback) {
454
+ if (!trigger) {
455
+ var toggle_1 = 0;
456
+ var el_1 = document.createTextNode("");
457
+ var config = { characterData: true };
458
+ new MutationObserver(function() {
459
+ return notify();
460
+ }).observe(el_1, config);
461
+ trigger = function() {
462
+ el_1.textContent = "".concat(toggle_1 ? toggle_1-- : toggle_1++);
463
+ };
464
+ }
465
+ callbacks.push(callback);
466
+ trigger();
467
+ };
468
+ var queueResizeObserver = function(cb) {
469
+ queueMicroTask(function ResizeObserver2() {
470
+ requestAnimationFrame(cb);
471
+ });
472
+ };
473
+ var watching = 0;
474
+ var isWatching = function() {
475
+ return !!watching;
476
+ };
477
+ var CATCH_PERIOD = 250;
478
+ var observerConfig = { attributes: true, characterData: true, childList: true, subtree: true };
479
+ var events = [
480
+ "resize",
481
+ "load",
482
+ "transitionend",
483
+ "animationend",
484
+ "animationstart",
485
+ "animationiteration",
486
+ "keyup",
487
+ "keydown",
488
+ "mouseup",
489
+ "mousedown",
490
+ "mouseover",
491
+ "mouseout",
492
+ "blur",
493
+ "focus"
494
+ ];
495
+ var time = function(timeout) {
496
+ if (timeout === void 0) {
497
+ timeout = 0;
498
+ }
499
+ return Date.now() + timeout;
500
+ };
501
+ var scheduled = false;
502
+ var Scheduler = function() {
503
+ function Scheduler2() {
504
+ var _this = this;
505
+ this.stopped = true;
506
+ this.listener = function() {
507
+ return _this.schedule();
508
+ };
509
+ }
510
+ Scheduler2.prototype.run = function(timeout) {
511
+ var _this = this;
512
+ if (timeout === void 0) {
513
+ timeout = CATCH_PERIOD;
514
+ }
515
+ if (scheduled) {
516
+ return;
517
+ }
518
+ scheduled = true;
519
+ var until = time(timeout);
520
+ queueResizeObserver(function() {
521
+ var elementsHaveResized = false;
522
+ try {
523
+ elementsHaveResized = process();
524
+ } finally {
525
+ scheduled = false;
526
+ timeout = until - time();
527
+ if (!isWatching()) {
528
+ return;
529
+ }
530
+ if (elementsHaveResized) {
531
+ _this.run(1e3);
532
+ } else if (timeout > 0) {
533
+ _this.run(timeout);
534
+ } else {
535
+ _this.start();
536
+ }
537
+ }
538
+ });
539
+ };
540
+ Scheduler2.prototype.schedule = function() {
541
+ this.stop();
542
+ this.run();
543
+ };
544
+ Scheduler2.prototype.observe = function() {
545
+ var _this = this;
546
+ var cb = function() {
547
+ return _this.observer && _this.observer.observe(document.body, observerConfig);
548
+ };
549
+ document.body ? cb() : global.addEventListener("DOMContentLoaded", cb);
550
+ };
551
+ Scheduler2.prototype.start = function() {
552
+ var _this = this;
553
+ if (this.stopped) {
554
+ this.stopped = false;
555
+ this.observer = new MutationObserver(this.listener);
556
+ this.observe();
557
+ events.forEach(function(name) {
558
+ return global.addEventListener(name, _this.listener, true);
559
+ });
560
+ }
561
+ };
562
+ Scheduler2.prototype.stop = function() {
563
+ var _this = this;
564
+ if (!this.stopped) {
565
+ this.observer && this.observer.disconnect();
566
+ events.forEach(function(name) {
567
+ return global.removeEventListener(name, _this.listener, true);
568
+ });
569
+ this.stopped = true;
570
+ }
571
+ };
572
+ return Scheduler2;
573
+ }();
574
+ var scheduler = new Scheduler();
575
+ var updateCount = function(n) {
576
+ !watching && n > 0 && scheduler.start();
577
+ watching += n;
578
+ !watching && scheduler.stop();
579
+ };
580
+ var skipNotifyOnElement = function(target) {
581
+ return !isSVG(target) && !isReplacedElement(target) && getComputedStyle(target).display === "inline";
582
+ };
583
+ var ResizeObservation = function() {
584
+ function ResizeObservation2(target, observedBox) {
585
+ this.target = target;
586
+ this.observedBox = observedBox || ResizeObserverBoxOptions.CONTENT_BOX;
587
+ this.lastReportedSize = {
588
+ inlineSize: 0,
589
+ blockSize: 0
590
+ };
591
+ }
592
+ ResizeObservation2.prototype.isActive = function() {
593
+ var size2 = calculateBoxSize(this.target, this.observedBox, true);
594
+ if (skipNotifyOnElement(this.target)) {
595
+ this.lastReportedSize = size2;
596
+ }
597
+ if (this.lastReportedSize.inlineSize !== size2.inlineSize || this.lastReportedSize.blockSize !== size2.blockSize) {
598
+ return true;
599
+ }
600
+ return false;
601
+ };
602
+ return ResizeObservation2;
603
+ }();
604
+ var ResizeObserverDetail = function() {
605
+ function ResizeObserverDetail2(resizeObserver, callback) {
606
+ this.activeTargets = [];
607
+ this.skippedTargets = [];
608
+ this.observationTargets = [];
609
+ this.observer = resizeObserver;
610
+ this.callback = callback;
611
+ }
612
+ return ResizeObserverDetail2;
613
+ }();
614
+ var observerMap = /* @__PURE__ */ new WeakMap();
615
+ var getObservationIndex = function(observationTargets, target) {
616
+ for (var i = 0; i < observationTargets.length; i += 1) {
617
+ if (observationTargets[i].target === target) {
618
+ return i;
619
+ }
620
+ }
621
+ return -1;
622
+ };
623
+ var ResizeObserverController = function() {
624
+ function ResizeObserverController2() {
625
+ }
626
+ ResizeObserverController2.connect = function(resizeObserver, callback) {
627
+ var detail = new ResizeObserverDetail(resizeObserver, callback);
628
+ observerMap.set(resizeObserver, detail);
629
+ };
630
+ ResizeObserverController2.observe = function(resizeObserver, target, options) {
631
+ var detail = observerMap.get(resizeObserver);
632
+ var firstObservation = detail.observationTargets.length === 0;
633
+ if (getObservationIndex(detail.observationTargets, target) < 0) {
634
+ firstObservation && resizeObservers.push(detail);
635
+ detail.observationTargets.push(new ResizeObservation(target, options && options.box));
636
+ updateCount(1);
637
+ scheduler.schedule();
638
+ }
639
+ };
640
+ ResizeObserverController2.unobserve = function(resizeObserver, target) {
641
+ var detail = observerMap.get(resizeObserver);
642
+ var index = getObservationIndex(detail.observationTargets, target);
643
+ var lastObservation = detail.observationTargets.length === 1;
644
+ if (index >= 0) {
645
+ lastObservation && resizeObservers.splice(resizeObservers.indexOf(detail), 1);
646
+ detail.observationTargets.splice(index, 1);
647
+ updateCount(-1);
648
+ }
649
+ };
650
+ ResizeObserverController2.disconnect = function(resizeObserver) {
651
+ var _this = this;
652
+ var detail = observerMap.get(resizeObserver);
653
+ detail.observationTargets.slice().forEach(function(ot) {
654
+ return _this.unobserve(resizeObserver, ot.target);
655
+ });
656
+ detail.activeTargets.splice(0, detail.activeTargets.length);
657
+ };
658
+ return ResizeObserverController2;
659
+ }();
660
+ var ResizeObserver$1 = function() {
661
+ function ResizeObserver2(callback) {
662
+ if (arguments.length === 0) {
663
+ throw new TypeError("Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.");
664
+ }
665
+ if (typeof callback !== "function") {
666
+ throw new TypeError("Failed to construct 'ResizeObserver': The callback provided as parameter 1 is not a function.");
667
+ }
668
+ ResizeObserverController.connect(this, callback);
669
+ }
670
+ ResizeObserver2.prototype.observe = function(target, options) {
671
+ if (arguments.length === 0) {
672
+ throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': 1 argument required, but only 0 present.");
673
+ }
674
+ if (!isElement(target)) {
675
+ throw new TypeError("Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element");
676
+ }
677
+ ResizeObserverController.observe(this, target, options);
678
+ };
679
+ ResizeObserver2.prototype.unobserve = function(target) {
680
+ if (arguments.length === 0) {
681
+ throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': 1 argument required, but only 0 present.");
682
+ }
683
+ if (!isElement(target)) {
684
+ throw new TypeError("Failed to execute 'unobserve' on 'ResizeObserver': parameter 1 is not of type 'Element");
685
+ }
686
+ ResizeObserverController.unobserve(this, target);
687
+ };
688
+ ResizeObserver2.prototype.disconnect = function() {
689
+ ResizeObserverController.disconnect(this);
690
+ };
691
+ ResizeObserver2.toString = function() {
692
+ return "function ResizeObserver () { [polyfill code] }";
693
+ };
694
+ return ResizeObserver2;
695
+ }();
696
+ function sidebarSVG(namespace) {
697
+ const NS = "http://www.w3.org/2000/svg";
698
+ const $svg = document.createElementNS(NS, "svg");
699
+ $svg.setAttribute("class", `${namespace}-footer-icon-sidebar`);
700
+ $svg.setAttribute("viewBox", "0 0 64 64");
701
+ const $path = document.createElementNS(NS, "path");
702
+ $path.setAttribute("fill", "currentColor");
703
+ $path.setAttribute(
704
+ "d",
705
+ "M50 8H14c-3.309 0-6 2.691-6 6v36c0 3.309 2.691 6 6 6h36c3.309 0 6-2.691 6-6V14c0-3.309-2.691-6-6-6zM12 50V14c0-1.103.897-2 2-2h8v40h-8c-1.103 0-2-.897-2-2zm40 0c0 1.103-.897 2-2 2H26V12h24c1.103 0 2 .897 2 2z"
706
+ );
707
+ $svg.appendChild($path);
708
+ return $svg;
709
+ }
710
+ function arrowLeftSVG(namespace) {
711
+ const NS = "http://www.w3.org/2000/svg";
712
+ const $svg = document.createElementNS(NS, "svg");
713
+ $svg.setAttribute("class", `${namespace}-footer-icon-arrow-left`);
714
+ $svg.setAttribute("viewBox", "0 0 500 500");
715
+ const $path = document.createElementNS(NS, "path");
716
+ $path.setAttribute("fill", "currentColor");
717
+ $path.setAttribute(
718
+ "d",
719
+ "M177.81 249.959L337.473 90.295c2.722-2.865 2.651-7.378-.143-10.1-2.793-2.65-7.163-2.65-9.956 0l-164.75 164.75c-2.793 2.793-2.793 7.306 0 10.1l164.75 164.75c2.865 2.722 7.378 2.65 10.099-.143 2.651-2.794 2.651-7.163 0-9.957L177.809 249.959z"
720
+ );
721
+ $svg.appendChild($path);
722
+ return $svg;
723
+ }
724
+ function arrowRightSVG(namespace) {
725
+ const NS = "http://www.w3.org/2000/svg";
726
+ const $svg = document.createElementNS(NS, "svg");
727
+ $svg.setAttribute("class", `${namespace}-footer-icon-arrow-right`);
728
+ $svg.setAttribute("viewBox", "0 0 500 500");
729
+ const $path = document.createElementNS(NS, "path");
730
+ $path.setAttribute("fill", "currentColor");
731
+ $path.setAttribute(
732
+ "d",
733
+ "M322.19 250.041L162.527 409.705c-2.722 2.865-2.651 7.378.143 10.1 2.793 2.65 7.163 2.65 9.956 0l164.75-164.75c2.793-2.793 2.793-7.306 0-10.1l-164.75-164.75c-2.865-2.722-7.378-2.65-10.099.143-2.651 2.794-2.651 7.163 0 9.957l159.664 159.736z"
734
+ );
735
+ $svg.appendChild($path);
736
+ return $svg;
737
+ }
738
+ function playSVG(namespace) {
739
+ const NS = "http://www.w3.org/2000/svg";
740
+ const $svg = document.createElementNS(NS, "svg");
741
+ $svg.setAttribute("class", `${namespace}-footer-icon-play`);
742
+ $svg.setAttribute("viewBox", "0 0 500 500");
743
+ const $path = document.createElementNS(NS, "path");
744
+ $path.setAttribute("fill", "currentColor");
745
+ $path.setAttribute(
746
+ "d",
747
+ "M418.158 257.419L174.663 413.33c-6.017 3.919-15.708 3.772-21.291-.29-2.791-2.018-4.295-4.483-4.295-7.084V94.109c0-5.65 6.883-10.289 15.271-10.289 4.298 0 8.391 1.307 11.181 3.332l242.629 155.484c6.016 3.917 6.451 10.292.649 14.491-.216.154-.432.154-.649.292zM170.621 391.288l223.116-141.301L170.71 107.753l-.089 283.535z"
748
+ );
749
+ $svg.appendChild($path);
750
+ return $svg;
751
+ }
752
+ function pauseSVG(namespace) {
753
+ const NS = "http://www.w3.org/2000/svg";
754
+ const $svg = document.createElementNS(NS, "svg");
755
+ $svg.setAttribute("class", `${namespace}-footer-icon-pause`);
756
+ $svg.setAttribute("viewBox", "0 0 500 500");
757
+ const $path = document.createElementNS(NS, "path");
758
+ $path.setAttribute("fill", "currentColor");
759
+ $path.setAttribute(
760
+ "d",
761
+ "M312.491 78.261c0-6.159 4.893-11.213 11.04-11.213 6.158 0 11.211 5.054 11.211 11.213v343.478c0 6.159-5.053 11.213-11.211 11.213-6.147 0-11.04-5.054-11.04-11.213V78.261zM165.257 78.261c0-6.159 4.893-11.213 11.04-11.213 6.158 0 11.211 5.054 11.211 11.213v343.478c0 6.159-5.053 11.213-11.211 11.213-6.147 0-11.04-5.054-11.04-11.213V78.261z"
762
+ );
763
+ $svg.appendChild($path);
764
+ return $svg;
765
+ }
766
+ const runningOnBrowser = typeof window !== "undefined";
767
+ const isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent);
768
+ const supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
769
+ const supportsClassList = runningOnBrowser && "classList" in document.createElement("p");
770
+ const isHiDpi = runningOnBrowser && window.devicePixelRatio > 1;
771
+ const defaultSettings = {
772
+ elements_selector: ".lazy",
773
+ container: isBot || runningOnBrowser ? document : null,
774
+ threshold: 300,
775
+ thresholds: null,
776
+ data_src: "src",
777
+ data_srcset: "srcset",
778
+ data_sizes: "sizes",
779
+ data_bg: "bg",
780
+ data_bg_hidpi: "bg-hidpi",
781
+ data_bg_multi: "bg-multi",
782
+ data_bg_multi_hidpi: "bg-multi-hidpi",
783
+ data_bg_set: "bg-set",
784
+ data_poster: "poster",
785
+ class_applied: "applied",
786
+ class_loading: "loading",
787
+ class_loaded: "loaded",
788
+ class_error: "error",
789
+ class_entered: "entered",
790
+ class_exited: "exited",
791
+ unobserve_completed: true,
792
+ unobserve_entered: false,
793
+ cancel_on_exit: true,
794
+ callback_enter: null,
795
+ callback_exit: null,
796
+ callback_applied: null,
797
+ callback_loading: null,
798
+ callback_loaded: null,
799
+ callback_error: null,
800
+ callback_finish: null,
801
+ callback_cancel: null,
802
+ use_native: false,
803
+ restore_on_error: false
804
+ };
805
+ const getExtendedSettings = (customSettings) => {
806
+ return Object.assign({}, defaultSettings, customSettings);
807
+ };
808
+ const createInstance = function(classObj, options) {
809
+ let event;
810
+ const eventString = "LazyLoad::Initialized";
811
+ const instance = new classObj(options);
812
+ try {
813
+ event = new CustomEvent(eventString, { detail: { instance } });
814
+ } catch (err) {
815
+ event = document.createEvent("CustomEvent");
816
+ event.initCustomEvent(eventString, false, false, { instance });
817
+ }
818
+ window.dispatchEvent(event);
819
+ };
820
+ const autoInitialize = (classObj, options) => {
821
+ if (!options) {
822
+ return;
823
+ }
824
+ if (!options.length) {
825
+ createInstance(classObj, options);
826
+ } else {
827
+ for (let i = 0, optionsItem; optionsItem = options[i]; i += 1) {
828
+ createInstance(classObj, optionsItem);
829
+ }
830
+ }
831
+ };
832
+ const SRC = "src";
833
+ const SRCSET = "srcset";
834
+ const SIZES = "sizes";
835
+ const POSTER = "poster";
836
+ const ORIGINALS = "llOriginalAttrs";
837
+ const DATA = "data";
838
+ const statusLoading = "loading";
839
+ const statusLoaded = "loaded";
840
+ const statusApplied = "applied";
841
+ const statusEntered = "entered";
842
+ const statusError = "error";
843
+ const statusNative = "native";
844
+ const dataPrefix = "data-";
845
+ const statusDataName = "ll-status";
846
+ const getData = (element, attribute) => {
847
+ return element.getAttribute(dataPrefix + attribute);
848
+ };
849
+ const setData = (element, attribute, value) => {
850
+ const attrName = dataPrefix + attribute;
851
+ if (value === null) {
852
+ element.removeAttribute(attrName);
853
+ return;
854
+ }
855
+ element.setAttribute(attrName, value);
856
+ };
857
+ const getStatus = (element) => getData(element, statusDataName);
858
+ const setStatus = (element, status) => setData(element, statusDataName, status);
859
+ const resetStatus = (element) => setStatus(element, null);
860
+ const hasEmptyStatus = (element) => getStatus(element) === null;
861
+ const hasStatusLoading = (element) => getStatus(element) === statusLoading;
862
+ const hasStatusError = (element) => getStatus(element) === statusError;
863
+ const hasStatusNative = (element) => getStatus(element) === statusNative;
864
+ const statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError];
865
+ const hadStartedLoading = (element) => statusesAfterLoading.indexOf(getStatus(element)) >= 0;
866
+ const safeCallback = (callback, arg1, arg2, arg3) => {
867
+ if (!callback || typeof callback !== "function") {
868
+ return;
869
+ }
870
+ if (arg3 !== void 0) {
871
+ callback(arg1, arg2, arg3);
872
+ return;
873
+ }
874
+ if (arg2 !== void 0) {
875
+ callback(arg1, arg2);
876
+ return;
877
+ }
878
+ callback(arg1);
879
+ };
880
+ const addClass = (element, className) => {
881
+ if (className === "") {
882
+ return;
883
+ }
884
+ if (supportsClassList) {
885
+ element.classList.add(className);
886
+ return;
887
+ }
888
+ element.className += (element.className ? " " : "") + className;
889
+ };
890
+ const removeClass = (element, className) => {
891
+ if (className === "") {
892
+ return;
893
+ }
894
+ if (supportsClassList) {
895
+ element.classList.remove(className);
896
+ return;
897
+ }
898
+ element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "");
899
+ };
900
+ const addTempImage = (element) => {
901
+ element.llTempImage = document.createElement("IMG");
902
+ };
903
+ const deleteTempImage = (element) => {
904
+ delete element.llTempImage;
905
+ };
906
+ const getTempImage = (element) => element.llTempImage;
907
+ const unobserve = (element, instance) => {
908
+ if (!instance)
909
+ return;
910
+ const observer = instance._observer;
911
+ if (!observer)
912
+ return;
913
+ observer.unobserve(element);
914
+ };
915
+ const resetObserver = (observer) => {
916
+ observer.disconnect();
917
+ };
918
+ const unobserveEntered = (element, settings, instance) => {
919
+ if (settings.unobserve_entered)
920
+ unobserve(element, instance);
921
+ };
922
+ const updateLoadingCount = (instance, delta) => {
923
+ if (!instance)
924
+ return;
925
+ instance.loadingCount += delta;
926
+ };
927
+ const decreaseToLoadCount = (instance) => {
928
+ if (!instance)
929
+ return;
930
+ instance.toLoadCount -= 1;
931
+ };
932
+ const setToLoadCount = (instance, value) => {
933
+ if (!instance)
934
+ return;
935
+ instance.toLoadCount = value;
936
+ };
937
+ const isSomethingLoading = (instance) => instance.loadingCount > 0;
938
+ const haveElementsToLoad = (instance) => instance.toLoadCount > 0;
939
+ const getSourceTags = (parentTag) => {
940
+ let sourceTags = [];
941
+ for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) {
942
+ if (childTag.tagName === "SOURCE") {
943
+ sourceTags.push(childTag);
944
+ }
945
+ }
946
+ return sourceTags;
947
+ };
948
+ const forEachPictureSource = (element, fn) => {
949
+ const parent = element.parentNode;
950
+ if (!parent || parent.tagName !== "PICTURE") {
951
+ return;
952
+ }
953
+ let sourceTags = getSourceTags(parent);
954
+ sourceTags.forEach(fn);
955
+ };
956
+ const forEachVideoSource = (element, fn) => {
957
+ let sourceTags = getSourceTags(element);
958
+ sourceTags.forEach(fn);
959
+ };
960
+ const attrsSrc = [SRC];
961
+ const attrsSrcPoster = [SRC, POSTER];
962
+ const attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES];
963
+ const attrsData = [DATA];
964
+ const hasOriginalAttrs = (element) => !!element[ORIGINALS];
965
+ const getOriginalAttrs = (element) => element[ORIGINALS];
966
+ const deleteOriginalAttrs = (element) => delete element[ORIGINALS];
967
+ const setOriginalsObject = (element, attributes) => {
968
+ if (hasOriginalAttrs(element)) {
969
+ return;
970
+ }
971
+ const originals = {};
972
+ attributes.forEach((attribute) => {
973
+ originals[attribute] = element.getAttribute(attribute);
974
+ });
975
+ element[ORIGINALS] = originals;
976
+ };
977
+ const saveOriginalBackgroundStyle = (element) => {
978
+ if (hasOriginalAttrs(element)) {
979
+ return;
980
+ }
981
+ element[ORIGINALS] = { backgroundImage: element.style.backgroundImage };
982
+ };
983
+ const setOrResetAttribute = (element, attrName, value) => {
984
+ if (!value) {
985
+ element.removeAttribute(attrName);
986
+ return;
987
+ }
988
+ element.setAttribute(attrName, value);
989
+ };
990
+ const restoreOriginalAttrs = (element, attributes) => {
991
+ if (!hasOriginalAttrs(element)) {
992
+ return;
993
+ }
994
+ const originals = getOriginalAttrs(element);
995
+ attributes.forEach((attribute) => {
996
+ setOrResetAttribute(element, attribute, originals[attribute]);
997
+ });
998
+ };
999
+ const restoreOriginalBgImage = (element) => {
1000
+ if (!hasOriginalAttrs(element)) {
1001
+ return;
1002
+ }
1003
+ const originals = getOriginalAttrs(element);
1004
+ element.style.backgroundImage = originals.backgroundImage;
1005
+ };
1006
+ const manageApplied = (element, settings, instance) => {
1007
+ addClass(element, settings.class_applied);
1008
+ setStatus(element, statusApplied);
1009
+ if (!instance)
1010
+ return;
1011
+ if (settings.unobserve_completed) {
1012
+ unobserve(element, settings);
1013
+ }
1014
+ safeCallback(settings.callback_applied, element, instance);
1015
+ };
1016
+ const manageLoading = (element, settings, instance) => {
1017
+ addClass(element, settings.class_loading);
1018
+ setStatus(element, statusLoading);
1019
+ if (!instance)
1020
+ return;
1021
+ updateLoadingCount(instance, 1);
1022
+ safeCallback(settings.callback_loading, element, instance);
1023
+ };
1024
+ const setAttributeIfValue = (element, attrName, value) => {
1025
+ if (!value) {
1026
+ return;
1027
+ }
1028
+ element.setAttribute(attrName, value);
1029
+ };
1030
+ const setImageAttributes = (element, settings) => {
1031
+ setAttributeIfValue(element, SIZES, getData(element, settings.data_sizes));
1032
+ setAttributeIfValue(element, SRCSET, getData(element, settings.data_srcset));
1033
+ setAttributeIfValue(element, SRC, getData(element, settings.data_src));
1034
+ };
1035
+ const setSourcesImg = (imgEl, settings) => {
1036
+ forEachPictureSource(imgEl, (sourceTag) => {
1037
+ setOriginalsObject(sourceTag, attrsSrcSrcsetSizes);
1038
+ setImageAttributes(sourceTag, settings);
1039
+ });
1040
+ setOriginalsObject(imgEl, attrsSrcSrcsetSizes);
1041
+ setImageAttributes(imgEl, settings);
1042
+ };
1043
+ const setSourcesIframe = (iframe, settings) => {
1044
+ setOriginalsObject(iframe, attrsSrc);
1045
+ setAttributeIfValue(iframe, SRC, getData(iframe, settings.data_src));
1046
+ };
1047
+ const setSourcesVideo = (videoEl, settings) => {
1048
+ forEachVideoSource(videoEl, (sourceEl) => {
1049
+ setOriginalsObject(sourceEl, attrsSrc);
1050
+ setAttributeIfValue(sourceEl, SRC, getData(sourceEl, settings.data_src));
1051
+ });
1052
+ setOriginalsObject(videoEl, attrsSrcPoster);
1053
+ setAttributeIfValue(videoEl, POSTER, getData(videoEl, settings.data_poster));
1054
+ setAttributeIfValue(videoEl, SRC, getData(videoEl, settings.data_src));
1055
+ videoEl.load();
1056
+ };
1057
+ const setSourcesObject = (object, settings) => {
1058
+ setOriginalsObject(object, attrsData);
1059
+ setAttributeIfValue(object, DATA, getData(object, settings.data_src));
1060
+ };
1061
+ const setBackground = (element, settings, instance) => {
1062
+ const bg1xValue = getData(element, settings.data_bg);
1063
+ const bgHiDpiValue = getData(element, settings.data_bg_hidpi);
1064
+ const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
1065
+ if (!bgDataValue)
1066
+ return;
1067
+ element.style.backgroundImage = `url("${bgDataValue}")`;
1068
+ getTempImage(element).setAttribute(SRC, bgDataValue);
1069
+ manageLoading(element, settings, instance);
1070
+ };
1071
+ const setMultiBackground = (element, settings, instance) => {
1072
+ const bg1xValue = getData(element, settings.data_bg_multi);
1073
+ const bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi);
1074
+ const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
1075
+ if (!bgDataValue) {
1076
+ return;
1077
+ }
1078
+ element.style.backgroundImage = bgDataValue;
1079
+ manageApplied(element, settings, instance);
1080
+ };
1081
+ const setImgsetBackground = (element, settings, instance) => {
1082
+ const bgImgSetDataValue = getData(element, settings.data_bg_set);
1083
+ if (!bgImgSetDataValue) {
1084
+ return;
1085
+ }
1086
+ const imgSetValues = bgImgSetDataValue.split("|");
1087
+ let bgImageValues = imgSetValues.map((value) => `image-set(${value})`);
1088
+ element.style.backgroundImage = bgImageValues.join();
1089
+ if (element.style.backgroundImage === "") {
1090
+ bgImageValues = imgSetValues.map((value) => `-webkit-image-set(${value})`);
1091
+ element.style.backgroundImage = bgImageValues.join();
1092
+ }
1093
+ manageApplied(element, settings, instance);
1094
+ };
1095
+ const setSourcesFunctions = {
1096
+ IMG: setSourcesImg,
1097
+ IFRAME: setSourcesIframe,
1098
+ VIDEO: setSourcesVideo,
1099
+ OBJECT: setSourcesObject
1100
+ };
1101
+ const setSourcesNative = (element, settings) => {
1102
+ const setSourcesFunction = setSourcesFunctions[element.tagName];
1103
+ if (!setSourcesFunction) {
1104
+ return;
1105
+ }
1106
+ setSourcesFunction(element, settings);
1107
+ };
1108
+ const setSources = (element, settings, instance) => {
1109
+ const setSourcesFunction = setSourcesFunctions[element.tagName];
1110
+ if (!setSourcesFunction) {
1111
+ return;
1112
+ }
1113
+ setSourcesFunction(element, settings);
1114
+ manageLoading(element, settings, instance);
1115
+ };
1116
+ const elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"];
1117
+ const hasLoadEvent = (element) => elementsWithLoadEvent.indexOf(element.tagName) > -1;
1118
+ const checkFinish = (settings, instance) => {
1119
+ if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) {
1120
+ safeCallback(settings.callback_finish, instance);
1121
+ }
1122
+ };
1123
+ const addEventListener = (element, eventName, handler) => {
1124
+ element.addEventListener(eventName, handler);
1125
+ element.llEvLisnrs[eventName] = handler;
1126
+ };
1127
+ const removeEventListener = (element, eventName, handler) => {
1128
+ element.removeEventListener(eventName, handler);
1129
+ };
1130
+ const hasEventListeners = (element) => {
1131
+ return !!element.llEvLisnrs;
1132
+ };
1133
+ const addEventListeners = (element, loadHandler2, errorHandler2) => {
1134
+ if (!hasEventListeners(element))
1135
+ element.llEvLisnrs = {};
1136
+ const loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load";
1137
+ addEventListener(element, loadEventName, loadHandler2);
1138
+ addEventListener(element, "error", errorHandler2);
1139
+ };
1140
+ const removeEventListeners = (element) => {
1141
+ if (!hasEventListeners(element)) {
1142
+ return;
1143
+ }
1144
+ const eventListeners = element.llEvLisnrs;
1145
+ for (let eventName in eventListeners) {
1146
+ const handler = eventListeners[eventName];
1147
+ removeEventListener(element, eventName, handler);
1148
+ }
1149
+ delete element.llEvLisnrs;
1150
+ };
1151
+ const doneHandler = (element, settings, instance) => {
1152
+ deleteTempImage(element);
1153
+ updateLoadingCount(instance, -1);
1154
+ decreaseToLoadCount(instance);
1155
+ removeClass(element, settings.class_loading);
1156
+ if (settings.unobserve_completed) {
1157
+ unobserve(element, instance);
1158
+ }
1159
+ };
1160
+ const loadHandler = (event, element, settings, instance) => {
1161
+ const goingNative = hasStatusNative(element);
1162
+ doneHandler(element, settings, instance);
1163
+ addClass(element, settings.class_loaded);
1164
+ setStatus(element, statusLoaded);
1165
+ safeCallback(settings.callback_loaded, element, instance);
1166
+ if (!goingNative)
1167
+ checkFinish(settings, instance);
1168
+ };
1169
+ const errorHandler = (event, element, settings, instance) => {
1170
+ const goingNative = hasStatusNative(element);
1171
+ doneHandler(element, settings, instance);
1172
+ addClass(element, settings.class_error);
1173
+ setStatus(element, statusError);
1174
+ safeCallback(settings.callback_error, element, instance);
1175
+ if (settings.restore_on_error)
1176
+ restoreOriginalAttrs(element, attrsSrcSrcsetSizes);
1177
+ if (!goingNative)
1178
+ checkFinish(settings, instance);
1179
+ };
1180
+ const addOneShotEventListeners = (element, settings, instance) => {
1181
+ const elementToListenTo = getTempImage(element) || element;
1182
+ if (hasEventListeners(elementToListenTo)) {
1183
+ return;
1184
+ }
1185
+ const _loadHandler = (event) => {
1186
+ loadHandler(event, element, settings, instance);
1187
+ removeEventListeners(elementToListenTo);
1188
+ };
1189
+ const _errorHandler = (event) => {
1190
+ errorHandler(event, element, settings, instance);
1191
+ removeEventListeners(elementToListenTo);
1192
+ };
1193
+ addEventListeners(elementToListenTo, _loadHandler, _errorHandler);
1194
+ };
1195
+ const loadBackground = (element, settings, instance) => {
1196
+ addTempImage(element);
1197
+ addOneShotEventListeners(element, settings, instance);
1198
+ saveOriginalBackgroundStyle(element);
1199
+ setBackground(element, settings, instance);
1200
+ setMultiBackground(element, settings, instance);
1201
+ setImgsetBackground(element, settings, instance);
1202
+ };
1203
+ const loadRegular = (element, settings, instance) => {
1204
+ addOneShotEventListeners(element, settings, instance);
1205
+ setSources(element, settings, instance);
1206
+ };
1207
+ const load = (element, settings, instance) => {
1208
+ if (hasLoadEvent(element)) {
1209
+ loadRegular(element, settings, instance);
1210
+ } else {
1211
+ loadBackground(element, settings, instance);
1212
+ }
1213
+ };
1214
+ const loadNative = (element, settings, instance) => {
1215
+ element.setAttribute("loading", "lazy");
1216
+ addOneShotEventListeners(element, settings, instance);
1217
+ setSourcesNative(element, settings);
1218
+ setStatus(element, statusNative);
1219
+ };
1220
+ const removeImageAttributes = (element) => {
1221
+ element.removeAttribute(SRC);
1222
+ element.removeAttribute(SRCSET);
1223
+ element.removeAttribute(SIZES);
1224
+ };
1225
+ const resetSourcesImg = (element) => {
1226
+ forEachPictureSource(element, (sourceTag) => {
1227
+ removeImageAttributes(sourceTag);
1228
+ });
1229
+ removeImageAttributes(element);
1230
+ };
1231
+ const restoreImg = (imgEl) => {
1232
+ forEachPictureSource(imgEl, (sourceEl) => {
1233
+ restoreOriginalAttrs(sourceEl, attrsSrcSrcsetSizes);
1234
+ });
1235
+ restoreOriginalAttrs(imgEl, attrsSrcSrcsetSizes);
1236
+ };
1237
+ const restoreVideo = (videoEl) => {
1238
+ forEachVideoSource(videoEl, (sourceEl) => {
1239
+ restoreOriginalAttrs(sourceEl, attrsSrc);
1240
+ });
1241
+ restoreOriginalAttrs(videoEl, attrsSrcPoster);
1242
+ videoEl.load();
1243
+ };
1244
+ const restoreIframe = (iframeEl) => {
1245
+ restoreOriginalAttrs(iframeEl, attrsSrc);
1246
+ };
1247
+ const restoreObject = (objectEl) => {
1248
+ restoreOriginalAttrs(objectEl, attrsData);
1249
+ };
1250
+ const restoreFunctions = {
1251
+ IMG: restoreImg,
1252
+ IFRAME: restoreIframe,
1253
+ VIDEO: restoreVideo,
1254
+ OBJECT: restoreObject
1255
+ };
1256
+ const restoreAttributes = (element) => {
1257
+ const restoreFunction = restoreFunctions[element.tagName];
1258
+ if (!restoreFunction) {
1259
+ restoreOriginalBgImage(element);
1260
+ return;
1261
+ }
1262
+ restoreFunction(element);
1263
+ };
1264
+ const resetClasses = (element, settings) => {
1265
+ if (hasEmptyStatus(element) || hasStatusNative(element)) {
1266
+ return;
1267
+ }
1268
+ removeClass(element, settings.class_entered);
1269
+ removeClass(element, settings.class_exited);
1270
+ removeClass(element, settings.class_applied);
1271
+ removeClass(element, settings.class_loading);
1272
+ removeClass(element, settings.class_loaded);
1273
+ removeClass(element, settings.class_error);
1274
+ };
1275
+ const restore = (element, settings) => {
1276
+ restoreAttributes(element);
1277
+ resetClasses(element, settings);
1278
+ resetStatus(element);
1279
+ deleteOriginalAttrs(element);
1280
+ };
1281
+ const cancelLoading = (element, entry, settings, instance) => {
1282
+ if (!settings.cancel_on_exit)
1283
+ return;
1284
+ if (!hasStatusLoading(element))
1285
+ return;
1286
+ if (element.tagName !== "IMG")
1287
+ return;
1288
+ removeEventListeners(element);
1289
+ resetSourcesImg(element);
1290
+ restoreImg(element);
1291
+ removeClass(element, settings.class_loading);
1292
+ updateLoadingCount(instance, -1);
1293
+ resetStatus(element);
1294
+ safeCallback(settings.callback_cancel, element, entry, instance);
1295
+ };
1296
+ const onEnter = (element, entry, settings, instance) => {
1297
+ const dontLoad = hadStartedLoading(element);
1298
+ setStatus(element, statusEntered);
1299
+ addClass(element, settings.class_entered);
1300
+ removeClass(element, settings.class_exited);
1301
+ unobserveEntered(element, settings, instance);
1302
+ safeCallback(settings.callback_enter, element, entry, instance);
1303
+ if (dontLoad)
1304
+ return;
1305
+ load(element, settings, instance);
1306
+ };
1307
+ const onExit = (element, entry, settings, instance) => {
1308
+ if (hasEmptyStatus(element))
1309
+ return;
1310
+ addClass(element, settings.class_exited);
1311
+ cancelLoading(element, entry, settings, instance);
1312
+ safeCallback(settings.callback_exit, element, entry, instance);
1313
+ };
1314
+ const tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"];
1315
+ const shouldUseNative = (settings) => settings.use_native && "loading" in HTMLImageElement.prototype;
1316
+ const loadAllNative = (elements, settings, instance) => {
1317
+ elements.forEach((element) => {
1318
+ if (tagsWithNativeLazy.indexOf(element.tagName) === -1) {
1319
+ return;
1320
+ }
1321
+ loadNative(element, settings, instance);
1322
+ });
1323
+ setToLoadCount(instance, 0);
1324
+ };
1325
+ const isIntersecting = (entry) => entry.isIntersecting || entry.intersectionRatio > 0;
1326
+ const getObserverSettings = (settings) => ({
1327
+ root: settings.container === document ? null : settings.container,
1328
+ rootMargin: settings.thresholds || settings.threshold + "px"
1329
+ });
1330
+ const intersectionHandler = (entries, settings, instance) => {
1331
+ entries.forEach(
1332
+ (entry) => isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance)
1333
+ );
1334
+ };
1335
+ const observeElements = (observer, elements) => {
1336
+ elements.forEach((element) => {
1337
+ observer.observe(element);
1338
+ });
1339
+ };
1340
+ const updateObserver = (observer, elementsToObserve) => {
1341
+ resetObserver(observer);
1342
+ observeElements(observer, elementsToObserve);
1343
+ };
1344
+ const setObserver = (settings, instance) => {
1345
+ if (!supportsIntersectionObserver || shouldUseNative(settings)) {
1346
+ return;
1347
+ }
1348
+ instance._observer = new IntersectionObserver((entries) => {
1349
+ intersectionHandler(entries, settings, instance);
1350
+ }, getObserverSettings(settings));
1351
+ };
1352
+ const toArray = (nodeSet) => Array.prototype.slice.call(nodeSet);
1353
+ const queryElements = (settings) => settings.container.querySelectorAll(settings.elements_selector);
1354
+ const excludeManagedElements = (elements) => toArray(elements).filter(hasEmptyStatus);
1355
+ const hasError = (element) => hasStatusError(element);
1356
+ const filterErrorElements = (elements) => toArray(elements).filter(hasError);
1357
+ const getElementsToLoad = (elements, settings) => excludeManagedElements(elements || queryElements(settings));
1358
+ const retryLazyLoad = (settings, instance) => {
1359
+ const errorElements = filterErrorElements(queryElements(settings));
1360
+ errorElements.forEach((element) => {
1361
+ removeClass(element, settings.class_error);
1362
+ resetStatus(element);
1363
+ });
1364
+ instance.update();
1365
+ };
1366
+ const setOnlineCheck = (settings, instance) => {
1367
+ if (!runningOnBrowser) {
1368
+ return;
1369
+ }
1370
+ instance._onlineHandler = () => {
1371
+ retryLazyLoad(settings, instance);
1372
+ };
1373
+ window.addEventListener("online", instance._onlineHandler);
1374
+ };
1375
+ const resetOnlineCheck = (instance) => {
1376
+ if (!runningOnBrowser) {
1377
+ return;
1378
+ }
1379
+ window.removeEventListener("online", instance._onlineHandler);
1380
+ };
1381
+ const LazyLoad = function(customSettings, elements) {
1382
+ const settings = getExtendedSettings(customSettings);
1383
+ this._settings = settings;
1384
+ this.loadingCount = 0;
1385
+ setObserver(settings, this);
1386
+ setOnlineCheck(settings, this);
1387
+ this.update(elements);
1388
+ };
1389
+ LazyLoad.prototype = {
1390
+ update: function(givenNodeset) {
1391
+ const settings = this._settings;
1392
+ const elementsToLoad = getElementsToLoad(givenNodeset, settings);
1393
+ setToLoadCount(this, elementsToLoad.length);
1394
+ if (isBot || !supportsIntersectionObserver) {
1395
+ this.loadAll(elementsToLoad);
1396
+ return;
1397
+ }
1398
+ if (shouldUseNative(settings)) {
1399
+ loadAllNative(elementsToLoad, settings, this);
1400
+ return;
1401
+ }
1402
+ updateObserver(this._observer, elementsToLoad);
1403
+ },
1404
+ destroy: function() {
1405
+ if (this._observer) {
1406
+ this._observer.disconnect();
1407
+ }
1408
+ resetOnlineCheck(this);
1409
+ queryElements(this._settings).forEach((element) => {
1410
+ deleteOriginalAttrs(element);
1411
+ });
1412
+ delete this._observer;
1413
+ delete this._settings;
1414
+ delete this._onlineHandler;
1415
+ delete this.loadingCount;
1416
+ delete this.toLoadCount;
1417
+ },
1418
+ loadAll: function(elements) {
1419
+ const settings = this._settings;
1420
+ const elementsToLoad = getElementsToLoad(elements, settings);
1421
+ elementsToLoad.forEach((element) => {
1422
+ unobserve(element, this);
1423
+ load(element, settings, this);
1424
+ });
1425
+ },
1426
+ restoreAll: function() {
1427
+ const settings = this._settings;
1428
+ queryElements(settings).forEach((element) => {
1429
+ restore(element, settings);
1430
+ });
1431
+ }
1432
+ };
1433
+ LazyLoad.load = (element, customSettings) => {
1434
+ const settings = getExtendedSettings(customSettings);
1435
+ load(element, settings);
1436
+ };
1437
+ LazyLoad.resetStatus = (element) => {
1438
+ resetStatus(element);
1439
+ };
1440
+ if (runningOnBrowser) {
1441
+ autoInitialize(LazyLoad, window.lazyLoadOptions);
1442
+ }
1443
+ class DocsViewer {
1444
+ constructor({ readonly, box, pages, onNewPageIndex, onPlay }) {
1445
+ this.pageIndex = 0;
1446
+ this.namespace = "netless-app-docs-viewer";
1447
+ this.isShowPreview = false;
1448
+ this.isSmallBox = false;
1449
+ this.sideEffect = new SideEffectManager();
1450
+ if (pages.length <= 0) {
1451
+ throw new Error("[DocsViewer] Empty pages.");
1452
+ }
1453
+ this.readonly = readonly;
1454
+ this.box = box;
1455
+ this.pages = pages;
1456
+ this.onNewPageIndex = onNewPageIndex;
1457
+ this.onPlay = onPlay;
1458
+ this.onPageIndexChanged = () => void 0;
1459
+ this.render();
1460
+ }
1461
+ mount() {
1462
+ this.box.mountContent(this.$content);
1463
+ this.box.mountFooter(this.$footer);
1464
+ this.sideEffect.add(() => {
1465
+ const previewLazyLoad = new LazyLoad({
1466
+ container: this.$preview,
1467
+ elements_selector: `.${this.wrapClassName("preview-page>img")}`
1468
+ });
1469
+ return () => previewLazyLoad.destroy();
1470
+ }, "preview-lazyload");
1471
+ }
1472
+ unmount() {
1473
+ this.$content.remove();
1474
+ this.$footer.remove();
1475
+ }
1476
+ setReadonly(readonly) {
1477
+ if (this.readonly !== readonly) {
1478
+ this.readonly = readonly;
1479
+ this.$content.classList.toggle(this.wrapClassName("readonly"), readonly);
1480
+ this.$footer.classList.toggle(this.wrapClassName("readonly"), readonly);
1481
+ this.$pageNumberInput.disabled = readonly;
1482
+ }
1483
+ }
1484
+ destroy() {
1485
+ this.sideEffect.flushAll();
1486
+ this.unmount();
1487
+ }
1488
+ setPageIndex(pageIndex) {
1489
+ if (!Number.isNaN(pageIndex)) {
1490
+ this.pageIndex = pageIndex;
1491
+ this.$pageNumberInput.value = String(pageIndex + 1);
1492
+ this.onPageIndexChanged(pageIndex);
1493
+ }
1494
+ }
1495
+ setSmallBox(isSmallBox) {
1496
+ if (this.isSmallBox !== isSmallBox) {
1497
+ this.isSmallBox = isSmallBox;
1498
+ this.$footer.classList.toggle(this.wrapClassName("float-footer"), isSmallBox);
1499
+ }
1500
+ }
1501
+ render() {
1502
+ this.renderContent();
1503
+ this.renderFooter();
1504
+ return this.$content;
1505
+ }
1506
+ renderContent() {
1507
+ if (!this.$content) {
1508
+ const $content = document.createElement("div");
1509
+ $content.className = this.wrapClassName("content");
1510
+ this.$content = $content;
1511
+ if (this.readonly) {
1512
+ $content.classList.add(this.wrapClassName("readonly"));
1513
+ }
1514
+ $content.appendChild(this.renderPreviewMask());
1515
+ $content.appendChild(this.renderPreview());
1516
+ }
1517
+ return this.$content;
1518
+ }
1519
+ renderPreview() {
1520
+ if (!this.$preview) {
1521
+ const $preview = document.createElement("div");
1522
+ $preview.className = this.wrapClassName("preview") + " tele-fancy-scrollbar";
1523
+ this.$preview = $preview;
1524
+ const pageClassName = this.wrapClassName("preview-page");
1525
+ const pageNameClassName = this.wrapClassName("preview-page-name");
1526
+ this.pages.forEach((page, i) => {
1527
+ var _a;
1528
+ const previewSRC = (_a = page.thumbnail) != null ? _a : page.src.startsWith("ppt") ? void 0 : page.src;
1529
+ if (!previewSRC) {
1530
+ return;
1531
+ }
1532
+ const pageIndex = String(i);
1533
+ const $page = document.createElement("a");
1534
+ $page.className = pageClassName + " " + this.wrapClassName(`preview-page-${i}`);
1535
+ $page.setAttribute("href", "#");
1536
+ $page.dataset.pageIndex = pageIndex;
1537
+ const $name = document.createElement("span");
1538
+ $name.className = pageNameClassName;
1539
+ $name.textContent = String(i + 1);
1540
+ $name.dataset.pageIndex = pageIndex;
1541
+ const $img = document.createElement("img");
1542
+ $img.width = page.width;
1543
+ $img.height = page.height;
1544
+ $img.dataset.src = previewSRC;
1545
+ $img.dataset.pageIndex = pageIndex;
1546
+ $page.appendChild($img);
1547
+ $page.appendChild($name);
1548
+ $preview.appendChild($page);
1549
+ });
1550
+ this.sideEffect.addEventListener($preview, "click", (ev) => {
1551
+ var _a;
1552
+ if (this.readonly) {
1553
+ return;
1554
+ }
1555
+ const pageIndex = (_a = ev.target.dataset) == null ? void 0 : _a.pageIndex;
1556
+ if (pageIndex) {
1557
+ ev.preventDefault();
1558
+ ev.stopPropagation();
1559
+ ev.stopImmediatePropagation();
1560
+ this.onNewPageIndex(Number(pageIndex));
1561
+ this.togglePreview(false);
1562
+ }
1563
+ });
1564
+ }
1565
+ return this.$preview;
1566
+ }
1567
+ renderPreviewMask() {
1568
+ if (!this.$previewMask) {
1569
+ this.$previewMask = document.createElement("div");
1570
+ this.$previewMask.className = this.wrapClassName("preview-mask");
1571
+ this.sideEffect.addEventListener(this.$previewMask, "click", (ev) => {
1572
+ if (this.readonly) {
1573
+ return;
1574
+ }
1575
+ if (ev.target === this.$previewMask) {
1576
+ this.togglePreview(false);
1577
+ }
1578
+ });
1579
+ }
1580
+ return this.$previewMask;
1581
+ }
1582
+ renderFooter() {
1583
+ if (!this.$footer) {
1584
+ const $footer = document.createElement("div");
1585
+ $footer.className = this.wrapClassName("footer");
1586
+ this.$footer = $footer;
1587
+ if (this.readonly) {
1588
+ $footer.classList.add(this.wrapClassName("readonly"));
1589
+ }
1590
+ if (this.isSmallBox) {
1591
+ $footer.classList.add(this.wrapClassName("float-footer"));
1592
+ }
1593
+ if (this.pages.some((page) => page.thumbnail || !page.src.startsWith("ppt"))) {
1594
+ const $btnSidebar = this.renderFooterBtn("btn-sidebar", sidebarSVG(this.namespace));
1595
+ this.sideEffect.addEventListener($btnSidebar, "click", () => {
1596
+ if (this.readonly) {
1597
+ return;
1598
+ }
1599
+ this.togglePreview();
1600
+ });
1601
+ this.$footer.appendChild($btnSidebar);
1602
+ }
1603
+ const $pageJumps = document.createElement("div");
1604
+ $pageJumps.className = this.wrapClassName("page-jumps");
1605
+ const $btnPageBack = this.renderFooterBtn("btn-page-back", arrowLeftSVG(this.namespace));
1606
+ this.sideEffect.addEventListener($btnPageBack, "click", () => {
1607
+ if (this.readonly) {
1608
+ return;
1609
+ }
1610
+ this.onNewPageIndex(this.pageIndex - 1);
1611
+ });
1612
+ $pageJumps.appendChild($btnPageBack);
1613
+ if (this.onPlay) {
1614
+ const $btnPlay = this.renderFooterBtn(
1615
+ "btn-page-play",
1616
+ playSVG(this.namespace),
1617
+ pauseSVG(this.namespace)
1618
+ );
1619
+ const returnPlay = () => {
1620
+ this.sideEffect.setTimeout(
1621
+ () => {
1622
+ $btnPlay.classList.toggle(this.wrapClassName("footer-btn-playing"), false);
1623
+ },
1624
+ 500,
1625
+ "returnPlay"
1626
+ );
1627
+ };
1628
+ this.sideEffect.addEventListener($btnPlay, "click", () => {
1629
+ if (this.readonly) {
1630
+ return;
1631
+ }
1632
+ $btnPlay.classList.toggle(this.wrapClassName("footer-btn-playing"), true);
1633
+ if (this.onPlay) {
1634
+ this.onPlay();
1635
+ }
1636
+ returnPlay();
1637
+ });
1638
+ $pageJumps.appendChild($btnPlay);
1639
+ }
1640
+ const $btnPageNext = this.renderFooterBtn("btn-page-next", arrowRightSVG(this.namespace));
1641
+ this.sideEffect.addEventListener($btnPageNext, "click", () => {
1642
+ if (this.readonly) {
1643
+ return;
1644
+ }
1645
+ this.onNewPageIndex(this.pageIndex + 1);
1646
+ });
1647
+ $pageJumps.appendChild($btnPageNext);
1648
+ const $pageNumber = document.createElement("div");
1649
+ $pageNumber.className = this.wrapClassName("page-number");
1650
+ const $pageNumberInput = document.createElement("input");
1651
+ $pageNumberInput.className = this.wrapClassName("page-number-input");
1652
+ $pageNumberInput.value = String(this.pageIndex + 1);
1653
+ if (this.readonly) {
1654
+ $pageNumberInput.disabled = true;
1655
+ }
1656
+ this.$pageNumberInput = $pageNumberInput;
1657
+ this.sideEffect.addEventListener($pageNumberInput, "focus", () => {
1658
+ $pageNumberInput.select();
1659
+ });
1660
+ this.sideEffect.addEventListener($pageNumberInput, "change", () => {
1661
+ if (this.readonly) {
1662
+ return;
1663
+ }
1664
+ if ($pageNumberInput.value) {
1665
+ this.onNewPageIndex(Number($pageNumberInput.value) - 1);
1666
+ }
1667
+ });
1668
+ const $totalPage = document.createElement("span");
1669
+ $totalPage.textContent = " / " + this.pages.length;
1670
+ $pageNumber.appendChild($pageNumberInput);
1671
+ $pageNumber.appendChild($totalPage);
1672
+ this.$footer.appendChild($pageJumps);
1673
+ this.$footer.appendChild($pageNumber);
1674
+ }
1675
+ return this.$footer;
1676
+ }
1677
+ renderFooterBtn(className, $icon, $iconActive) {
1678
+ const $btn = document.createElement("button");
1679
+ $btn.className = this.wrapClassName("footer-btn") + " " + this.wrapClassName(className);
1680
+ $btn.appendChild($icon);
1681
+ if ($iconActive) {
1682
+ $btn.appendChild($iconActive);
1683
+ }
1684
+ return $btn;
1685
+ }
1686
+ togglePreview(isShowPreview) {
1687
+ this.isShowPreview = isShowPreview != null ? isShowPreview : !this.isShowPreview;
1688
+ this.$content.classList.toggle(this.wrapClassName("preview-active"), this.isShowPreview);
1689
+ if (this.isShowPreview) {
1690
+ const $previewPage = this.$preview.querySelector(
1691
+ "." + this.wrapClassName(`preview-page-${this.pageIndex}`)
1692
+ );
1693
+ if ($previewPage) {
1694
+ this.$preview.scrollTo({
1695
+ top: $previewPage.offsetTop - 16
1696
+ });
1697
+ }
1698
+ }
1699
+ }
1700
+ wrapClassName(className) {
1701
+ return `${this.namespace}-${className}`;
1702
+ }
1703
+ }
1704
+ function clamp(value, min, max) {
1705
+ return Math.min(Math.max(value, min), max);
1706
+ }
1707
+ function flattenEvent(ev) {
1708
+ return ev.touches ? ev.touches[0] : ev;
1709
+ }
1710
+ function preventEvent(ev) {
1711
+ ev.stopPropagation();
1712
+ if (ev.cancelable) {
1713
+ ev.preventDefault();
1714
+ }
1715
+ }
1716
+ function isEditable(el) {
1717
+ if (!el)
1718
+ return false;
1719
+ const tagName = el.tagName;
1720
+ return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT";
1721
+ }
1722
+ class Stepper {
1723
+ constructor(config) {
1724
+ var _a, _b, _c;
1725
+ this.velocity = 0;
1726
+ this.paused = true;
1727
+ this._animationFrameID = null;
1728
+ this._loopTimestamp = 0;
1729
+ this.looper = (timestamp) => {
1730
+ if (this.paused) {
1731
+ return;
1732
+ }
1733
+ let frames = Math.floor((timestamp - this._loopTimestamp) / 1e3 * 60) + 1;
1734
+ this._loopTimestamp = timestamp;
1735
+ while (frames-- > 0) {
1736
+ this.stepper();
1737
+ }
1738
+ this.onStep(this.current, this);
1739
+ if (!this.paused && this.current !== this.target) {
1740
+ window.requestAnimationFrame(this.looper);
1741
+ }
1742
+ };
1743
+ this.current = (_a = config.start) != null ? _a : 0;
1744
+ this.target = this.current;
1745
+ this.stiffness = (_b = config.stiffness) != null ? _b : 170;
1746
+ this.damping = (_c = config.damping) != null ? _c : 26;
1747
+ this.onStep = config.onStep;
1748
+ }
1749
+ stepTo(target, start) {
1750
+ if (this.paused && start != null) {
1751
+ this.current = start;
1752
+ }
1753
+ this.paused = false;
1754
+ this.target = target;
1755
+ this.onStep(this.current, this);
1756
+ this._loopTimestamp = Date.now();
1757
+ window.requestAnimationFrame(this.looper);
1758
+ }
1759
+ pause() {
1760
+ this.paused = true;
1761
+ }
1762
+ destroy() {
1763
+ this.pause();
1764
+ }
1765
+ stepper() {
1766
+ const fSpring = -this.stiffness * (this.current - this.target);
1767
+ const fDamper = -this.damping * this.velocity;
1768
+ const newVelocity = this.velocity + (fSpring + fDamper) / 60;
1769
+ const newCurrent = this.current + newVelocity / 60;
1770
+ if (Math.abs(newVelocity - 0) < 0.01 && Math.abs(newCurrent - this.target) < 0.01) {
1771
+ this.current = this.target;
1772
+ this.velocity = 0;
1773
+ } else {
1774
+ this.current = newCurrent;
1775
+ this.velocity = newVelocity;
1776
+ }
1777
+ }
1778
+ }
1779
+ class PageEl {
1780
+ constructor(index, page, scale, pagesIntrinsicWidth) {
1781
+ this.scale = 1;
1782
+ this.lastVisit = Date.now();
1783
+ this.pageOffsetY = 0;
1784
+ this.pageOffsetX = 0;
1785
+ this.visible = true;
1786
+ this.index = index;
1787
+ this.page = page;
1788
+ this.scale = scale;
1789
+ this.pageOffsetX = (pagesIntrinsicWidth - page.width) / 2;
1790
+ const $page = document.createElement("div");
1791
+ $page.className = "page-renderer-page";
1792
+ $page.dataset.index = `${index}`;
1793
+ $page.style.width = `${page.width * scale}px`;
1794
+ $page.style.height = `${page.height * scale}px`;
1795
+ if (page.thumbnail) {
1796
+ $page.style.backgroundImage = `url("${page.thumbnail}")`;
1797
+ }
1798
+ const $img = document.createElement("img");
1799
+ $img.className = "page-renderer-page-img";
1800
+ $img.width = page.width;
1801
+ $img.height = page.height;
1802
+ $img.src = page.src;
1803
+ $page.appendChild($img);
1804
+ this.$page = $page;
1805
+ }
1806
+ translateY(pageOffsetY) {
1807
+ if (Math.abs(pageOffsetY - this.pageOffsetY) >= 1e-3) {
1808
+ this.pageOffsetY = pageOffsetY;
1809
+ this.$page.style.transform = `translate(${this.pageOffsetX * this.scale}px, ${this.pageOffsetY * this.scale}px)`;
1810
+ }
1811
+ }
1812
+ setScale(scale) {
1813
+ if (Math.abs(scale - this.scale) >= 1e-3) {
1814
+ this.scale = scale;
1815
+ this.$page.style.width = `${this.page.width * this.scale}px`;
1816
+ this.$page.style.height = `${this.page.height * this.scale}px`;
1817
+ this.$page.style.transform = `translate(${this.pageOffsetX * this.scale}px, ${this.pageOffsetY * this.scale}px)`;
1818
+ }
1819
+ }
1820
+ setVisible(visible) {
1821
+ if (visible !== this.visible) {
1822
+ this.visible = visible;
1823
+ this.$page.style.opacity = visible ? "1" : "0";
1824
+ }
1825
+ }
1826
+ }
1827
+ const schedule = window.requestIdleCallback || ((handler) => window.setTimeout(handler, 5e3));
1828
+ const cancelSchedule = window.cancelIdleCallback || window.clearTimeout;
1829
+ class PageElManager {
1830
+ constructor(pages, pagesIntrinsicWidth, scale) {
1831
+ this.pages = pages;
1832
+ this.pagesIntrinsicWidth = pagesIntrinsicWidth;
1833
+ this.scale = scale;
1834
+ this.els = /* @__PURE__ */ new Map();
1835
+ this.maxElCount = 200;
1836
+ this.gcTimer = null;
1837
+ this.gc = () => {
1838
+ this.gcTimer = null;
1839
+ if (this.els.size > this.maxElCount) {
1840
+ const sortedEls = [...this.els.values()].sort((x, y) => y.lastVisit - x.lastVisit);
1841
+ for (let i = Math.floor(this.maxElCount / 4); i < sortedEls.length; i++) {
1842
+ this.els.delete(sortedEls[i].index);
1843
+ }
1844
+ }
1845
+ };
1846
+ }
1847
+ getEl(index) {
1848
+ let el = this.els.get(index);
1849
+ if (!el) {
1850
+ el = new PageEl(index, this.pages[index], this.scale, this.pagesIntrinsicWidth);
1851
+ this.els.set(index, el);
1852
+ }
1853
+ el.lastVisit = Date.now();
1854
+ if (this.els.size > this.maxElCount && this.gcTimer === null) {
1855
+ this.gcTimer = schedule(this.gc);
1856
+ }
1857
+ return el;
1858
+ }
1859
+ setScale(scale) {
1860
+ if (scale !== this.scale) {
1861
+ this.scale = scale;
1862
+ this.els.forEach((pageEl) => pageEl.setScale(scale));
1863
+ }
1864
+ }
1865
+ destroy() {
1866
+ this.els.clear();
1867
+ if (this.gcTimer !== null) {
1868
+ cancelSchedule(this.gcTimer);
1869
+ this.gcTimer = null;
1870
+ }
1871
+ }
1872
+ }
1873
+ class PageRenderer {
1874
+ constructor(config) {
1875
+ this._hwaTimeout = NaN;
1876
+ this._turnOffHWA = () => {
1877
+ window.clearTimeout(this._hwaTimeout);
1878
+ this._hwaTimeout = NaN;
1879
+ this.$pages.classList.toggle("is-hwa", false);
1880
+ };
1881
+ this.pagesScrollTop = config.pagesScrollTop || 0;
1882
+ this.containerWidth = config.containerWidth || 1;
1883
+ this.containerHeight = config.containerHeight || 1;
1884
+ this.pages = config.pages.map((page) => {
1885
+ if (page.thumbnail) {
1886
+ return page;
1887
+ }
1888
+ try {
1889
+ const url = new URL(page.src);
1890
+ url.searchParams.set("x-oss-process", "image/resize,l_50");
1891
+ return { ...page, thumbnail: url.toString() };
1892
+ } catch (e) {
1893
+ console.error(e);
1894
+ return page;
1895
+ }
1896
+ });
1897
+ const pagesIntrinsicYs = Array(this.pages.length);
1898
+ let pagesMinHeight = Infinity;
1899
+ let pagesIntrinsicWidth = 0;
1900
+ this.pagesIntrinsicHeight = this.pages.reduce((pageY, page, i) => {
1901
+ pagesIntrinsicYs[i] = pageY;
1902
+ if (page.width > pagesIntrinsicWidth) {
1903
+ pagesIntrinsicWidth = page.width;
1904
+ }
1905
+ if (page.height <= pagesMinHeight) {
1906
+ pagesMinHeight = page.height;
1907
+ }
1908
+ return pageY + page.height;
1909
+ }, 0);
1910
+ this.pagesIntrinsicWidth = pagesIntrinsicWidth;
1911
+ this.pagesMinHeight = pagesMinHeight;
1912
+ this.pagesIntrinsicYs = pagesIntrinsicYs;
1913
+ this.scale = this._calcScale();
1914
+ this.threshold = this._calcThreshold();
1915
+ this.onPageIndexChanged = config.onPageIndexChanged;
1916
+ this.pageScrollIndex = 0;
1917
+ if (this.pagesScrollTop !== 0) {
1918
+ this.pageScrollIndex = this.findScrollPageIndex();
1919
+ if (this.onPageIndexChanged && this.pageScrollIndex > 0) {
1920
+ this.onPageIndexChanged(this.pageScrollIndex);
1921
+ }
1922
+ }
1923
+ this.pageElManager = new PageElManager(this.pages, pagesIntrinsicWidth, this.scale);
1924
+ this.$pages = this.renderPages();
1925
+ }
1926
+ setContainerSize(width, height) {
1927
+ if (width > 0 && height > 0) {
1928
+ if (width !== this.containerWidth || height !== this.containerHeight) {
1929
+ this.containerWidth = width;
1930
+ this.containerHeight = height;
1931
+ this.$pages.style.width = `${this.containerWidth}px`;
1932
+ this.$pages.style.height = `${this.containerHeight}px`;
1933
+ this.scale = this._calcScale();
1934
+ this.threshold = this._calcThreshold();
1935
+ this.pageElManager.setScale(this.scale);
1936
+ if (this.$pages.parentElement) {
1937
+ this.pagesScrollTo(this.pagesScrollTop, true);
1938
+ }
1939
+ }
1940
+ }
1941
+ }
1942
+ renderPages() {
1943
+ const $pages = document.createElement("div");
1944
+ $pages.className = "page-renderer-pages-container";
1945
+ $pages.style.width = `${this.containerWidth}px`;
1946
+ $pages.style.height = `${this.containerHeight}px`;
1947
+ return $pages;
1948
+ }
1949
+ pagesScrollTo(pagesScrollTop, force) {
1950
+ pagesScrollTop = clamp(
1951
+ pagesScrollTop,
1952
+ 0,
1953
+ this.pagesIntrinsicHeight - this.containerHeight / this.scale
1954
+ );
1955
+ if (force || Math.abs(pagesScrollTop - this.pagesScrollTop) >= 1e-3) {
1956
+ this._turnOnHWA();
1957
+ this.pagesScrollTop = pagesScrollTop;
1958
+ const pageScrollIndex = this.findScrollPageIndex();
1959
+ const startIndex = Math.max(pageScrollIndex - this.threshold, 0);
1960
+ const endIndex = Math.min(pageScrollIndex + this.threshold, this.pages.length - 1);
1961
+ for (let i = 0; i < this.$pages.children.length; i++) {
1962
+ const $page = this.$pages.children[i];
1963
+ const index = Number($page.dataset.index);
1964
+ if (!(index >= startIndex && index <= endIndex)) {
1965
+ $page.remove();
1966
+ i--;
1967
+ }
1968
+ }
1969
+ for (let i = startIndex; i <= endIndex; i++) {
1970
+ const pageEl = this.pageElManager.getEl(i);
1971
+ if (pageEl.$page.parentElement !== this.$pages) {
1972
+ this.$pages.appendChild(pageEl.$page);
1973
+ }
1974
+ pageEl.translateY(this.pagesIntrinsicYs[i] - this.pagesScrollTop);
1975
+ }
1976
+ if (pageScrollIndex !== this.pageScrollIndex) {
1977
+ this.pageScrollIndex = pageScrollIndex;
1978
+ if (this.onPageIndexChanged) {
1979
+ this.onPageIndexChanged(pageScrollIndex);
1980
+ }
1981
+ }
1982
+ }
1983
+ }
1984
+ findScrollPageIndex() {
1985
+ for (let i = 0; i < this.pagesIntrinsicYs.length; i++) {
1986
+ if (this.pagesIntrinsicYs[i] + this.pages[i].height - this.pagesScrollTop >= 1e-3) {
1987
+ return i;
1988
+ }
1989
+ }
1990
+ return this.pagesIntrinsicYs.length - 1;
1991
+ }
1992
+ mount($parent) {
1993
+ $parent.appendChild(this.$pages);
1994
+ this.pagesScrollTo(this.pagesScrollTop, true);
1995
+ }
1996
+ unmount() {
1997
+ this.$pages.remove();
1998
+ }
1999
+ destroy() {
2000
+ this.unmount();
2001
+ this.onPageIndexChanged = void 0;
2002
+ this.pageElManager.destroy();
2003
+ if (this._hwaTimeout) {
2004
+ window.clearTimeout(this._hwaTimeout);
2005
+ this._hwaTimeout = NaN;
2006
+ }
2007
+ }
2008
+ _calcScale() {
2009
+ return this.containerWidth / this.pagesIntrinsicWidth || 1;
2010
+ }
2011
+ _calcThreshold() {
2012
+ return clamp(
2013
+ Math.ceil(this.containerHeight / this.scale / this.pagesMinHeight / 2),
2014
+ 1,
2015
+ this.pages.length
2016
+ );
2017
+ }
2018
+ _turnOnHWA() {
2019
+ if (this._hwaTimeout) {
2020
+ window.clearTimeout(this._hwaTimeout);
2021
+ } else {
2022
+ this.$pages.classList.toggle("is-hwa", true);
2023
+ }
2024
+ this._hwaTimeout = window.setTimeout(this._turnOffHWA, 1e3);
2025
+ }
2026
+ }
2027
+ const SCROLLBAR_DEFAULT_MIN_HEIGHT = 30;
2028
+ class ScrollBar {
2029
+ constructor(config) {
2030
+ this.sideEffect = new SideEffectManager();
2031
+ this.pagesScrollTop = config.pagesScrollTop || 0;
2032
+ this.containerWidth = config.containerWidth || 1;
2033
+ this.containerHeight = config.containerHeight || 1;
2034
+ this.pagesWidth = config.pagesWidth || 1;
2035
+ this.pagesHeight = config.pagesHeight || 1;
2036
+ this.scale = this._calcScale();
2037
+ this.scrollbarMinHeight = config.scrollbarMinHeight || SCROLLBAR_DEFAULT_MIN_HEIGHT;
2038
+ this.scrollbarHeight = this._calcScrollbarHeight();
2039
+ this.readonly = config.readonly;
2040
+ this.wrapClassName = config.wrapClassName;
2041
+ this.onDragScroll = config.onDragScroll;
2042
+ this.$scrollbar = this.renderScrollbar();
2043
+ }
2044
+ mount($parent) {
2045
+ $parent.appendChild(this.$scrollbar);
2046
+ this.pagesScrollTo(this.pagesScrollTop, true);
2047
+ }
2048
+ unmount() {
2049
+ this.$scrollbar.remove();
2050
+ }
2051
+ setReadonly(readonly) {
2052
+ this.readonly = readonly;
2053
+ }
2054
+ setContainerSize(width, height) {
2055
+ if (width > 0 && height > 0) {
2056
+ if (width !== this.containerWidth || height !== this.containerHeight) {
2057
+ this.containerWidth = width;
2058
+ this.containerHeight = height;
2059
+ this.scale = this._calcScale();
2060
+ this._updateScrollbarHeight();
2061
+ if (this.$scrollbar.parentElement) {
2062
+ this.pagesScrollTo(this.pagesScrollTop, true);
2063
+ }
2064
+ }
2065
+ }
2066
+ }
2067
+ pagesScrollTo(pagesScrollTop, force) {
2068
+ pagesScrollTop = clamp(pagesScrollTop, 0, this.pagesHeight - this.containerHeight / this.scale);
2069
+ if (force || Math.abs(pagesScrollTop - this.pagesScrollTop) >= 1e-3) {
2070
+ this.pagesScrollTop = pagesScrollTop;
2071
+ const elScrollTop = this.pagesScrollTop * this.scale;
2072
+ const elPagesHeight = this.pagesHeight * this.scale;
2073
+ const translateY = elScrollTop / (elPagesHeight - this.containerHeight) * (this.containerHeight - this.scrollbarHeight);
2074
+ if (window.requestAnimationFrame) {
2075
+ window.requestAnimationFrame(() => {
2076
+ this.$scrollbar.style.transform = `translateY(${translateY}px)`;
2077
+ });
2078
+ } else {
2079
+ this.$scrollbar.style.transform = `translateY(${translateY}px)`;
2080
+ }
2081
+ }
2082
+ }
2083
+ destroy() {
2084
+ this.unmount();
2085
+ this.onDragScroll = void 0;
2086
+ this.sideEffect.flushAll();
2087
+ }
2088
+ renderScrollbar() {
2089
+ const $scrollbar = document.createElement("button");
2090
+ $scrollbar.className = this.wrapClassName("scrollbar");
2091
+ $scrollbar.style.minHeight = `${this.scrollbarMinHeight}px`;
2092
+ $scrollbar.style.height = `${this.scrollbarHeight}px`;
2093
+ const trackStart = (ev) => {
2094
+ if (this.readonly) {
2095
+ return;
2096
+ }
2097
+ if (ev.button != null && ev.button !== 0) {
2098
+ return;
2099
+ }
2100
+ preventEvent(ev);
2101
+ const draggingClassName = this.wrapClassName("scrollbar-dragging");
2102
+ $scrollbar.classList.toggle(draggingClassName, true);
2103
+ const startTop = this.pagesScrollTop;
2104
+ const { clientY: startY } = flattenEvent(ev);
2105
+ const tracking = (ev2) => {
2106
+ if (this.readonly) {
2107
+ return;
2108
+ }
2109
+ const { clientY } = flattenEvent(ev2);
2110
+ const offsetY = (clientY - startY) / this.scale;
2111
+ if (Math.abs(offsetY) > 0 && this.onDragScroll) {
2112
+ this.onDragScroll(
2113
+ startTop + offsetY * (this.pagesHeight * this.scale / this.containerHeight)
2114
+ );
2115
+ }
2116
+ };
2117
+ const trackEnd = () => {
2118
+ $scrollbar.classList.toggle(draggingClassName, false);
2119
+ window.removeEventListener("mousemove", tracking, true);
2120
+ window.removeEventListener("touchmove", tracking, true);
2121
+ window.removeEventListener("mouseup", trackEnd, true);
2122
+ window.removeEventListener("touchend", trackEnd, true);
2123
+ window.removeEventListener("touchcancel", trackEnd, true);
2124
+ };
2125
+ window.addEventListener("mousemove", tracking, true);
2126
+ window.addEventListener("touchmove", tracking, true);
2127
+ window.addEventListener("mouseup", trackEnd, true);
2128
+ window.addEventListener("touchend", trackEnd, true);
2129
+ window.addEventListener("touchcancel", trackEnd, true);
2130
+ };
2131
+ this.sideEffect.addEventListener($scrollbar, "mousedown", trackStart);
2132
+ this.sideEffect.addEventListener($scrollbar, "touchstart", trackStart);
2133
+ return $scrollbar;
2134
+ }
2135
+ _calcScale() {
2136
+ return this.containerWidth / this.pagesWidth || 1;
2137
+ }
2138
+ _calcScrollbarHeight() {
2139
+ return clamp(
2140
+ this.containerHeight / (this.pagesHeight * this.scale) * this.containerHeight,
2141
+ this.scrollbarMinHeight,
2142
+ this.containerHeight
2143
+ );
2144
+ }
2145
+ _updateScrollbarHeight() {
2146
+ const newHeight = this._calcScrollbarHeight();
2147
+ if (Math.abs(newHeight - this.scrollbarHeight) > 1e-3) {
2148
+ this.scrollbarHeight = newHeight;
2149
+ this.$scrollbar.style.height = `${newHeight}px`;
2150
+ }
2151
+ }
2152
+ }
2153
+ const ResizeObserver = window.ResizeObserver || ResizeObserver$1;
2154
+ const RATIO_BASE_CONTAINER_HEIGHT = 640;
2155
+ class StaticDocsViewer {
2156
+ constructor({
2157
+ context,
2158
+ whiteboardView,
2159
+ readonly,
2160
+ box,
2161
+ pages,
2162
+ pageScrollTop = 0,
2163
+ mountWhiteboard,
2164
+ onUserScroll,
2165
+ baseScenePath,
2166
+ appId
2167
+ }) {
2168
+ this.sideEffect = new SideEffectManager();
2169
+ this.userScrolling = false;
2170
+ this.docsViewReadonly = false;
2171
+ this.onNewPageIndex = (index) => {
2172
+ this.scrollToPage(index);
2173
+ };
2174
+ this.toPdf = async () => {
2175
+ const whiteSnapshotCanvas = document.createElement("canvas");
2176
+ const whiteCtx = whiteSnapshotCanvas.getContext("2d");
2177
+ if (!whiteCtx || !this.baseScenePath) {
2178
+ this.reportProgress(100, null);
2179
+ return;
2180
+ }
2181
+ const scenePath = this.whiteboardView.focusScenePath || `${this.baseScenePath}/1`;
2182
+ const firstPage = this.pages[0];
2183
+ const { jsPDF } = await import("jspdf");
2184
+ const pdf = new jsPDF({
2185
+ format: [firstPage.width, firstPage.height],
2186
+ orientation: firstPage.width > firstPage.height ? "l" : "p",
2187
+ compress: true
2188
+ });
2189
+ for (const [index, page] of this.pages.entries()) {
2190
+ const { width, height, src } = page;
2191
+ whiteSnapshotCanvas.width = width;
2192
+ whiteSnapshotCanvas.height = height;
2193
+ const orientation = width > height ? "l" : "p";
2194
+ if (index > 0) {
2195
+ pdf.addPage([width, height], orientation);
2196
+ }
2197
+ const pdfPageSrc = await this.getBase64FromUrl(src);
2198
+ const img = document.createElement("img");
2199
+ img.src = pdfPageSrc;
2200
+ await new Promise((resolve) => img.onload = resolve);
2201
+ whiteCtx.drawImage(img, 0, 0);
2202
+ const pdfPageBase64 = whiteSnapshotCanvas.toDataURL("image/png");
2203
+ whiteCtx.clearRect(0, 0, width, height);
2204
+ const camera = {
2205
+ centerX: width / 2,
2206
+ centerY: height / 2 + index * height,
2207
+ scale: 1
2208
+ };
2209
+ const windowManger = this.context.manager.windowManger;
2210
+ if (windowManger._appliancePlugin) {
2211
+ await windowManger._appliancePlugin.screenshotToCanvasAsync(
2212
+ whiteCtx,
2213
+ scenePath,
2214
+ width,
2215
+ height,
2216
+ camera
2217
+ );
2218
+ } else {
2219
+ this.whiteboardView.screenshotToCanvas(whiteCtx, scenePath, width, height, camera);
2220
+ }
2221
+ const snapshot = whiteSnapshotCanvas.toDataURL("image/png");
2222
+ pdf.addImage(pdfPageBase64, "PNG", 0, 0, width, height, "", "FAST");
2223
+ pdf.addImage(snapshot, "PNG", 0, 0, width, height, "", "FAST");
2224
+ whiteCtx.clearRect(0, 0, width, height);
2225
+ const progress = Math.ceil((index + 1) / this.pages.length * 100);
2226
+ if (progress < 100) {
2227
+ this.reportProgress(Math.ceil((index + 1) / this.pages.length * 100), null);
2228
+ }
2229
+ }
2230
+ const dataUrl = pdf.output("arraybuffer");
2231
+ this.reportProgress(100, { pdf: dataUrl, title: this.box.title });
2232
+ };
2233
+ this.context = context;
2234
+ this.whiteboardView = whiteboardView;
2235
+ this.readonly = readonly;
2236
+ this.box = box;
2237
+ this.pages = pages;
2238
+ this.baseScenePath = baseScenePath;
2239
+ this.appId = appId;
2240
+ this.mountWhiteboard = mountWhiteboard;
2241
+ this._onUserScroll = onUserScroll;
2242
+ const debouncedOnUserScroll = this.debounce(
2243
+ () => {
2244
+ this.userScrolling = false;
2245
+ if (this._onUserScroll) {
2246
+ this._onUserScroll(this.pageRenderer.pagesScrollTop);
2247
+ }
2248
+ },
2249
+ { wait: 80 },
2250
+ "debounce-updateUserScroll"
2251
+ );
2252
+ this.updateUserScroll = () => {
2253
+ this.userScrolling = true;
2254
+ debouncedOnUserScroll();
2255
+ };
2256
+ this.viewer = new DocsViewer({
2257
+ readonly,
2258
+ box,
2259
+ pages,
2260
+ onNewPageIndex: this.onNewPageIndex
2261
+ });
2262
+ const { width: containerWidth, height: containerHeight } = this.whiteboardView.size;
2263
+ this.pageRenderer = new PageRenderer({
2264
+ pagesScrollTop: pageScrollTop,
2265
+ pages: this.pages,
2266
+ containerWidth,
2267
+ containerHeight,
2268
+ onPageIndexChanged: this.viewer.setPageIndex.bind(this.viewer)
2269
+ });
2270
+ this.scrollbar = new ScrollBar({
2271
+ pagesScrollTop: this.pageRenderer.pagesScrollTop,
2272
+ containerWidth,
2273
+ containerHeight,
2274
+ pagesWidth: this.pageRenderer.pagesIntrinsicWidth,
2275
+ pagesHeight: this.pageRenderer.pagesIntrinsicHeight,
2276
+ readonly: this.readonly,
2277
+ wrapClassName: this.wrapClassName.bind(this),
2278
+ onDragScroll: (pageScrollTop2) => {
2279
+ this.pageScrollTo(pageScrollTop2);
2280
+ this.updateUserScroll();
2281
+ }
2282
+ });
2283
+ this.pageScrollStepper = new Stepper({
2284
+ start: this.pageRenderer.pagesScrollTop,
2285
+ onStep: (pageScrollTop2) => {
2286
+ this.pageScrollTo(pageScrollTop2);
2287
+ }
2288
+ });
2289
+ this.render();
2290
+ }
2291
+ setDocsViewReadonly(isReadonly) {
2292
+ this.docsViewReadonly = isReadonly;
2293
+ }
2294
+ mount() {
2295
+ this.viewer.mount();
2296
+ this.setupScrollListener();
2297
+ const debouncedRenderRatioHeight = this.debounce(this.renderRatioHeight.bind(this), {
2298
+ wait: 80
2299
+ });
2300
+ this.sideEffect.add(() => {
2301
+ const observer = new ResizeObserver(debouncedRenderRatioHeight);
2302
+ observer.observe(this.viewer.$content);
2303
+ return () => observer.disconnect();
2304
+ });
2305
+ this.sideEffect.setTimeout(() => {
2306
+ if (!this.userScrolling) {
2307
+ this.pageScrollTo(this.pageRenderer.pagesScrollTop);
2308
+ }
2309
+ }, 100);
2310
+ this.sideEffect.add(() => {
2311
+ const handleDownloadPdf = (evt) => {
2312
+ if (evt.data.type === "@netless/_request_save_pdf_" && evt.data.appId === this.appId) {
2313
+ this.toPdf().catch(() => this.reportProgress(100, null));
2314
+ }
2315
+ };
2316
+ window.addEventListener("message", handleDownloadPdf);
2317
+ return () => {
2318
+ window.removeEventListener("message", handleDownloadPdf);
2319
+ };
2320
+ });
2321
+ return this;
2322
+ }
2323
+ unmount() {
2324
+ this.viewer.unmount();
2325
+ return this;
2326
+ }
2327
+ setReadonly(readonly) {
2328
+ if (this.readonly !== readonly) {
2329
+ this.readonly = readonly;
2330
+ this.viewer.setReadonly(readonly);
2331
+ this.scrollbar.setReadonly(readonly);
2332
+ }
2333
+ }
2334
+ destroy() {
2335
+ this.sideEffect.flushAll();
2336
+ this.pageScrollStepper.destroy();
2337
+ this._onUserScroll = void 0;
2338
+ this.unmount();
2339
+ this.viewer.destroy();
2340
+ this.pageRenderer.destroy();
2341
+ this.scrollbar.destroy();
2342
+ }
2343
+ syncPageScrollTop(pageScrollTop) {
2344
+ if (!this.userScrolling && pageScrollTop >= 0 && Math.abs(this.pageRenderer.pagesScrollTop - pageScrollTop) > 0.01) {
2345
+ this.pageScrollStepper.stepTo(pageScrollTop, this.pageRenderer.pagesScrollTop);
2346
+ }
2347
+ }
2348
+ render() {
2349
+ this.pageRenderer.mount(this.viewer.$content);
2350
+ this.viewer.$content.appendChild(this.renderWhiteboardView());
2351
+ this.scrollbar.mount(this.viewer.$content);
2352
+ this.renderRatioHeight();
2353
+ }
2354
+ renderRatioHeight() {
2355
+ const boxHeight = this.box.absoluteHeight;
2356
+ const isSmallBox = boxHeight <= RATIO_BASE_CONTAINER_HEIGHT;
2357
+ this.viewer.setSmallBox(isSmallBox);
2358
+ if (isSmallBox) {
2359
+ const titleBarSupposedHeight = 26 / RATIO_BASE_CONTAINER_HEIGHT;
2360
+ const titleBarActualHeight = 26 / boxHeight;
2361
+ const footerSupposedHeight = 26 / RATIO_BASE_CONTAINER_HEIGHT;
2362
+ const footerActualHeight = 0;
2363
+ const emptySpace = Math.max(
2364
+ (titleBarSupposedHeight + footerSupposedHeight - (titleBarActualHeight + footerActualHeight)) / 2,
2365
+ 0
2366
+ );
2367
+ if (this.box.$titleBar) {
2368
+ const titleBarHeight = titleBarActualHeight + emptySpace;
2369
+ this.box.$titleBar.style.height = `${titleBarHeight * 100}%`;
2370
+ }
2371
+ if (this.box.$footer) {
2372
+ const footerHeight = footerActualHeight + emptySpace;
2373
+ this.box.$footer.style.height = `${footerHeight * 100}%`;
2374
+ }
2375
+ } else {
2376
+ if (this.box.$titleBar) {
2377
+ const titleBarHeight = Math.max(26 / RATIO_BASE_CONTAINER_HEIGHT, 26 / boxHeight);
2378
+ this.box.$titleBar.style.height = `${titleBarHeight * 100}%`;
2379
+ }
2380
+ if (this.box.$footer) {
2381
+ const footerHeight = Math.max(26 / RATIO_BASE_CONTAINER_HEIGHT, 26 / boxHeight);
2382
+ this.box.$footer.style.height = `${footerHeight * 100}%`;
2383
+ }
2384
+ }
2385
+ }
2386
+ renderWhiteboardView() {
2387
+ if (!this.$whiteboardView) {
2388
+ this.$whiteboardView = document.createElement("div");
2389
+ this.$whiteboardView.className = this.wrapClassName("wb-view");
2390
+ this.mountWhiteboard(this.$whiteboardView);
2391
+ this.sideEffect.addEventListener(
2392
+ this.$whiteboardView,
2393
+ "wheel",
2394
+ (ev) => {
2395
+ preventEvent(ev);
2396
+ if (!this.readonly) {
2397
+ this.pageScrollTo(this.pageRenderer.pagesScrollTop + ev.deltaY);
2398
+ this.updateUserScroll();
2399
+ }
2400
+ },
2401
+ { passive: false, capture: true }
2402
+ );
2403
+ this.sideEffect.addEventListener(
2404
+ this.$whiteboardView,
2405
+ "touchmove",
2406
+ (ev) => {
2407
+ if (this.readonly || ev.touches.length <= 1) {
2408
+ return;
2409
+ }
2410
+ this.updateUserScroll();
2411
+ },
2412
+ { passive: true, capture: true }
2413
+ );
2414
+ }
2415
+ return this.$whiteboardView;
2416
+ }
2417
+ scrollTopPageToEl(pageScrollTop) {
2418
+ return pageScrollTop * this.pageRenderer.scale;
2419
+ }
2420
+ scrollTopElToPage(elScrollTop) {
2421
+ return elScrollTop / this.pageRenderer.scale;
2422
+ }
2423
+ elScrollTo(elScrollTop) {
2424
+ this.pageScrollTo(this.scrollTopElToPage(elScrollTop));
2425
+ }
2426
+ pageScrollTo(pageScrollTop) {
2427
+ const halfWbHeight = this.scrollTopElToPage(this.whiteboardView.size.height / 2);
2428
+ this.whiteboardView.moveCamera({
2429
+ centerY: clamp(
2430
+ pageScrollTop + halfWbHeight,
2431
+ halfWbHeight,
2432
+ this.pageRenderer.pagesIntrinsicHeight - halfWbHeight
2433
+ ),
2434
+ animationMode: "immediately"
2435
+ });
2436
+ }
2437
+ scrollToPage(index) {
2438
+ if (!this.readonly && !Number.isNaN(index)) {
2439
+ const offsetY = this.pageRenderer.pagesIntrinsicYs[index];
2440
+ if (offsetY >= 0) {
2441
+ this.pageScrollTo(offsetY + 5 / this.pageRenderer.scale);
2442
+ this.updateUserScroll();
2443
+ }
2444
+ }
2445
+ }
2446
+ setupScrollListener() {
2447
+ this.sideEffect.add(() => {
2448
+ const handleCameraUpdate = (camera) => {
2449
+ const { width: wbWidth, height: wbHeight } = this.whiteboardView.size;
2450
+ if (wbWidth <= 0 || wbHeight <= 0) {
2451
+ return;
2452
+ }
2453
+ const pagesScrollTop = camera.centerY - this.pageRenderer.containerHeight / this.pageRenderer.scale / 2;
2454
+ this.pageRenderer.pagesScrollTo(pagesScrollTop);
2455
+ this.scrollbar.pagesScrollTo(pagesScrollTop);
2456
+ };
2457
+ this.whiteboardView.callbacks.on("onCameraUpdated", handleCameraUpdate);
2458
+ return () => this.whiteboardView.callbacks.off("onCameraUpdated", handleCameraUpdate);
2459
+ });
2460
+ this.sideEffect.add(() => {
2461
+ const { updateUserScroll } = this;
2462
+ this.whiteboardView.callbacks.on("onCameraUpdatedByDevice", updateUserScroll);
2463
+ return () => this.whiteboardView.callbacks.off("onCameraUpdatedByDevice", updateUserScroll);
2464
+ });
2465
+ this.sideEffect.add(() => {
2466
+ const handleSizeUpdate = ({ width: wbWidth, height: wbHeight }) => {
2467
+ if (wbWidth <= 0 || wbHeight <= 0) {
2468
+ return;
2469
+ }
2470
+ this.pageRenderer.setContainerSize(wbWidth, wbHeight);
2471
+ this.scrollbar.setContainerSize(wbWidth, wbHeight);
2472
+ const { pagesIntrinsicWidth, pagesIntrinsicHeight } = this.pageRenderer;
2473
+ this.whiteboardView.moveCameraToContain({
2474
+ originX: 0,
2475
+ originY: this.pageRenderer.pagesScrollTop,
2476
+ width: pagesIntrinsicWidth,
2477
+ height: wbHeight / this.pageRenderer.scale,
2478
+ animationMode: "immediately"
2479
+ });
2480
+ this.whiteboardView.setCameraBound({
2481
+ damping: 1,
2482
+ maxContentMode: () => this.pageRenderer.scale,
2483
+ minContentMode: () => this.pageRenderer.scale,
2484
+ centerX: pagesIntrinsicWidth / 2,
2485
+ centerY: pagesIntrinsicHeight / 2,
2486
+ width: pagesIntrinsicWidth,
2487
+ height: pagesIntrinsicHeight
2488
+ });
2489
+ };
2490
+ this.whiteboardView.callbacks.on("onSizeUpdated", handleSizeUpdate);
2491
+ return () => {
2492
+ this.whiteboardView.callbacks.off("onSizeUpdated", handleSizeUpdate);
2493
+ };
2494
+ }, "whiteboard-size-update");
2495
+ this.sideEffect.addEventListener(
2496
+ window,
2497
+ "keyup",
2498
+ (ev) => {
2499
+ if (this.readonly || !this.box.focus || this.box.minimized || isEditable(ev.target)) {
2500
+ return;
2501
+ }
2502
+ if (this.docsViewReadonly) {
2503
+ return;
2504
+ }
2505
+ let newPageScrollTop = null;
2506
+ switch (ev.key) {
2507
+ case "PageDown": {
2508
+ newPageScrollTop = this.pageRenderer.pagesScrollTop + this.pageRenderer.containerHeight / this.pageRenderer.scale;
2509
+ break;
2510
+ }
2511
+ case "PageUp": {
2512
+ newPageScrollTop = this.pageRenderer.pagesScrollTop - this.pageRenderer.containerHeight / this.pageRenderer.scale;
2513
+ break;
2514
+ }
2515
+ case "ArrowDown": {
2516
+ newPageScrollTop = this.pageRenderer.pagesScrollTop + this.pageRenderer.containerHeight / 4 / this.pageRenderer.scale;
2517
+ break;
2518
+ }
2519
+ case "ArrowUp": {
2520
+ newPageScrollTop = this.pageRenderer.pagesScrollTop - this.pageRenderer.containerHeight / 4 / this.pageRenderer.scale;
2521
+ break;
2522
+ }
2523
+ }
2524
+ if (newPageScrollTop !== null) {
2525
+ if (this._onUserScroll) {
2526
+ this._onUserScroll(newPageScrollTop);
2527
+ } else {
2528
+ this.pageScrollTo(newPageScrollTop);
2529
+ this.updateUserScroll();
2530
+ }
2531
+ }
2532
+ },
2533
+ { capture: true }
2534
+ );
2535
+ }
2536
+ debounce(fn, options, disposerID) {
2537
+ const dFn = debounceFn(fn, options);
2538
+ this.sideEffect.addDisposer(() => dFn.cancel(), disposerID);
2539
+ return dFn;
2540
+ }
2541
+ wrapClassName(className) {
2542
+ return "netless-app-docs-viewer-static-" + className;
2543
+ }
2544
+ async getBase64FromUrl(url) {
2545
+ const data = await fetch(this._invalidate(url));
2546
+ const blob = await data.blob();
2547
+ return new Promise((resolve) => {
2548
+ const reader = new FileReader();
2549
+ reader.readAsDataURL(blob);
2550
+ reader.onloadend = () => {
2551
+ const base64data = reader.result;
2552
+ resolve(base64data);
2553
+ };
2554
+ });
2555
+ }
2556
+ _invalidate(url) {
2557
+ try {
2558
+ const a = new URL(url);
2559
+ a.searchParams.set("t", Date.now().toString());
2560
+ return a.toString();
2561
+ } catch {
2562
+ return url;
2563
+ }
2564
+ }
2565
+ reportProgress(progress, result) {
2566
+ window.postMessage({
2567
+ type: "@netless/_result_save_pdf_",
2568
+ appId: this.appId,
2569
+ progress,
2570
+ result
2571
+ });
2572
+ }
2573
+ }
2574
+ class DynamicDocsViewer {
2575
+ constructor({ context, whiteboardView, box, pages }) {
2576
+ this.sideEffect = new SideEffectManager();
2577
+ this.docsViewReadonly = false;
2578
+ this.onPlayPPT = () => {
2579
+ const room = this.context.getRoom();
2580
+ if (room) {
2581
+ room.pptNextStep();
2582
+ }
2583
+ };
2584
+ this._scaleDocsToFitImpl = () => {
2585
+ const page = this.pages[this.getPageIndex()];
2586
+ if (page) {
2587
+ this.whiteboardView.moveCameraToContain({
2588
+ originX: -page.width / 2,
2589
+ originY: -page.height / 2,
2590
+ width: page.width,
2591
+ height: page.height,
2592
+ animationMode: "immediately"
2593
+ });
2594
+ this.whiteboardView.setCameraBound({
2595
+ damping: 1,
2596
+ maxContentMode: () => this.whiteboardView.camera.scale,
2597
+ minContentMode: () => this.whiteboardView.camera.scale,
2598
+ centerX: 0,
2599
+ centerY: 0,
2600
+ width: page.width,
2601
+ height: page.height
2602
+ });
2603
+ }
2604
+ };
2605
+ this._scaleDocsToFitDebounced = () => {
2606
+ this.sideEffect.setTimeout(this._scaleDocsToFitImpl, 1e3, "_scaleDocsToFitDebounced");
2607
+ };
2608
+ this.scaleDocsToFit = () => {
2609
+ this._scaleDocsToFitImpl();
2610
+ this._scaleDocsToFitDebounced();
2611
+ };
2612
+ this.onNewPageIndex = (index) => {
2613
+ this.jumpToPage(index, true);
2614
+ };
2615
+ this.context = context;
2616
+ this.whiteboardView = whiteboardView;
2617
+ this.box = box;
2618
+ this.pages = pages;
2619
+ this.displayer = context.getDisplayer();
2620
+ this.viewer = new DocsViewer({
2621
+ readonly: !context.getIsWritable(),
2622
+ box,
2623
+ pages,
2624
+ onNewPageIndex: this.onNewPageIndex,
2625
+ onPlay: this.onPlayPPT
2626
+ });
2627
+ this.render();
2628
+ this.sideEffect.add(() => {
2629
+ const handler = (isWritable) => {
2630
+ this.viewer.setReadonly(!isWritable);
2631
+ };
2632
+ this.context.emitter.on("writableChange", handler);
2633
+ return () => this.context.emitter.off("writableChange", handler);
2634
+ });
2635
+ this.sideEffect.add(() => {
2636
+ const handler = (sceneState) => {
2637
+ this.jumpToPage(sceneState.index);
2638
+ };
2639
+ this.context.emitter.on("sceneStateChange", handler);
2640
+ return () => this.context.emitter.off("sceneStateChange", handler);
2641
+ });
2642
+ }
2643
+ setDocsViewReadonly(isReadonly) {
2644
+ this.docsViewReadonly = isReadonly;
2645
+ }
2646
+ mount() {
2647
+ this.viewer.mount();
2648
+ const pageIndex = this.getPageIndex();
2649
+ if (pageIndex !== 0) {
2650
+ this.jumpToPage(pageIndex);
2651
+ }
2652
+ this.scaleDocsToFit();
2653
+ this.sideEffect.add(() => {
2654
+ this.whiteboardView.callbacks.on("onSizeUpdated", this.scaleDocsToFit);
2655
+ return () => {
2656
+ this.whiteboardView.callbacks.off("onSizeUpdated", this.scaleDocsToFit);
2657
+ };
2658
+ });
2659
+ return this;
2660
+ }
2661
+ unmount() {
2662
+ this.viewer.unmount();
2663
+ return this;
2664
+ }
2665
+ destroy() {
2666
+ this.sideEffect.flushAll();
2667
+ this.unmount();
2668
+ this.viewer.destroy();
2669
+ }
2670
+ getPageIndex() {
2671
+ return this.displayer.state.sceneState.index;
2672
+ }
2673
+ jumpToPage(index, reset) {
2674
+ var _a, _b;
2675
+ index = clamp(index, 0, this.pages.length - 1);
2676
+ if (index !== this.getPageIndex()) {
2677
+ if (this.context.getIsWritable()) {
2678
+ const initScenePath = this.context.getInitScenePath();
2679
+ const scene = (_b = (_a = this.context.getScenes()) == null ? void 0 : _a[index]) == null ? void 0 : _b.name;
2680
+ if (initScenePath && scene) {
2681
+ this.context.setScenePath(`${initScenePath}/${scene}`);
2682
+ }
2683
+ this.scaleDocsToFit();
2684
+ }
2685
+ }
2686
+ if (index !== this.viewer.pageIndex) {
2687
+ this.viewer.setPageIndex(index);
2688
+ }
2689
+ if (reset) {
2690
+ const room = this.context.getRoom();
2691
+ if (room) {
2692
+ const pptState = room.state.globalState.__pptState;
2693
+ room.setGlobalState({
2694
+ __pptState: pptState && {
2695
+ uuid: pptState.uuid,
2696
+ pageIndex: index,
2697
+ disableAutoPlay: pptState.disableAutoPlay
2698
+ }
2699
+ });
2700
+ }
2701
+ }
2702
+ }
2703
+ render() {
2704
+ this.viewer.$content.appendChild(this.renderMask());
2705
+ this.viewer.$content.appendChild(this.renderWhiteboardView());
2706
+ this.sideEffect.addEventListener(window, "keydown", (ev) => {
2707
+ var _a;
2708
+ if (this.docsViewReadonly) {
2709
+ return;
2710
+ }
2711
+ if (this.box.focus && !isEditable(ev.target)) {
2712
+ switch (ev.key) {
2713
+ case "ArrowUp":
2714
+ case "ArrowLeft": {
2715
+ this.jumpToPage(this.getPageIndex() - 1, true);
2716
+ break;
2717
+ }
2718
+ case "ArrowRight":
2719
+ case "ArrowDown": {
2720
+ (_a = this.context.getRoom()) == null ? void 0 : _a.pptNextStep();
2721
+ break;
2722
+ }
2723
+ }
2724
+ }
2725
+ });
2726
+ }
2727
+ renderMask() {
2728
+ if (!this.$mask) {
2729
+ const $mask = document.createElement("div");
2730
+ $mask.className = this.wrapClassName("mask");
2731
+ this.$mask = $mask;
2732
+ const $back = document.createElement("button");
2733
+ $back.className = this.wrapClassName("back");
2734
+ const $next = document.createElement("button");
2735
+ $next.className = this.wrapClassName("next");
2736
+ }
2737
+ return this.$mask;
2738
+ }
2739
+ renderWhiteboardView() {
2740
+ if (!this.$whiteboardView) {
2741
+ this.$whiteboardView = document.createElement("div");
2742
+ this.$whiteboardView.className = this.wrapClassName("wb-view");
2743
+ this.sideEffect.addEventListener(this.$whiteboardView, "click", (ev) => {
2744
+ var _a;
2745
+ const room = this.context.getRoom();
2746
+ if (room && room.state.memberState.currentApplianceName === "clicker") {
2747
+ for (let el = ev.target; el; el = el.parentElement) {
2748
+ if ((_a = el.classList) == null ? void 0 : _a.contains("ppt-event-source")) {
2749
+ return;
2750
+ }
2751
+ }
2752
+ room.pptNextStep();
2753
+ }
2754
+ });
2755
+ this.context.mountView(this.$whiteboardView);
2756
+ }
2757
+ return this.$whiteboardView;
2758
+ }
2759
+ wrapClassName(className) {
2760
+ return "netless-app-docs-viewer-dynamic-" + className;
2761
+ }
2762
+ }
2763
+ const kind = "DocsViewer";
2764
+ const NetlessAppDocsViewer = {
2765
+ kind,
2766
+ setup(context) {
2767
+ const box = context.getBox();
2768
+ const scenes = context.getScenes();
2769
+ if (!scenes) {
2770
+ throw new Error("[Docs Viewer]: scenes not found.");
2771
+ }
2772
+ const whiteboardView = context.getView();
2773
+ if (!whiteboardView) {
2774
+ throw new Error("[Docs Viewer]: no whiteboard view.");
2775
+ }
2776
+ const pages = scenes.map(
2777
+ ({ ppt }) => ppt ? {
2778
+ width: ppt.width,
2779
+ height: ppt.height,
2780
+ src: ppt.src,
2781
+ thumbnail: ppt.previewURL
2782
+ } : null
2783
+ ).filter((page) => Boolean(page));
2784
+ if (pages.length <= 0) {
2785
+ throw new Error("[Docs Viewer]: empty scenes.");
2786
+ }
2787
+ box.mountStyles(styles);
2788
+ let docsViewer = null;
2789
+ if (pages[0].src.startsWith("ppt")) {
2790
+ docsViewer = setupDynamicDocsViewer(
2791
+ context,
2792
+ whiteboardView,
2793
+ box,
2794
+ pages
2795
+ );
2796
+ } else {
2797
+ docsViewer = setupStaticDocsViewer(
2798
+ context,
2799
+ whiteboardView,
2800
+ box,
2801
+ pages
2802
+ );
2803
+ }
2804
+ const appOptions = context.getAppOptions() || {};
2805
+ if (appOptions.justDocsViewReadonly) {
2806
+ docsViewer.setDocsViewReadonly(true);
2807
+ }
2808
+ return {
2809
+ setDocsViewReadonly: (bol) => {
2810
+ docsViewer == null ? void 0 : docsViewer.setDocsViewReadonly(bol);
2811
+ }
2812
+ };
2813
+ }
2814
+ };
2815
+ function setupStaticDocsViewer(context, whiteboardView, box, pages) {
2816
+ var _a;
2817
+ whiteboardView.disableCameraTransform = !context.getIsWritable();
2818
+ const docsViewer = new StaticDocsViewer({
2819
+ context,
2820
+ whiteboardView,
2821
+ readonly: !context.getIsWritable(),
2822
+ box,
2823
+ pages,
2824
+ pageScrollTop: (_a = context.getAttributes()) == null ? void 0 : _a.pageScrollTop,
2825
+ mountWhiteboard: context.mountView.bind(context),
2826
+ onUserScroll: (pageScrollTop) => {
2827
+ var _a2;
2828
+ if (((_a2 = context.getAttributes()) == null ? void 0 : _a2.pageScrollTop) !== pageScrollTop && !box.readonly) {
2829
+ context.updateAttributes(["pageScrollTop"], pageScrollTop);
2830
+ }
2831
+ },
2832
+ baseScenePath: context.getInitScenePath(),
2833
+ appId: context.appId
2834
+ }).mount();
2835
+ docsViewer.viewer.onPageIndexChanged = (index) => {
2836
+ context.dispatchAppEvent("pageStateChange", { index, length: pages.length });
2837
+ };
2838
+ context.dispatchAppEvent("pageStateChange", {
2839
+ index: docsViewer.viewer.pageIndex,
2840
+ length: pages.length
2841
+ });
2842
+ context.emitter.on("attributesUpdate", (attributes) => {
2843
+ if (attributes) {
2844
+ if (attributes.pageScrollTop != null) {
2845
+ docsViewer.syncPageScrollTop(attributes.pageScrollTop);
2846
+ }
2847
+ }
2848
+ });
2849
+ context.emitter.on("writableChange", (isWritable) => {
2850
+ docsViewer.setReadonly(!isWritable);
2851
+ whiteboardView.disableCameraTransform = !isWritable;
2852
+ });
2853
+ return docsViewer;
2854
+ }
2855
+ function setupDynamicDocsViewer(context, whiteboardView, box, pages) {
2856
+ whiteboardView.disableCameraTransform = true;
2857
+ const docsViewer = new DynamicDocsViewer({
2858
+ context,
2859
+ whiteboardView,
2860
+ box,
2861
+ pages
2862
+ }).mount();
2863
+ docsViewer.viewer.onPageIndexChanged = (index) => {
2864
+ context.dispatchAppEvent("pageStateChange", { index, length: pages.length });
2865
+ };
2866
+ context.dispatchAppEvent("pageStateChange", {
2867
+ index: docsViewer.getPageIndex(),
2868
+ length: pages.length
2869
+ });
2870
+ context.mountView(docsViewer.$whiteboardView);
2871
+ if (context.isAddApp) {
2872
+ whiteboardView.callbacks.once(
2873
+ "onSizeUpdated",
2874
+ ({ width: contentWidth, height: contentHeight }) => {
2875
+ if (pages.length > 0 && box.state !== "maximized") {
2876
+ const { width: pageWidth, height: pageHeight } = pages[0];
2877
+ const preferHeight = pageHeight / pageWidth * contentWidth;
2878
+ const diff = preferHeight - contentHeight;
2879
+ if (diff !== 0 && context.getIsWritable()) {
2880
+ context.emitter.emit("setBoxSize", {
2881
+ width: box.width,
2882
+ height: box.height + diff / box.containerRect.height
2883
+ });
2884
+ }
2885
+ }
2886
+ }
2887
+ );
2888
+ }
2889
+ return docsViewer;
2890
+ }
2891
+ export { NetlessAppDocsViewer as default };
2892
+ //# sourceMappingURL=app-docs-viewer.mjs.map