@novely/core 0.45.1 → 0.45.2

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.
@@ -31,61 +31,31 @@ var Novely = (() => {
31
31
  novely: () => novely
32
32
  });
33
33
 
34
- // src/constants.ts
35
- var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
36
- var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
37
- var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
38
- var AUDIO_ACTIONS = /* @__PURE__ */ new Set([
39
- "playMusic",
40
- "stopMusic",
41
- "playSound",
42
- "stopSound",
43
- "voice",
44
- "stopVoice"
45
- ]);
46
- var EMPTY_SET = /* @__PURE__ */ new Set();
47
- var DEFAULT_TYPEWRITER_SPEED = "Medium";
48
- var HOWLER_SUPPORTED_FILE_FORMATS = /* @__PURE__ */ new Set([
49
- "mp3",
50
- "mpeg",
51
- "opus",
52
- "ogg",
53
- "oga",
54
- "wav",
55
- "aac",
56
- "caf",
57
- "m4a",
58
- "m4b",
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();
86
-
87
- // ../../node_modules/.pnpm/esm-env@1.0.0/node_modules/esm-env/prod-ssr.js
88
- var DEV = false;
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
+ }
89
59
 
90
60
  // ../../node_modules/.pnpm/es-toolkit@1.16.0/node_modules/es-toolkit/dist/function/once.mjs
91
61
  function once(func) {
@@ -131,132 +101,314 @@ var Novely = (() => {
131
101
  return memoizedFn;
132
102
  }
133
103
 
134
- // src/audio-codecs.ts
135
- var cut = (str2) => str2.replace(/^no$/, "");
136
- var audio = new Audio();
137
- var canPlay = (type) => !!cut(audio.canPlayType(type));
138
- var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
139
- var supportsMap = {
140
- mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
141
- mpeg: canPlay("audio/mpeg;"),
142
- opus: canPlay('audio/ogg; codecs="opus"'),
143
- ogg: canPlay('audio/ogg; codecs="vorbis"'),
144
- oga: canPlay('audio/ogg; codecs="vorbis"'),
145
- wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
146
- aac: canPlay("audio/aac;"),
147
- caf: canPlay("audio/x-caf;"),
148
- m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
149
- m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
150
- mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
151
- weba: canPlay('audio/webm; codecs="vorbis"'),
152
- webm: canPlay('audio/webm; codecs="vorbis"'),
153
- dolby: canPlay('audio/mp4; codecs="ec-3"'),
154
- flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
155
- };
104
+ // ../../node_modules/.pnpm/es-toolkit@1.16.0/node_modules/es-toolkit/dist/compat/predicate/isObjectLike.mjs
105
+ function isObjectLike(value) {
106
+ return typeof value === "object" && value !== null;
107
+ }
156
108
 
157
- // src/image-formats.ts
158
- var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
159
- var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
160
- var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
161
- var supportsFormat = (source) => {
162
- const { promise, resolve } = Promise.withResolvers();
163
- const img = Object.assign(document.createElement("img"), {
164
- src: source
165
- });
166
- img.onload = img.onerror = () => {
167
- resolve(img.height === 2);
168
- };
169
- return promise;
170
- };
171
- var supportsMap2 = {
172
- avif: false,
173
- jxl: false,
174
- webp: false
175
- };
176
- var formatsMap = {
177
- avif,
178
- jxl,
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);
109
+ // ../../node_modules/.pnpm/es-toolkit@1.16.0/node_modules/es-toolkit/dist/object/merge.mjs
110
+ function merge(target, source) {
111
+ const sourceKeys = Object.keys(source);
112
+ for (let i = 0; i < sourceKeys.length; i++) {
113
+ const key = sourceKeys[i];
114
+ const sourceValue = source[key];
115
+ const targetValue = target[key];
116
+ if (Array.isArray(sourceValue)) {
117
+ target[key] = merge(targetValue ?? [], sourceValue);
118
+ } else if (isObjectLike(targetValue) && isObjectLike(sourceValue)) {
119
+ target[key] = merge(targetValue ?? {}, sourceValue);
120
+ } else if (targetValue === void 0 || sourceValue !== void 0) {
121
+ target[key] = sourceValue;
122
+ }
188
123
  }
189
- await Promise.all(promises);
190
- };
191
- loadImageFormatsSupport();
124
+ return target;
125
+ }
192
126
 
193
- // src/asset.ts
194
- var getType = memoize(
195
- (extensions) => {
196
- if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
197
- return "audio";
127
+ // ../../node_modules/.pnpm/esm-env@1.0.0/node_modules/esm-env/prod-ssr.js
128
+ var DEV = false;
129
+
130
+ // ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
131
+ function set(obj, key, val) {
132
+ if (typeof val.value === "object") val.value = klona(val.value);
133
+ if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
134
+ Object.defineProperty(obj, key, val);
135
+ } else obj[key] = val.value;
136
+ }
137
+ function klona(x) {
138
+ if (typeof x !== "object") return x;
139
+ var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
140
+ if (str2 === "[object Object]") {
141
+ tmp = Object.create(x.__proto__ || null);
142
+ } else if (str2 === "[object Array]") {
143
+ tmp = Array(x.length);
144
+ } else if (str2 === "[object Set]") {
145
+ tmp = /* @__PURE__ */ new Set();
146
+ x.forEach(function(val) {
147
+ tmp.add(klona(val));
148
+ });
149
+ } else if (str2 === "[object Map]") {
150
+ tmp = /* @__PURE__ */ new Map();
151
+ x.forEach(function(val, key) {
152
+ tmp.set(klona(key), klona(val));
153
+ });
154
+ } else if (str2 === "[object Date]") {
155
+ tmp = /* @__PURE__ */ new Date(+x);
156
+ } else if (str2 === "[object RegExp]") {
157
+ tmp = new RegExp(x.source, x.flags);
158
+ } else if (str2 === "[object DataView]") {
159
+ tmp = new x.constructor(klona(x.buffer));
160
+ } else if (str2 === "[object ArrayBuffer]") {
161
+ tmp = x.slice(0);
162
+ } else if (str2.slice(-6) === "Array]") {
163
+ tmp = new x.constructor(x);
164
+ }
165
+ if (tmp) {
166
+ for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
167
+ set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
198
168
  }
199
- if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
200
- return "image";
169
+ for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
170
+ if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
171
+ set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
201
172
  }
202
- throw extensions;
203
- },
204
- {
205
- getCacheKey: (extensions) => extensions.join("~")
206
173
  }
207
- );
208
- var SUPPORT_MAPS = {
209
- "image": supportsMap2,
210
- "audio": supportsMap
174
+ return tmp || x;
175
+ }
176
+
177
+ // ../../node_modules/.pnpm/yocto-queue@1.1.1/node_modules/yocto-queue/index.js
178
+ var Node = class {
179
+ value;
180
+ next;
181
+ constructor(value) {
182
+ this.value = value;
183
+ }
211
184
  };
212
- var assetPrivate = memoize(
213
- (variants) => {
214
- if (DEV && variants.length === 0) {
215
- throw new Error(`Attempt to use "asset" function without arguments`);
185
+ var Queue = class {
186
+ #head;
187
+ #tail;
188
+ #size;
189
+ constructor() {
190
+ this.clear();
191
+ }
192
+ enqueue(value) {
193
+ const node = new Node(value);
194
+ if (this.#head) {
195
+ this.#tail.next = node;
196
+ this.#tail = node;
197
+ } else {
198
+ this.#head = node;
199
+ this.#tail = node;
216
200
  }
217
- const map = {};
218
- const extensions = [];
219
- for (const v of variants) {
220
- const e = getUrlFileExtension(v);
221
- map[e] = v;
222
- extensions.push(e);
201
+ this.#size++;
202
+ }
203
+ dequeue() {
204
+ const current = this.#head;
205
+ if (!current) {
206
+ return;
223
207
  }
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
- }
208
+ this.#head = this.#head.next;
209
+ this.#size--;
210
+ return current.value;
211
+ }
212
+ peek() {
213
+ if (!this.#head) {
214
+ return;
215
+ }
216
+ return this.#head.value;
217
+ }
218
+ clear() {
219
+ this.#head = void 0;
220
+ this.#tail = void 0;
221
+ this.#size = 0;
222
+ }
223
+ get size() {
224
+ return this.#size;
225
+ }
226
+ *[Symbol.iterator]() {
227
+ let current = this.#head;
228
+ while (current) {
229
+ yield current.value;
230
+ current = current.next;
231
+ }
232
+ }
233
+ };
234
+
235
+ // ../../node_modules/.pnpm/p-limit@6.1.0/node_modules/p-limit/index.js
236
+ function pLimit(concurrency) {
237
+ validateConcurrency(concurrency);
238
+ const queue = new Queue();
239
+ let activeCount = 0;
240
+ const resumeNext = () => {
241
+ if (activeCount < concurrency && queue.size > 0) {
242
+ queue.dequeue()();
243
+ activeCount++;
244
+ }
245
+ };
246
+ const next = () => {
247
+ activeCount--;
248
+ resumeNext();
249
+ };
250
+ const run = async (function_, resolve, arguments_) => {
251
+ const result = (async () => function_(...arguments_))();
252
+ resolve(result);
253
+ try {
254
+ await result;
255
+ } catch {
256
+ }
257
+ next();
258
+ };
259
+ const enqueue = (function_, resolve, arguments_) => {
260
+ new Promise((internalResolve) => {
261
+ queue.enqueue(internalResolve);
262
+ }).then(
263
+ run.bind(void 0, function_, resolve, arguments_)
264
+ );
265
+ (async () => {
266
+ await Promise.resolve();
267
+ if (activeCount < concurrency) {
268
+ resumeNext();
235
269
  }
236
- if (DEV) {
237
- throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
270
+ })();
271
+ };
272
+ const generator = (function_, ...arguments_) => new Promise((resolve) => {
273
+ enqueue(function_, resolve, arguments_);
274
+ });
275
+ Object.defineProperties(generator, {
276
+ activeCount: {
277
+ get: () => activeCount
278
+ },
279
+ pendingCount: {
280
+ get: () => queue.size
281
+ },
282
+ clearQueue: {
283
+ value() {
284
+ queue.clear();
238
285
  }
239
- return "";
240
- });
241
- return {
242
- get source() {
243
- return getSource();
244
- },
245
- get type() {
246
- return type;
286
+ },
287
+ concurrency: {
288
+ get: () => concurrency,
289
+ set(newConcurrency) {
290
+ validateConcurrency(newConcurrency);
291
+ concurrency = newConcurrency;
292
+ queueMicrotask(() => {
293
+ while (activeCount < concurrency && queue.size > 0) {
294
+ resumeNext();
295
+ }
296
+ });
247
297
  }
248
- };
249
- },
250
- {
251
- getCacheKey: (variants) => variants.join("~")
298
+ }
299
+ });
300
+ return generator;
301
+ }
302
+ function validateConcurrency(concurrency) {
303
+ if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
304
+ throw new TypeError("Expected `concurrency` to be a number from 1 and up");
252
305
  }
253
- );
254
- var asset = (...variants) => {
255
- return assetPrivate(variants);
306
+ }
307
+
308
+ // src/audio-codecs.ts
309
+ var cut = (str2) => str2.replace(/^no$/, "");
310
+ var audio = new Audio();
311
+ var canPlay = (type) => !!cut(audio.canPlayType(type));
312
+ var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
313
+ var supportsMap = {
314
+ mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
315
+ mpeg: canPlay("audio/mpeg;"),
316
+ opus: canPlay('audio/ogg; codecs="opus"'),
317
+ ogg: canPlay('audio/ogg; codecs="vorbis"'),
318
+ oga: canPlay('audio/ogg; codecs="vorbis"'),
319
+ wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
320
+ aac: canPlay("audio/aac;"),
321
+ caf: canPlay("audio/x-caf;"),
322
+ m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
323
+ m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
324
+ mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
325
+ weba: canPlay('audio/webm; codecs="vorbis"'),
326
+ webm: canPlay('audio/webm; codecs="vorbis"'),
327
+ dolby: canPlay('audio/mp4; codecs="ec-3"'),
328
+ flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
256
329
  };
257
- var isAsset = (suspect) => {
258
- return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
330
+
331
+ // src/constants.ts
332
+ var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
333
+ var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
334
+ var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
335
+ var AUDIO_ACTIONS = /* @__PURE__ */ new Set(["playMusic", "stopMusic", "playSound", "stopSound", "voice", "stopVoice"]);
336
+ var EMPTY_SET = /* @__PURE__ */ new Set();
337
+ var DEFAULT_TYPEWRITER_SPEED = "Medium";
338
+ var HOWLER_SUPPORTED_FILE_FORMATS = /* @__PURE__ */ new Set([
339
+ "mp3",
340
+ "mpeg",
341
+ "opus",
342
+ "ogg",
343
+ "oga",
344
+ "wav",
345
+ "aac",
346
+ "caf",
347
+ "m4a",
348
+ "m4b",
349
+ "mp4",
350
+ "weba",
351
+ "webm",
352
+ "dolby",
353
+ "flac"
354
+ ]);
355
+ var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
356
+ "apng",
357
+ "avif",
358
+ "gif",
359
+ "jpg",
360
+ "jpeg",
361
+ "jfif",
362
+ "pjpeg",
363
+ "pjp",
364
+ "png",
365
+ "svg",
366
+ "webp",
367
+ "bmp"
368
+ ]);
369
+ var MAIN_CONTEXT_KEY = "$MAIN";
370
+
371
+ // src/image-formats.ts
372
+ var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
373
+ var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
374
+ var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
375
+ var supportsFormat = (source) => {
376
+ const { promise, resolve } = Promise.withResolvers();
377
+ const img = Object.assign(document.createElement("img"), {
378
+ src: source
379
+ });
380
+ img.onload = img.onerror = () => {
381
+ resolve(img.height === 2);
382
+ };
383
+ return promise;
384
+ };
385
+ var supportsMap2 = {
386
+ avif: false,
387
+ jxl: false,
388
+ webp: false
389
+ };
390
+ var formatsMap = {
391
+ avif,
392
+ jxl,
393
+ webp
394
+ };
395
+ var loadImageFormatsSupport = async () => {
396
+ const promises = [];
397
+ for (const [format, source] of Object.entries(formatsMap)) {
398
+ const promise = supportsFormat(source).then((supported) => {
399
+ supportsMap2[format] = supported;
400
+ });
401
+ promises.push(promise);
402
+ }
403
+ await Promise.all(promises);
259
404
  };
405
+ loadImageFormatsSupport();
406
+
407
+ // src/shared.ts
408
+ var STACK_MAP = /* @__PURE__ */ new Map();
409
+ var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
410
+ var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
411
+ var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
260
412
 
261
413
  // src/utils.ts
262
414
  var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
@@ -267,18 +419,21 @@ var Novely = (() => {
267
419
  props,
268
420
  ctx: context
269
421
  });
270
- return values[action]({
271
- ctx: context,
272
- data,
273
- push() {
274
- if (context.meta.preview) return;
275
- push(context);
422
+ return values[action](
423
+ {
424
+ ctx: context,
425
+ data,
426
+ push() {
427
+ if (context.meta.preview) return;
428
+ push(context);
429
+ },
430
+ forward() {
431
+ if (context.meta.preview) return;
432
+ forward(context);
433
+ }
276
434
  },
277
- forward() {
278
- if (context.meta.preview) return;
279
- forward(context);
280
- }
281
- }, props);
435
+ props
436
+ );
282
437
  };
283
438
  };
284
439
  var isNumber = (val) => {
@@ -390,10 +545,10 @@ var Novely = (() => {
390
545
  };
391
546
  var getOppositeAction = (action) => {
392
547
  const MAP = {
393
- "showCharacter": "hideCharacter",
394
- "playSound": "stopSound",
395
- "playMusic": "stopMusic",
396
- "voice": "stopVoice"
548
+ showCharacter: "hideCharacter",
549
+ playSound: "stopSound",
550
+ playMusic: "stopMusic",
551
+ voice: "stopVoice"
397
552
  };
398
553
  return MAP[action];
399
554
  };
@@ -804,7 +959,10 @@ var Novely = (() => {
804
959
  }
805
960
  collection.push(action);
806
961
  if (action[0] === "jump") {
807
- path = [["jump", action[1]], [null, 0]];
962
+ path = [
963
+ ["jump", action[1]],
964
+ [null, 0]
965
+ ];
808
966
  } else if (action[0] == "block") {
809
967
  path.push(["block", action[1]], [null, 0]);
810
968
  } else {
@@ -849,422 +1007,185 @@ var Novely = (() => {
849
1007
  };
850
1008
  };
851
1009
 
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;
1010
+ // src/asset.ts
1011
+ var getType = memoize(
1012
+ (extensions) => {
1013
+ if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
1014
+ return "audio";
1015
+ }
1016
+ if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
1017
+ return "image";
870
1018
  }
1019
+ throw extensions;
1020
+ },
1021
+ {
1022
+ getCacheKey: (extensions) => extensions.join("~")
871
1023
  }
872
- return target;
873
- }
874
-
875
- // ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
876
- var has = Object.prototype.hasOwnProperty;
877
- function dequal(foo, bar) {
878
- var ctor, len;
879
- if (foo === bar) return true;
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
- };
923
-
924
- // ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
925
- function set(obj, key, val) {
926
- if (typeof val.value === "object") val.value = klona(val.value);
927
- if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
928
- Object.defineProperty(obj, key, val);
929
- } else obj[key] = val.value;
930
- }
931
- function klona(x) {
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
- }
967
- }
968
- return tmp || x;
969
- }
970
-
971
- // src/translation.ts
972
- var RGX = /{{(.*?)}}/g;
973
- var split = (input, delimeters) => {
974
- const output = [];
975
- for (const delimeter of delimeters) {
976
- if (!input) break;
977
- const [start, end] = input.split(delimeter, 2);
978
- output.push(start);
979
- input = end;
980
- }
981
- output.push(input);
982
- return output;
983
- };
984
- var flattenAllowedContent = (c, state) => {
985
- if (Array.isArray(c)) {
986
- return c.map((item) => flattenAllowedContent(item, state)).join("<br>");
987
- }
988
- if (typeof c === "function") {
989
- return flattenAllowedContent(c(state), state);
990
- }
991
- return c;
992
- };
993
- var replace = (input, data, pluralization, actions, pr) => {
994
- return input.replaceAll(RGX, (x, key, y) => {
995
- x = 0;
996
- y = data;
997
- const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
998
- if (!pathstr) {
999
- return "";
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)];
1005
- }
1006
- const actionHandler = actions && action ? actions[action] : void 0;
1007
- if (actionHandler) y = actionHandler(y);
1008
- return y == null ? "" : y;
1009
- });
1010
- };
1011
-
1012
- // src/custom-action.ts
1013
- var createCustomActionNode = (id) => {
1014
- const div = document.createElement("div");
1015
- div.setAttribute("data-id", id);
1016
- return div;
1017
- };
1018
- var getCustomActionHolder = (ctx, fn) => {
1019
- const cached = CUSTOM_ACTION_MAP.get(ctx.id + fn.key);
1020
- if (cached) {
1021
- return cached;
1022
- }
1023
- const holder = {
1024
- cleanup: noop,
1025
- node: null,
1026
- fn,
1027
- localData: {}
1028
- };
1029
- CUSTOM_ACTION_MAP.set(ctx.id + fn.key, holder);
1030
- return holder;
1024
+ );
1025
+ var SUPPORT_MAPS = {
1026
+ image: supportsMap2,
1027
+ audio: supportsMap
1031
1028
  };
