@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.
- package/dist/index.d.ts +33 -31
- package/dist/index.global.js +622 -612
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +345 -335
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.global.js
CHANGED
|
@@ -31,61 +31,31 @@ 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();
|
|
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
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
190
|
-
}
|
|
191
|
-
loadImageFormatsSupport();
|
|
124
|
+
return target;
|
|
125
|
+
}
|
|
192
126
|
|
|
193
|
-
//
|
|
194
|
-
var
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
200
|
-
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
201
|
+
this.#size++;
|
|
202
|
+
}
|
|
203
|
+
dequeue() {
|
|
204
|
+
const current = this.#head;
|
|
205
|
+
if (!current) {
|
|
206
|
+
return;
|
|
223
207
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
237
|
-
|
|
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
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
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
|
-
|
|
255
|
-
|
|
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
|
-
|
|
258
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
278
|
-
|
|
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
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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 = [
|
|
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
|
-
//
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
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
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
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
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
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
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
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
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
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
|
-
//
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1188
|
-
|
|
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
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1086
|
+
addEventListener("visibilitychange", onVisibilityChange);
|
|
1087
|
+
addEventListener("beforeunload", onChange);
|
|
1088
|
+
return () => {
|
|
1089
|
+
removeEventListener("visibilitychange", onVisibilityChange);
|
|
1090
|
+
removeEventListener("beforeunload", onChange);
|
|
1197
1091
|
};
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
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
|
-
|
|
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
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
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
|
|
1221
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
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 ({
|
|
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
|
|
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[
|
|
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(
|
|
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(
|
|
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 {
|
|
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(
|
|
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(
|
|
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
|
-
|
|
1892
|
+
all: handleImageAsset(background)
|
|
1876
1893
|
});
|
|
1877
1894
|
} else {
|
|
1878
|
-
ctx.background(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
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(
|
|
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
|
* }
|