@novely/core 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +47 -19
- package/dist/index.js +403 -468
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/dist/index.global.js +0 -2867
- package/dist/index.global.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
|
+
// ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
2
|
+
var has = Object.prototype.hasOwnProperty;
|
|
3
|
+
function dequal(foo, bar) {
|
|
4
|
+
var ctor, len;
|
|
5
|
+
if (foo === bar) return true;
|
|
6
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
7
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
8
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
9
|
+
if (ctor === Array) {
|
|
10
|
+
if ((len = foo.length) === bar.length) {
|
|
11
|
+
while (len-- && dequal(foo[len], bar[len])) ;
|
|
12
|
+
}
|
|
13
|
+
return len === -1;
|
|
14
|
+
}
|
|
15
|
+
if (!ctor || typeof foo === "object") {
|
|
16
|
+
len = 0;
|
|
17
|
+
for (ctor in foo) {
|
|
18
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
19
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
20
|
+
}
|
|
21
|
+
return Object.keys(bar).length === len;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return foo !== foo && bar !== bar;
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
// src/novely.ts
|
|
2
|
-
import {
|
|
3
|
-
import { memoize as memoize4, throttle } from "es-toolkit/function";
|
|
28
|
+
import { memoize as memoize5, throttle } from "es-toolkit/function";
|
|
4
29
|
import { merge as deepmerge } from "es-toolkit/object";
|
|
5
30
|
import { DEV as DEV5 } from "esm-env";
|
|
6
31
|
|
|
@@ -94,6 +119,12 @@ var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
|
94
119
|
]);
|
|
95
120
|
var MAIN_CONTEXT_KEY = "$MAIN";
|
|
96
121
|
|
|
122
|
+
// src/shared.ts
|
|
123
|
+
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
124
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
125
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
126
|
+
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
127
|
+
|
|
97
128
|
// src/utilities/assertions.ts
|
|
98
129
|
var isNumber = (val) => {
|
|
99
130
|
return typeof val === "number";
|
|
@@ -177,72 +208,174 @@ var matchAction = (callbacks, values) => {
|
|
|
177
208
|
};
|
|
178
209
|
};
|
|
179
210
|
|
|
180
|
-
// src/
|
|
181
|
-
import { memoize } from "es-toolkit/function";
|
|
211
|
+
// src/asset.ts
|
|
212
|
+
import { memoize, once } from "es-toolkit/function";
|
|
182
213
|
import { DEV } from "esm-env";
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
214
|
+
|
|
215
|
+
// src/audio-codecs.ts
|
|
216
|
+
var cut = (str) => str.replace(/^no$/, "");
|
|
217
|
+
var audio = new Audio();
|
|
218
|
+
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
219
|
+
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
220
|
+
var supportsMap = {
|
|
221
|
+
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
222
|
+
mpeg: canPlay("audio/mpeg;"),
|
|
223
|
+
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
224
|
+
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
225
|
+
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
226
|
+
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
227
|
+
aac: canPlay("audio/aac;"),
|
|
228
|
+
caf: canPlay("audio/x-caf;"),
|
|
229
|
+
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
230
|
+
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
231
|
+
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
232
|
+
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
233
|
+
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
234
|
+
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
235
|
+
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
193
236
|
};
|
|
194
|
-
|
|
237
|
+
|
|
238
|
+
// src/image-formats.ts
|
|
239
|
+
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
240
|
+
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
241
|
+
var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
|
|
242
|
+
var supportsFormat = (source) => {
|
|
243
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
244
|
+
const img = Object.assign(document.createElement("img"), {
|
|
245
|
+
src: source
|
|
246
|
+
});
|
|
247
|
+
img.onload = img.onerror = () => {
|
|
248
|
+
resolve(img.height === 2);
|
|
249
|
+
};
|
|
250
|
+
return promise;
|
|
195
251
|
};
|
|
196
|
-
var
|
|
197
|
-
|
|
252
|
+
var supportsMap2 = {
|
|
253
|
+
avif: false,
|
|
254
|
+
jxl: false,
|
|
255
|
+
webp: false
|
|
198
256
|
};
|
|
199
|
-
var
|
|
200
|
-
|
|
257
|
+
var formatsMap = {
|
|
258
|
+
avif,
|
|
259
|
+
jxl,
|
|
260
|
+
webp
|
|
201
261
|
};
|
|
202
|
-
var
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
262
|
+
var loadImageFormatsSupport = async () => {
|
|
263
|
+
const promises = [];
|
|
264
|
+
for (const [format, source] of Object.entries(formatsMap)) {
|
|
265
|
+
const promise = supportsFormat(source).then((supported) => {
|
|
266
|
+
supportsMap2[format] = supported;
|
|
206
267
|
});
|
|
207
|
-
|
|
208
|
-
} catch {
|
|
209
|
-
return lang;
|
|
268
|
+
promises.push(promise);
|
|
210
269
|
}
|
|
211
|
-
|
|
270
|
+
await Promise.all(promises);
|
|
271
|
+
};
|
|
272
|
+
loadImageFormatsSupport();
|
|
273
|
+
|
|
274
|
+
// src/asset.ts
|
|
275
|
+
var generateRandomId = () => Math.random().toString(36);
|
|
276
|
+
var getType = memoize(
|
|
277
|
+
(extensions) => {
|
|
278
|
+
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
279
|
+
return "audio";
|
|
280
|
+
}
|
|
281
|
+
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
282
|
+
return "image";
|
|
283
|
+
}
|
|
284
|
+
throw extensions;
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
getCacheKey: (extensions) => extensions.join("~")
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
var SUPPORT_MAPS = {
|
|
291
|
+
image: supportsMap2,
|
|
292
|
+
audio: supportsMap
|
|
293
|
+
};
|
|
294
|
+
var assetPrivate = memoize(
|
|
295
|
+
(variants) => {
|
|
296
|
+
if (DEV && variants.length === 0) {
|
|
297
|
+
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
298
|
+
}
|
|
299
|
+
const map = {};
|
|
300
|
+
const extensions = [];
|
|
301
|
+
for (const v of variants) {
|
|
302
|
+
const e = getUrlFileExtension(v);
|
|
303
|
+
map[e] = v;
|
|
304
|
+
extensions.push(e);
|
|
305
|
+
}
|
|
306
|
+
const type = getType(extensions);
|
|
307
|
+
const getSource = once(() => {
|
|
308
|
+
const support = SUPPORT_MAPS[type];
|
|
309
|
+
for (const extension of extensions) {
|
|
310
|
+
if (extension in support) {
|
|
311
|
+
if (support[extension]) {
|
|
312
|
+
return map[extension];
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
return map[extension];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (DEV) {
|
|
319
|
+
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
320
|
+
}
|
|
321
|
+
return "";
|
|
322
|
+
});
|
|
323
|
+
return {
|
|
324
|
+
get source() {
|
|
325
|
+
return getSource();
|
|
326
|
+
},
|
|
327
|
+
get type() {
|
|
328
|
+
return type;
|
|
329
|
+
},
|
|
330
|
+
id: generateRandomId()
|
|
331
|
+
};
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
getCacheKey: (variants) => variants.join("~")
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
var asset = (...variants) => {
|
|
338
|
+
return assetPrivate(variants);
|
|
339
|
+
};
|
|
340
|
+
asset.image = (source) => {
|
|
341
|
+
if (assetPrivate.cache.has(source)) {
|
|
342
|
+
return assetPrivate.cache.get(source);
|
|
343
|
+
}
|
|
344
|
+
const asset2 = {
|
|
345
|
+
type: "image",
|
|
346
|
+
source,
|
|
347
|
+
id: generateRandomId()
|
|
348
|
+
};
|
|
349
|
+
assetPrivate.cache.set(source, asset2);
|
|
350
|
+
return asset2;
|
|
351
|
+
};
|
|
352
|
+
asset.audio = (source) => {
|
|
353
|
+
if (assetPrivate.cache.has(source)) {
|
|
354
|
+
return assetPrivate.cache.get(source);
|
|
355
|
+
}
|
|
356
|
+
const asset2 = {
|
|
357
|
+
type: "audio",
|
|
358
|
+
source,
|
|
359
|
+
id: generateRandomId()
|
|
360
|
+
};
|
|
361
|
+
assetPrivate.cache.set(source, asset2);
|
|
362
|
+
return asset2;
|
|
363
|
+
};
|
|
212
364
|
var unwrapAsset = (asset2) => {
|
|
213
365
|
return isAsset(asset2) ? asset2.source : asset2;
|
|
214
366
|
};
|
|
215
|
-
var
|
|
367
|
+
var unwrapAudioAsset = (asset2) => {
|
|
216
368
|
if (DEV && isAsset(asset2) && asset2.type !== "audio") {
|
|
217
369
|
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
218
370
|
}
|
|
219
371
|
return unwrapAsset(asset2);
|
|
220
372
|
};
|
|
221
|
-
var
|
|
373
|
+
var unwrapImageAsset = (asset2) => {
|
|
222
374
|
if (DEV && isAsset(asset2) && asset2.type !== "image") {
|
|
223
375
|
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
224
376
|
}
|
|
225
377
|
return unwrapAsset(asset2);
|
|
226
378
|
};
|
|
227
|
-
var getCharactersData = (characters) => {
|
|
228
|
-
const entries = Object.entries(characters);
|
|
229
|
-
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
230
|
-
return Object.fromEntries(mapped);
|
|
231
|
-
};
|
|
232
|
-
var toArray = (target) => {
|
|
233
|
-
return Array.isArray(target) ? target : [target];
|
|
234
|
-
};
|
|
235
|
-
var getLanguageFromStore = (store2) => {
|
|
236
|
-
return store2.get().meta[0];
|
|
237
|
-
};
|
|
238
|
-
var getVolumeFromStore = (store2) => {
|
|
239
|
-
const { meta } = store2.get();
|
|
240
|
-
return {
|
|
241
|
-
music: meta[2],
|
|
242
|
-
sound: meta[3],
|
|
243
|
-
voice: meta[4]
|
|
244
|
-
};
|
|
245
|
-
};
|
|
246
379
|
|
|
247
380
|
// src/utilities/actions-processing.ts
|
|
248
381
|
import { DEV as DEV2 } from "esm-env";
|
|
@@ -704,14 +837,6 @@ var getResourseType = memoize2(
|
|
|
704
837
|
|
|
705
838
|
// src/utilities/stack.ts
|
|
706
839
|
import { memoize as memoize3 } from "es-toolkit/function";
|
|
707
|
-
|
|
708
|
-
// src/shared.ts
|
|
709
|
-
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
710
|
-
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
711
|
-
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
712
|
-
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
713
|
-
|
|
714
|
-
// src/utilities/stack.ts
|
|
715
840
|
var getStack = memoize3(
|
|
716
841
|
(_) => {
|
|
717
842
|
return [];
|
|
@@ -767,22 +892,65 @@ var flatStory = (story) => {
|
|
|
767
892
|
return story;
|
|
768
893
|
};
|
|
769
894
|
|
|
770
|
-
// src/
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
895
|
+
// src/utilities/internationalization.ts
|
|
896
|
+
import { memoize as memoize4 } from "es-toolkit/function";
|
|
897
|
+
var getLanguage = (languages) => {
|
|
898
|
+
let { language } = navigator;
|
|
899
|
+
if (languages.includes(language)) {
|
|
900
|
+
return language;
|
|
901
|
+
} else if (languages.includes(language = language.slice(0, 2))) {
|
|
902
|
+
return language;
|
|
903
|
+
} else if (language = languages.find((value) => navigator.languages.includes(value))) {
|
|
904
|
+
return language;
|
|
905
|
+
}
|
|
906
|
+
return languages[0];
|
|
907
|
+
};
|
|
908
|
+
var getIntlLanguageDisplayName = memoize4((lang) => {
|
|
909
|
+
try {
|
|
910
|
+
const intl = new Intl.DisplayNames([lang], {
|
|
911
|
+
type: "language"
|
|
912
|
+
});
|
|
913
|
+
return intl.of(lang) || lang;
|
|
914
|
+
} catch {
|
|
915
|
+
return lang;
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
var capitalize = (str) => {
|
|
919
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
// src/utilities/functions.ts
|
|
923
|
+
var noop = () => {
|
|
924
|
+
};
|
|
925
|
+
|
|
926
|
+
// src/utilities/store.ts
|
|
927
|
+
var getLanguageFromStore = (store2) => {
|
|
928
|
+
return store2.get().meta[0];
|
|
929
|
+
};
|
|
930
|
+
var getVolumeFromStore = (store2) => {
|
|
931
|
+
const { meta } = store2.get();
|
|
932
|
+
return {
|
|
933
|
+
music: meta[2],
|
|
934
|
+
sound: meta[3],
|
|
935
|
+
voice: meta[4]
|
|
783
936
|
};
|
|
784
937
|
};
|
|
785
938
|
|
|
939
|
+
// src/utilities/array.ts
|
|
940
|
+
var mapSet = (set2, fn) => {
|
|
941
|
+
return [...set2].map(fn);
|
|
942
|
+
};
|
|
943
|
+
var toArray = (target) => {
|
|
944
|
+
return Array.isArray(target) ? target : [target];
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
// src/utilities/else.ts
|
|
948
|
+
var getCharactersData = (characters) => {
|
|
949
|
+
const entries = Object.entries(characters);
|
|
950
|
+
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
951
|
+
return Object.fromEntries(mapped);
|
|
952
|
+
};
|
|
953
|
+
|
|
786
954
|
// src/custom-action.ts
|
|
787
955
|
var createCustomActionNode = (id) => {
|
|
788
956
|
const div = document.createElement("div");
|
|
@@ -910,17 +1078,17 @@ var handleAssetsPreloading = async ({
|
|
|
910
1078
|
await Promise.allSettled(list);
|
|
911
1079
|
ASSETS_TO_PRELOAD.clear();
|
|
912
1080
|
};
|
|
913
|
-
var huntAssets = ({ volume, lang,
|
|
1081
|
+
var huntAssets = ({ volume, lang, characters, action, props, handle }) => {
|
|
914
1082
|
if (action === "showBackground") {
|
|
915
1083
|
if (isString(props[0])) {
|
|
916
|
-
handle(
|
|
1084
|
+
handle(unwrapAudioAsset(props[0]));
|
|
917
1085
|
}
|
|
918
1086
|
if (props[0] && typeof props[0] === "object") {
|
|
919
1087
|
for (const value of Object.values(props[0])) {
|
|
920
1088
|
if (isImageAsset(value)) {
|
|
921
1089
|
handle(value);
|
|
922
1090
|
} else if (isAsset(value)) {
|
|
923
|
-
const unwrapped =
|
|
1091
|
+
const unwrapped = unwrapImageAsset(value);
|
|
924
1092
|
if (isImageAsset(unwrapped)) {
|
|
925
1093
|
handle(unwrapped);
|
|
926
1094
|
}
|
|
@@ -937,7 +1105,7 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
937
1105
|
};
|
|
938
1106
|
if (isAudioAction(action) && isString(props[0])) {
|
|
939
1107
|
if (getVolumeFor(action) > 0) {
|
|
940
|
-
handle(
|
|
1108
|
+
handle(unwrapAudioAsset(props[0]));
|
|
941
1109
|
}
|
|
942
1110
|
return;
|
|
943
1111
|
}
|
|
@@ -946,10 +1114,8 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
946
1114
|
return;
|
|
947
1115
|
}
|
|
948
1116
|
for (const [language, value] of Object.entries(props[0])) {
|
|
949
|
-
if (
|
|
950
|
-
value && handle(
|
|
951
|
-
} else if (language === lang) {
|
|
952
|
-
value && handle(handleAudioAsset(value));
|
|
1117
|
+
if (language === lang) {
|
|
1118
|
+
value && handle(unwrapAudioAsset(value));
|
|
953
1119
|
}
|
|
954
1120
|
}
|
|
955
1121
|
return;
|
|
@@ -957,7 +1123,7 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
957
1123
|
if (action === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
958
1124
|
const images = toArray(characters[props[0]].emotions[props[1]]);
|
|
959
1125
|
for (const asset2 of images) {
|
|
960
|
-
handle(
|
|
1126
|
+
handle(unwrapImageAsset(asset2));
|
|
961
1127
|
}
|
|
962
1128
|
return;
|
|
963
1129
|
}
|
|
@@ -971,7 +1137,7 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
971
1137
|
for (let i = 1; i < props.length; i++) {
|
|
972
1138
|
const data = props[i];
|
|
973
1139
|
if (Array.isArray(data)) {
|
|
974
|
-
handle(
|
|
1140
|
+
handle(unwrapImageAsset(data[5]));
|
|
975
1141
|
}
|
|
976
1142
|
}
|
|
977
1143
|
}
|
|
@@ -1068,9 +1234,7 @@ var VIRTUAL_ACTIONS = ["say"];
|
|
|
1068
1234
|
var buildActionObject = ({
|
|
1069
1235
|
rendererActions,
|
|
1070
1236
|
nativeActions,
|
|
1071
|
-
characters
|
|
1072
|
-
preloadAssets,
|
|
1073
|
-
storageData
|
|
1237
|
+
characters
|
|
1074
1238
|
}) => {
|
|
1075
1239
|
const allActions = [...nativeActions, ...VIRTUAL_ACTIONS];
|
|
1076
1240
|
const object = { ...rendererActions };
|
|
@@ -1109,23 +1273,63 @@ var buildActionObject = ({
|
|
|
1109
1273
|
actions[key] = flatActions(actions[key]);
|
|
1110
1274
|
}
|
|
1111
1275
|
}
|
|
1112
|
-
if (preloadAssets === "blocking") {
|
|
1113
|
-
huntAssets({
|
|
1114
|
-
action,
|
|
1115
|
-
props,
|
|
1116
|
-
mode: preloadAssets,
|
|
1117
|
-
characters,
|
|
1118
|
-
lang: getLanguageFromStore(storageData),
|
|
1119
|
-
volume: getVolumeFromStore(storageData),
|
|
1120
|
-
handle: enqueueAssetForPreloading
|
|
1121
|
-
});
|
|
1122
|
-
}
|
|
1123
1276
|
return [action, ...props];
|
|
1124
1277
|
};
|
|
1125
1278
|
}
|
|
1126
1279
|
return object;
|
|
1127
1280
|
};
|
|
1128
1281
|
|
|
1282
|
+
// src/utilities/dialog-overview.ts
|
|
1283
|
+
var getDialogOverview = async function() {
|
|
1284
|
+
const { value: save } = this.getStack();
|
|
1285
|
+
const stateSnapshots = save[3];
|
|
1286
|
+
if (stateSnapshots.length == 0) {
|
|
1287
|
+
return [];
|
|
1288
|
+
}
|
|
1289
|
+
const { queue } = await getActionsFromPath({
|
|
1290
|
+
story: this.story,
|
|
1291
|
+
path: save[0],
|
|
1292
|
+
filter: false,
|
|
1293
|
+
referGuarded: this.referGuarded
|
|
1294
|
+
});
|
|
1295
|
+
const lang = this.getLanguage();
|
|
1296
|
+
const dialogItems = [];
|
|
1297
|
+
for (let p = 0, a = stateSnapshots.length, i = queue.length - 1; a > 0 && i > 0; i--) {
|
|
1298
|
+
const action = queue[i];
|
|
1299
|
+
if (action[0] === "dialog") {
|
|
1300
|
+
const [_, name, text] = action;
|
|
1301
|
+
let voice = void 0;
|
|
1302
|
+
for (let j = i - 1; j > p && j > 0; j--) {
|
|
1303
|
+
const action2 = queue[j];
|
|
1304
|
+
if (isUserRequiredAction(action2) || isSkippedDuringRestore(action2[0])) break;
|
|
1305
|
+
if (action2[0] === "stopVoice") break;
|
|
1306
|
+
if (action2[0] === "voice") {
|
|
1307
|
+
voice = action2[1];
|
|
1308
|
+
break;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
dialogItems.push({
|
|
1312
|
+
name,
|
|
1313
|
+
text,
|
|
1314
|
+
voice
|
|
1315
|
+
});
|
|
1316
|
+
p = i;
|
|
1317
|
+
a--;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
const entries = dialogItems.reverse().map(({ name, text, voice }, i) => {
|
|
1321
|
+
const state = stateSnapshots[i];
|
|
1322
|
+
const audioSource = isString(voice) ? voice : isAsset(voice) ? voice : voice == void 0 ? voice : voice[lang];
|
|
1323
|
+
name = name ? this.getCharacterName(name) : "";
|
|
1324
|
+
return {
|
|
1325
|
+
name: this.templateReplace(name, state),
|
|
1326
|
+
text: this.templateReplace(text, state),
|
|
1327
|
+
voice: audioSource ? unwrapAudioAsset(audioSource) : ""
|
|
1328
|
+
};
|
|
1329
|
+
});
|
|
1330
|
+
return entries;
|
|
1331
|
+
};
|
|
1332
|
+
|
|
1129
1333
|
// src/novely.ts
|
|
1130
1334
|
var novely = ({
|
|
1131
1335
|
characters,
|
|
@@ -1144,7 +1348,7 @@ var novely = ({
|
|
|
1144
1348
|
getLanguage: getLanguage2 = getLanguage,
|
|
1145
1349
|
overrideLanguage = false,
|
|
1146
1350
|
askBeforeExit = true,
|
|
1147
|
-
preloadAssets = "
|
|
1351
|
+
preloadAssets = "automatic",
|
|
1148
1352
|
parallelAssetsDownloadLimit = 15,
|
|
1149
1353
|
fetch: request = fetch,
|
|
1150
1354
|
cloneFunction: clone = klona,
|
|
@@ -1165,7 +1369,7 @@ var novely = ({
|
|
|
1165
1369
|
storyOptions.preloadSaves ??= 4;
|
|
1166
1370
|
}
|
|
1167
1371
|
const storyLoad = storyOptions.mode === "static" ? noop : storyOptions.load;
|
|
1168
|
-
const onUnknownSceneHit =
|
|
1372
|
+
const onUnknownSceneHit = memoize5(async (scene) => {
|
|
1169
1373
|
const part = await storyLoad(scene);
|
|
1170
1374
|
if (part) {
|
|
1171
1375
|
await script(part);
|
|
@@ -1180,14 +1384,6 @@ var novely = ({
|
|
|
1180
1384
|
if (!initialScreenWasShown) {
|
|
1181
1385
|
renderer.ui.showLoading();
|
|
1182
1386
|
}
|
|
1183
|
-
if (preloadAssets === "blocking" && ASSETS_TO_PRELOAD.size > 0) {
|
|
1184
|
-
renderer.ui.showLoading();
|
|
1185
|
-
await handleAssetsPreloading({
|
|
1186
|
-
...renderer.misc,
|
|
1187
|
-
limiter: limitAssetsDownload,
|
|
1188
|
-
request
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
1387
|
await dataLoaded.promise;
|
|
1192
1388
|
renderer.ui.hideLoading();
|
|
1193
1389
|
if (!initialScreenWasShown) {
|
|
@@ -1246,11 +1442,7 @@ var novely = ({
|
|
|
1246
1442
|
referGuarded(path);
|
|
1247
1443
|
}
|
|
1248
1444
|
};
|
|
1249
|
-
|
|
1250
|
-
await preload();
|
|
1251
|
-
} else {
|
|
1252
|
-
void preload();
|
|
1253
|
-
}
|
|
1445
|
+
preload();
|
|
1254
1446
|
coreData.update((data2) => {
|
|
1255
1447
|
data2.dataLoaded = true;
|
|
1256
1448
|
return data2;
|
|
@@ -1265,13 +1457,12 @@ var novely = ({
|
|
|
1265
1457
|
}
|
|
1266
1458
|
storage.set(data2);
|
|
1267
1459
|
};
|
|
1268
|
-
const
|
|
1269
|
-
const
|
|
1270
|
-
if (saveOnUnload === true || saveOnUnload === "prod" && !DEV5) {
|
|
1271
|
-
onStorageDataChange(storageData.get());
|
|
1272
|
-
}
|
|
1273
|
-
}, 10);
|
|
1460
|
+
const throttledShortOnStorageDataChange = throttle(() => onStorageDataChange(storageData.get()), 10);
|
|
1461
|
+
const throttledOnStorageDataChange = throttle(throttledShortOnStorageDataChange, throttleTimeout);
|
|
1274
1462
|
storageData.subscribe(throttledOnStorageDataChange);
|
|
1463
|
+
if (saveOnUnload === true || saveOnUnload === "prod" && !DEV5) {
|
|
1464
|
+
addEventListener("beforeunload", throttledShortOnStorageDataChange);
|
|
1465
|
+
}
|
|
1275
1466
|
const getStoredData = async () => {
|
|
1276
1467
|
let stored = await storage.get();
|
|
1277
1468
|
for (const migration of migrations) {
|
|
@@ -1295,9 +1486,6 @@ var novely = ({
|
|
|
1295
1486
|
};
|
|
1296
1487
|
storageDelay.then(getStoredData);
|
|
1297
1488
|
const initial = getDefaultSave(clone(defaultState));
|
|
1298
|
-
const unsubscribeFromBrowserVisibilityChange = setupBrowserVisibilityChangeListeners({
|
|
1299
|
-
onChange: throttledEmergencyOnStorageDataChange
|
|
1300
|
-
});
|
|
1301
1489
|
const save = (type) => {
|
|
1302
1490
|
if (!coreData.get().dataLoaded) return;
|
|
1303
1491
|
if (!autosaves && type === "auto") return;
|
|
@@ -1514,7 +1702,6 @@ var novely = ({
|
|
|
1514
1702
|
huntAssets({
|
|
1515
1703
|
action: action2,
|
|
1516
1704
|
props,
|
|
1517
|
-
mode: preloadAssets,
|
|
1518
1705
|
characters,
|
|
1519
1706
|
lang: getLanguageFromStore(storageData),
|
|
1520
1707
|
volume: getVolumeFromStore(storageData),
|
|
@@ -1561,7 +1748,7 @@ var novely = ({
|
|
|
1561
1748
|
const clearCustomAction = (ctx, fn) => {
|
|
1562
1749
|
getCustomActionHolder(ctx, fn).cleanup();
|
|
1563
1750
|
};
|
|
1564
|
-
const
|
|
1751
|
+
const getResourseTypeWrapper = (url) => {
|
|
1565
1752
|
return getResourseType({
|
|
1566
1753
|
url,
|
|
1567
1754
|
request
|
|
@@ -1571,12 +1758,12 @@ var novely = ({
|
|
|
1571
1758
|
return c in characters ? characters[c].color : "#000000";
|
|
1572
1759
|
};
|
|
1573
1760
|
const getCharacterAssets = (character, emotion) => {
|
|
1574
|
-
return toArray(characters[character].emotions[emotion]).map(
|
|
1761
|
+
return toArray(characters[character].emotions[emotion]).map(unwrapImageAsset);
|
|
1575
1762
|
};
|
|
1576
1763
|
const getCharacterName = (character) => {
|
|
1577
1764
|
const c = character;
|
|
1578
1765
|
const cs = characters;
|
|
1579
|
-
const
|
|
1766
|
+
const lang = getLanguageFromStore(storageData);
|
|
1580
1767
|
if (c && c in cs) {
|
|
1581
1768
|
const block = cs[c].name;
|
|
1582
1769
|
if (typeof block === "string") {
|
|
@@ -1586,56 +1773,7 @@ var novely = ({
|
|
|
1586
1773
|
return block[lang];
|
|
1587
1774
|
}
|
|
1588
1775
|
}
|
|
1589
|
-
return String(c)
|
|
1590
|
-
};
|
|
1591
|
-
const getDialogOverview = async () => {
|
|
1592
|
-
const { value: save2 } = useStack(MAIN_CONTEXT_KEY);
|
|
1593
|
-
const stateSnapshots = save2[3];
|
|
1594
|
-
if (stateSnapshots.length == 0) {
|
|
1595
|
-
return [];
|
|
1596
|
-
}
|
|
1597
|
-
const { queue } = await getActionsFromPath({
|
|
1598
|
-
story,
|
|
1599
|
-
path: save2[0],
|
|
1600
|
-
filter: false,
|
|
1601
|
-
referGuarded
|
|
1602
|
-
});
|
|
1603
|
-
const [lang] = storageData.get().meta;
|
|
1604
|
-
const dialogItems = [];
|
|
1605
|
-
for (let p = 0, a = stateSnapshots.length, i = queue.length - 1; a > 0 && i > 0; i--) {
|
|
1606
|
-
const action2 = queue[i];
|
|
1607
|
-
if (action2[0] === "dialog") {
|
|
1608
|
-
const [_, name, text] = action2;
|
|
1609
|
-
let voice = void 0;
|
|
1610
|
-
for (let j = i - 1; j > p && j > 0; j--) {
|
|
1611
|
-
const action3 = queue[j];
|
|
1612
|
-
if (isUserRequiredAction(action3) || isSkippedDuringRestore(action3[0])) break;
|
|
1613
|
-
if (action3[0] === "stopVoice") break;
|
|
1614
|
-
if (action3[0] === "voice") {
|
|
1615
|
-
voice = action3[1];
|
|
1616
|
-
break;
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
dialogItems.push({
|
|
1620
|
-
name,
|
|
1621
|
-
text,
|
|
1622
|
-
voice
|
|
1623
|
-
});
|
|
1624
|
-
p = i;
|
|
1625
|
-
a--;
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
const entries = dialogItems.reverse().map(({ name, text, voice }, i) => {
|
|
1629
|
-
const state = stateSnapshots[i];
|
|
1630
|
-
const audioSource = isString(voice) ? voice : isAsset(voice) ? voice : voice == void 0 ? voice : voice[lang];
|
|
1631
|
-
name = name ? getCharacterName(name) : "";
|
|
1632
|
-
return {
|
|
1633
|
-
name: templateReplace(name, state),
|
|
1634
|
-
text: templateReplace(text, state),
|
|
1635
|
-
voice: audioSource ? handleAudioAsset(audioSource) : ""
|
|
1636
|
-
};
|
|
1637
|
-
});
|
|
1638
|
-
return entries;
|
|
1776
|
+
return String(c);
|
|
1639
1777
|
};
|
|
1640
1778
|
const renderer = createRenderer({
|
|
1641
1779
|
mainContextKey: MAIN_CONTEXT_KEY,
|
|
@@ -1658,8 +1796,15 @@ var novely = ({
|
|
|
1658
1796
|
getLanguageDisplayName,
|
|
1659
1797
|
getCharacterColor,
|
|
1660
1798
|
getCharacterAssets,
|
|
1661
|
-
getDialogOverview
|
|
1662
|
-
|
|
1799
|
+
getDialogOverview: getDialogOverview.bind({
|
|
1800
|
+
referGuarded,
|
|
1801
|
+
story,
|
|
1802
|
+
getCharacterName,
|
|
1803
|
+
getLanguage: () => getLanguageFromStore(storageData),
|
|
1804
|
+
getStack: () => useStack(MAIN_CONTEXT_KEY),
|
|
1805
|
+
templateReplace: (...args) => templateReplace(...args)
|
|
1806
|
+
}),
|
|
1807
|
+
getResourseType: getResourseTypeWrapper
|
|
1663
1808
|
});
|
|
1664
1809
|
const useStack = createUseStackFunction(renderer);
|
|
1665
1810
|
useStack(MAIN_CONTEXT_KEY).push(initial);
|
|
@@ -1703,7 +1848,6 @@ var novely = ({
|
|
|
1703
1848
|
huntAssets({
|
|
1704
1849
|
action: action3,
|
|
1705
1850
|
props: props2,
|
|
1706
|
-
mode: preloadAssets,
|
|
1707
1851
|
characters,
|
|
1708
1852
|
lang: getLanguageFromStore(storageData),
|
|
1709
1853
|
volume: getVolumeFromStore(storageData),
|
|
@@ -1728,47 +1872,47 @@ var novely = ({
|
|
|
1728
1872
|
showBackground({ ctx, push }, [background]) {
|
|
1729
1873
|
if (isString(background) || isAsset(background)) {
|
|
1730
1874
|
ctx.background({
|
|
1731
|
-
all:
|
|
1875
|
+
all: unwrapImageAsset(background)
|
|
1732
1876
|
});
|
|
1733
1877
|
} else {
|
|
1734
1878
|
ctx.background(
|
|
1735
|
-
Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media,
|
|
1879
|
+
Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, unwrapImageAsset(asset2)]))
|
|
1736
1880
|
);
|
|
1737
1881
|
}
|
|
1738
1882
|
push();
|
|
1739
1883
|
},
|
|
1740
1884
|
playMusic({ ctx, push }, [source]) {
|
|
1741
|
-
ctx.audio.music(
|
|
1885
|
+
ctx.audio.music(unwrapAudioAsset(source), "music").play(true);
|
|
1742
1886
|
push();
|
|
1743
1887
|
},
|
|
1744
1888
|
pauseMusic({ ctx, push }, [source]) {
|
|
1745
|
-
ctx.audio.music(
|
|
1889
|
+
ctx.audio.music(unwrapAudioAsset(source), "music").pause();
|
|
1746
1890
|
push();
|
|
1747
1891
|
},
|
|
1748
1892
|
stopMusic({ ctx, push }, [source]) {
|
|
1749
|
-
ctx.audio.music(
|
|
1893
|
+
ctx.audio.music(unwrapAudioAsset(source), "music").stop();
|
|
1750
1894
|
push();
|
|
1751
1895
|
},
|
|
1752
1896
|
playSound({ ctx, push }, [source, loop]) {
|
|
1753
|
-
ctx.audio.music(
|
|
1897
|
+
ctx.audio.music(unwrapAudioAsset(source), "sound").play(loop || false);
|
|
1754
1898
|
push();
|
|
1755
1899
|
},
|
|
1756
1900
|
pauseSound({ ctx, push }, [source]) {
|
|
1757
|
-
ctx.audio.music(
|
|
1901
|
+
ctx.audio.music(unwrapAudioAsset(source), "sound").pause();
|
|
1758
1902
|
push();
|
|
1759
1903
|
},
|
|
1760
1904
|
stopSound({ ctx, push }, [source]) {
|
|
1761
|
-
ctx.audio.music(
|
|
1905
|
+
ctx.audio.music(unwrapAudioAsset(source), "sound").stop();
|
|
1762
1906
|
push();
|
|
1763
1907
|
},
|
|
1764
1908
|
voice({ ctx, push }, [source]) {
|
|
1765
|
-
const
|
|
1909
|
+
const lang = getLanguageFromStore(storageData);
|
|
1766
1910
|
const audioSource = isString(source) ? source : isAsset(source) ? source : source[lang];
|
|
1767
1911
|
if (!audioSource) {
|
|
1768
1912
|
push();
|
|
1769
1913
|
return;
|
|
1770
1914
|
}
|
|
1771
|
-
ctx.audio.voice(
|
|
1915
|
+
ctx.audio.voice(unwrapAudioAsset(audioSource));
|
|
1772
1916
|
push();
|
|
1773
1917
|
},
|
|
1774
1918
|
stopVoice({ ctx, push }) {
|
|
@@ -1845,7 +1989,7 @@ var novely = ({
|
|
|
1845
1989
|
recompute: update
|
|
1846
1990
|
});
|
|
1847
1991
|
};
|
|
1848
|
-
const imageValue = image ?
|
|
1992
|
+
const imageValue = image ? unwrapImageAsset(image) : "";
|
|
1849
1993
|
return [templateReplace(content, data2), active$, visible$, onSelectWrapped, imageValue];
|
|
1850
1994
|
});
|
|
1851
1995
|
if (DEV5 && transformedChoices.length === 0) {
|
|
@@ -1990,11 +2134,28 @@ var novely = ({
|
|
|
1990
2134
|
preload({ ctx, push }, [source]) {
|
|
1991
2135
|
if (DEV5 && preloadAssets !== "lazy") {
|
|
1992
2136
|
console.error(
|
|
1993
|
-
`You do not need a preload action
|
|
2137
|
+
`You do not need a preload action because "preloadAssets" strategy was set to "${preloadAssets}"`
|
|
1994
2138
|
);
|
|
2139
|
+
push();
|
|
2140
|
+
return;
|
|
1995
2141
|
}
|
|
1996
|
-
|
|
1997
|
-
|
|
2142
|
+
const src = unwrapAsset(source);
|
|
2143
|
+
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(src)) {
|
|
2144
|
+
const process = async () => {
|
|
2145
|
+
const type = isAsset(source) ? source.type : await getResourseTypeWrapper(src);
|
|
2146
|
+
if (type === "image") {
|
|
2147
|
+
renderer.misc.preloadAudioBlocking(src);
|
|
2148
|
+
} else if (type === "audio") {
|
|
2149
|
+
renderer.misc.preloadImage(src);
|
|
2150
|
+
} else {
|
|
2151
|
+
if (DEV5) {
|
|
2152
|
+
console.error(`Preload error: Unknown type of the following resource: `, source);
|
|
2153
|
+
}
|
|
2154
|
+
return;
|
|
2155
|
+
}
|
|
2156
|
+
PRELOADED_ASSETS.add(src);
|
|
2157
|
+
};
|
|
2158
|
+
process();
|
|
1998
2159
|
}
|
|
1999
2160
|
push();
|
|
2000
2161
|
},
|
|
@@ -2015,9 +2176,7 @@ var novely = ({
|
|
|
2015
2176
|
const action = buildActionObject({
|
|
2016
2177
|
rendererActions: renderer.actions,
|
|
2017
2178
|
nativeActions,
|
|
2018
|
-
characters
|
|
2019
|
-
preloadAssets,
|
|
2020
|
-
storageData
|
|
2179
|
+
characters
|
|
2021
2180
|
});
|
|
2022
2181
|
const render = async (ctx) => {
|
|
2023
2182
|
const stack = useStack(ctx);
|
|
@@ -2072,12 +2231,6 @@ var novely = ({
|
|
|
2072
2231
|
});
|
|
2073
2232
|
return void 0;
|
|
2074
2233
|
};
|
|
2075
|
-
const typeEssentials = {
|
|
2076
|
-
l: null,
|
|
2077
|
-
s: null,
|
|
2078
|
-
d: null,
|
|
2079
|
-
c: null
|
|
2080
|
-
};
|
|
2081
2234
|
const getCurrentStorageData = () => {
|
|
2082
2235
|
return coreData.get().dataLoaded ? clone(storageData.get()) : null;
|
|
2083
2236
|
};
|
|
@@ -2143,7 +2296,7 @@ var novely = ({
|
|
|
2143
2296
|
data,
|
|
2144
2297
|
/**
|
|
2145
2298
|
* Used in combination with type utilities
|
|
2146
|
-
*
|
|
2299
|
+
* @deprecated Use `engine.types` instead
|
|
2147
2300
|
* @example
|
|
2148
2301
|
* ```ts
|
|
2149
2302
|
* import type { ConditionParams, StateFunction } from '@novely/core';
|
|
@@ -2153,7 +2306,21 @@ var novely = ({
|
|
|
2153
2306
|
* }
|
|
2154
2307
|
* ```
|
|
2155
2308
|
*/
|
|
2156
|
-
typeEssentials,
|
|
2309
|
+
typeEssentials: {},
|
|
2310
|
+
/**
|
|
2311
|
+
* Used in combination with type utilities
|
|
2312
|
+
* @example
|
|
2313
|
+
* ```ts
|
|
2314
|
+
* import type { TypesFromEngine, ConditionParams, StateFunction } from '@novely/core';
|
|
2315
|
+
*
|
|
2316
|
+
* type Types = TypesFromEngine<typeof engine>;
|
|
2317
|
+
*
|
|
2318
|
+
* const conditionCheck = (state: StateFunction<ConditionParams<Types>>) => {
|
|
2319
|
+
* return state.age >= 18;
|
|
2320
|
+
* }
|
|
2321
|
+
* ```
|
|
2322
|
+
*/
|
|
2323
|
+
types: null,
|
|
2157
2324
|
/**
|
|
2158
2325
|
* Replaces content inside {{braces}} using global data
|
|
2159
2326
|
* @example
|
|
@@ -2182,7 +2349,7 @@ var novely = ({
|
|
|
2182
2349
|
destroy() {
|
|
2183
2350
|
dataLoaded.cancel();
|
|
2184
2351
|
UIInstance.unmount();
|
|
2185
|
-
|
|
2352
|
+
removeEventListener("beforeunload", throttledShortOnStorageDataChange);
|
|
2186
2353
|
destroyed = true;
|
|
2187
2354
|
},
|
|
2188
2355
|
/**
|
|
@@ -2224,42 +2391,42 @@ var extendAction = (base, extension) => {
|
|
|
2224
2391
|
|
|
2225
2392
|
// src/translations.ts
|
|
2226
2393
|
var RU = {
|
|
2227
|
-
NewGame: "
|
|
2228
|
-
HomeScreen: "
|
|
2229
|
-
ToTheGame: "
|
|
2230
|
-
Language: "
|
|
2231
|
-
NoSaves: "
|
|
2232
|
-
LoadSave: "
|
|
2233
|
-
Saves: "
|
|
2234
|
-
Settings: "
|
|
2235
|
-
Sumbit: "
|
|
2236
|
-
GoBack: "
|
|
2237
|
-
DoSave: "
|
|
2238
|
-
Auto: "
|
|
2239
|
-
Stop: "
|
|
2240
|
-
Exit: "
|
|
2241
|
-
Automatic: "
|
|
2242
|
-
Manual: "
|
|
2243
|
-
Remove: "
|
|
2244
|
-
LoadASaveFrom: "
|
|
2245
|
-
DeleteASaveFrom: "
|
|
2246
|
-
TextSpeed: "
|
|
2247
|
-
TextSpeedSlow: "
|
|
2248
|
-
TextSpeedMedium: "
|
|
2249
|
-
TextSpeedFast: "
|
|
2250
|
-
TextSpeedAuto: "
|
|
2251
|
-
CompleteText: "
|
|
2252
|
-
GoForward: "
|
|
2253
|
-
ExitDialogWarning: "
|
|
2254
|
-
ExitDialogExit: "
|
|
2255
|
-
ExitDialogBack: "
|
|
2256
|
-
OpenMenu: "
|
|
2257
|
-
CloseMenu: "
|
|
2258
|
-
MusicVolume: "
|
|
2259
|
-
SoundVolume: "
|
|
2260
|
-
VoiceVolume: "
|
|
2261
|
-
Close: "
|
|
2262
|
-
DialogOverview: "
|
|
2394
|
+
NewGame: "Новая игра",
|
|
2395
|
+
HomeScreen: "Главный экран",
|
|
2396
|
+
ToTheGame: "К игре",
|
|
2397
|
+
Language: "Язык",
|
|
2398
|
+
NoSaves: "Сохранений нет",
|
|
2399
|
+
LoadSave: "Загрузить",
|
|
2400
|
+
Saves: "Сохранения",
|
|
2401
|
+
Settings: "Настройки",
|
|
2402
|
+
Sumbit: "Подтвердить",
|
|
2403
|
+
GoBack: "Назад",
|
|
2404
|
+
DoSave: "Сохранение",
|
|
2405
|
+
Auto: "Авто",
|
|
2406
|
+
Stop: "Стоп",
|
|
2407
|
+
Exit: "Выход",
|
|
2408
|
+
Automatic: "Автоматическое",
|
|
2409
|
+
Manual: "Ручное",
|
|
2410
|
+
Remove: "Удалить",
|
|
2411
|
+
LoadASaveFrom: "Загрузить сохранение от",
|
|
2412
|
+
DeleteASaveFrom: "Удалить сохранение от",
|
|
2413
|
+
TextSpeed: "Скорость текста",
|
|
2414
|
+
TextSpeedSlow: "Медленная",
|
|
2415
|
+
TextSpeedMedium: "Средняя",
|
|
2416
|
+
TextSpeedFast: "Быстрая",
|
|
2417
|
+
TextSpeedAuto: "Автоматическая",
|
|
2418
|
+
CompleteText: "Завершить текст",
|
|
2419
|
+
GoForward: "Перейти вперёд",
|
|
2420
|
+
ExitDialogWarning: "Вы уверены, что хотите выйти? Прогресс будет сохранён.",
|
|
2421
|
+
ExitDialogExit: "Выйти",
|
|
2422
|
+
ExitDialogBack: "Вернуться в игру",
|
|
2423
|
+
OpenMenu: "Открыть меню",
|
|
2424
|
+
CloseMenu: "Закрыть меню",
|
|
2425
|
+
MusicVolume: "Громкость музыки",
|
|
2426
|
+
SoundVolume: "Громкость звуков",
|
|
2427
|
+
VoiceVolume: "Громкость речи",
|
|
2428
|
+
Close: "Закрыть",
|
|
2429
|
+
DialogOverview: "Обзор диалога"
|
|
2263
2430
|
};
|
|
2264
2431
|
var EN = {
|
|
2265
2432
|
NewGame: "New Game",
|
|
@@ -2299,240 +2466,8 @@ var EN = {
|
|
|
2299
2466
|
Close: "Close",
|
|
2300
2467
|
DialogOverview: "Dialog Overview"
|
|
2301
2468
|
};
|
|
2302
|
-
var KK = {
|
|
2303
|
-
NewGame: "\u0416\u0430\u04A3\u0430 \u043E\u0439\u044B\u043D",
|
|
2304
|
-
HomeScreen: "\u041D\u0435\u0433\u0456\u0437\u0433\u0456 \u044D\u043A\u0440\u0430\u043D",
|
|
2305
|
-
ToTheGame: "\u041E\u0439\u044B\u043D\u0493\u0430",
|
|
2306
|
-
Language: "\u0422\u0456\u043B",
|
|
2307
|
-
NoSaves: "\u0421\u0430\u049B\u0442\u0430\u0443 \u0436\u043E\u049B",
|
|
2308
|
-
LoadSave: "\u0416\u04AF\u043A\u0442\u0435\u0443",
|
|
2309
|
-
Saves: "\u0421\u0430\u049B\u0442\u0430\u0443",
|
|
2310
|
-
Settings: "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043B\u0435\u0440",
|
|
2311
|
-
Sumbit: "\u0420\u0430\u0441\u0442\u0430\u0443",
|
|
2312
|
-
GoBack: "\u0410\u0440\u0442\u049B\u0430",
|
|
2313
|
-
DoSave: "\u0421\u0430\u049B\u0442\u0430\u0443",
|
|
2314
|
-
Auto: "\u0410\u0432\u0442\u043E",
|
|
2315
|
-
Stop: "\u0422\u043E\u049B\u0442\u0430",
|
|
2316
|
-
Exit: "\u0428\u044B\u0493\u0443",
|
|
2317
|
-
Automatic: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0442\u044B",
|
|
2318
|
-
Manual: "\u049A\u043E\u043B\u043C\u0435\u043D",
|
|
2319
|
-
Remove: "\u0416\u043E\u044E",
|
|
2320
|
-
LoadASaveFrom: "\u0421\u0430\u049B\u0442\u0430\u0443\u0434\u044B \u0436\u04AF\u043A\u0442\u0435\u0443",
|
|
2321
|
-
DeleteASaveFrom: "\u0421\u0430\u049B\u0442\u0430\u0443\u0434\u044B \u0436\u043E\u044E",
|
|
2322
|
-
TextSpeed: "\u041C\u04D9\u0442\u0456\u043D \u0416\u044B\u043B\u0434\u0430\u043C\u0434\u044B\u0493\u044B",
|
|
2323
|
-
TextSpeedSlow: "\u0411\u0430\u044F\u0443",
|
|
2324
|
-
TextSpeedMedium: "\u041E\u0440\u0442\u0430\u0448\u0430",
|
|
2325
|
-
TextSpeedFast: "\u0416\u044B\u043B\u0434\u0430\u043C",
|
|
2326
|
-
TextSpeedAuto: "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0442\u044B",
|
|
2327
|
-
CompleteText: "\u041C\u04D9\u0442\u0456\u043D\u0434\u0456 \u0430\u044F\u049B\u0442\u0430\u0443",
|
|
2328
|
-
GoForward: "\u0410\u043B\u0493\u0430 \u0436\u044B\u043B\u0436\u0443",
|
|
2329
|
-
ExitDialogWarning: "\u0421\u0456\u0437 \u0448\u044B\u049B\u049B\u044B\u04A3\u044B\u0437 \u043A\u0435\u043B\u0435\u0442\u0456\u043D\u0456\u043D\u0435 \u0441\u0435\u043D\u0456\u043C\u0434\u0456\u0441\u0456\u0437 \u0431\u0435? \u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441 \u0441\u0430\u049B\u0442\u0430\u043B\u0430\u0434\u044B",
|
|
2330
|
-
ExitDialogExit: "\u0428\u044B\u0493\u0443",
|
|
2331
|
-
ExitDialogBack: "\u041E\u0439\u044B\u043D\u0493\u0430 \u043E\u0440\u0430\u043B\u0443",
|
|
2332
|
-
OpenMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0430\u0448\u044B\u04A3\u044B\u0437",
|
|
2333
|
-
CloseMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0436\u0430\u0431\u0443",
|
|
2334
|
-
MusicVolume: "\u041C\u0443\u0437\u044B\u043A\u0430\u043D\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2335
|
-
SoundVolume: "\u0414\u044B\u0431\u044B\u0441\u0442\u0430\u0440\u0434\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2336
|
-
VoiceVolume: "\u0421\u04E9\u0439\u043B\u0435\u0443 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2337
|
-
Close: "\u0416\u0430\u0431\u0443",
|
|
2338
|
-
DialogOverview: "\u0414\u0438\u0430\u043B\u043E\u0433\u049B\u0430 \u0428\u043E\u043B\u0443"
|
|
2339
|
-
};
|
|
2340
|
-
var JP = {
|
|
2341
|
-
NewGame: "\u300C\u65B0\u3057\u3044\u30B2\u30FC\u30E0\u300D",
|
|
2342
|
-
HomeScreen: "\u30DB\u30FC\u30E0\u753B\u9762",
|
|
2343
|
-
ToTheGame: "\u300C\u30B2\u30FC\u30E0\u306B\u623B\u308B\u300D",
|
|
2344
|
-
Language: "\u8A00\u8A9E",
|
|
2345
|
-
NoSaves: "\u30CE\u30FC\u30BB\u30FC\u30D6",
|
|
2346
|
-
LoadSave: "\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
|
|
2347
|
-
Saves: "\u4FDD\u5B58",
|
|
2348
|
-
Settings: "\u8A2D\u5B9A",
|
|
2349
|
-
Sumbit: "\u78BA\u8A8D",
|
|
2350
|
-
GoBack: "\u300C\u623B\u308B\u300D",
|
|
2351
|
-
DoSave: "\u4FDD\u5B58",
|
|
2352
|
-
Auto: "\u30AA\u30FC\u30C8",
|
|
2353
|
-
Stop: "\u6B62\u307E\u308C",
|
|
2354
|
-
Exit: "\u51FA\u53E3",
|
|
2355
|
-
Automatic: "\u81EA\u52D5",
|
|
2356
|
-
Manual: "\u30DE\u30CB\u30E5\u30A2\u30EB",
|
|
2357
|
-
Remove: "\u524A\u9664",
|
|
2358
|
-
LoadASaveFrom: "\u30ED\u30FC\u30C9\u30BB\u30FC\u30D6\u304B\u3089",
|
|
2359
|
-
DeleteASaveFrom: "\u304B\u3089\u4FDD\u5B58\u3092\u524A\u9664",
|
|
2360
|
-
TextSpeed: "\u30C6\u30AD\u30B9\u30C8\u30B9\u30D4\u30FC\u30C9",
|
|
2361
|
-
TextSpeedSlow: "\u300C\u9045\u3044\u300D",
|
|
2362
|
-
TextSpeedMedium: "\u30DF\u30C7\u30A3\u30A2\u30E0",
|
|
2363
|
-
TextSpeedFast: "\u300C\u901F\u3044\u300D",
|
|
2364
|
-
TextSpeedAuto: "\u81EA\u52D5",
|
|
2365
|
-
CompleteText: "\u30C6\u30AD\u30B9\u30C8\u3092\u5B8C\u6210\u3055\u305B\u308B",
|
|
2366
|
-
GoForward: "\u5148\u306B\u884C\u304F",
|
|
2367
|
-
ExitDialogWarning: "\u672C\u5F53\u306B\u7D42\u4E86\u3057\u307E\u3059\u304B\uFF1F\u9032\u884C\u72B6\u6CC1\u306F\u4FDD\u5B58\u3055\u308C\u307E\u3059",
|
|
2368
|
-
ExitDialogExit: "\u7D42\u4E86",
|
|
2369
|
-
ExitDialogBack: "\u30B2\u30FC\u30E0\u306B\u623B\u308B",
|
|
2370
|
-
OpenMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u958B\u304F",
|
|
2371
|
-
CloseMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B",
|
|
2372
|
-
MusicVolume: "\u97F3\u697D\u306E\u30DC\u30EA\u30E5\u30FC\u30E0",
|
|
2373
|
-
SoundVolume: "\u97F3\u91CF",
|
|
2374
|
-
VoiceVolume: "\u30B9\u30D4\u30FC\u30C1\u306E\u91CF",
|
|
2375
|
-
Close: "\u9589\u3058\u308B",
|
|
2376
|
-
DialogOverview: "\u30C0\u30A4\u30A2\u30ED\u30B0\u306E\u6982\u8981"
|
|
2377
|
-
};
|
|
2378
|
-
|
|
2379
|
-
// src/asset.ts
|
|
2380
|
-
import { memoize as memoize5, once } from "es-toolkit/function";
|
|
2381
|
-
import { DEV as DEV6 } from "esm-env";
|
|
2382
|
-
|
|
2383
|
-
// src/audio-codecs.ts
|
|
2384
|
-
var cut = (str) => str.replace(/^no$/, "");
|
|
2385
|
-
var audio = new Audio();
|
|
2386
|
-
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
2387
|
-
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
2388
|
-
var supportsMap = {
|
|
2389
|
-
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
2390
|
-
mpeg: canPlay("audio/mpeg;"),
|
|
2391
|
-
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
2392
|
-
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2393
|
-
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2394
|
-
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
2395
|
-
aac: canPlay("audio/aac;"),
|
|
2396
|
-
caf: canPlay("audio/x-caf;"),
|
|
2397
|
-
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
2398
|
-
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
2399
|
-
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
2400
|
-
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
2401
|
-
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
2402
|
-
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
2403
|
-
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
2404
|
-
};
|
|
2405
|
-
|
|
2406
|
-
// src/image-formats.ts
|
|
2407
|
-
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
2408
|
-
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
2409
|
-
var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
|
|
2410
|
-
var supportsFormat = (source) => {
|
|
2411
|
-
const { promise, resolve } = Promise.withResolvers();
|
|
2412
|
-
const img = Object.assign(document.createElement("img"), {
|
|
2413
|
-
src: source
|
|
2414
|
-
});
|
|
2415
|
-
img.onload = img.onerror = () => {
|
|
2416
|
-
resolve(img.height === 2);
|
|
2417
|
-
};
|
|
2418
|
-
return promise;
|
|
2419
|
-
};
|
|
2420
|
-
var supportsMap2 = {
|
|
2421
|
-
avif: false,
|
|
2422
|
-
jxl: false,
|
|
2423
|
-
webp: false
|
|
2424
|
-
};
|
|
2425
|
-
var formatsMap = {
|
|
2426
|
-
avif,
|
|
2427
|
-
jxl,
|
|
2428
|
-
webp
|
|
2429
|
-
};
|
|
2430
|
-
var loadImageFormatsSupport = async () => {
|
|
2431
|
-
const promises = [];
|
|
2432
|
-
for (const [format, source] of Object.entries(formatsMap)) {
|
|
2433
|
-
const promise = supportsFormat(source).then((supported) => {
|
|
2434
|
-
supportsMap2[format] = supported;
|
|
2435
|
-
});
|
|
2436
|
-
promises.push(promise);
|
|
2437
|
-
}
|
|
2438
|
-
await Promise.all(promises);
|
|
2439
|
-
};
|
|
2440
|
-
loadImageFormatsSupport();
|
|
2441
|
-
|
|
2442
|
-
// src/asset.ts
|
|
2443
|
-
var generateRandomId = () => Math.random().toString(36);
|
|
2444
|
-
var getType = memoize5(
|
|
2445
|
-
(extensions) => {
|
|
2446
|
-
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
2447
|
-
return "audio";
|
|
2448
|
-
}
|
|
2449
|
-
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
2450
|
-
return "image";
|
|
2451
|
-
}
|
|
2452
|
-
throw extensions;
|
|
2453
|
-
},
|
|
2454
|
-
{
|
|
2455
|
-
getCacheKey: (extensions) => extensions.join("~")
|
|
2456
|
-
}
|
|
2457
|
-
);
|
|
2458
|
-
var SUPPORT_MAPS = {
|
|
2459
|
-
image: supportsMap2,
|
|
2460
|
-
audio: supportsMap
|
|
2461
|
-
};
|
|
2462
|
-
var assetPrivate = memoize5(
|
|
2463
|
-
(variants) => {
|
|
2464
|
-
if (DEV6 && variants.length === 0) {
|
|
2465
|
-
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
2466
|
-
}
|
|
2467
|
-
const map = {};
|
|
2468
|
-
const extensions = [];
|
|
2469
|
-
for (const v of variants) {
|
|
2470
|
-
const e = getUrlFileExtension(v);
|
|
2471
|
-
map[e] = v;
|
|
2472
|
-
extensions.push(e);
|
|
2473
|
-
}
|
|
2474
|
-
const type = getType(extensions);
|
|
2475
|
-
const getSource = once(() => {
|
|
2476
|
-
const support = SUPPORT_MAPS[type];
|
|
2477
|
-
for (const extension of extensions) {
|
|
2478
|
-
if (extension in support) {
|
|
2479
|
-
if (support[extension]) {
|
|
2480
|
-
return map[extension];
|
|
2481
|
-
}
|
|
2482
|
-
} else {
|
|
2483
|
-
return map[extension];
|
|
2484
|
-
}
|
|
2485
|
-
}
|
|
2486
|
-
if (DEV6) {
|
|
2487
|
-
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
2488
|
-
}
|
|
2489
|
-
return "";
|
|
2490
|
-
});
|
|
2491
|
-
return {
|
|
2492
|
-
get source() {
|
|
2493
|
-
return getSource();
|
|
2494
|
-
},
|
|
2495
|
-
get type() {
|
|
2496
|
-
return type;
|
|
2497
|
-
},
|
|
2498
|
-
id: generateRandomId()
|
|
2499
|
-
};
|
|
2500
|
-
},
|
|
2501
|
-
{
|
|
2502
|
-
getCacheKey: (variants) => variants.join("~")
|
|
2503
|
-
}
|
|
2504
|
-
);
|
|
2505
|
-
var asset = (...variants) => {
|
|
2506
|
-
return assetPrivate(variants);
|
|
2507
|
-
};
|
|
2508
|
-
asset.image = (source) => {
|
|
2509
|
-
if (assetPrivate.cache.has(source)) {
|
|
2510
|
-
return assetPrivate.cache.get(source);
|
|
2511
|
-
}
|
|
2512
|
-
const asset2 = {
|
|
2513
|
-
type: "image",
|
|
2514
|
-
source,
|
|
2515
|
-
id: generateRandomId()
|
|
2516
|
-
};
|
|
2517
|
-
assetPrivate.cache.set(source, asset2);
|
|
2518
|
-
return asset2;
|
|
2519
|
-
};
|
|
2520
|
-
asset.audio = (source) => {
|
|
2521
|
-
if (assetPrivate.cache.has(source)) {
|
|
2522
|
-
return assetPrivate.cache.get(source);
|
|
2523
|
-
}
|
|
2524
|
-
const asset2 = {
|
|
2525
|
-
type: "audio",
|
|
2526
|
-
source,
|
|
2527
|
-
id: generateRandomId()
|
|
2528
|
-
};
|
|
2529
|
-
assetPrivate.cache.set(source, asset2);
|
|
2530
|
-
return asset2;
|
|
2531
|
-
};
|
|
2532
2469
|
export {
|
|
2533
2470
|
EN,
|
|
2534
|
-
JP,
|
|
2535
|
-
KK,
|
|
2536
2471
|
RU,
|
|
2537
2472
|
asset,
|
|
2538
2473
|
extendAction,
|