1032
- var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, remove: renderersRemove, getStack: getStack2 }) => {
1033
- const holder = getCustomActionHolder(ctx, fn);
1034
- const flags = {
1035
- ...ctx.meta
1036
- };
1037
- const getDomNodes = (insert = true) => {
1038
- if (holder.node || !insert) {
1039
- return {
1040
- element: holder.node,
1041
- root: ctx.root
1042
- };
1029
+ var assetPrivate = memoize(
1030
+ (variants) => {
1031
+ if (DEV && variants.length === 0) {
1032
+ throw new Error(`Attempt to use "asset" function without arguments`);
1043
1033
  }
1044
- holder.node = insert ? createCustomActionNode(fn.key) : null;
1045
- setMountElement(holder.node);
1046
- return {
1047
- element: holder.node,
1048
- root: ctx.root
1049
- };
1050
- };
1051
- const clear = (func) => {
1052
- setClear(holder.cleanup = () => {
1053
- func();
1054
- holder.node = null;
1055
- holder.cleanup = noop;
1056
- setMountElement(null);
1057
- setClear(noop);
1058
- });
1059
- };
1060
- const data = (updatedData) => {
1061
- if (updatedData) {
1062
- return holder.localData = updatedData;
1034
+ const map = {};
1035
+ const extensions = [];
1036
+ for (const v of variants) {
1037
+ const e = getUrlFileExtension(v);
1038
+ map[e] = v;
1039
+ extensions.push(e);
1063
1040
  }
1064
- return holder.localData;
1065
- };
1066
- const remove = () => {
1067
- holder.cleanup();
1068
- renderersRemove();
1069
- };
1070
- const stack = getStack2(ctx);
1071
- const getPath = () => {
1072
- return stack.value[0];
1073
- };
1074
- return fn({
1075
- flags,
1076
- 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 {
1041
+ const type = getType(extensions);
1042
+ const getSource = once(() => {
1043
+ const support = SUPPORT_MAPS[type];
1044
+ for (const extension of extensions) {
1045
+ if (extension in support) {
1046
+ if (support[extension]) {
1047
+ return map[extension];
1048
+ }
1049
+ } else {
1050
+ return map[extension];
1051
+ }
1104
1052
  }
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
- }
1053
+ if (DEV) {
1054
+ throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
1055
+ }
1056
+ return "";
1057
+ });
1058
+ return {
1059
+ get source() {
1060
+ return getSource();
1061
+ },
1062
+ get type() {
1063
+ return type;
1064
+ }
1065
+ };
1066
+ },
1067
+ {
1068
+ getCacheKey: (variants) => variants.join("~")
1180
1069
  }
1070
+ );
1071
+ var asset = (...variants) => {
1072
+ return assetPrivate(variants);
1073
+ };
1074
+ var isAsset = (suspect) => {
1075
+ return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
1181
1076
  };
1182
1077
 
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++;
1078
+ // src/browser.ts
1079
+ var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
1080
+ if (typeof document === "undefined") return noop;
1081
+ const onVisibilityChange = () => {
1082
+ if (document.visibilityState === "hidden") {
1083
+ onChange();
1192
1084
  }
1193
1085
  };
1194
- const next = () => {
1195
- activeCount--;
1196
- resumeNext();
1086
+ addEventListener("visibilitychange", onVisibilityChange);
1087
+ addEventListener("beforeunload", onChange);
1088
+ return () => {
1089
+ removeEventListener("visibilitychange", onVisibilityChange);
1090
+ removeEventListener("beforeunload", onChange);
1197
1091
  };
1198
- const run = async (function_, resolve, arguments_) => {
1199
- const result = (async () => function_(...arguments_))();
1200
- resolve(result);
1201
- try {
1202
- await result;
1203
- } catch {
1092
+ };
1093
+
1094
+ // src/custom-action.ts
1095
+ var createCustomActionNode = (id) => {
1096
+ const div = document.createElement("div");
1097
+ div.setAttribute("data-id", id);
1098
+ return div;
1099
+ };
1100
+ var getCustomActionHolder = (ctx, fn) => {
1101
+ const cached = CUSTOM_ACTION_MAP.get(ctx.id + fn.key);
1102
+ if (cached) {
1103
+ return cached;
1104
+ }
1105
+ const holder = {
1106
+ cleanup: noop,
1107
+ node: null,
1108
+ fn,
1109
+ localData: {}
1110
+ };
1111
+ CUSTOM_ACTION_MAP.set(ctx.id + fn.key, holder);
1112
+ return holder;
1113
+ };
1114
+ var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, remove: renderersRemove, getStack: getStack2 }) => {
1115
+ const holder = getCustomActionHolder(ctx, fn);
1116
+ const flags = {
1117
+ ...ctx.meta
1118
+ };
1119
+ const getDomNodes = (insert = true) => {
1120
+ if (holder.node || !insert) {
1121
+ return {
1122
+ element: holder.node,
1123
+ root: ctx.root
1124
+ };
1204
1125
  }
1205
- next();
1126
+ holder.node = insert ? createCustomActionNode(fn.key) : null;
1127
+ setMountElement(holder.node);
1128
+ return {
1129
+ element: holder.node,
1130
+ root: ctx.root
1131
+ };
1206
1132
  };
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();
1133
+ const clear = (func) => {
1134
+ setClear(
1135
+ holder.cleanup = () => {
1136
+ func();
1137
+ holder.node = null;
1138
+ holder.cleanup = noop;
1139
+ setMountElement(null);
1140
+ setClear(noop);
1217
1141
  }
1218
- })();
1142
+ );
1219
1143
  };
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
- }
1144
+ const data = (updatedData) => {
1145
+ if (updatedData) {
1146
+ return holder.localData = updatedData;
1246
1147
  }
1148
+ return holder.localData;
1149
+ };
1150
+ const remove = () => {
1151
+ holder.cleanup();
1152
+ renderersRemove();
1153
+ };
1154
+ const stack = getStack2(ctx);
1155
+ const getPath = () => {
1156
+ return stack.value[0];
1157
+ };
1158
+ return fn({
1159
+ flags,
1160
+ lang,
1161
+ state,
1162
+ data,
1163
+ clear,
1164
+ remove,
1165
+ rendererContext: ctx,
1166
+ getDomNodes,
1167
+ getPath,
1168
+ contextKey: ctx.id
1247
1169
  });
1248
- return generator;
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
- }
1170
+ };
1255
1171
 
1256
1172
  // src/preloading.ts
1257
1173
  var ACTION_NAME_TO_VOLUME_MAP = {
1258
- "playMusic": "music",
1259
- "playSound": "sound",
1260
- "voice": "voice"
1174
+ playMusic: "music",
1175
+ playSound: "sound",
1176
+ voice: "voice"
1261
1177
  };
1262
1178
  var enqueueAssetForPreloading = (asset2) => {
1263
1179
  if (!PRELOADED_ASSETS.has(asset2)) {
1264
1180
  ASSETS_TO_PRELOAD.add(asset2);
1265
1181
  }
1266
1182
  };
1267
- var handleAssetsPreloading = async ({ request, limiter, preloadAudioBlocking, preloadImageBlocking }) => {
1183
+ var handleAssetsPreloading = async ({
1184
+ request,
1185
+ limiter,
1186
+ preloadAudioBlocking,
1187
+ preloadImageBlocking
1188
+ }) => {
1268
1189
  const list = mapSet(ASSETS_TO_PRELOAD, (asset2) => {
1269
1190
  return limiter(async () => {
1270
1191
  const type = await getResourseType({
@@ -1339,9 +1260,9 @@ var Novely = (() => {
1339
1260
  }
1340
1261
  return;
1341
1262
  }
1342
- if (action === "custom" && props[0].assets && props[0].assets.length > 0) {
1263
+ if (action === "custom" && props[0].assets) {
1343
1264
  for (const asset2 of props[0].assets) {
1344
- handle(asset2);
1265
+ isAsset(asset2) ? handle(asset2.source) : handle(asset2);
1345
1266
  }
1346
1267
  return;
1347
1268
  }
@@ -1349,10 +1270,95 @@ var Novely = (() => {
1349
1270
  for (let i = 1; i < props.length; i++) {
1350
1271
  const data = props[i];
1351
1272
  if (Array.isArray(data)) {
1352
- handle(handleImageAsset(data[4]));
1273
+ handle(handleImageAsset(data[5]));
1274
+ }
1275
+ }
1276
+ }
1277
+ };
1278
+
1279
+ // src/storage.ts
1280
+ var localStorageStorage = (options) => {
1281
+ return {
1282
+ async get() {
1283
+ const fallback = { saves: [], data: {}, meta: [] };
1284
+ try {
1285
+ const value = localStorage.getItem(options.key);
1286
+ return value ? JSON.parse(value) : fallback;
1287
+ } catch {
1288
+ return fallback;
1289
+ }
1290
+ },
1291
+ async set(data) {
1292
+ try {
1293
+ localStorage.setItem(options.key, JSON.stringify(data));
1294
+ } catch {
1353
1295
  }
1354
1296
  }
1297
+ };
1298
+ };
1299
+
1300
+ // src/store.ts
1301
+ var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
1302
+ const subscribe = (cb) => {
1303
+ subscribers.add(cb), cb(current);
1304
+ return () => {
1305
+ subscribers.delete(cb);
1306
+ };
1307
+ };
1308
+ const push = (value) => {
1309
+ for (const cb of subscribers) cb(value);
1310
+ };
1311
+ const update = (fn) => {
1312
+ push(current = fn(current));
1313
+ };
1314
+ const set2 = (val) => {
1315
+ update(() => val);
1316
+ };
1317
+ const get = () => {
1318
+ return current;
1319
+ };
1320
+ return { subscribe, update, set: set2, get };
1321
+ };
1322
+
1323
+ // src/translation.ts
1324
+ var RGX = /{{(.*?)}}/g;
1325
+ var split = (input, delimeters) => {
1326
+ const output = [];
1327
+ for (const delimeter of delimeters) {
1328
+ if (!input) break;
1329
+ const [start, end] = input.split(delimeter, 2);
1330
+ output.push(start);
1331
+ input = end;
1332
+ }
1333
+ output.push(input);
1334
+ return output;
1335
+ };
1336
+ var flattenAllowedContent = (c, state) => {
1337
+ if (Array.isArray(c)) {
1338
+ return c.map((item) => flattenAllowedContent(item, state)).join("<br>");
1339
+ }
1340
+ if (typeof c === "function") {
1341
+ return flattenAllowedContent(c(state), state);
1355
1342
  }
1343
+ return c;
1344
+ };
1345
+ var replace = (input, data, pluralization, actions, pr) => {
1346
+ return input.replaceAll(RGX, (x, key, y) => {
1347
+ x = 0;
1348
+ y = data;
1349
+ const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
1350
+ if (!pathstr) {
1351
+ return "";
1352
+ }
1353
+ const path = pathstr.split(".");
1354
+ while (y && x < path.length) y = y[path[x++]];
1355
+ if (plural && pluralization && y && pr) {
1356
+ y = pluralization[plural][pr.select(y)];
1357
+ }
1358
+ const actionHandler = actions && action ? actions[action] : void 0;
1359
+ if (actionHandler) y = actionHandler(y);
1360
+ return y == null ? "" : y;
1361
+ });
1356
1362
  };
1357
1363
 
1358
1364
  // src/novely.ts
@@ -1481,7 +1487,9 @@ var Novely = (() => {
1481
1487
  return language;
1482
1488
  }
1483
1489
  if (DEV) {
1484
- throw new Error(`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`);
1490
+ throw new Error(
1491
+ `Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
1492
+ );
1485
1493
  }
1486
1494
  throw 0;
1487
1495
  };
@@ -1597,7 +1605,9 @@ var Novely = (() => {
1597
1605
  const restore = async (save2) => {
1598
1606
  if (isEmpty(story)) {
1599
1607
  if (DEV) {
1600
- throw new Error("Story is empty. You should call an `enine.script` function [https://novely.pages.dev/guide/story.html]");
1608
+ throw new Error(
1609
+ "Story is empty. You should call an `enine.script` function [https://novely.pages.dev/guide/story.html]"
1610
+ );
1601
1611
  }
1602
1612
  return;
1603
1613
  }
@@ -1617,7 +1627,10 @@ var Novely = (() => {
1617
1627
  const [path] = stack.value = latest;
1618
1628
  renderer.ui.showScreen("game");
1619
1629
  const { queue, skip, skipPreserve } = getActionsFromPath(story, path, false);
1620
- const { run, keep: { keep, characters: characters2, audio: audio2 } } = createQueueProcessor(queue, {
1630
+ const {
1631
+ run,
1632
+ keep: { keep, characters: characters2, audio: audio2 }
1633
+ } = createQueueProcessor(queue, {
1621
1634
  skip,
1622
1635
  skipPreserve
1623
1636
  });
@@ -1667,7 +1680,9 @@ var Novely = (() => {
1667
1680
  const isSaved = () => {
1668
1681
  const { saves } = storageData.get();
1669
1682
  const [currentPath, currentData] = stack.value;
1670
- return saves.some(([path, data2, [date, type2]]) => type2 === "manual" && times.has(date) && dequal(path, currentPath) && dequal(data2, currentData));
1683
+ return saves.some(
1684
+ ([path, data2, [date, type2]]) => type2 === "manual" && times.has(date) && dequal(path, currentPath) && dequal(data2, currentData)
1685
+ );
1671
1686
  };
1672
1687
  if (interacted > 1 && !force && askBeforeExit && !isSaved()) {
1673
1688
  renderer.ui.showExitPrompt();
@@ -1763,7 +1778,9 @@ var Novely = (() => {
1763
1778
  const getLanguageDisplayName = (lang) => {
1764
1779
  const language = translation[lang];
1765
1780
  if (DEV && !language) {
1766
- throw new Error(`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`);
1781
+ throw new Error(
1782
+ `Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
1783
+ );
1767
1784
  }
1768
1785
  return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
1769
1786
  };
@@ -1872,10 +1889,12 @@ var Novely = (() => {
1872
1889
  showBackground({ ctx, push }, [background]) {
1873
1890
  if (isString(background) || isAsset(background)) {
1874
1891
  ctx.background({
1875
- "all": handleImageAsset(background)
1892
+ all: handleImageAsset(background)
1876
1893
  });
1877
1894
  } else {
1878
- ctx.background(Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, handleImageAsset(asset2)])));
1895
+ ctx.background(
1896
+ Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, handleImageAsset(asset2)]))
1897
+ );
1879
1898
  }
1880
1899
  push();
1881
1900
  },
@@ -1951,13 +1970,7 @@ var Novely = (() => {
1951
1970
  return c || "";
1952
1971
  })();
1953
1972
  ctx.clearBlockingActions("dialog");
1954
- ctx.dialog(
1955
- templateReplace(content, data2),
1956
- templateReplace(name, data2),
1957
- character,
1958
- emotion,
1959
- forward
1960
- );
1973
+ ctx.dialog(templateReplace(content, data2), templateReplace(name, data2), character, emotion, forward);
1961
1974
  },
1962
1975
  function({ ctx, push }, [fn]) {
1963
1976
  const { restoring, goingBack, preview: preview2 } = ctx.meta;
@@ -2007,7 +2020,9 @@ var Novely = (() => {
2007
2020
  return [templateReplace(content, data2), active$, visible$, onSelectWrapped, imageValue];
2008
2021
  });
2009
2022
  if (DEV && transformedChoices.length === 0) {
2010
- throw new Error(`Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`);
2023
+ throw new Error(
2024
+ `Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`
2025
+ );
2011
2026
  }
2012
2027
  ctx.clearBlockingActions("choice");
2013
2028
  ctx.choices(templateReplace(question, data2), transformedChoices, (selected) => {
@@ -2062,7 +2077,7 @@ var Novely = (() => {
2062
2077
  if (DEV && variants[val].length === 0) {
2063
2078
  throw new Error(`Attempt to go to empty variant "${val}"`);
2064
2079
  }
2065
- const stack = useStack(MAIN_CONTEXT_KEY);
2080
+ const stack = useStack(ctx);
2066
2081
  stack.value[0].push(["condition", val], [null, 0]);
2067
2082
  render(ctx);
2068
2083
  }
@@ -2073,12 +2088,7 @@ var Novely = (() => {
2073
2088
  },
2074
2089
  input({ ctx, data: data2, forward }, [question, onInput, setup]) {
2075
2090
  ctx.clearBlockingActions("input");
2076
- ctx.input(
2077
- templateReplace(question, data2),
2078
- onInput,
2079
- setup || noop,
2080
- forward
2081
- );
2091
+ ctx.input(templateReplace(question, data2), onInput, setup || noop, forward);
2082
2092
  },
2083
2093
  custom({ ctx, push }, [fn]) {
2084
2094
  if (fn.requireUserAction) {
@@ -2118,7 +2128,9 @@ var Novely = (() => {
2118
2128
  animateCharacter({ ctx, push }, [character, className]) {
2119
2129
  const classes = className.split(" ");
2120
2130
  if (DEV && classes.length === 0) {
2121
- throw new Error("Attempt to use AnimateCharacter without classes. Classes should be provided [https://novely.pages.dev/guide/actions/animateCharacter.html]");
2131
+ throw new Error(
2132
+ "Attempt to use AnimateCharacter without classes. Classes should be provided [https://novely.pages.dev/guide/actions/animateCharacter.html]"
2133
+ );
2122
2134
  }
2123
2135
  if (ctx.meta.preview) return;
2124
2136
  ctx.character(character).animate(classes);
@@ -2152,7 +2164,9 @@ var Novely = (() => {
2152
2164
  },
2153
2165
  preload({ ctx, push }, [source]) {
2154
2166
  if (DEV && preloadAssets !== "lazy") {
2155
- console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
2167
+ console.error(
2168
+ `You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`
2169
+ );
2156
2170
  }
2157
2171
  if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
2158
2172
  PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
@@ -2198,21 +2212,15 @@ var Novely = (() => {
2198
2212
  interacted = value ? interacted + 1 : 0;
2199
2213
  };
2200
2214
  const templateReplace = (content, values) => {
2201
- const { data: data2, meta: [lang] } = storageData.get();
2215
+ const {
2216
+ data: data2,
2217
+ meta: [lang]
2218
+ } = storageData.get();
2202
2219
  const obj = values || data2;
2203
- const str2 = flattenAllowedContent(
2204
- !isFunction(content) && !isString(content) ? content[lang] : content,
2205
- obj
2206
- );
2220
+ const str2 = flattenAllowedContent(!isFunction(content) && !isString(content) ? content[lang] : content, obj);
2207
2221
  const t2 = translation[lang];
2208
2222
  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
- );
2223
+ return replace(str2, obj, t2.plural, t2.actions, pluralRules);
2216
2224
  };
2217
2225
  const data = (value) => {
2218
2226
  const _data = storageData.get().data;
@@ -2236,7 +2244,9 @@ var Novely = (() => {
2236
2244
  const setStorageData = (data2) => {
2237
2245
  if (destroyed) {
2238
2246
  if (DEV) {
2239
- throw new Error(`function \`setStorageData\` was called after novely instance was destroyed. Data is not updater nor synced after destroy.`);
2247
+ throw new Error(
2248
+ `function \`setStorageData\` was called after novely instance was destroyed. Data is not updater nor synced after destroy.`
2249
+ );
2240
2250
  }
2241
2251
  return;
2242
2252
  }
@@ -2296,7 +2306,7 @@ var Novely = (() => {
2296
2306
  * @example
2297
2307
  * ```ts
2298
2308
  * import type { ConditionParams, StateFunction } from '@novely/core';
2299
- *
2309
+ *
2300
2310
  * const conditionCheck = (state: StateFunction<ConditionParams<typeof engine.typeEssintials>>) => {
2301
2311
  * return state.age >= 18;
2302
2312
  * }