@novely/core 0.45.1 → 0.46.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +53 -33
- package/dist/index.global.js +1115 -939
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +817 -733
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.global.js
CHANGED
|
@@ -31,63 +31,96 @@ var Novely = (() => {
|
|
|
31
31
|
novely: () => novely
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"mp4",
|
|
60
|
-
"weba",
|
|
61
|
-
"webm",
|
|
62
|
-
"dolby",
|
|
63
|
-
"flac"
|
|
64
|
-
]);
|
|
65
|
-
var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
66
|
-
"apng",
|
|
67
|
-
"avif",
|
|
68
|
-
"gif",
|
|
69
|
-
"jpg",
|
|
70
|
-
"jpeg",
|
|
71
|
-
"jfif",
|
|
72
|
-
"pjpeg",
|
|
73
|
-
"pjp",
|
|
74
|
-
"png",
|
|
75
|
-
"svg",
|
|
76
|
-
"webp",
|
|
77
|
-
"bmp"
|
|
78
|
-
]);
|
|
79
|
-
var MAIN_CONTEXT_KEY = "$MAIN";
|
|
80
|
-
|
|
81
|
-
// src/shared.ts
|
|
82
|
-
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
83
|
-
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
84
|
-
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
85
|
-
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
34
|
+
// ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
35
|
+
var has = Object.prototype.hasOwnProperty;
|
|
36
|
+
function dequal(foo, bar) {
|
|
37
|
+
var ctor, len;
|
|
38
|
+
if (foo === bar) return true;
|
|
39
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
40
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
41
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
42
|
+
if (ctor === Array) {
|
|
43
|
+
if ((len = foo.length) === bar.length) {
|
|
44
|
+
while (len-- && dequal(foo[len], bar[len])) ;
|
|
45
|
+
}
|
|
46
|
+
return len === -1;
|
|
47
|
+
}
|
|
48
|
+
if (!ctor || typeof foo === "object") {
|
|
49
|
+
len = 0;
|
|
50
|
+
for (ctor in foo) {
|
|
51
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
52
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
53
|
+
}
|
|
54
|
+
return Object.keys(bar).length === len;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return foo !== foo && bar !== bar;
|
|
58
|
+
}
|
|
86
59
|
|
|
87
|
-
// ../../node_modules/.pnpm/
|
|
88
|
-
|
|
60
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/function/debounce.mjs
|
|
61
|
+
function debounce(func, debounceMs, { signal, edges } = {}) {
|
|
62
|
+
let pendingThis = void 0;
|
|
63
|
+
let pendingArgs = null;
|
|
64
|
+
const leading = edges != null && edges.includes("leading");
|
|
65
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
66
|
+
const invoke = () => {
|
|
67
|
+
if (pendingArgs !== null) {
|
|
68
|
+
func.apply(pendingThis, pendingArgs);
|
|
69
|
+
pendingThis = void 0;
|
|
70
|
+
pendingArgs = null;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const onTimerEnd = () => {
|
|
74
|
+
if (trailing) {
|
|
75
|
+
invoke();
|
|
76
|
+
}
|
|
77
|
+
cancel();
|
|
78
|
+
};
|
|
79
|
+
let timeoutId = null;
|
|
80
|
+
const schedule = () => {
|
|
81
|
+
if (timeoutId != null) {
|
|
82
|
+
clearTimeout(timeoutId);
|
|
83
|
+
}
|
|
84
|
+
timeoutId = setTimeout(() => {
|
|
85
|
+
timeoutId = null;
|
|
86
|
+
onTimerEnd();
|
|
87
|
+
}, debounceMs);
|
|
88
|
+
};
|
|
89
|
+
const cancelTimer = () => {
|
|
90
|
+
if (timeoutId !== null) {
|
|
91
|
+
clearTimeout(timeoutId);
|
|
92
|
+
timeoutId = null;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const cancel = () => {
|
|
96
|
+
cancelTimer();
|
|
97
|
+
pendingThis = void 0;
|
|
98
|
+
pendingArgs = null;
|
|
99
|
+
};
|
|
100
|
+
const flush = () => {
|
|
101
|
+
cancelTimer();
|
|
102
|
+
invoke();
|
|
103
|
+
};
|
|
104
|
+
const debounced = function(...args) {
|
|
105
|
+
if (signal?.aborted) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
pendingThis = this;
|
|
109
|
+
pendingArgs = args;
|
|
110
|
+
const isFirstCall = timeoutId == null;
|
|
111
|
+
schedule();
|
|
112
|
+
if (leading && isFirstCall) {
|
|
113
|
+
invoke();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
debounced.schedule = schedule;
|
|
117
|
+
debounced.cancel = cancel;
|
|
118
|
+
debounced.flush = flush;
|
|
119
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
120
|
+
return debounced;
|
|
121
|
+
}
|
|
89
122
|
|
|
90
|
-
// ../../node_modules/.pnpm/es-toolkit@1.
|
|
123
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/function/once.mjs
|
|
91
124
|
function once(func) {
|
|
92
125
|
let called = false;
|
|
93
126
|
let cache;
|
|
@@ -102,20 +135,28 @@ var Novely = (() => {
|
|
|
102
135
|
};
|
|
103
136
|
}
|
|
104
137
|
|
|
105
|
-
// ../../node_modules/.pnpm/es-toolkit@1.
|
|
106
|
-
function throttle(func, throttleMs) {
|
|
107
|
-
let
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/function/throttle.mjs
|
|
139
|
+
function throttle(func, throttleMs, { signal, edges = ["leading", "trailing"] } = {}) {
|
|
140
|
+
let pendingAt = null;
|
|
141
|
+
const debounced = debounce(func, throttleMs, { signal, edges });
|
|
142
|
+
const throttled = function(...args) {
|
|
143
|
+
if (pendingAt == null) {
|
|
144
|
+
pendingAt = Date.now();
|
|
145
|
+
} else {
|
|
146
|
+
if (Date.now() - pendingAt >= throttleMs) {
|
|
147
|
+
pendingAt = Date.now();
|
|
148
|
+
debounced.cancel();
|
|
149
|
+
debounced(...args);
|
|
150
|
+
}
|
|
113
151
|
}
|
|
152
|
+
debounced(...args);
|
|
114
153
|
};
|
|
115
|
-
|
|
154
|
+
throttled.cancel = debounced.cancel;
|
|
155
|
+
throttled.flush = debounced.flush;
|
|
156
|
+
return throttled;
|
|
116
157
|
}
|
|
117
158
|
|
|
118
|
-
// ../../node_modules/.pnpm/es-toolkit@1.
|
|
159
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/function/memoize.mjs
|
|
119
160
|
function memoize(fn, options = {}) {
|
|
120
161
|
const { cache = /* @__PURE__ */ new Map(), getCacheKey } = options;
|
|
121
162
|
const memoizedFn = function(arg) {
|
|
@@ -131,156 +172,275 @@ var Novely = (() => {
|
|
|
131
172
|
return memoizedFn;
|
|
132
173
|
}
|
|
133
174
|
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
155
|
-
};
|
|
175
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
|
|
176
|
+
function isPlainObject(value) {
|
|
177
|
+
if (typeof value !== "object") {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
if (value == null) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
if (Object.getPrototypeOf(value) === null) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
if (value.toString() !== "[object Object]") {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
let proto = value;
|
|
190
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
191
|
+
proto = Object.getPrototypeOf(proto);
|
|
192
|
+
}
|
|
193
|
+
return Object.getPrototypeOf(value) === proto;
|
|
194
|
+
}
|
|
156
195
|
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
webp
|
|
180
|
-
};
|
|
181
|
-
var loadImageFormatsSupport = async () => {
|
|
182
|
-
const promises = [];
|
|
183
|
-
for (const [format, source] of Object.entries(formatsMap)) {
|
|
184
|
-
const promise = supportsFormat(source).then((supported) => {
|
|
185
|
-
supportsMap2[format] = supported;
|
|
186
|
-
});
|
|
187
|
-
promises.push(promise);
|
|
196
|
+
// ../../node_modules/.pnpm/es-toolkit@1.23.0/node_modules/es-toolkit/dist/object/merge.mjs
|
|
197
|
+
function merge(target, source) {
|
|
198
|
+
const sourceKeys = Object.keys(source);
|
|
199
|
+
for (let i = 0; i < sourceKeys.length; i++) {
|
|
200
|
+
const key = sourceKeys[i];
|
|
201
|
+
const sourceValue = source[key];
|
|
202
|
+
const targetValue = target[key];
|
|
203
|
+
if (Array.isArray(sourceValue)) {
|
|
204
|
+
if (Array.isArray(targetValue)) {
|
|
205
|
+
target[key] = merge(targetValue, sourceValue);
|
|
206
|
+
} else {
|
|
207
|
+
target[key] = merge([], sourceValue);
|
|
208
|
+
}
|
|
209
|
+
} else if (isPlainObject(sourceValue)) {
|
|
210
|
+
if (isPlainObject(targetValue)) {
|
|
211
|
+
target[key] = merge(targetValue, sourceValue);
|
|
212
|
+
} else {
|
|
213
|
+
target[key] = merge({}, sourceValue);
|
|
214
|
+
}
|
|
215
|
+
} else if (targetValue === void 0 || sourceValue !== void 0) {
|
|
216
|
+
target[key] = sourceValue;
|
|
217
|
+
}
|
|
188
218
|
}
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
loadImageFormatsSupport();
|
|
219
|
+
return target;
|
|
220
|
+
}
|
|
192
221
|
|
|
193
|
-
//
|
|
194
|
-
var
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
222
|
+
// ../../node_modules/.pnpm/esm-env@1.0.0/node_modules/esm-env/prod-ssr.js
|
|
223
|
+
var DEV = false;
|
|
224
|
+
|
|
225
|
+
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
226
|
+
function set(obj, key, val) {
|
|
227
|
+
if (typeof val.value === "object") val.value = klona(val.value);
|
|
228
|
+
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
229
|
+
Object.defineProperty(obj, key, val);
|
|
230
|
+
} else obj[key] = val.value;
|
|
231
|
+
}
|
|
232
|
+
function klona(x) {
|
|
233
|
+
if (typeof x !== "object") return x;
|
|
234
|
+
var i = 0, k, list, tmp, str = Object.prototype.toString.call(x);
|
|
235
|
+
if (str === "[object Object]") {
|
|
236
|
+
tmp = Object.create(x.__proto__ || null);
|
|
237
|
+
} else if (str === "[object Array]") {
|
|
238
|
+
tmp = Array(x.length);
|
|
239
|
+
} else if (str === "[object Set]") {
|
|
240
|
+
tmp = /* @__PURE__ */ new Set();
|
|
241
|
+
x.forEach(function(val) {
|
|
242
|
+
tmp.add(klona(val));
|
|
243
|
+
});
|
|
244
|
+
} else if (str === "[object Map]") {
|
|
245
|
+
tmp = /* @__PURE__ */ new Map();
|
|
246
|
+
x.forEach(function(val, key) {
|
|
247
|
+
tmp.set(klona(key), klona(val));
|
|
248
|
+
});
|
|
249
|
+
} else if (str === "[object Date]") {
|
|
250
|
+
tmp = /* @__PURE__ */ new Date(+x);
|
|
251
|
+
} else if (str === "[object RegExp]") {
|
|
252
|
+
tmp = new RegExp(x.source, x.flags);
|
|
253
|
+
} else if (str === "[object DataView]") {
|
|
254
|
+
tmp = new x.constructor(klona(x.buffer));
|
|
255
|
+
} else if (str === "[object ArrayBuffer]") {
|
|
256
|
+
tmp = x.slice(0);
|
|
257
|
+
} else if (str.slice(-6) === "Array]") {
|
|
258
|
+
tmp = new x.constructor(x);
|
|
259
|
+
}
|
|
260
|
+
if (tmp) {
|
|
261
|
+
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
262
|
+
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
198
263
|
}
|
|
199
|
-
|
|
200
|
-
|
|
264
|
+
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
265
|
+
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
266
|
+
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
201
267
|
}
|
|
202
|
-
throw extensions;
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
getCacheKey: (extensions) => extensions.join("~")
|
|
206
268
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
269
|
+
return tmp || x;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ../../node_modules/.pnpm/yocto-queue@1.1.1/node_modules/yocto-queue/index.js
|
|
273
|
+
var Node = class {
|
|
274
|
+
value;
|
|
275
|
+
next;
|
|
276
|
+
constructor(value) {
|
|
277
|
+
this.value = value;
|
|
278
|
+
}
|
|
211
279
|
};
|
|
212
|
-
var
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
280
|
+
var Queue = class {
|
|
281
|
+
#head;
|
|
282
|
+
#tail;
|
|
283
|
+
#size;
|
|
284
|
+
constructor() {
|
|
285
|
+
this.clear();
|
|
286
|
+
}
|
|
287
|
+
enqueue(value) {
|
|
288
|
+
const node = new Node(value);
|
|
289
|
+
if (this.#head) {
|
|
290
|
+
this.#tail.next = node;
|
|
291
|
+
this.#tail = node;
|
|
292
|
+
} else {
|
|
293
|
+
this.#head = node;
|
|
294
|
+
this.#tail = node;
|
|
216
295
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
296
|
+
this.#size++;
|
|
297
|
+
}
|
|
298
|
+
dequeue() {
|
|
299
|
+
const current = this.#head;
|
|
300
|
+
if (!current) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.#head = this.#head.next;
|
|
304
|
+
this.#size--;
|
|
305
|
+
return current.value;
|
|
306
|
+
}
|
|
307
|
+
peek() {
|
|
308
|
+
if (!this.#head) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
return this.#head.value;
|
|
312
|
+
}
|
|
313
|
+
clear() {
|
|
314
|
+
this.#head = void 0;
|
|
315
|
+
this.#tail = void 0;
|
|
316
|
+
this.#size = 0;
|
|
317
|
+
}
|
|
318
|
+
get size() {
|
|
319
|
+
return this.#size;
|
|
320
|
+
}
|
|
321
|
+
*[Symbol.iterator]() {
|
|
322
|
+
let current = this.#head;
|
|
323
|
+
while (current) {
|
|
324
|
+
yield current.value;
|
|
325
|
+
current = current.next;
|
|
223
326
|
}
|
|
224
|
-
const type = getType(extensions);
|
|
225
|
-
const getSource = once(() => {
|
|
226
|
-
const support = SUPPORT_MAPS[type];
|
|
227
|
-
for (const extension of extensions) {
|
|
228
|
-
if (extension in support) {
|
|
229
|
-
if (support[extension]) {
|
|
230
|
-
return map[extension];
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
return map[extension];
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
if (DEV) {
|
|
237
|
-
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
238
|
-
}
|
|
239
|
-
return "";
|
|
240
|
-
});
|
|
241
|
-
return {
|
|
242
|
-
get source() {
|
|
243
|
-
return getSource();
|
|
244
|
-
},
|
|
245
|
-
get type() {
|
|
246
|
-
return type;
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
getCacheKey: (variants) => variants.join("~")
|
|
252
327
|
}
|
|
253
|
-
);
|
|
254
|
-
var asset = (...variants) => {
|
|
255
|
-
return assetPrivate(variants);
|
|
256
|
-
};
|
|
257
|
-
var isAsset = (suspect) => {
|
|
258
|
-
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
259
328
|
};
|
|
260
329
|
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
330
|
+
// ../../node_modules/.pnpm/p-limit@6.1.0/node_modules/p-limit/index.js
|
|
331
|
+
function pLimit(concurrency) {
|
|
332
|
+
validateConcurrency(concurrency);
|
|
333
|
+
const queue = new Queue();
|
|
334
|
+
let activeCount = 0;
|
|
335
|
+
const resumeNext = () => {
|
|
336
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
337
|
+
queue.dequeue()();
|
|
338
|
+
activeCount++;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
const next = () => {
|
|
342
|
+
activeCount--;
|
|
343
|
+
resumeNext();
|
|
344
|
+
};
|
|
345
|
+
const run = async (function_, resolve, arguments_) => {
|
|
346
|
+
const result = (async () => function_(...arguments_))();
|
|
347
|
+
resolve(result);
|
|
348
|
+
try {
|
|
349
|
+
await result;
|
|
350
|
+
} catch {
|
|
351
|
+
}
|
|
352
|
+
next();
|
|
353
|
+
};
|
|
354
|
+
const enqueue = (function_, resolve, arguments_) => {
|
|
355
|
+
new Promise((internalResolve) => {
|
|
356
|
+
queue.enqueue(internalResolve);
|
|
357
|
+
}).then(
|
|
358
|
+
run.bind(void 0, function_, resolve, arguments_)
|
|
359
|
+
);
|
|
360
|
+
(async () => {
|
|
361
|
+
await Promise.resolve();
|
|
362
|
+
if (activeCount < concurrency) {
|
|
363
|
+
resumeNext();
|
|
280
364
|
}
|
|
281
|
-
}
|
|
365
|
+
})();
|
|
282
366
|
};
|
|
283
|
-
|
|
367
|
+
const generator = (function_, ...arguments_) => new Promise((resolve) => {
|
|
368
|
+
enqueue(function_, resolve, arguments_);
|
|
369
|
+
});
|
|
370
|
+
Object.defineProperties(generator, {
|
|
371
|
+
activeCount: {
|
|
372
|
+
get: () => activeCount
|
|
373
|
+
},
|
|
374
|
+
pendingCount: {
|
|
375
|
+
get: () => queue.size
|
|
376
|
+
},
|
|
377
|
+
clearQueue: {
|
|
378
|
+
value() {
|
|
379
|
+
queue.clear();
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
concurrency: {
|
|
383
|
+
get: () => concurrency,
|
|
384
|
+
set(newConcurrency) {
|
|
385
|
+
validateConcurrency(newConcurrency);
|
|
386
|
+
concurrency = newConcurrency;
|
|
387
|
+
queueMicrotask(() => {
|
|
388
|
+
while (activeCount < concurrency && queue.size > 0) {
|
|
389
|
+
resumeNext();
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
return generator;
|
|
396
|
+
}
|
|
397
|
+
function validateConcurrency(concurrency) {
|
|
398
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
399
|
+
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// src/constants.ts
|
|
404
|
+
var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
|
|
405
|
+
var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
|
|
406
|
+
var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
|
|
407
|
+
var AUDIO_ACTIONS = /* @__PURE__ */ new Set(["playMusic", "stopMusic", "playSound", "stopSound", "voice", "stopVoice"]);
|
|
408
|
+
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
409
|
+
var DEFAULT_TYPEWRITER_SPEED = "Medium";
|
|
410
|
+
var HOWLER_SUPPORTED_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
411
|
+
"mp3",
|
|
412
|
+
"mpeg",
|
|
413
|
+
"opus",
|
|
414
|
+
"ogg",
|
|
415
|
+
"oga",
|
|
416
|
+
"wav",
|
|
417
|
+
"aac",
|
|
418
|
+
"caf",
|
|
419
|
+
"m4a",
|
|
420
|
+
"m4b",
|
|
421
|
+
"mp4",
|
|
422
|
+
"weba",
|
|
423
|
+
"webm",
|
|
424
|
+
"dolby",
|
|
425
|
+
"flac"
|
|
426
|
+
]);
|
|
427
|
+
var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
428
|
+
"apng",
|
|
429
|
+
"avif",
|
|
430
|
+
"gif",
|
|
431
|
+
"jpg",
|
|
432
|
+
"jpeg",
|
|
433
|
+
"jfif",
|
|
434
|
+
"pjpeg",
|
|
435
|
+
"pjp",
|
|
436
|
+
"png",
|
|
437
|
+
"svg",
|
|
438
|
+
"webp",
|
|
439
|
+
"bmp"
|
|
440
|
+
]);
|
|
441
|
+
var MAIN_CONTEXT_KEY = "$MAIN";
|
|
442
|
+
|
|
443
|
+
// src/utilities/assertions.ts
|
|
284
444
|
var isNumber = (val) => {
|
|
285
445
|
return typeof val === "number";
|
|
286
446
|
};
|
|
@@ -299,54 +459,13 @@ var Novely = (() => {
|
|
|
299
459
|
var isEmpty = (val) => {
|
|
300
460
|
return typeof val === "object" && !isNull(val) && Object.keys(val).length === 0;
|
|
301
461
|
};
|
|
302
|
-
var
|
|
303
|
-
const startsWith = String.prototype.startsWith.bind(
|
|
462
|
+
var isCSSImageURL = (url) => {
|
|
463
|
+
const startsWith = String.prototype.startsWith.bind(url);
|
|
304
464
|
return startsWith("http") || startsWith("/") || startsWith(".") || startsWith("data");
|
|
305
465
|
};
|
|
306
|
-
var str = String;
|
|
307
466
|
var isUserRequiredAction = ([action, ...meta]) => {
|
|
308
467
|
return Boolean(action === "custom" && meta[0] && meta[0].requireUserAction);
|
|
309
468
|
};
|
|
310
|
-
var getLanguage = (languages) => {
|
|
311
|
-
let { language } = navigator;
|
|
312
|
-
if (languages.includes(language)) {
|
|
313
|
-
return language;
|
|
314
|
-
} else if (languages.includes(language = language.slice(0, 2))) {
|
|
315
|
-
return language;
|
|
316
|
-
} else if (language = languages.find((value) => navigator.languages.includes(value))) {
|
|
317
|
-
return language;
|
|
318
|
-
}
|
|
319
|
-
return languages[0];
|
|
320
|
-
};
|
|
321
|
-
var createControlledPromise = () => {
|
|
322
|
-
const object = {
|
|
323
|
-
resolve: null,
|
|
324
|
-
reject: null,
|
|
325
|
-
promise: null,
|
|
326
|
-
cancel: null
|
|
327
|
-
};
|
|
328
|
-
const init = () => {
|
|
329
|
-
const promise = new Promise((resolve, reject) => {
|
|
330
|
-
object.reject = reject;
|
|
331
|
-
object.resolve = (value) => {
|
|
332
|
-
resolve({ cancelled: false, value });
|
|
333
|
-
};
|
|
334
|
-
object.cancel = () => {
|
|
335
|
-
resolve({ cancelled: true, value: null });
|
|
336
|
-
init();
|
|
337
|
-
};
|
|
338
|
-
});
|
|
339
|
-
object.promise = promise;
|
|
340
|
-
};
|
|
341
|
-
return init(), object;
|
|
342
|
-
};
|
|
343
|
-
var findLastPathItemBeforeItemOfType = (path, name) => {
|
|
344
|
-
const item = path.findLast(([_name, _value], i, array) => {
|
|
345
|
-
const next = array[i + 1];
|
|
346
|
-
return isNull(_name) && isNumber(_value) && next != null && next[0] === name;
|
|
347
|
-
});
|
|
348
|
-
return item;
|
|
349
|
-
};
|
|
350
469
|
var isBlockStatement = (statement) => {
|
|
351
470
|
return BLOCK_STATEMENTS.has(statement);
|
|
352
471
|
};
|
|
@@ -359,49 +478,290 @@ var Novely = (() => {
|
|
|
359
478
|
var isAudioAction = (action) => {
|
|
360
479
|
return AUDIO_ACTIONS.has(action);
|
|
361
480
|
};
|
|
362
|
-
var noop = () => {
|
|
363
|
-
};
|
|
364
481
|
var isAction = (element) => {
|
|
365
482
|
return Array.isArray(element) && isString(element[0]);
|
|
366
483
|
};
|
|
367
|
-
var
|
|
368
|
-
return
|
|
369
|
-
const type = data[0];
|
|
370
|
-
if (Array.isArray(type)) return flatActions(data);
|
|
371
|
-
return [data];
|
|
372
|
-
});
|
|
484
|
+
var isImageAsset = (asset2) => {
|
|
485
|
+
return isString(asset2) && isCSSImageURL(asset2);
|
|
373
486
|
};
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
return [name, flatActions(items)];
|
|
377
|
-
});
|
|
378
|
-
return Object.fromEntries(entries);
|
|
487
|
+
var isBlockingAction = (action) => {
|
|
488
|
+
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
379
489
|
};
|
|
380
|
-
var
|
|
381
|
-
|
|
382
|
-
const blockExitStatements = path.filter(([item]) => isBlockExitStatement(item));
|
|
383
|
-
if (blockStatements.length === 0 && blockExitStatements.length === 0) {
|
|
384
|
-
return true;
|
|
385
|
-
}
|
|
386
|
-
if (blockStatements.length > blockExitStatements.length) {
|
|
387
|
-
return false;
|
|
388
|
-
}
|
|
389
|
-
return !blockExitStatements.every(([name], i) => name && name.startsWith(blockStatements[i][0]));
|
|
490
|
+
var isAsset = (suspect) => {
|
|
491
|
+
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
390
492
|
};
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
"
|
|
493
|
+
|
|
494
|
+
// src/utilities/match-action.ts
|
|
495
|
+
var matchAction = (callbacks, values) => {
|
|
496
|
+
const { getContext, onBeforeActionCall, push, forward } = callbacks;
|
|
497
|
+
return (action, props, { ctx, data }) => {
|
|
498
|
+
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
499
|
+
onBeforeActionCall({
|
|
500
|
+
action,
|
|
501
|
+
props,
|
|
502
|
+
ctx: context
|
|
503
|
+
});
|
|
504
|
+
return values[action](
|
|
505
|
+
{
|
|
506
|
+
ctx: context,
|
|
507
|
+
data,
|
|
508
|
+
push() {
|
|
509
|
+
if (context.meta.preview) return;
|
|
510
|
+
push(context);
|
|
511
|
+
},
|
|
512
|
+
forward() {
|
|
513
|
+
if (context.meta.preview) return;
|
|
514
|
+
forward(context);
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
props
|
|
518
|
+
);
|
|
397
519
|
};
|
|
398
|
-
return MAP[action];
|
|
399
520
|
};
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
let
|
|
404
|
-
|
|
521
|
+
|
|
522
|
+
// src/utilities/ungrupped.ts
|
|
523
|
+
var getLanguage = (languages) => {
|
|
524
|
+
let { language } = navigator;
|
|
525
|
+
if (languages.includes(language)) {
|
|
526
|
+
return language;
|
|
527
|
+
} else if (languages.includes(language = language.slice(0, 2))) {
|
|
528
|
+
return language;
|
|
529
|
+
} else if (language = languages.find((value) => navigator.languages.includes(value))) {
|
|
530
|
+
return language;
|
|
531
|
+
}
|
|
532
|
+
return languages[0];
|
|
533
|
+
};
|
|
534
|
+
var noop = () => {
|
|
535
|
+
};
|
|
536
|
+
var mapSet = (set2, fn) => {
|
|
537
|
+
return [...set2].map(fn);
|
|
538
|
+
};
|
|
539
|
+
var capitalize = (str) => {
|
|
540
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
541
|
+
};
|
|
542
|
+
var getIntlLanguageDisplayName = memoize((lang) => {
|
|
543
|
+
try {
|
|
544
|
+
const intl = new Intl.DisplayNames([lang], {
|
|
545
|
+
type: "language"
|
|
546
|
+
});
|
|
547
|
+
return intl.of(lang) || lang;
|
|
548
|
+
} catch {
|
|
549
|
+
return lang;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
var unwrapAsset = (asset2) => {
|
|
553
|
+
return isAsset(asset2) ? asset2.source : asset2;
|
|
554
|
+
};
|
|
555
|
+
var handleAudioAsset = (asset2) => {
|
|
556
|
+
if (DEV && isAsset(asset2) && asset2.type !== "audio") {
|
|
557
|
+
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
558
|
+
}
|
|
559
|
+
return unwrapAsset(asset2);
|
|
560
|
+
};
|
|
561
|
+
var handleImageAsset = (asset2) => {
|
|
562
|
+
if (DEV && isAsset(asset2) && asset2.type !== "image") {
|
|
563
|
+
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
564
|
+
}
|
|
565
|
+
return unwrapAsset(asset2);
|
|
566
|
+
};
|
|
567
|
+
var getCharactersData = (characters) => {
|
|
568
|
+
const entries = Object.entries(characters);
|
|
569
|
+
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
570
|
+
return Object.fromEntries(mapped);
|
|
571
|
+
};
|
|
572
|
+
var toArray = (target) => {
|
|
573
|
+
return Array.isArray(target) ? target : [target];
|
|
574
|
+
};
|
|
575
|
+
var getLanguageFromStore = (store2) => {
|
|
576
|
+
return store2.get().meta[0];
|
|
577
|
+
};
|
|
578
|
+
var getVolumeFromStore = (store2) => {
|
|
579
|
+
const { meta } = store2.get();
|
|
580
|
+
return {
|
|
581
|
+
music: meta[2],
|
|
582
|
+
sound: meta[3],
|
|
583
|
+
voice: meta[4]
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// src/utilities/actions-processing.ts
|
|
588
|
+
var isExitImpossible = (path) => {
|
|
589
|
+
const blockStatements = path.filter(([item]) => isBlockStatement(item));
|
|
590
|
+
const blockExitStatements = path.filter(([item]) => isBlockExitStatement(item));
|
|
591
|
+
if (blockStatements.length === 0 && blockExitStatements.length === 0) {
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
if (blockStatements.length > blockExitStatements.length) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
return !blockExitStatements.every(([name], i) => name && name.startsWith(blockStatements[i][0]));
|
|
598
|
+
};
|
|
599
|
+
var createReferFunction = (story) => {
|
|
600
|
+
const refer = (path) => {
|
|
601
|
+
let current = story;
|
|
602
|
+
let precurrent = story;
|
|
603
|
+
const blocks = [];
|
|
604
|
+
for (const [type, val] of path) {
|
|
605
|
+
if (type === "jump") {
|
|
606
|
+
precurrent = story;
|
|
607
|
+
current = current[val];
|
|
608
|
+
} else if (type === null) {
|
|
609
|
+
precurrent = current;
|
|
610
|
+
current = current[val];
|
|
611
|
+
} else if (type === "choice") {
|
|
612
|
+
blocks.push(precurrent);
|
|
613
|
+
current = current[val + 1][1];
|
|
614
|
+
} else if (type === "condition") {
|
|
615
|
+
blocks.push(precurrent);
|
|
616
|
+
current = current[2][val];
|
|
617
|
+
} else if (type === "block") {
|
|
618
|
+
blocks.push(precurrent);
|
|
619
|
+
current = story[val];
|
|
620
|
+
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
621
|
+
current = blocks.pop();
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return current;
|
|
625
|
+
};
|
|
626
|
+
return refer;
|
|
627
|
+
};
|
|
628
|
+
var exitPath = ({ path, refer, onExitImpossible }) => {
|
|
629
|
+
const last = path.at(-1);
|
|
630
|
+
const ignore = [];
|
|
631
|
+
let wasExitImpossible = false;
|
|
632
|
+
if (!isAction(refer(path))) {
|
|
633
|
+
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
634
|
+
last[1]--;
|
|
635
|
+
} else {
|
|
636
|
+
path.pop();
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (isExitImpossible(path)) {
|
|
640
|
+
const referred = refer(path);
|
|
641
|
+
if (isAction(referred) && isSkippedDuringRestore(referred[0])) {
|
|
642
|
+
onExitImpossible?.();
|
|
643
|
+
}
|
|
644
|
+
wasExitImpossible = true;
|
|
645
|
+
return {
|
|
646
|
+
exitImpossible: wasExitImpossible
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
for (let i = path.length - 1; i > 0; i--) {
|
|
650
|
+
const [name] = path[i];
|
|
651
|
+
if (isBlockExitStatement(name)) {
|
|
652
|
+
ignore.push(name);
|
|
653
|
+
}
|
|
654
|
+
if (!isBlockStatement(name)) continue;
|
|
655
|
+
if (ignore.at(-1)?.startsWith(name)) {
|
|
656
|
+
ignore.pop();
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
path.push([`${name}:exit`]);
|
|
660
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
661
|
+
if (prev) path.push([null, prev[1] + 1]);
|
|
662
|
+
if (!isAction(refer(path))) {
|
|
663
|
+
path.pop();
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
exitImpossible: wasExitImpossible
|
|
670
|
+
};
|
|
671
|
+
};
|
|
672
|
+
var nextPath = (path) => {
|
|
673
|
+
const last = path.at(-1);
|
|
674
|
+
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
675
|
+
last[1]++;
|
|
676
|
+
} else {
|
|
677
|
+
path.push([null, 0]);
|
|
678
|
+
}
|
|
679
|
+
return path;
|
|
680
|
+
};
|
|
681
|
+
var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
682
|
+
const collection = [];
|
|
683
|
+
let action = refer(path);
|
|
684
|
+
while (true) {
|
|
685
|
+
if (action == void 0) {
|
|
686
|
+
const { exitImpossible } = exitPath({
|
|
687
|
+
path,
|
|
688
|
+
refer
|
|
689
|
+
});
|
|
690
|
+
if (exitImpossible) {
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (!action) {
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
if (isBlockingAction(action)) {
|
|
698
|
+
const [name, ...props] = action;
|
|
699
|
+
if (name === "choice") {
|
|
700
|
+
const choiceProps = props;
|
|
701
|
+
for (let i = 0; i < choiceProps.length; i++) {
|
|
702
|
+
const branchContent = choiceProps[i];
|
|
703
|
+
if (!Array.isArray(branchContent)) continue;
|
|
704
|
+
const virtualPath = clone(path);
|
|
705
|
+
virtualPath.push(["choice", i], [null, 0]);
|
|
706
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
707
|
+
path: virtualPath,
|
|
708
|
+
refer,
|
|
709
|
+
clone
|
|
710
|
+
});
|
|
711
|
+
collection.push(...innerActions);
|
|
712
|
+
}
|
|
713
|
+
} else if (name === "condition") {
|
|
714
|
+
const conditionProps = props;
|
|
715
|
+
const conditions = Object.keys(conditionProps[1]);
|
|
716
|
+
for (const condition of conditions) {
|
|
717
|
+
const virtualPath = clone(path);
|
|
718
|
+
virtualPath.push(["condition", condition], [null, 0]);
|
|
719
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
720
|
+
path: virtualPath,
|
|
721
|
+
refer,
|
|
722
|
+
clone
|
|
723
|
+
});
|
|
724
|
+
collection.push(...innerActions);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
collection.push(action);
|
|
730
|
+
if (action[0] === "jump") {
|
|
731
|
+
path = [
|
|
732
|
+
["jump", action[1]],
|
|
733
|
+
[null, 0]
|
|
734
|
+
];
|
|
735
|
+
} else if (action[0] == "block") {
|
|
736
|
+
path.push(["block", action[1]], [null, 0]);
|
|
737
|
+
} else {
|
|
738
|
+
nextPath(path);
|
|
739
|
+
}
|
|
740
|
+
action = refer(path);
|
|
741
|
+
}
|
|
742
|
+
return collection;
|
|
743
|
+
};
|
|
744
|
+
var findLastPathItemBeforeItemOfType = (path, name) => {
|
|
745
|
+
const item = path.findLast(([_name, _value], i, array) => {
|
|
746
|
+
const next = array[i + 1];
|
|
747
|
+
return isNull(_name) && isNumber(_value) && next != null && next[0] === name;
|
|
748
|
+
});
|
|
749
|
+
return item;
|
|
750
|
+
};
|
|
751
|
+
var getOppositeAction = (action) => {
|
|
752
|
+
const MAP = {
|
|
753
|
+
showCharacter: "hideCharacter",
|
|
754
|
+
playSound: "stopSound",
|
|
755
|
+
playMusic: "stopMusic",
|
|
756
|
+
voice: "stopVoice"
|
|
757
|
+
};
|
|
758
|
+
return MAP[action];
|
|
759
|
+
};
|
|
760
|
+
var getActionsFromPath = (story, path, filter) => {
|
|
761
|
+
let current = story;
|
|
762
|
+
let precurrent;
|
|
763
|
+
let ignoreNestedBefore = null;
|
|
764
|
+
let index = 0;
|
|
405
765
|
let skipPreserve = void 0;
|
|
406
766
|
const skip = /* @__PURE__ */ new Set();
|
|
407
767
|
const max = path.reduce((acc, [type, val]) => {
|
|
@@ -493,7 +853,7 @@ var Novely = (() => {
|
|
|
493
853
|
const c1 = fn;
|
|
494
854
|
const isIdenticalID = Boolean(c0.id && c1.id && c0.id === c1.id);
|
|
495
855
|
const isIdenticalByReference = c0 === c1;
|
|
496
|
-
return isIdenticalID || isIdenticalByReference ||
|
|
856
|
+
return isIdenticalID || isIdenticalByReference || String(c0) === String(c1);
|
|
497
857
|
});
|
|
498
858
|
if (notLatest) continue;
|
|
499
859
|
} else if ("skipOnRestore" in fn && fn.skipOnRestore) {
|
|
@@ -560,53 +920,32 @@ var Novely = (() => {
|
|
|
560
920
|
}
|
|
561
921
|
};
|
|
562
922
|
};
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
);
|
|
572
|
-
var createUseStackFunction = (renderer) => {
|
|
573
|
-
const useStack = (context) => {
|
|
574
|
-
const ctx = typeof context === "string" ? renderer.getContext(context) : context;
|
|
575
|
-
const stack = getStack(ctx);
|
|
576
|
-
return {
|
|
577
|
-
get previous() {
|
|
578
|
-
return stack.previous;
|
|
579
|
-
},
|
|
580
|
-
get value() {
|
|
581
|
-
return stack.at(-1);
|
|
582
|
-
},
|
|
583
|
-
set value(value) {
|
|
584
|
-
stack[stack.length - 1] = value;
|
|
585
|
-
},
|
|
586
|
-
back() {
|
|
587
|
-
if (stack.length > 1) {
|
|
588
|
-
stack.previous = stack.pop();
|
|
589
|
-
ctx.meta.goingBack = true;
|
|
590
|
-
}
|
|
591
|
-
},
|
|
592
|
-
push(value) {
|
|
593
|
-
stack.push(value);
|
|
594
|
-
},
|
|
595
|
-
clear() {
|
|
596
|
-
stack.previous = void 0;
|
|
597
|
-
stack.length = 0;
|
|
598
|
-
stack.length = 1;
|
|
599
|
-
}
|
|
600
|
-
};
|
|
923
|
+
|
|
924
|
+
// src/utilities/controlled-promise.ts
|
|
925
|
+
var createControlledPromise = () => {
|
|
926
|
+
const object = {
|
|
927
|
+
resolve: null,
|
|
928
|
+
reject: null,
|
|
929
|
+
promise: null,
|
|
930
|
+
cancel: null
|
|
601
931
|
};
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
932
|
+
const init = () => {
|
|
933
|
+
const promise = new Promise((resolve, reject) => {
|
|
934
|
+
object.reject = reject;
|
|
935
|
+
object.resolve = (value) => {
|
|
936
|
+
resolve({ cancelled: false, value });
|
|
937
|
+
};
|
|
938
|
+
object.cancel = () => {
|
|
939
|
+
resolve({ cancelled: true, value: null });
|
|
940
|
+
init();
|
|
941
|
+
};
|
|
942
|
+
});
|
|
943
|
+
object.promise = promise;
|
|
944
|
+
};
|
|
945
|
+
return init(), object;
|
|
609
946
|
};
|
|
947
|
+
|
|
948
|
+
// src/utilities/resources.ts
|
|
610
949
|
var getUrlFileExtension = (address) => {
|
|
611
950
|
try {
|
|
612
951
|
const { pathname } = new URL(address, location.href);
|
|
@@ -633,7 +972,7 @@ var Novely = (() => {
|
|
|
633
972
|
};
|
|
634
973
|
var getResourseType = memoize(
|
|
635
974
|
async ({ url, request }) => {
|
|
636
|
-
if (!
|
|
975
|
+
if (!isCSSImageURL(url)) {
|
|
637
976
|
return "other";
|
|
638
977
|
}
|
|
639
978
|
const extension = getUrlFileExtension(url);
|
|
@@ -656,357 +995,85 @@ var Novely = (() => {
|
|
|
656
995
|
getCacheKey: ({ url }) => url
|
|
657
996
|
}
|
|
658
997
|
);
|
|
659
|
-
var capitalize = (str2) => {
|
|
660
|
-
return str2[0].toUpperCase() + str2.slice(1);
|
|
661
|
-
};
|
|
662
|
-
var getIntlLanguageDisplayName = memoize((lang) => {
|
|
663
|
-
try {
|
|
664
|
-
const intl = new Intl.DisplayNames([lang], {
|
|
665
|
-
type: "language"
|
|
666
|
-
});
|
|
667
|
-
return intl.of(lang) || lang;
|
|
668
|
-
} catch {
|
|
669
|
-
return lang;
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
var createReferFunction = (story) => {
|
|
673
|
-
const refer = (path) => {
|
|
674
|
-
let current = story;
|
|
675
|
-
let precurrent = story;
|
|
676
|
-
const blocks = [];
|
|
677
|
-
for (const [type, val] of path) {
|
|
678
|
-
if (type === "jump") {
|
|
679
|
-
precurrent = story;
|
|
680
|
-
current = current[val];
|
|
681
|
-
} else if (type === null) {
|
|
682
|
-
precurrent = current;
|
|
683
|
-
current = current[val];
|
|
684
|
-
} else if (type === "choice") {
|
|
685
|
-
blocks.push(precurrent);
|
|
686
|
-
current = current[val + 1][1];
|
|
687
|
-
} else if (type === "condition") {
|
|
688
|
-
blocks.push(precurrent);
|
|
689
|
-
current = current[2][val];
|
|
690
|
-
} else if (type === "block") {
|
|
691
|
-
blocks.push(precurrent);
|
|
692
|
-
current = story[val];
|
|
693
|
-
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
694
|
-
current = blocks.pop();
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
return current;
|
|
698
|
-
};
|
|
699
|
-
return refer;
|
|
700
|
-
};
|
|
701
|
-
var exitPath = ({ path, refer, onExitImpossible }) => {
|
|
702
|
-
const last = path.at(-1);
|
|
703
|
-
const ignore = [];
|
|
704
|
-
let wasExitImpossible = false;
|
|
705
|
-
if (!isAction(refer(path))) {
|
|
706
|
-
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
707
|
-
last[1]--;
|
|
708
|
-
} else {
|
|
709
|
-
path.pop();
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
if (isExitImpossible(path)) {
|
|
713
|
-
const referred = refer(path);
|
|
714
|
-
if (isAction(referred) && isSkippedDuringRestore(referred[0])) {
|
|
715
|
-
onExitImpossible?.();
|
|
716
|
-
}
|
|
717
|
-
wasExitImpossible = true;
|
|
718
|
-
return {
|
|
719
|
-
exitImpossible: wasExitImpossible
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
for (let i = path.length - 1; i > 0; i--) {
|
|
723
|
-
const [name] = path[i];
|
|
724
|
-
if (isBlockExitStatement(name)) {
|
|
725
|
-
ignore.push(name);
|
|
726
|
-
}
|
|
727
|
-
if (!isBlockStatement(name)) continue;
|
|
728
|
-
if (ignore.at(-1)?.startsWith(name)) {
|
|
729
|
-
ignore.pop();
|
|
730
|
-
continue;
|
|
731
|
-
}
|
|
732
|
-
path.push([`${name}:exit`]);
|
|
733
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
734
|
-
if (prev) path.push([null, prev[1] + 1]);
|
|
735
|
-
if (!isAction(refer(path))) {
|
|
736
|
-
path.pop();
|
|
737
|
-
continue;
|
|
738
|
-
}
|
|
739
|
-
break;
|
|
740
|
-
}
|
|
741
|
-
return {
|
|
742
|
-
exitImpossible: wasExitImpossible
|
|
743
|
-
};
|
|
744
|
-
};
|
|
745
|
-
var nextPath = (path) => {
|
|
746
|
-
const last = path.at(-1);
|
|
747
|
-
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
748
|
-
last[1]++;
|
|
749
|
-
} else {
|
|
750
|
-
path.push([null, 0]);
|
|
751
|
-
}
|
|
752
|
-
return path;
|
|
753
|
-
};
|
|
754
|
-
var isBlockingAction = (action) => {
|
|
755
|
-
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
756
|
-
};
|
|
757
|
-
var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
758
|
-
const collection = [];
|
|
759
|
-
let action = refer(path);
|
|
760
|
-
while (true) {
|
|
761
|
-
if (action == void 0) {
|
|
762
|
-
const { exitImpossible } = exitPath({
|
|
763
|
-
path,
|
|
764
|
-
refer
|
|
765
|
-
});
|
|
766
|
-
if (exitImpossible) {
|
|
767
|
-
break;
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
if (!action) {
|
|
771
|
-
break;
|
|
772
|
-
}
|
|
773
|
-
if (isBlockingAction(action)) {
|
|
774
|
-
const [name, ...props] = action;
|
|
775
|
-
if (name === "choice") {
|
|
776
|
-
const choiceProps = props;
|
|
777
|
-
for (let i = 0; i < choiceProps.length; i++) {
|
|
778
|
-
const branchContent = choiceProps[i];
|
|
779
|
-
if (!Array.isArray(branchContent)) continue;
|
|
780
|
-
const virtualPath = clone(path);
|
|
781
|
-
virtualPath.push(["choice", i], [null, 0]);
|
|
782
|
-
const innerActions = collectActionsBeforeBlockingAction({
|
|
783
|
-
path: virtualPath,
|
|
784
|
-
refer,
|
|
785
|
-
clone
|
|
786
|
-
});
|
|
787
|
-
collection.push(...innerActions);
|
|
788
|
-
}
|
|
789
|
-
} else if (name === "condition") {
|
|
790
|
-
const conditionProps = props;
|
|
791
|
-
const conditions = Object.keys(conditionProps[1]);
|
|
792
|
-
for (const condition of conditions) {
|
|
793
|
-
const virtualPath = clone(path);
|
|
794
|
-
virtualPath.push(["condition", condition], [null, 0]);
|
|
795
|
-
const innerActions = collectActionsBeforeBlockingAction({
|
|
796
|
-
path: virtualPath,
|
|
797
|
-
refer,
|
|
798
|
-
clone
|
|
799
|
-
});
|
|
800
|
-
collection.push(...innerActions);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
break;
|
|
804
|
-
}
|
|
805
|
-
collection.push(action);
|
|
806
|
-
if (action[0] === "jump") {
|
|
807
|
-
path = [["jump", action[1]], [null, 0]];
|
|
808
|
-
} else if (action[0] == "block") {
|
|
809
|
-
path.push(["block", action[1]], [null, 0]);
|
|
810
|
-
} else {
|
|
811
|
-
nextPath(path);
|
|
812
|
-
}
|
|
813
|
-
action = refer(path);
|
|
814
|
-
}
|
|
815
|
-
return collection;
|
|
816
|
-
};
|
|
817
|
-
var unwrapAsset = (asset2) => {
|
|
818
|
-
return isAsset(asset2) ? asset2.source : asset2;
|
|
819
|
-
};
|
|
820
|
-
var handleAudioAsset = (asset2) => {
|
|
821
|
-
if (DEV && isAsset(asset2) && asset2.type !== "audio") {
|
|
822
|
-
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
823
|
-
}
|
|
824
|
-
return unwrapAsset(asset2);
|
|
825
|
-
};
|
|
826
|
-
var handleImageAsset = (asset2) => {
|
|
827
|
-
if (DEV && isAsset(asset2) && asset2.type !== "image") {
|
|
828
|
-
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
829
|
-
}
|
|
830
|
-
return unwrapAsset(asset2);
|
|
831
|
-
};
|
|
832
|
-
var getCharactersData = (characters) => {
|
|
833
|
-
const entries = Object.entries(characters);
|
|
834
|
-
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
835
|
-
return Object.fromEntries(mapped);
|
|
836
|
-
};
|
|
837
|
-
var toArray = (target) => {
|
|
838
|
-
return Array.isArray(target) ? target : [target];
|
|
839
|
-
};
|
|
840
|
-
var getLanguageFromStore = (store2) => {
|
|
841
|
-
return store2.get().meta[0];
|
|
842
|
-
};
|
|
843
|
-
var getVolumeFromStore = (store2) => {
|
|
844
|
-
const { meta } = store2.get();
|
|
845
|
-
return {
|
|
846
|
-
music: meta[2],
|
|
847
|
-
sound: meta[3],
|
|
848
|
-
voice: meta[4]
|
|
849
|
-
};
|
|
850
|
-
};
|
|
851
|
-
|
|
852
|
-
// ../../node_modules/.pnpm/es-toolkit@1.16.0/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.mjs
|
|
853
|
-
function isObjectLike(value) {
|
|
854
|
-
return typeof value === "object" && value !== null;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
// ../../node_modules/.pnpm/es-toolkit@1.16.0/node_modules/es-toolkit/dist/object/merge.mjs
|
|
858
|
-
function merge(target, source) {
|
|
859
|
-
const sourceKeys = Object.keys(source);
|
|
860
|
-
for (let i = 0; i < sourceKeys.length; i++) {
|
|
861
|
-
const key = sourceKeys[i];
|
|
862
|
-
const sourceValue = source[key];
|
|
863
|
-
const targetValue = target[key];
|
|
864
|
-
if (Array.isArray(sourceValue)) {
|
|
865
|
-
target[key] = merge(targetValue ?? [], sourceValue);
|
|
866
|
-
} else if (isObjectLike(targetValue) && isObjectLike(sourceValue)) {
|
|
867
|
-
target[key] = merge(targetValue ?? {}, sourceValue);
|
|
868
|
-
} else if (targetValue === void 0 || sourceValue !== void 0) {
|
|
869
|
-
target[key] = sourceValue;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
return target;
|
|
873
|
-
}
|
|
874
998
|
|
|
875
|
-
//
|
|
876
|
-
var
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
881
|
-
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
882
|
-
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
883
|
-
if (ctor === Array) {
|
|
884
|
-
if ((len = foo.length) === bar.length) {
|
|
885
|
-
while (len-- && dequal(foo[len], bar[len])) ;
|
|
886
|
-
}
|
|
887
|
-
return len === -1;
|
|
888
|
-
}
|
|
889
|
-
if (!ctor || typeof foo === "object") {
|
|
890
|
-
len = 0;
|
|
891
|
-
for (ctor in foo) {
|
|
892
|
-
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
893
|
-
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
894
|
-
}
|
|
895
|
-
return Object.keys(bar).length === len;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
return foo !== foo && bar !== bar;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
// src/store.ts
|
|
902
|
-
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
903
|
-
const subscribe = (cb) => {
|
|
904
|
-
subscribers.add(cb), cb(current);
|
|
905
|
-
return () => {
|
|
906
|
-
subscribers.delete(cb);
|
|
907
|
-
};
|
|
908
|
-
};
|
|
909
|
-
const push = (value) => {
|
|
910
|
-
for (const cb of subscribers) cb(value);
|
|
911
|
-
};
|
|
912
|
-
const update = (fn) => {
|
|
913
|
-
push(current = fn(current));
|
|
914
|
-
};
|
|
915
|
-
const set2 = (val) => {
|
|
916
|
-
update(() => val);
|
|
917
|
-
};
|
|
918
|
-
const get = () => {
|
|
919
|
-
return current;
|
|
920
|
-
};
|
|
921
|
-
return { subscribe, update, set: set2, get };
|
|
922
|
-
};
|
|
999
|
+
// src/shared.ts
|
|
1000
|
+
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
1001
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
1002
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
1003
|
+
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
923
1004
|
|
|
924
|
-
//
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
if (typeof x !== "object") return x;
|
|
933
|
-
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
934
|
-
if (str2 === "[object Object]") {
|
|
935
|
-
tmp = Object.create(x.__proto__ || null);
|
|
936
|
-
} else if (str2 === "[object Array]") {
|
|
937
|
-
tmp = Array(x.length);
|
|
938
|
-
} else if (str2 === "[object Set]") {
|
|
939
|
-
tmp = /* @__PURE__ */ new Set();
|
|
940
|
-
x.forEach(function(val) {
|
|
941
|
-
tmp.add(klona(val));
|
|
942
|
-
});
|
|
943
|
-
} else if (str2 === "[object Map]") {
|
|
944
|
-
tmp = /* @__PURE__ */ new Map();
|
|
945
|
-
x.forEach(function(val, key) {
|
|
946
|
-
tmp.set(klona(key), klona(val));
|
|
947
|
-
});
|
|
948
|
-
} else if (str2 === "[object Date]") {
|
|
949
|
-
tmp = /* @__PURE__ */ new Date(+x);
|
|
950
|
-
} else if (str2 === "[object RegExp]") {
|
|
951
|
-
tmp = new RegExp(x.source, x.flags);
|
|
952
|
-
} else if (str2 === "[object DataView]") {
|
|
953
|
-
tmp = new x.constructor(klona(x.buffer));
|
|
954
|
-
} else if (str2 === "[object ArrayBuffer]") {
|
|
955
|
-
tmp = x.slice(0);
|
|
956
|
-
} else if (str2.slice(-6) === "Array]") {
|
|
957
|
-
tmp = new x.constructor(x);
|
|
958
|
-
}
|
|
959
|
-
if (tmp) {
|
|
960
|
-
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
961
|
-
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
962
|
-
}
|
|
963
|
-
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
964
|
-
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
965
|
-
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
966
|
-
}
|
|
1005
|
+
// src/utilities/stack.ts
|
|
1006
|
+
var getStack = memoize(
|
|
1007
|
+
(_) => {
|
|
1008
|
+
return [];
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
cache: STACK_MAP,
|
|
1012
|
+
getCacheKey: (ctx) => ctx.id
|
|
967
1013
|
}
|
|
968
|
-
|
|
969
|
-
|
|
1014
|
+
);
|
|
1015
|
+
var createUseStackFunction = (renderer) => {
|
|
1016
|
+
const useStack = (context) => {
|
|
1017
|
+
const ctx = typeof context === "string" ? renderer.getContext(context) : context;
|
|
1018
|
+
const stack = getStack(ctx);
|
|
1019
|
+
return {
|
|
1020
|
+
get previous() {
|
|
1021
|
+
return stack.previous;
|
|
1022
|
+
},
|
|
1023
|
+
get value() {
|
|
1024
|
+
return stack.at(-1);
|
|
1025
|
+
},
|
|
1026
|
+
set value(value) {
|
|
1027
|
+
stack[stack.length - 1] = value;
|
|
1028
|
+
},
|
|
1029
|
+
back() {
|
|
1030
|
+
if (stack.length > 1) {
|
|
1031
|
+
stack.previous = stack.pop();
|
|
1032
|
+
ctx.meta.goingBack = true;
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
1035
|
+
push(value) {
|
|
1036
|
+
stack.push(value);
|
|
1037
|
+
},
|
|
1038
|
+
clear() {
|
|
1039
|
+
stack.previous = void 0;
|
|
1040
|
+
stack.length = 0;
|
|
1041
|
+
stack.length = 1;
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
};
|
|
1045
|
+
return useStack;
|
|
1046
|
+
};
|
|
970
1047
|
|
|
971
|
-
// src/
|
|
972
|
-
var
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
output.push(start);
|
|
979
|
-
input = end;
|
|
980
|
-
}
|
|
981
|
-
output.push(input);
|
|
982
|
-
return output;
|
|
1048
|
+
// src/utilities/story.ts
|
|
1049
|
+
var flatActions = (item) => {
|
|
1050
|
+
return item.flatMap((data) => {
|
|
1051
|
+
const type = data[0];
|
|
1052
|
+
if (Array.isArray(type)) return flatActions(data);
|
|
1053
|
+
return [data];
|
|
1054
|
+
});
|
|
983
1055
|
};
|
|
984
|
-
var
|
|
985
|
-
|
|
986
|
-
return
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
return flattenAllowedContent(c(state), state);
|
|
990
|
-
}
|
|
991
|
-
return c;
|
|
1056
|
+
var flatStory = (story) => {
|
|
1057
|
+
const entries = Object.entries(story).map(([name, items]) => {
|
|
1058
|
+
return [name, flatActions(items)];
|
|
1059
|
+
});
|
|
1060
|
+
return Object.fromEntries(entries);
|
|
992
1061
|
};
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
if (
|
|
999
|
-
|
|
1000
|
-
}
|
|
1001
|
-
const path = pathstr.split(".");
|
|
1002
|
-
while (y && x < path.length) y = y[path[x++]];
|
|
1003
|
-
if (plural && pluralization && y && pr) {
|
|
1004
|
-
y = pluralization[plural][pr.select(y)];
|
|
1062
|
+
|
|
1063
|
+
// src/browser.ts
|
|
1064
|
+
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
1065
|
+
if (typeof document === "undefined") return noop;
|
|
1066
|
+
const onVisibilityChange = () => {
|
|
1067
|
+
if (document.visibilityState === "hidden") {
|
|
1068
|
+
onChange();
|
|
1005
1069
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1070
|
+
};
|
|
1071
|
+
addEventListener("visibilitychange", onVisibilityChange);
|
|
1072
|
+
addEventListener("beforeunload", onChange);
|
|
1073
|
+
return () => {
|
|
1074
|
+
removeEventListener("visibilitychange", onVisibilityChange);
|
|
1075
|
+
removeEventListener("beforeunload", onChange);
|
|
1076
|
+
};
|
|
1010
1077
|
};
|
|
1011
1078
|
|
|
1012
1079
|
// src/custom-action.ts
|
|
@@ -1049,13 +1116,15 @@ var Novely = (() => {
|
|
|
1049
1116
|
};
|
|
1050
1117
|
};
|
|
1051
1118
|
const clear = (func) => {
|
|
1052
|
-
setClear(
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1119
|
+
setClear(
|
|
1120
|
+
holder.cleanup = () => {
|
|
1121
|
+
func();
|
|
1122
|
+
holder.node = null;
|
|
1123
|
+
holder.cleanup = noop;
|
|
1124
|
+
setMountElement(null);
|
|
1125
|
+
setClear(noop);
|
|
1126
|
+
}
|
|
1127
|
+
);
|
|
1059
1128
|
};
|
|
1060
1129
|
const data = (updatedData) => {
|
|
1061
1130
|
if (updatedData) {
|
|
@@ -1074,197 +1143,34 @@ var Novely = (() => {
|
|
|
1074
1143
|
return fn({
|
|
1075
1144
|
flags,
|
|
1076
1145
|
lang,
|
|
1077
|
-
state,
|
|
1078
|
-
data,
|
|
1079
|
-
clear,
|
|
1080
|
-
remove,
|
|
1081
|
-
rendererContext: ctx,
|
|
1082
|
-
getDomNodes,
|
|
1083
|
-
getPath,
|
|
1084
|
-
contextKey: ctx.id
|
|
1085
|
-
});
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
// src/storage.ts
|
|
1089
|
-
var localStorageStorage = (options) => {
|
|
1090
|
-
return {
|
|
1091
|
-
async get() {
|
|
1092
|
-
const fallback = { saves: [], data: {}, meta: [] };
|
|
1093
|
-
try {
|
|
1094
|
-
const value = localStorage.getItem(options.key);
|
|
1095
|
-
return value ? JSON.parse(value) : fallback;
|
|
1096
|
-
} catch {
|
|
1097
|
-
return fallback;
|
|
1098
|
-
}
|
|
1099
|
-
},
|
|
1100
|
-
async set(data) {
|
|
1101
|
-
try {
|
|
1102
|
-
localStorage.setItem(options.key, JSON.stringify(data));
|
|
1103
|
-
} catch {
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
};
|
|
1107
|
-
};
|
|
1108
|
-
|
|
1109
|
-
// src/browser.ts
|
|
1110
|
-
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
1111
|
-
if (typeof document === "undefined") return noop;
|
|
1112
|
-
const onVisibilityChange = () => {
|
|
1113
|
-
if (document.visibilityState === "hidden") {
|
|
1114
|
-
onChange();
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
addEventListener("visibilitychange", onVisibilityChange);
|
|
1118
|
-
addEventListener("beforeunload", onChange);
|
|
1119
|
-
return () => {
|
|
1120
|
-
removeEventListener("visibilitychange", onVisibilityChange);
|
|
1121
|
-
removeEventListener("beforeunload", onChange);
|
|
1122
|
-
};
|
|
1123
|
-
};
|
|
1124
|
-
|
|
1125
|
-
// ../../node_modules/.pnpm/yocto-queue@1.1.1/node_modules/yocto-queue/index.js
|
|
1126
|
-
var Node = class {
|
|
1127
|
-
value;
|
|
1128
|
-
next;
|
|
1129
|
-
constructor(value) {
|
|
1130
|
-
this.value = value;
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
var Queue = class {
|
|
1134
|
-
#head;
|
|
1135
|
-
#tail;
|
|
1136
|
-
#size;
|
|
1137
|
-
constructor() {
|
|
1138
|
-
this.clear();
|
|
1139
|
-
}
|
|
1140
|
-
enqueue(value) {
|
|
1141
|
-
const node = new Node(value);
|
|
1142
|
-
if (this.#head) {
|
|
1143
|
-
this.#tail.next = node;
|
|
1144
|
-
this.#tail = node;
|
|
1145
|
-
} else {
|
|
1146
|
-
this.#head = node;
|
|
1147
|
-
this.#tail = node;
|
|
1148
|
-
}
|
|
1149
|
-
this.#size++;
|
|
1150
|
-
}
|
|
1151
|
-
dequeue() {
|
|
1152
|
-
const current = this.#head;
|
|
1153
|
-
if (!current) {
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
this.#head = this.#head.next;
|
|
1157
|
-
this.#size--;
|
|
1158
|
-
return current.value;
|
|
1159
|
-
}
|
|
1160
|
-
peek() {
|
|
1161
|
-
if (!this.#head) {
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
return this.#head.value;
|
|
1165
|
-
}
|
|
1166
|
-
clear() {
|
|
1167
|
-
this.#head = void 0;
|
|
1168
|
-
this.#tail = void 0;
|
|
1169
|
-
this.#size = 0;
|
|
1170
|
-
}
|
|
1171
|
-
get size() {
|
|
1172
|
-
return this.#size;
|
|
1173
|
-
}
|
|
1174
|
-
*[Symbol.iterator]() {
|
|
1175
|
-
let current = this.#head;
|
|
1176
|
-
while (current) {
|
|
1177
|
-
yield current.value;
|
|
1178
|
-
current = current.next;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
};
|
|
1182
|
-
|
|
1183
|
-
// ../../node_modules/.pnpm/p-limit@6.1.0/node_modules/p-limit/index.js
|
|
1184
|
-
function pLimit(concurrency) {
|
|
1185
|
-
validateConcurrency(concurrency);
|
|
1186
|
-
const queue = new Queue();
|
|
1187
|
-
let activeCount = 0;
|
|
1188
|
-
const resumeNext = () => {
|
|
1189
|
-
if (activeCount < concurrency && queue.size > 0) {
|
|
1190
|
-
queue.dequeue()();
|
|
1191
|
-
activeCount++;
|
|
1192
|
-
}
|
|
1193
|
-
};
|
|
1194
|
-
const next = () => {
|
|
1195
|
-
activeCount--;
|
|
1196
|
-
resumeNext();
|
|
1197
|
-
};
|
|
1198
|
-
const run = async (function_, resolve, arguments_) => {
|
|
1199
|
-
const result = (async () => function_(...arguments_))();
|
|
1200
|
-
resolve(result);
|
|
1201
|
-
try {
|
|
1202
|
-
await result;
|
|
1203
|
-
} catch {
|
|
1204
|
-
}
|
|
1205
|
-
next();
|
|
1206
|
-
};
|
|
1207
|
-
const enqueue = (function_, resolve, arguments_) => {
|
|
1208
|
-
new Promise((internalResolve) => {
|
|
1209
|
-
queue.enqueue(internalResolve);
|
|
1210
|
-
}).then(
|
|
1211
|
-
run.bind(void 0, function_, resolve, arguments_)
|
|
1212
|
-
);
|
|
1213
|
-
(async () => {
|
|
1214
|
-
await Promise.resolve();
|
|
1215
|
-
if (activeCount < concurrency) {
|
|
1216
|
-
resumeNext();
|
|
1217
|
-
}
|
|
1218
|
-
})();
|
|
1219
|
-
};
|
|
1220
|
-
const generator = (function_, ...arguments_) => new Promise((resolve) => {
|
|
1221
|
-
enqueue(function_, resolve, arguments_);
|
|
1222
|
-
});
|
|
1223
|
-
Object.defineProperties(generator, {
|
|
1224
|
-
activeCount: {
|
|
1225
|
-
get: () => activeCount
|
|
1226
|
-
},
|
|
1227
|
-
pendingCount: {
|
|
1228
|
-
get: () => queue.size
|
|
1229
|
-
},
|
|
1230
|
-
clearQueue: {
|
|
1231
|
-
value() {
|
|
1232
|
-
queue.clear();
|
|
1233
|
-
}
|
|
1234
|
-
},
|
|
1235
|
-
concurrency: {
|
|
1236
|
-
get: () => concurrency,
|
|
1237
|
-
set(newConcurrency) {
|
|
1238
|
-
validateConcurrency(newConcurrency);
|
|
1239
|
-
concurrency = newConcurrency;
|
|
1240
|
-
queueMicrotask(() => {
|
|
1241
|
-
while (activeCount < concurrency && queue.size > 0) {
|
|
1242
|
-
resumeNext();
|
|
1243
|
-
}
|
|
1244
|
-
});
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1146
|
+
state,
|
|
1147
|
+
data,
|
|
1148
|
+
clear,
|
|
1149
|
+
remove,
|
|
1150
|
+
rendererContext: ctx,
|
|
1151
|
+
getDomNodes,
|
|
1152
|
+
getPath,
|
|
1153
|
+
contextKey: ctx.id
|
|
1247
1154
|
});
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1250
|
-
function validateConcurrency(concurrency) {
|
|
1251
|
-
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
1252
|
-
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1155
|
+
};
|
|
1255
1156
|
|
|
1256
1157
|
// src/preloading.ts
|
|
1257
1158
|
var ACTION_NAME_TO_VOLUME_MAP = {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1159
|
+
playMusic: "music",
|
|
1160
|
+
playSound: "sound",
|
|
1161
|
+
voice: "voice"
|
|
1261
1162
|
};
|
|
1262
1163
|
var enqueueAssetForPreloading = (asset2) => {
|
|
1263
1164
|
if (!PRELOADED_ASSETS.has(asset2)) {
|
|
1264
1165
|
ASSETS_TO_PRELOAD.add(asset2);
|
|
1265
1166
|
}
|
|
1266
1167
|
};
|
|
1267
|
-
var handleAssetsPreloading = async ({
|
|
1168
|
+
var handleAssetsPreloading = async ({
|
|
1169
|
+
request,
|
|
1170
|
+
limiter,
|
|
1171
|
+
preloadAudioBlocking,
|
|
1172
|
+
preloadImageBlocking
|
|
1173
|
+
}) => {
|
|
1268
1174
|
const list = mapSet(ASSETS_TO_PRELOAD, (asset2) => {
|
|
1269
1175
|
return limiter(async () => {
|
|
1270
1176
|
const type = await getResourseType({
|
|
@@ -1339,9 +1245,9 @@ var Novely = (() => {
|
|
|
1339
1245
|
}
|
|
1340
1246
|
return;
|
|
1341
1247
|
}
|
|
1342
|
-
if (action === "custom" && props[0].assets
|
|
1248
|
+
if (action === "custom" && props[0].assets) {
|
|
1343
1249
|
for (const asset2 of props[0].assets) {
|
|
1344
|
-
handle(asset2);
|
|
1250
|
+
isAsset(asset2) ? handle(asset2.source) : handle(asset2);
|
|
1345
1251
|
}
|
|
1346
1252
|
return;
|
|
1347
1253
|
}
|
|
@@ -1349,10 +1255,95 @@ var Novely = (() => {
|
|
|
1349
1255
|
for (let i = 1; i < props.length; i++) {
|
|
1350
1256
|
const data = props[i];
|
|
1351
1257
|
if (Array.isArray(data)) {
|
|
1352
|
-
handle(handleImageAsset(data[
|
|
1258
|
+
handle(handleImageAsset(data[5]));
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
// src/storage.ts
|
|
1265
|
+
var localStorageStorage = (options) => {
|
|
1266
|
+
return {
|
|
1267
|
+
async get() {
|
|
1268
|
+
const fallback = { saves: [], data: {}, meta: [] };
|
|
1269
|
+
try {
|
|
1270
|
+
const value = localStorage.getItem(options.key);
|
|
1271
|
+
return value ? JSON.parse(value) : fallback;
|
|
1272
|
+
} catch {
|
|
1273
|
+
return fallback;
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
async set(data) {
|
|
1277
|
+
try {
|
|
1278
|
+
localStorage.setItem(options.key, JSON.stringify(data));
|
|
1279
|
+
} catch {
|
|
1353
1280
|
}
|
|
1354
1281
|
}
|
|
1282
|
+
};
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
// src/store.ts
|
|
1286
|
+
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
1287
|
+
const subscribe = (cb) => {
|
|
1288
|
+
subscribers.add(cb), cb(current);
|
|
1289
|
+
return () => {
|
|
1290
|
+
subscribers.delete(cb);
|
|
1291
|
+
};
|
|
1292
|
+
};
|
|
1293
|
+
const push = (value) => {
|
|
1294
|
+
for (const cb of subscribers) cb(value);
|
|
1295
|
+
};
|
|
1296
|
+
const update = (fn) => {
|
|
1297
|
+
push(current = fn(current));
|
|
1298
|
+
};
|
|
1299
|
+
const set2 = (val) => {
|
|
1300
|
+
update(() => val);
|
|
1301
|
+
};
|
|
1302
|
+
const get = () => {
|
|
1303
|
+
return current;
|
|
1304
|
+
};
|
|
1305
|
+
return { subscribe, update, set: set2, get };
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
// src/translation.ts
|
|
1309
|
+
var RGX = /{{(.*?)}}/g;
|
|
1310
|
+
var split = (input, delimeters) => {
|
|
1311
|
+
const output = [];
|
|
1312
|
+
for (const delimeter of delimeters) {
|
|
1313
|
+
if (!input) break;
|
|
1314
|
+
const [start, end] = input.split(delimeter, 2);
|
|
1315
|
+
output.push(start);
|
|
1316
|
+
input = end;
|
|
1317
|
+
}
|
|
1318
|
+
output.push(input);
|
|
1319
|
+
return output;
|
|
1320
|
+
};
|
|
1321
|
+
var flattenAllowedContent = (c, state) => {
|
|
1322
|
+
if (Array.isArray(c)) {
|
|
1323
|
+
return c.map((item) => flattenAllowedContent(item, state)).join("<br>");
|
|
1355
1324
|
}
|
|
1325
|
+
if (typeof c === "function") {
|
|
1326
|
+
return flattenAllowedContent(c(state), state);
|
|
1327
|
+
}
|
|
1328
|
+
return c;
|
|
1329
|
+
};
|
|
1330
|
+
var replace = (input, data, pluralization, actions, pr) => {
|
|
1331
|
+
return input.replaceAll(RGX, (x, key, y) => {
|
|
1332
|
+
x = 0;
|
|
1333
|
+
y = data;
|
|
1334
|
+
const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
|
|
1335
|
+
if (!pathstr) {
|
|
1336
|
+
return "";
|
|
1337
|
+
}
|
|
1338
|
+
const path = pathstr.split(".");
|
|
1339
|
+
while (y && x < path.length) y = y[path[x++]];
|
|
1340
|
+
if (plural && pluralization && y && pr) {
|
|
1341
|
+
y = pluralization[plural][pr.select(y)];
|
|
1342
|
+
}
|
|
1343
|
+
const actionHandler = actions && action ? actions[action] : void 0;
|
|
1344
|
+
if (actionHandler) y = actionHandler(y);
|
|
1345
|
+
return y == null ? "" : y;
|
|
1346
|
+
});
|
|
1356
1347
|
};
|
|
1357
1348
|
|
|
1358
1349
|
// src/novely.ts
|
|
@@ -1393,7 +1384,7 @@ var Novely = (() => {
|
|
|
1393
1384
|
};
|
|
1394
1385
|
const scriptBase = async (part) => {
|
|
1395
1386
|
if (destroyed) return;
|
|
1396
|
-
Object.assign(story,
|
|
1387
|
+
Object.assign(story, flatStory(part));
|
|
1397
1388
|
let loadingIsShown = false;
|
|
1398
1389
|
if (!initialScreenWasShown) {
|
|
1399
1390
|
renderer.ui.showLoading();
|
|
@@ -1472,7 +1463,8 @@ var Novely = (() => {
|
|
|
1472
1463
|
[null, 0]
|
|
1473
1464
|
],
|
|
1474
1465
|
state,
|
|
1475
|
-
[intime(Date.now()), "auto"]
|
|
1466
|
+
[intime(Date.now()), "auto"],
|
|
1467
|
+
[]
|
|
1476
1468
|
];
|
|
1477
1469
|
};
|
|
1478
1470
|
const getLanguageWithoutParameters = () => {
|
|
@@ -1481,7 +1473,9 @@ var Novely = (() => {
|
|
|
1481
1473
|
return language;
|
|
1482
1474
|
}
|
|
1483
1475
|
if (DEV) {
|
|
1484
|
-
throw new Error(
|
|
1476
|
+
throw new Error(
|
|
1477
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1478
|
+
);
|
|
1485
1479
|
}
|
|
1486
1480
|
throw 0;
|
|
1487
1481
|
};
|
|
@@ -1597,7 +1591,9 @@ var Novely = (() => {
|
|
|
1597
1591
|
const restore = async (save2) => {
|
|
1598
1592
|
if (isEmpty(story)) {
|
|
1599
1593
|
if (DEV) {
|
|
1600
|
-
throw new Error(
|
|
1594
|
+
throw new Error(
|
|
1595
|
+
"Story is empty. You should call an `enine.script` function [https://novely.pages.dev/guide/story.html]"
|
|
1596
|
+
);
|
|
1601
1597
|
}
|
|
1602
1598
|
return;
|
|
1603
1599
|
}
|
|
@@ -1617,7 +1613,10 @@ var Novely = (() => {
|
|
|
1617
1613
|
const [path] = stack.value = latest;
|
|
1618
1614
|
renderer.ui.showScreen("game");
|
|
1619
1615
|
const { queue, skip, skipPreserve } = getActionsFromPath(story, path, false);
|
|
1620
|
-
const {
|
|
1616
|
+
const {
|
|
1617
|
+
run,
|
|
1618
|
+
keep: { keep, characters: characters2, audio: audio2 }
|
|
1619
|
+
} = createQueueProcessor(queue, {
|
|
1621
1620
|
skip,
|
|
1622
1621
|
skipPreserve
|
|
1623
1622
|
});
|
|
@@ -1667,7 +1666,9 @@ var Novely = (() => {
|
|
|
1667
1666
|
const isSaved = () => {
|
|
1668
1667
|
const { saves } = storageData.get();
|
|
1669
1668
|
const [currentPath, currentData] = stack.value;
|
|
1670
|
-
return saves.some(
|
|
1669
|
+
return saves.some(
|
|
1670
|
+
([path, data2, [date, type2]]) => type2 === "manual" && times.has(date) && dequal(path, currentPath) && dequal(data2, currentData)
|
|
1671
|
+
);
|
|
1671
1672
|
};
|
|
1672
1673
|
if (interacted > 1 && !force && askBeforeExit && !isSaved()) {
|
|
1673
1674
|
renderer.ui.showExitPrompt();
|
|
@@ -1763,7 +1764,9 @@ var Novely = (() => {
|
|
|
1763
1764
|
const getLanguageDisplayName = (lang) => {
|
|
1764
1765
|
const language = translation[lang];
|
|
1765
1766
|
if (DEV && !language) {
|
|
1766
|
-
throw new Error(
|
|
1767
|
+
throw new Error(
|
|
1768
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1769
|
+
);
|
|
1767
1770
|
}
|
|
1768
1771
|
return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
|
|
1769
1772
|
};
|
|
@@ -1782,6 +1785,61 @@ var Novely = (() => {
|
|
|
1782
1785
|
const getCharacterAssets = (character, emotion) => {
|
|
1783
1786
|
return toArray(characters[character].emotions[emotion]).map(handleImageAsset);
|
|
1784
1787
|
};
|
|
1788
|
+
const getCharacterName = (character) => {
|
|
1789
|
+
const c = character;
|
|
1790
|
+
const cs = characters;
|
|
1791
|
+
const [lang] = storageData.get().meta;
|
|
1792
|
+
if (c && c in cs) {
|
|
1793
|
+
const block = cs[c].name;
|
|
1794
|
+
if (typeof block === "string") {
|
|
1795
|
+
return block;
|
|
1796
|
+
}
|
|
1797
|
+
if (lang in block) {
|
|
1798
|
+
return block[lang];
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
return String(c) || "";
|
|
1802
|
+
};
|
|
1803
|
+
const getDialogOverview = () => {
|
|
1804
|
+
const { value: save2 } = useStack(MAIN_CONTEXT_KEY);
|
|
1805
|
+
const stateSnapshots = save2[3];
|
|
1806
|
+
const { queue } = getActionsFromPath(story, save2[0], false);
|
|
1807
|
+
const [lang] = storageData.get().meta;
|
|
1808
|
+
const dialogItem = [];
|
|
1809
|
+
for (let p = 0, i = 0; i < queue.length; i++) {
|
|
1810
|
+
const action2 = queue[i];
|
|
1811
|
+
if (action2[0] === "dialog") {
|
|
1812
|
+
const [_, name, text] = action2;
|
|
1813
|
+
let voice = void 0;
|
|
1814
|
+
for (let j = i - 1; j > p; j--) {
|
|
1815
|
+
const action3 = queue[j];
|
|
1816
|
+
if (isUserRequiredAction(action3) || isSkippedDuringRestore(action3[0])) break;
|
|
1817
|
+
if (action3[0] === "stopVoice") break;
|
|
1818
|
+
if (action3[0] === "voice") {
|
|
1819
|
+
voice = action3[1];
|
|
1820
|
+
break;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
dialogItem.push({
|
|
1824
|
+
name,
|
|
1825
|
+
text,
|
|
1826
|
+
voice
|
|
1827
|
+
});
|
|
1828
|
+
p = i;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
const entries = dialogItem.map(({ name, text, voice }, i) => {
|
|
1832
|
+
const state = stateSnapshots[i];
|
|
1833
|
+
const audioSource = isString(voice) ? voice : isAsset(voice) ? voice : voice == void 0 ? voice : voice[lang];
|
|
1834
|
+
name = name ? getCharacterName(name) : "";
|
|
1835
|
+
return {
|
|
1836
|
+
name: templateReplace(name, state),
|
|
1837
|
+
text: templateReplace(text, state),
|
|
1838
|
+
voice: audioSource ? handleAudioAsset(audioSource) : ""
|
|
1839
|
+
};
|
|
1840
|
+
});
|
|
1841
|
+
return entries;
|
|
1842
|
+
};
|
|
1785
1843
|
const renderer = createRenderer({
|
|
1786
1844
|
mainContextKey: MAIN_CONTEXT_KEY,
|
|
1787
1845
|
characters: getCharactersData(characters),
|
|
@@ -1803,6 +1861,7 @@ var Novely = (() => {
|
|
|
1803
1861
|
getLanguageDisplayName,
|
|
1804
1862
|
getCharacterColor,
|
|
1805
1863
|
getCharacterAssets,
|
|
1864
|
+
getDialogOverview,
|
|
1806
1865
|
getResourseType: getResourseTypeForRenderer
|
|
1807
1866
|
});
|
|
1808
1867
|
const useStack = createUseStackFunction(renderer);
|
|
@@ -1865,17 +1924,19 @@ var Novely = (() => {
|
|
|
1865
1924
|
}
|
|
1866
1925
|
};
|
|
1867
1926
|
const match = matchAction(matchActionOptions, {
|
|
1868
|
-
wait({ ctx, push }, [time]) {
|
|
1927
|
+
wait({ ctx, data: data2, push }, [time]) {
|
|
1869
1928
|
if (ctx.meta.restoring) return;
|
|
1870
|
-
setTimeout(push, isFunction(time) ? time(
|
|
1929
|
+
setTimeout(push, isFunction(time) ? time(data2) : time);
|
|
1871
1930
|
},
|
|
1872
1931
|
showBackground({ ctx, push }, [background]) {
|
|
1873
1932
|
if (isString(background) || isAsset(background)) {
|
|
1874
1933
|
ctx.background({
|
|
1875
|
-
|
|
1934
|
+
all: handleImageAsset(background)
|
|
1876
1935
|
});
|
|
1877
1936
|
} else {
|
|
1878
|
-
ctx.background(
|
|
1937
|
+
ctx.background(
|
|
1938
|
+
Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, handleImageAsset(asset2)]))
|
|
1939
|
+
);
|
|
1879
1940
|
}
|
|
1880
1941
|
push();
|
|
1881
1942
|
},
|
|
@@ -1935,29 +1996,13 @@ var Novely = (() => {
|
|
|
1935
1996
|
ctx.character(character).remove(className, style, duration, ctx.meta.restoring).then(push);
|
|
1936
1997
|
},
|
|
1937
1998
|
dialog({ ctx, data: data2, forward }, [character, content, emotion]) {
|
|
1938
|
-
const name = (
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
const block = cs[c].name;
|
|
1944
|
-
if (typeof block === "string") {
|
|
1945
|
-
return block;
|
|
1946
|
-
}
|
|
1947
|
-
if (lang in block) {
|
|
1948
|
-
return block[lang];
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
return c || "";
|
|
1952
|
-
})();
|
|
1999
|
+
const name = getCharacterName(character);
|
|
2000
|
+
const stack = useStack(ctx);
|
|
2001
|
+
if (!ctx.meta.restoring && !ctx.meta.goingBack) {
|
|
2002
|
+
stack.value[3].push(clone(data2));
|
|
2003
|
+
}
|
|
1953
2004
|
ctx.clearBlockingActions("dialog");
|
|
1954
|
-
ctx.dialog(
|
|
1955
|
-
templateReplace(content, data2),
|
|
1956
|
-
templateReplace(name, data2),
|
|
1957
|
-
character,
|
|
1958
|
-
emotion,
|
|
1959
|
-
forward
|
|
1960
|
-
);
|
|
2005
|
+
ctx.dialog(templateReplace(content, data2), templateReplace(name, data2), character, emotion, forward);
|
|
1961
2006
|
},
|
|
1962
2007
|
function({ ctx, push }, [fn]) {
|
|
1963
2008
|
const { restoring, goingBack, preview: preview2 } = ctx.meta;
|
|
@@ -1982,19 +2027,19 @@ var Novely = (() => {
|
|
|
1982
2027
|
const transformedChoices = choices.map(([content, _children, active, visible, onSelect, image]) => {
|
|
1983
2028
|
const active$ = store(false);
|
|
1984
2029
|
const visible$ = store(false);
|
|
1985
|
-
const
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
});
|
|
1992
|
-
const visibleValue = !visible || visible({
|
|
2030
|
+
const lang = getLanguageFromStore(storageData);
|
|
2031
|
+
const getCheckValue = (fn) => {
|
|
2032
|
+
if (!fn) {
|
|
2033
|
+
return true;
|
|
2034
|
+
}
|
|
2035
|
+
return fn({
|
|
1993
2036
|
lang,
|
|
1994
|
-
state
|
|
2037
|
+
state: getStateAtCtx(ctx)
|
|
1995
2038
|
});
|
|
1996
|
-
|
|
1997
|
-
|
|
2039
|
+
};
|
|
2040
|
+
const update = () => {
|
|
2041
|
+
active$.set(getCheckValue(active));
|
|
2042
|
+
visible$.set(getCheckValue(visible));
|
|
1998
2043
|
};
|
|
1999
2044
|
update();
|
|
2000
2045
|
const onSelectGuarded = onSelect || noop;
|
|
@@ -2007,7 +2052,9 @@ var Novely = (() => {
|
|
|
2007
2052
|
return [templateReplace(content, data2), active$, visible$, onSelectWrapped, imageValue];
|
|
2008
2053
|
});
|
|
2009
2054
|
if (DEV && transformedChoices.length === 0) {
|
|
2010
|
-
throw new Error(
|
|
2055
|
+
throw new Error(
|
|
2056
|
+
`Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`
|
|
2057
|
+
);
|
|
2011
2058
|
}
|
|
2012
2059
|
ctx.clearBlockingActions("choice");
|
|
2013
2060
|
ctx.choices(templateReplace(question, data2), transformedChoices, (selected) => {
|
|
@@ -2036,6 +2083,7 @@ var Novely = (() => {
|
|
|
2036
2083
|
["jump", scene],
|
|
2037
2084
|
[null, -1]
|
|
2038
2085
|
];
|
|
2086
|
+
stack.value[3] = [];
|
|
2039
2087
|
match("clear", [], {
|
|
2040
2088
|
ctx,
|
|
2041
2089
|
data: data2
|
|
@@ -2050,19 +2098,19 @@ var Novely = (() => {
|
|
|
2050
2098
|
push
|
|
2051
2099
|
);
|
|
2052
2100
|
},
|
|
2053
|
-
condition({ ctx }, [condition, variants]) {
|
|
2101
|
+
condition({ ctx, data: data2 }, [condition, variants]) {
|
|
2054
2102
|
if (DEV && Object.values(variants).length === 0) {
|
|
2055
2103
|
throw new Error(`Attempt to use Condition action with empty variants object`);
|
|
2056
2104
|
}
|
|
2057
2105
|
if (!ctx.meta.restoring) {
|
|
2058
|
-
const val = String(condition(
|
|
2106
|
+
const val = String(condition(data2));
|
|
2059
2107
|
if (DEV && !variants[val]) {
|
|
2060
2108
|
throw new Error(`Attempt to go to unknown variant "${val}"`);
|
|
2061
2109
|
}
|
|
2062
2110
|
if (DEV && variants[val].length === 0) {
|
|
2063
2111
|
throw new Error(`Attempt to go to empty variant "${val}"`);
|
|
2064
2112
|
}
|
|
2065
|
-
const stack = useStack(
|
|
2113
|
+
const stack = useStack(ctx);
|
|
2066
2114
|
stack.value[0].push(["condition", val], [null, 0]);
|
|
2067
2115
|
render(ctx);
|
|
2068
2116
|
}
|
|
@@ -2073,12 +2121,7 @@ var Novely = (() => {
|
|
|
2073
2121
|
},
|
|
2074
2122
|
input({ ctx, data: data2, forward }, [question, onInput, setup]) {
|
|
2075
2123
|
ctx.clearBlockingActions("input");
|
|
2076
|
-
ctx.input(
|
|
2077
|
-
templateReplace(question, data2),
|
|
2078
|
-
onInput,
|
|
2079
|
-
setup || noop,
|
|
2080
|
-
forward
|
|
2081
|
-
);
|
|
2124
|
+
ctx.input(templateReplace(question, data2), onInput, setup || noop, forward);
|
|
2082
2125
|
},
|
|
2083
2126
|
custom({ ctx, push }, [fn]) {
|
|
2084
2127
|
if (fn.requireUserAction) {
|
|
@@ -2118,7 +2161,9 @@ var Novely = (() => {
|
|
|
2118
2161
|
animateCharacter({ ctx, push }, [character, className]) {
|
|
2119
2162
|
const classes = className.split(" ");
|
|
2120
2163
|
if (DEV && classes.length === 0) {
|
|
2121
|
-
throw new Error(
|
|
2164
|
+
throw new Error(
|
|
2165
|
+
"Attempt to use AnimateCharacter without classes. Classes should be provided [https://novely.pages.dev/guide/actions/animateCharacter.html]"
|
|
2166
|
+
);
|
|
2122
2167
|
}
|
|
2123
2168
|
if (ctx.meta.preview) return;
|
|
2124
2169
|
ctx.character(character).animate(classes);
|
|
@@ -2152,7 +2197,9 @@ var Novely = (() => {
|
|
|
2152
2197
|
},
|
|
2153
2198
|
preload({ ctx, push }, [source]) {
|
|
2154
2199
|
if (DEV && preloadAssets !== "lazy") {
|
|
2155
|
-
console.error(
|
|
2200
|
+
console.error(
|
|
2201
|
+
`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`
|
|
2202
|
+
);
|
|
2156
2203
|
}
|
|
2157
2204
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
2158
2205
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
@@ -2175,22 +2222,23 @@ var Novely = (() => {
|
|
|
2175
2222
|
});
|
|
2176
2223
|
const render = (ctx) => {
|
|
2177
2224
|
const stack = useStack(ctx);
|
|
2178
|
-
const
|
|
2225
|
+
const [path, state] = stack.value;
|
|
2226
|
+
const referred = refer(path);
|
|
2179
2227
|
if (isAction(referred)) {
|
|
2180
2228
|
const [action2, ...props] = referred;
|
|
2181
2229
|
match(action2, props, {
|
|
2182
2230
|
ctx,
|
|
2183
|
-
data:
|
|
2231
|
+
data: state
|
|
2184
2232
|
});
|
|
2185
2233
|
} else if (Object.values(story).some((branch) => branch === referred)) {
|
|
2186
2234
|
match("end", [], {
|
|
2187
2235
|
ctx,
|
|
2188
|
-
data:
|
|
2236
|
+
data: state
|
|
2189
2237
|
});
|
|
2190
2238
|
} else {
|
|
2191
2239
|
match("exit", [], {
|
|
2192
2240
|
ctx,
|
|
2193
|
-
data:
|
|
2241
|
+
data: state
|
|
2194
2242
|
});
|
|
2195
2243
|
}
|
|
2196
2244
|
};
|
|
@@ -2198,21 +2246,15 @@ var Novely = (() => {
|
|
|
2198
2246
|
interacted = value ? interacted + 1 : 0;
|
|
2199
2247
|
};
|
|
2200
2248
|
const templateReplace = (content, values) => {
|
|
2201
|
-
const {
|
|
2249
|
+
const {
|
|
2250
|
+
data: data2,
|
|
2251
|
+
meta: [lang]
|
|
2252
|
+
} = storageData.get();
|
|
2202
2253
|
const obj = values || data2;
|
|
2203
|
-
const
|
|
2204
|
-
!isFunction(content) && !isString(content) ? content[lang] : content,
|
|
2205
|
-
obj
|
|
2206
|
-
);
|
|
2254
|
+
const str = flattenAllowedContent(!isFunction(content) && !isString(content) ? content[lang] : content, obj);
|
|
2207
2255
|
const t2 = translation[lang];
|
|
2208
2256
|
const pluralRules = (t2.plural || t2.actions) && new Intl.PluralRules(t2.tag || lang);
|
|
2209
|
-
return replace(
|
|
2210
|
-
str2,
|
|
2211
|
-
obj,
|
|
2212
|
-
t2.plural,
|
|
2213
|
-
t2.actions,
|
|
2214
|
-
pluralRules
|
|
2215
|
-
);
|
|
2257
|
+
return replace(str, obj, t2.plural, t2.actions, pluralRules);
|
|
2216
2258
|
};
|
|
2217
2259
|
const data = (value) => {
|
|
2218
2260
|
const _data = storageData.get().data;
|
|
@@ -2236,7 +2278,9 @@ var Novely = (() => {
|
|
|
2236
2278
|
const setStorageData = (data2) => {
|
|
2237
2279
|
if (destroyed) {
|
|
2238
2280
|
if (DEV) {
|
|
2239
|
-
throw new Error(
|
|
2281
|
+
throw new Error(
|
|
2282
|
+
`function \`setStorageData\` was called after novely instance was destroyed. Data is not updater nor synced after destroy.`
|
|
2283
|
+
);
|
|
2240
2284
|
}
|
|
2241
2285
|
return;
|
|
2242
2286
|
}
|
|
@@ -2296,7 +2340,7 @@ var Novely = (() => {
|
|
|
2296
2340
|
* @example
|
|
2297
2341
|
* ```ts
|
|
2298
2342
|
* import type { ConditionParams, StateFunction } from '@novely/core';
|
|
2299
|
-
|
|
2343
|
+
*
|
|
2300
2344
|
* const conditionCheck = (state: StateFunction<ConditionParams<typeof engine.typeEssintials>>) => {
|
|
2301
2345
|
* return state.age >= 18;
|
|
2302
2346
|
* }
|
|
@@ -2407,7 +2451,9 @@ var Novely = (() => {
|
|
|
2407
2451
|
CloseMenu: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u043D\u044E",
|
|
2408
2452
|
MusicVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u043C\u0443\u0437\u044B\u043A\u0438",
|
|
2409
2453
|
SoundVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0437\u0432\u0443\u043A\u043E\u0432",
|
|
2410
|
-
VoiceVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0440\u0435\u0447\u0438"
|
|
2454
|
+
VoiceVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0440\u0435\u0447\u0438",
|
|
2455
|
+
Close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
|
|
2456
|
+
DialogOverview: "\u041E\u0431\u0437\u043E\u0440 \u0434\u0438\u0430\u043B\u043E\u0433\u0430"
|
|
2411
2457
|
};
|
|
2412
2458
|
var EN = {
|
|
2413
2459
|
NewGame: "New Game",
|
|
@@ -2443,7 +2489,9 @@ var Novely = (() => {
|
|
|
2443
2489
|
CloseMenu: "Close menu",
|
|
2444
2490
|
MusicVolume: "Music volume",
|
|
2445
2491
|
SoundVolume: "Sound volume",
|
|
2446
|
-
VoiceVolume: "Voice volume"
|
|
2492
|
+
VoiceVolume: "Voice volume",
|
|
2493
|
+
Close: "Close",
|
|
2494
|
+
DialogOverview: "Dialog Overview"
|
|
2447
2495
|
};
|
|
2448
2496
|
var KK = {
|
|
2449
2497
|
NewGame: "\u0416\u0430\u04A3\u0430 \u043E\u0439\u044B\u043D",
|
|
@@ -2479,7 +2527,9 @@ var Novely = (() => {
|
|
|
2479
2527
|
CloseMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0436\u0430\u0431\u0443",
|
|
2480
2528
|
MusicVolume: "\u041C\u0443\u0437\u044B\u043A\u0430\u043D\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2481
2529
|
SoundVolume: "\u0414\u044B\u0431\u044B\u0441\u0442\u0430\u0440\u0434\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2482
|
-
VoiceVolume: "\u0421\u04E9\u0439\u043B\u0435\u0443 \u043A\u04E9\u043B\u0435\u043C\u0456"
|
|
2530
|
+
VoiceVolume: "\u0421\u04E9\u0439\u043B\u0435\u0443 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2531
|
+
Close: "\u0416\u0430\u0431\u0443",
|
|
2532
|
+
DialogOverview: "\u0414\u0438\u0430\u043B\u043E\u0433\u049B\u0430 \u0428\u043E\u043B\u0443"
|
|
2483
2533
|
};
|
|
2484
2534
|
var JP = {
|
|
2485
2535
|
NewGame: "\u300C\u65B0\u3057\u3044\u30B2\u30FC\u30E0\u300D",
|
|
@@ -2515,7 +2565,133 @@ var Novely = (() => {
|
|
|
2515
2565
|
CloseMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B",
|
|
2516
2566
|
MusicVolume: "\u97F3\u697D\u306E\u30DC\u30EA\u30E5\u30FC\u30E0",
|
|
2517
2567
|
SoundVolume: "\u97F3\u91CF",
|
|
2518
|
-
VoiceVolume: "\u30B9\u30D4\u30FC\u30C1\u306E\u91CF"
|
|
2568
|
+
VoiceVolume: "\u30B9\u30D4\u30FC\u30C1\u306E\u91CF",
|
|
2569
|
+
Close: "\u9589\u3058\u308B",
|
|
2570
|
+
DialogOverview: "\u30C0\u30A4\u30A2\u30ED\u30B0\u306E\u6982\u8981"
|
|
2571
|
+
};
|
|
2572
|
+
|
|
2573
|
+
// src/audio-codecs.ts
|
|
2574
|
+
var cut = (str) => str.replace(/^no$/, "");
|
|
2575
|
+
var audio = new Audio();
|
|
2576
|
+
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
2577
|
+
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
2578
|
+
var supportsMap = {
|
|
2579
|
+
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
2580
|
+
mpeg: canPlay("audio/mpeg;"),
|
|
2581
|
+
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
2582
|
+
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2583
|
+
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2584
|
+
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
2585
|
+
aac: canPlay("audio/aac;"),
|
|
2586
|
+
caf: canPlay("audio/x-caf;"),
|
|
2587
|
+
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
2588
|
+
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
2589
|
+
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
2590
|
+
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
2591
|
+
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
2592
|
+
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
2593
|
+
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
2594
|
+
};
|
|
2595
|
+
|
|
2596
|
+
// src/image-formats.ts
|
|
2597
|
+
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
2598
|
+
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
2599
|
+
var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
|
|
2600
|
+
var supportsFormat = (source) => {
|
|
2601
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
2602
|
+
const img = Object.assign(document.createElement("img"), {
|
|
2603
|
+
src: source
|
|
2604
|
+
});
|
|
2605
|
+
img.onload = img.onerror = () => {
|
|
2606
|
+
resolve(img.height === 2);
|
|
2607
|
+
};
|
|
2608
|
+
return promise;
|
|
2609
|
+
};
|
|
2610
|
+
var supportsMap2 = {
|
|
2611
|
+
avif: false,
|
|
2612
|
+
jxl: false,
|
|
2613
|
+
webp: false
|
|
2614
|
+
};
|
|
2615
|
+
var formatsMap = {
|
|
2616
|
+
avif,
|
|
2617
|
+
jxl,
|
|
2618
|
+
webp
|
|
2619
|
+
};
|
|
2620
|
+
var loadImageFormatsSupport = async () => {
|
|
2621
|
+
const promises = [];
|
|
2622
|
+
for (const [format, source] of Object.entries(formatsMap)) {
|
|
2623
|
+
const promise = supportsFormat(source).then((supported) => {
|
|
2624
|
+
supportsMap2[format] = supported;
|
|
2625
|
+
});
|
|
2626
|
+
promises.push(promise);
|
|
2627
|
+
}
|
|
2628
|
+
await Promise.all(promises);
|
|
2629
|
+
};
|
|
2630
|
+
loadImageFormatsSupport();
|
|
2631
|
+
|
|
2632
|
+
// src/asset.ts
|
|
2633
|
+
var getType = memoize(
|
|
2634
|
+
(extensions) => {
|
|
2635
|
+
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
2636
|
+
return "audio";
|
|
2637
|
+
}
|
|
2638
|
+
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
2639
|
+
return "image";
|
|
2640
|
+
}
|
|
2641
|
+
throw extensions;
|
|
2642
|
+
},
|
|
2643
|
+
{
|
|
2644
|
+
getCacheKey: (extensions) => extensions.join("~")
|
|
2645
|
+
}
|
|
2646
|
+
);
|
|
2647
|
+
var SUPPORT_MAPS = {
|
|
2648
|
+
image: supportsMap2,
|
|
2649
|
+
audio: supportsMap
|
|
2650
|
+
};
|
|
2651
|
+
var assetPrivate = memoize(
|
|
2652
|
+
(variants) => {
|
|
2653
|
+
if (DEV && variants.length === 0) {
|
|
2654
|
+
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
2655
|
+
}
|
|
2656
|
+
const map = {};
|
|
2657
|
+
const extensions = [];
|
|
2658
|
+
for (const v of variants) {
|
|
2659
|
+
const e = getUrlFileExtension(v);
|
|
2660
|
+
map[e] = v;
|
|
2661
|
+
extensions.push(e);
|
|
2662
|
+
}
|
|
2663
|
+
const type = getType(extensions);
|
|
2664
|
+
const getSource = once(() => {
|
|
2665
|
+
const support = SUPPORT_MAPS[type];
|
|
2666
|
+
for (const extension of extensions) {
|
|
2667
|
+
if (extension in support) {
|
|
2668
|
+
if (support[extension]) {
|
|
2669
|
+
return map[extension];
|
|
2670
|
+
}
|
|
2671
|
+
} else {
|
|
2672
|
+
return map[extension];
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
if (DEV) {
|
|
2676
|
+
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
2677
|
+
}
|
|
2678
|
+
return "";
|
|
2679
|
+
});
|
|
2680
|
+
return {
|
|
2681
|
+
get source() {
|
|
2682
|
+
return getSource();
|
|
2683
|
+
},
|
|
2684
|
+
get type() {
|
|
2685
|
+
return type;
|
|
2686
|
+
}
|
|
2687
|
+
};
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
getCacheKey: (variants) => variants.join("~")
|
|
2691
|
+
}
|
|
2692
|
+
);
|
|
2693
|
+
var asset = (...variants) => {
|
|
2694
|
+
return assetPrivate(variants);
|
|
2519
2695
|
};
|
|
2520
2696
|
return __toCommonJS(src_exports);
|
|
2521
2697
|
})();
|