@novely/core 0.45.0 → 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 +41 -33
- package/dist/index.global.js +631 -618
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +355 -342
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,15 +1,91 @@
|
|
|
1
|
+
// src/novely.ts
|
|
2
|
+
import { dequal } from "dequal/lite";
|
|
3
|
+
import { throttle } from "es-toolkit/function";
|
|
4
|
+
import { merge as deepmerge } from "es-toolkit/object";
|
|
5
|
+
import { DEV as DEV3 } from "esm-env";
|
|
6
|
+
|
|
7
|
+
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
8
|
+
function set(obj, key, val) {
|
|
9
|
+
if (typeof val.value === "object") val.value = klona(val.value);
|
|
10
|
+
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
11
|
+
Object.defineProperty(obj, key, val);
|
|
12
|
+
} else obj[key] = val.value;
|
|
13
|
+
}
|
|
14
|
+
function klona(x) {
|
|
15
|
+
if (typeof x !== "object") return x;
|
|
16
|
+
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
17
|
+
if (str2 === "[object Object]") {
|
|
18
|
+
tmp = Object.create(x.__proto__ || null);
|
|
19
|
+
} else if (str2 === "[object Array]") {
|
|
20
|
+
tmp = Array(x.length);
|
|
21
|
+
} else if (str2 === "[object Set]") {
|
|
22
|
+
tmp = /* @__PURE__ */ new Set();
|
|
23
|
+
x.forEach(function(val) {
|
|
24
|
+
tmp.add(klona(val));
|
|
25
|
+
});
|
|
26
|
+
} else if (str2 === "[object Map]") {
|
|
27
|
+
tmp = /* @__PURE__ */ new Map();
|
|
28
|
+
x.forEach(function(val, key) {
|
|
29
|
+
tmp.set(klona(key), klona(val));
|
|
30
|
+
});
|
|
31
|
+
} else if (str2 === "[object Date]") {
|
|
32
|
+
tmp = /* @__PURE__ */ new Date(+x);
|
|
33
|
+
} else if (str2 === "[object RegExp]") {
|
|
34
|
+
tmp = new RegExp(x.source, x.flags);
|
|
35
|
+
} else if (str2 === "[object DataView]") {
|
|
36
|
+
tmp = new x.constructor(klona(x.buffer));
|
|
37
|
+
} else if (str2 === "[object ArrayBuffer]") {
|
|
38
|
+
tmp = x.slice(0);
|
|
39
|
+
} else if (str2.slice(-6) === "Array]") {
|
|
40
|
+
tmp = new x.constructor(x);
|
|
41
|
+
}
|
|
42
|
+
if (tmp) {
|
|
43
|
+
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
44
|
+
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
45
|
+
}
|
|
46
|
+
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
47
|
+
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
48
|
+
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return tmp || x;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/novely.ts
|
|
55
|
+
import pLimit from "p-limit";
|
|
56
|
+
|
|
57
|
+
// src/asset.ts
|
|
58
|
+
import { memoize as memoize2, once } from "es-toolkit/function";
|
|
59
|
+
import { DEV as DEV2 } from "esm-env";
|
|
60
|
+
|
|
61
|
+
// src/audio-codecs.ts
|
|
62
|
+
var cut = (str2) => str2.replace(/^no$/, "");
|
|
63
|
+
var audio = new Audio();
|
|
64
|
+
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
65
|
+
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
66
|
+
var supportsMap = {
|
|
67
|
+
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
68
|
+
mpeg: canPlay("audio/mpeg;"),
|
|
69
|
+
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
70
|
+
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
71
|
+
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
72
|
+
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
73
|
+
aac: canPlay("audio/aac;"),
|
|
74
|
+
caf: canPlay("audio/x-caf;"),
|
|
75
|
+
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
76
|
+
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
77
|
+
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
78
|
+
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
79
|
+
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
80
|
+
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
81
|
+
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
82
|
+
};
|
|
83
|
+
|
|
1
84
|
// src/constants.ts
|
|
2
85
|
var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
|
|
3
86
|
var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
|
|
4
87
|
var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
|
|
5
|
-
var AUDIO_ACTIONS = /* @__PURE__ */ new Set([
|
|
6
|
-
"playMusic",
|
|
7
|
-
"stopMusic",
|
|
8
|
-
"playSound",
|
|
9
|
-
"stopSound",
|
|
10
|
-
"voice",
|
|
11
|
-
"stopVoice"
|
|
12
|
-
]);
|
|
88
|
+
var AUDIO_ACTIONS = /* @__PURE__ */ new Set(["playMusic", "stopMusic", "playSound", "stopSound", "voice", "stopVoice"]);
|
|
13
89
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
14
90
|
var DEFAULT_TYPEWRITER_SPEED = "Medium";
|
|
15
91
|
var HOWLER_SUPPORTED_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
@@ -45,42 +121,6 @@ var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
|
45
121
|
]);
|
|
46
122
|
var MAIN_CONTEXT_KEY = "$MAIN";
|
|
47
123
|
|
|
48
|
-
// src/shared.ts
|
|
49
|
-
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
50
|
-
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
51
|
-
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
52
|
-
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
53
|
-
|
|
54
|
-
// src/utils.ts
|
|
55
|
-
import { DEV as DEV2 } from "esm-env";
|
|
56
|
-
import { memoize as memoize2 } from "es-toolkit/function";
|
|
57
|
-
|
|
58
|
-
// src/asset.ts
|
|
59
|
-
import { DEV } from "esm-env";
|
|
60
|
-
|
|
61
|
-
// src/audio-codecs.ts
|
|
62
|
-
var cut = (str2) => str2.replace(/^no$/, "");
|
|
63
|
-
var audio = new Audio();
|
|
64
|
-
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
65
|
-
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
66
|
-
var supportsMap = {
|
|
67
|
-
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
68
|
-
mpeg: canPlay("audio/mpeg;"),
|
|
69
|
-
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
70
|
-
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
71
|
-
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
72
|
-
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
73
|
-
aac: canPlay("audio/aac;"),
|
|
74
|
-
caf: canPlay("audio/x-caf;"),
|
|
75
|
-
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
76
|
-
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
77
|
-
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
78
|
-
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
79
|
-
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
80
|
-
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
81
|
-
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
82
|
-
};
|
|
83
|
-
|
|
84
124
|
// src/image-formats.ts
|
|
85
125
|
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
86
126
|
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
@@ -117,74 +157,15 @@ var loadImageFormatsSupport = async () => {
|
|
|
117
157
|
};
|
|
118
158
|
loadImageFormatsSupport();
|
|
119
159
|
|
|
120
|
-
// src/
|
|
121
|
-
import { memoize
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
throw extensions;
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
getCacheKey: (extensions) => extensions.join("~")
|
|
134
|
-
}
|
|
135
|
-
);
|
|
136
|
-
var SUPPORT_MAPS = {
|
|
137
|
-
"image": supportsMap2,
|
|
138
|
-
"audio": supportsMap
|
|
139
|
-
};
|
|
140
|
-
var assetPrivate = memoize(
|
|
141
|
-
(variants) => {
|
|
142
|
-
if (DEV && variants.length === 0) {
|
|
143
|
-
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
144
|
-
}
|
|
145
|
-
const map = {};
|
|
146
|
-
const extensions = [];
|
|
147
|
-
for (const v of variants) {
|
|
148
|
-
const e = getUrlFileExtension(v);
|
|
149
|
-
map[e] = v;
|
|
150
|
-
extensions.push(e);
|
|
151
|
-
}
|
|
152
|
-
const type = getType(extensions);
|
|
153
|
-
const getSource = once(() => {
|
|
154
|
-
const support = SUPPORT_MAPS[type];
|
|
155
|
-
for (const extension of extensions) {
|
|
156
|
-
if (extension in support) {
|
|
157
|
-
if (support[extension]) {
|
|
158
|
-
return map[extension];
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
return map[extension];
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (DEV) {
|
|
165
|
-
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
166
|
-
}
|
|
167
|
-
return "";
|
|
168
|
-
});
|
|
169
|
-
return {
|
|
170
|
-
get source() {
|
|
171
|
-
return getSource();
|
|
172
|
-
},
|
|
173
|
-
get type() {
|
|
174
|
-
return type;
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
getCacheKey: (variants) => variants.join("~")
|
|
180
|
-
}
|
|
181
|
-
);
|
|
182
|
-
var asset = (...variants) => {
|
|
183
|
-
return assetPrivate(variants);
|
|
184
|
-
};
|
|
185
|
-
var isAsset = (suspect) => {
|
|
186
|
-
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
187
|
-
};
|
|
160
|
+
// src/utils.ts
|
|
161
|
+
import { memoize } from "es-toolkit/function";
|
|
162
|
+
import { DEV } from "esm-env";
|
|
163
|
+
|
|
164
|
+
// src/shared.ts
|
|
165
|
+
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
166
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
167
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
168
|
+
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
188
169
|
|
|
189
170
|
// src/utils.ts
|
|
190
171
|
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
@@ -195,18 +176,21 @@ var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) =>
|
|
|
195
176
|
props,
|
|
196
177
|
ctx: context
|
|
197
178
|
});
|
|
198
|
-
return values[action](
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
179
|
+
return values[action](
|
|
180
|
+
{
|
|
181
|
+
ctx: context,
|
|
182
|
+
data,
|
|
183
|
+
push() {
|
|
184
|
+
if (context.meta.preview) return;
|
|
185
|
+
push(context);
|
|
186
|
+
},
|
|
187
|
+
forward() {
|
|
188
|
+
if (context.meta.preview) return;
|
|
189
|
+
forward(context);
|
|
190
|
+
}
|
|
204
191
|
},
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
forward(context);
|
|
208
|
-
}
|
|
209
|
-
}, props);
|
|
192
|
+
props
|
|
193
|
+
);
|
|
210
194
|
};
|
|
211
195
|
};
|
|
212
196
|
var isNumber = (val) => {
|
|
@@ -318,10 +302,10 @@ var isExitImpossible = (path) => {
|
|
|
318
302
|
};
|
|
319
303
|
var getOppositeAction = (action) => {
|
|
320
304
|
const MAP = {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
305
|
+
showCharacter: "hideCharacter",
|
|
306
|
+
playSound: "stopSound",
|
|
307
|
+
playMusic: "stopMusic",
|
|
308
|
+
voice: "stopVoice"
|
|
325
309
|
};
|
|
326
310
|
return MAP[action];
|
|
327
311
|
};
|
|
@@ -488,7 +472,7 @@ var createQueueProcessor = (queue, options) => {
|
|
|
488
472
|
}
|
|
489
473
|
};
|
|
490
474
|
};
|
|
491
|
-
var getStack =
|
|
475
|
+
var getStack = memoize(
|
|
492
476
|
(_) => {
|
|
493
477
|
return [];
|
|
494
478
|
},
|
|
@@ -540,7 +524,7 @@ var getUrlFileExtension = (address) => {
|
|
|
540
524
|
const { pathname } = new URL(address, location.href);
|
|
541
525
|
return pathname.split(".").at(-1).split("!")[0].split(":")[0];
|
|
542
526
|
} catch (error) {
|
|
543
|
-
if (
|
|
527
|
+
if (DEV) {
|
|
544
528
|
console.error(new Error(`Could not construct URL "${address}".`, { cause: error }));
|
|
545
529
|
}
|
|
546
530
|
return "";
|
|
@@ -553,13 +537,13 @@ var fetchContentType = async (url, request) => {
|
|
|
553
537
|
});
|
|
554
538
|
return response.headers.get("Content-Type") || "";
|
|
555
539
|
} catch (error) {
|
|
556
|
-
if (
|
|
540
|
+
if (DEV) {
|
|
557
541
|
console.error(new Error(`Failed to fetch file at "${url}"`, { cause: error }));
|
|
558
542
|
}
|
|
559
543
|
return "";
|
|
560
544
|
}
|
|
561
545
|
};
|
|
562
|
-
var getResourseType =
|
|
546
|
+
var getResourseType = memoize(
|
|
563
547
|
async ({ url, request }) => {
|
|
564
548
|
if (!isCSSImage(url)) {
|
|
565
549
|
return "other";
|
|
@@ -587,7 +571,7 @@ var getResourseType = memoize2(
|
|
|
587
571
|
var capitalize = (str2) => {
|
|
588
572
|
return str2[0].toUpperCase() + str2.slice(1);
|
|
589
573
|
};
|
|
590
|
-
var getIntlLanguageDisplayName =
|
|
574
|
+
var getIntlLanguageDisplayName = memoize((lang) => {
|
|
591
575
|
try {
|
|
592
576
|
const intl = new Intl.DisplayNames([lang], {
|
|
593
577
|
type: "language"
|
|
@@ -732,7 +716,10 @@ var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
|
732
716
|
}
|
|
733
717
|
collection.push(action);
|
|
734
718
|
if (action[0] === "jump") {
|
|
735
|
-
path = [
|
|
719
|
+
path = [
|
|
720
|
+
["jump", action[1]],
|
|
721
|
+
[null, 0]
|
|
722
|
+
];
|
|
736
723
|
} else if (action[0] == "block") {
|
|
737
724
|
path.push(["block", action[1]], [null, 0]);
|
|
738
725
|
} else {
|
|
@@ -746,13 +733,13 @@ var unwrapAsset = (asset2) => {
|
|
|
746
733
|
return isAsset(asset2) ? asset2.source : asset2;
|
|
747
734
|
};
|
|
748
735
|
var handleAudioAsset = (asset2) => {
|
|
749
|
-
if (
|
|
736
|
+
if (DEV && isAsset(asset2) && asset2.type !== "audio") {
|
|
750
737
|
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
751
738
|
}
|
|
752
739
|
return unwrapAsset(asset2);
|
|
753
740
|
};
|
|
754
741
|
var handleImageAsset = (asset2) => {
|
|
755
|
-
if (
|
|
742
|
+
if (DEV && isAsset(asset2) && asset2.type !== "image") {
|
|
756
743
|
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
757
744
|
}
|
|
758
745
|
return unwrapAsset(asset2);
|
|
@@ -777,120 +764,88 @@ var getVolumeFromStore = (store2) => {
|
|
|
777
764
|
};
|
|
778
765
|
};
|
|
779
766
|
|
|
780
|
-
// src/
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
// src/store.ts
|
|
786
|
-
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
787
|
-
const subscribe = (cb) => {
|
|
788
|
-
subscribers.add(cb), cb(current);
|
|
789
|
-
return () => {
|
|
790
|
-
subscribers.delete(cb);
|
|
791
|
-
};
|
|
792
|
-
};
|
|
793
|
-
const push = (value) => {
|
|
794
|
-
for (const cb of subscribers) cb(value);
|
|
795
|
-
};
|
|
796
|
-
const update = (fn) => {
|
|
797
|
-
push(current = fn(current));
|
|
798
|
-
};
|
|
799
|
-
const set2 = (val) => {
|
|
800
|
-
update(() => val);
|
|
801
|
-
};
|
|
802
|
-
const get = () => {
|
|
803
|
-
return current;
|
|
804
|
-
};
|
|
805
|
-
return { subscribe, update, set: set2, get };
|
|
806
|
-
};
|
|
807
|
-
|
|
808
|
-
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
809
|
-
function set(obj, key, val) {
|
|
810
|
-
if (typeof val.value === "object") val.value = klona(val.value);
|
|
811
|
-
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
812
|
-
Object.defineProperty(obj, key, val);
|
|
813
|
-
} else obj[key] = val.value;
|
|
814
|
-
}
|
|
815
|
-
function klona(x) {
|
|
816
|
-
if (typeof x !== "object") return x;
|
|
817
|
-
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
818
|
-
if (str2 === "[object Object]") {
|
|
819
|
-
tmp = Object.create(x.__proto__ || null);
|
|
820
|
-
} else if (str2 === "[object Array]") {
|
|
821
|
-
tmp = Array(x.length);
|
|
822
|
-
} else if (str2 === "[object Set]") {
|
|
823
|
-
tmp = /* @__PURE__ */ new Set();
|
|
824
|
-
x.forEach(function(val) {
|
|
825
|
-
tmp.add(klona(val));
|
|
826
|
-
});
|
|
827
|
-
} else if (str2 === "[object Map]") {
|
|
828
|
-
tmp = /* @__PURE__ */ new Map();
|
|
829
|
-
x.forEach(function(val, key) {
|
|
830
|
-
tmp.set(klona(key), klona(val));
|
|
831
|
-
});
|
|
832
|
-
} else if (str2 === "[object Date]") {
|
|
833
|
-
tmp = /* @__PURE__ */ new Date(+x);
|
|
834
|
-
} else if (str2 === "[object RegExp]") {
|
|
835
|
-
tmp = new RegExp(x.source, x.flags);
|
|
836
|
-
} else if (str2 === "[object DataView]") {
|
|
837
|
-
tmp = new x.constructor(klona(x.buffer));
|
|
838
|
-
} else if (str2 === "[object ArrayBuffer]") {
|
|
839
|
-
tmp = x.slice(0);
|
|
840
|
-
} else if (str2.slice(-6) === "Array]") {
|
|
841
|
-
tmp = new x.constructor(x);
|
|
842
|
-
}
|
|
843
|
-
if (tmp) {
|
|
844
|
-
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
845
|
-
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
767
|
+
// src/asset.ts
|
|
768
|
+
var getType = memoize2(
|
|
769
|
+
(extensions) => {
|
|
770
|
+
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
771
|
+
return "audio";
|
|
846
772
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
773
|
+
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
774
|
+
return "image";
|
|
850
775
|
}
|
|
776
|
+
throw extensions;
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
getCacheKey: (extensions) => extensions.join("~")
|
|
851
780
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
var RGX = /{{(.*?)}}/g;
|
|
857
|
-
var split = (input, delimeters) => {
|
|
858
|
-
const output = [];
|
|
859
|
-
for (const delimeter of delimeters) {
|
|
860
|
-
if (!input) break;
|
|
861
|
-
const [start, end] = input.split(delimeter, 2);
|
|
862
|
-
output.push(start);
|
|
863
|
-
input = end;
|
|
864
|
-
}
|
|
865
|
-
output.push(input);
|
|
866
|
-
return output;
|
|
781
|
+
);
|
|
782
|
+
var SUPPORT_MAPS = {
|
|
783
|
+
image: supportsMap2,
|
|
784
|
+
audio: supportsMap
|
|
867
785
|
};
|
|
868
|
-
var
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
786
|
+
var assetPrivate = memoize2(
|
|
787
|
+
(variants) => {
|
|
788
|
+
if (DEV2 && variants.length === 0) {
|
|
789
|
+
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
790
|
+
}
|
|
791
|
+
const map = {};
|
|
792
|
+
const extensions = [];
|
|
793
|
+
for (const v of variants) {
|
|
794
|
+
const e = getUrlFileExtension(v);
|
|
795
|
+
map[e] = v;
|
|
796
|
+
extensions.push(e);
|
|
797
|
+
}
|
|
798
|
+
const type = getType(extensions);
|
|
799
|
+
const getSource = once(() => {
|
|
800
|
+
const support = SUPPORT_MAPS[type];
|
|
801
|
+
for (const extension of extensions) {
|
|
802
|
+
if (extension in support) {
|
|
803
|
+
if (support[extension]) {
|
|
804
|
+
return map[extension];
|
|
805
|
+
}
|
|
806
|
+
} else {
|
|
807
|
+
return map[extension];
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (DEV2) {
|
|
811
|
+
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
812
|
+
}
|
|
813
|
+
return "";
|
|
814
|
+
});
|
|
815
|
+
return {
|
|
816
|
+
get source() {
|
|
817
|
+
return getSource();
|
|
818
|
+
},
|
|
819
|
+
get type() {
|
|
820
|
+
return type;
|
|
821
|
+
}
|
|
822
|
+
};
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
getCacheKey: (variants) => variants.join("~")
|
|
874
826
|
}
|
|
875
|
-
|
|
827
|
+
);
|
|
828
|
+
var asset = (...variants) => {
|
|
829
|
+
return assetPrivate(variants);
|
|
876
830
|
};
|
|
877
|
-
var
|
|
878
|
-
return
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
if (plural && pluralization && y && pr) {
|
|
888
|
-
y = pluralization[plural][pr.select(y)];
|
|
831
|
+
var isAsset = (suspect) => {
|
|
832
|
+
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
// src/browser.ts
|
|
836
|
+
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
837
|
+
if (typeof document === "undefined") return noop;
|
|
838
|
+
const onVisibilityChange = () => {
|
|
839
|
+
if (document.visibilityState === "hidden") {
|
|
840
|
+
onChange();
|
|
889
841
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
842
|
+
};
|
|
843
|
+
addEventListener("visibilitychange", onVisibilityChange);
|
|
844
|
+
addEventListener("beforeunload", onChange);
|
|
845
|
+
return () => {
|
|
846
|
+
removeEventListener("visibilitychange", onVisibilityChange);
|
|
847
|
+
removeEventListener("beforeunload", onChange);
|
|
848
|
+
};
|
|
894
849
|
};
|
|
895
850
|
|
|
896
851
|
// src/custom-action.ts
|
|
@@ -933,13 +888,15 @@ var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, rem
|
|
|
933
888
|
};
|
|
934
889
|
};
|
|
935
890
|
const clear = (func) => {
|
|
936
|
-
setClear(
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
891
|
+
setClear(
|
|
892
|
+
holder.cleanup = () => {
|
|
893
|
+
func();
|
|
894
|
+
holder.node = null;
|
|
895
|
+
holder.cleanup = noop;
|
|
896
|
+
setMountElement(null);
|
|
897
|
+
setClear(noop);
|
|
898
|
+
}
|
|
899
|
+
);
|
|
943
900
|
};
|
|
944
901
|
const data = (updatedData) => {
|
|
945
902
|
if (updatedData) {
|
|
@@ -969,59 +926,23 @@ var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, rem
|
|
|
969
926
|
});
|
|
970
927
|
};
|
|
971
928
|
|
|
972
|
-
// src/storage.ts
|
|
973
|
-
var localStorageStorage = (options) => {
|
|
974
|
-
return {
|
|
975
|
-
async get() {
|
|
976
|
-
const fallback = { saves: [], data: {}, meta: [] };
|
|
977
|
-
try {
|
|
978
|
-
const value = localStorage.getItem(options.key);
|
|
979
|
-
return value ? JSON.parse(value) : fallback;
|
|
980
|
-
} catch {
|
|
981
|
-
return fallback;
|
|
982
|
-
}
|
|
983
|
-
},
|
|
984
|
-
async set(data) {
|
|
985
|
-
try {
|
|
986
|
-
localStorage.setItem(options.key, JSON.stringify(data));
|
|
987
|
-
} catch {
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
};
|
|
991
|
-
};
|
|
992
|
-
|
|
993
|
-
// src/browser.ts
|
|
994
|
-
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
995
|
-
if (typeof document === "undefined") return noop;
|
|
996
|
-
const onVisibilityChange = () => {
|
|
997
|
-
if (document.visibilityState === "hidden") {
|
|
998
|
-
onChange();
|
|
999
|
-
}
|
|
1000
|
-
};
|
|
1001
|
-
addEventListener("visibilitychange", onVisibilityChange);
|
|
1002
|
-
addEventListener("beforeunload", onChange);
|
|
1003
|
-
return () => {
|
|
1004
|
-
removeEventListener("visibilitychange", onVisibilityChange);
|
|
1005
|
-
removeEventListener("beforeunload", onChange);
|
|
1006
|
-
};
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
// src/novely.ts
|
|
1010
|
-
import pLimit from "p-limit";
|
|
1011
|
-
import { DEV as DEV3 } from "esm-env";
|
|
1012
|
-
|
|
1013
929
|
// src/preloading.ts
|
|
1014
930
|
var ACTION_NAME_TO_VOLUME_MAP = {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
931
|
+
playMusic: "music",
|
|
932
|
+
playSound: "sound",
|
|
933
|
+
voice: "voice"
|
|
1018
934
|
};
|
|
1019
935
|
var enqueueAssetForPreloading = (asset2) => {
|
|
1020
936
|
if (!PRELOADED_ASSETS.has(asset2)) {
|
|
1021
937
|
ASSETS_TO_PRELOAD.add(asset2);
|
|
1022
938
|
}
|
|
1023
939
|
};
|
|
1024
|
-
var handleAssetsPreloading = async ({
|
|
940
|
+
var handleAssetsPreloading = async ({
|
|
941
|
+
request,
|
|
942
|
+
limiter,
|
|
943
|
+
preloadAudioBlocking,
|
|
944
|
+
preloadImageBlocking
|
|
945
|
+
}) => {
|
|
1025
946
|
const list = mapSet(ASSETS_TO_PRELOAD, (asset2) => {
|
|
1026
947
|
return limiter(async () => {
|
|
1027
948
|
const type = await getResourseType({
|
|
@@ -1096,9 +1017,9 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
1096
1017
|
}
|
|
1097
1018
|
return;
|
|
1098
1019
|
}
|
|
1099
|
-
if (action === "custom" && props[0].assets
|
|
1020
|
+
if (action === "custom" && props[0].assets) {
|
|
1100
1021
|
for (const asset2 of props[0].assets) {
|
|
1101
|
-
handle(asset2);
|
|
1022
|
+
isAsset(asset2) ? handle(asset2.source) : handle(asset2);
|
|
1102
1023
|
}
|
|
1103
1024
|
return;
|
|
1104
1025
|
}
|
|
@@ -1106,12 +1027,97 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
1106
1027
|
for (let i = 1; i < props.length; i++) {
|
|
1107
1028
|
const data = props[i];
|
|
1108
1029
|
if (Array.isArray(data)) {
|
|
1109
|
-
handle(handleImageAsset(data[
|
|
1030
|
+
handle(handleImageAsset(data[5]));
|
|
1110
1031
|
}
|
|
1111
1032
|
}
|
|
1112
1033
|
}
|
|
1113
1034
|
};
|
|
1114
1035
|
|
|
1036
|
+
// src/storage.ts
|
|
1037
|
+
var localStorageStorage = (options) => {
|
|
1038
|
+
return {
|
|
1039
|
+
async get() {
|
|
1040
|
+
const fallback = { saves: [], data: {}, meta: [] };
|
|
1041
|
+
try {
|
|
1042
|
+
const value = localStorage.getItem(options.key);
|
|
1043
|
+
return value ? JSON.parse(value) : fallback;
|
|
1044
|
+
} catch {
|
|
1045
|
+
return fallback;
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
async set(data) {
|
|
1049
|
+
try {
|
|
1050
|
+
localStorage.setItem(options.key, JSON.stringify(data));
|
|
1051
|
+
} catch {
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
// src/store.ts
|
|
1058
|
+
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
1059
|
+
const subscribe = (cb) => {
|
|
1060
|
+
subscribers.add(cb), cb(current);
|
|
1061
|
+
return () => {
|
|
1062
|
+
subscribers.delete(cb);
|
|
1063
|
+
};
|
|
1064
|
+
};
|
|
1065
|
+
const push = (value) => {
|
|
1066
|
+
for (const cb of subscribers) cb(value);
|
|
1067
|
+
};
|
|
1068
|
+
const update = (fn) => {
|
|
1069
|
+
push(current = fn(current));
|
|
1070
|
+
};
|
|
1071
|
+
const set2 = (val) => {
|
|
1072
|
+
update(() => val);
|
|
1073
|
+
};
|
|
1074
|
+
const get = () => {
|
|
1075
|
+
return current;
|
|
1076
|
+
};
|
|
1077
|
+
return { subscribe, update, set: set2, get };
|
|
1078
|
+
};
|
|
1079
|
+
|
|
1080
|
+
// src/translation.ts
|
|
1081
|
+
var RGX = /{{(.*?)}}/g;
|
|
1082
|
+
var split = (input, delimeters) => {
|
|
1083
|
+
const output = [];
|
|
1084
|
+
for (const delimeter of delimeters) {
|
|
1085
|
+
if (!input) break;
|
|
1086
|
+
const [start, end] = input.split(delimeter, 2);
|
|
1087
|
+
output.push(start);
|
|
1088
|
+
input = end;
|
|
1089
|
+
}
|
|
1090
|
+
output.push(input);
|
|
1091
|
+
return output;
|
|
1092
|
+
};
|
|
1093
|
+
var flattenAllowedContent = (c, state) => {
|
|
1094
|
+
if (Array.isArray(c)) {
|
|
1095
|
+
return c.map((item) => flattenAllowedContent(item, state)).join("<br>");
|
|
1096
|
+
}
|
|
1097
|
+
if (typeof c === "function") {
|
|
1098
|
+
return flattenAllowedContent(c(state), state);
|
|
1099
|
+
}
|
|
1100
|
+
return c;
|
|
1101
|
+
};
|
|
1102
|
+
var replace = (input, data, pluralization, actions, pr) => {
|
|
1103
|
+
return input.replaceAll(RGX, (x, key, y) => {
|
|
1104
|
+
x = 0;
|
|
1105
|
+
y = data;
|
|
1106
|
+
const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
|
|
1107
|
+
if (!pathstr) {
|
|
1108
|
+
return "";
|
|
1109
|
+
}
|
|
1110
|
+
const path = pathstr.split(".");
|
|
1111
|
+
while (y && x < path.length) y = y[path[x++]];
|
|
1112
|
+
if (plural && pluralization && y && pr) {
|
|
1113
|
+
y = pluralization[plural][pr.select(y)];
|
|
1114
|
+
}
|
|
1115
|
+
const actionHandler = actions && action ? actions[action] : void 0;
|
|
1116
|
+
if (actionHandler) y = actionHandler(y);
|
|
1117
|
+
return y == null ? "" : y;
|
|
1118
|
+
});
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1115
1121
|
// src/novely.ts
|
|
1116
1122
|
var novely = ({
|
|
1117
1123
|
characters,
|
|
@@ -1238,7 +1244,9 @@ var novely = ({
|
|
|
1238
1244
|
return language;
|
|
1239
1245
|
}
|
|
1240
1246
|
if (DEV3) {
|
|
1241
|
-
throw new Error(
|
|
1247
|
+
throw new Error(
|
|
1248
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1249
|
+
);
|
|
1242
1250
|
}
|
|
1243
1251
|
throw 0;
|
|
1244
1252
|
};
|
|
@@ -1354,7 +1362,9 @@ var novely = ({
|
|
|
1354
1362
|
const restore = async (save2) => {
|
|
1355
1363
|
if (isEmpty(story)) {
|
|
1356
1364
|
if (DEV3) {
|
|
1357
|
-
throw new Error(
|
|
1365
|
+
throw new Error(
|
|
1366
|
+
"Story is empty. You should call an `enine.script` function [https://novely.pages.dev/guide/story.html]"
|
|
1367
|
+
);
|
|
1358
1368
|
}
|
|
1359
1369
|
return;
|
|
1360
1370
|
}
|
|
@@ -1374,7 +1384,10 @@ var novely = ({
|
|
|
1374
1384
|
const [path] = stack.value = latest;
|
|
1375
1385
|
renderer.ui.showScreen("game");
|
|
1376
1386
|
const { queue, skip, skipPreserve } = getActionsFromPath(story, path, false);
|
|
1377
|
-
const {
|
|
1387
|
+
const {
|
|
1388
|
+
run,
|
|
1389
|
+
keep: { keep, characters: characters2, audio: audio2 }
|
|
1390
|
+
} = createQueueProcessor(queue, {
|
|
1378
1391
|
skip,
|
|
1379
1392
|
skipPreserve
|
|
1380
1393
|
});
|
|
@@ -1424,7 +1437,9 @@ var novely = ({
|
|
|
1424
1437
|
const isSaved = () => {
|
|
1425
1438
|
const { saves } = storageData.get();
|
|
1426
1439
|
const [currentPath, currentData] = stack.value;
|
|
1427
|
-
return saves.some(
|
|
1440
|
+
return saves.some(
|
|
1441
|
+
([path, data2, [date, type2]]) => type2 === "manual" && times.has(date) && dequal(path, currentPath) && dequal(data2, currentData)
|
|
1442
|
+
);
|
|
1428
1443
|
};
|
|
1429
1444
|
if (interacted > 1 && !force && askBeforeExit && !isSaved()) {
|
|
1430
1445
|
renderer.ui.showExitPrompt();
|
|
@@ -1520,7 +1535,9 @@ var novely = ({
|
|
|
1520
1535
|
const getLanguageDisplayName = (lang) => {
|
|
1521
1536
|
const language = translation[lang];
|
|
1522
1537
|
if (DEV3 && !language) {
|
|
1523
|
-
throw new Error(
|
|
1538
|
+
throw new Error(
|
|
1539
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1540
|
+
);
|
|
1524
1541
|
}
|
|
1525
1542
|
return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
|
|
1526
1543
|
};
|
|
@@ -1629,10 +1646,12 @@ var novely = ({
|
|
|
1629
1646
|
showBackground({ ctx, push }, [background]) {
|
|
1630
1647
|
if (isString(background) || isAsset(background)) {
|
|
1631
1648
|
ctx.background({
|
|
1632
|
-
|
|
1649
|
+
all: handleImageAsset(background)
|
|
1633
1650
|
});
|
|
1634
1651
|
} else {
|
|
1635
|
-
ctx.background(
|
|
1652
|
+
ctx.background(
|
|
1653
|
+
Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, handleImageAsset(asset2)]))
|
|
1654
|
+
);
|
|
1636
1655
|
}
|
|
1637
1656
|
push();
|
|
1638
1657
|
},
|
|
@@ -1708,13 +1727,7 @@ var novely = ({
|
|
|
1708
1727
|
return c || "";
|
|
1709
1728
|
})();
|
|
1710
1729
|
ctx.clearBlockingActions("dialog");
|
|
1711
|
-
ctx.dialog(
|
|
1712
|
-
templateReplace(content, data2),
|
|
1713
|
-
templateReplace(name, data2),
|
|
1714
|
-
character,
|
|
1715
|
-
emotion,
|
|
1716
|
-
forward
|
|
1717
|
-
);
|
|
1730
|
+
ctx.dialog(templateReplace(content, data2), templateReplace(name, data2), character, emotion, forward);
|
|
1718
1731
|
},
|
|
1719
1732
|
function({ ctx, push }, [fn]) {
|
|
1720
1733
|
const { restoring, goingBack, preview: preview2 } = ctx.meta;
|
|
@@ -1740,28 +1753,33 @@ var novely = ({
|
|
|
1740
1753
|
const active$ = store(false);
|
|
1741
1754
|
const visible$ = store(false);
|
|
1742
1755
|
const update = () => {
|
|
1756
|
+
const lang = getLanguageFromStore(storageData);
|
|
1757
|
+
const state = getStateAtCtx(ctx);
|
|
1743
1758
|
const activeValue = !active || active({
|
|
1744
|
-
lang
|
|
1745
|
-
state
|
|
1759
|
+
lang,
|
|
1760
|
+
state
|
|
1746
1761
|
});
|
|
1747
1762
|
const visibleValue = !visible || visible({
|
|
1748
|
-
lang
|
|
1749
|
-
state
|
|
1763
|
+
lang,
|
|
1764
|
+
state
|
|
1750
1765
|
});
|
|
1751
1766
|
active$.set(activeValue);
|
|
1752
1767
|
visible$.set(visibleValue);
|
|
1753
1768
|
};
|
|
1754
1769
|
update();
|
|
1755
1770
|
const onSelectGuarded = onSelect || noop;
|
|
1756
|
-
const onSelectWrapped =
|
|
1757
|
-
|
|
1758
|
-
|
|
1771
|
+
const onSelectWrapped = () => {
|
|
1772
|
+
onSelectGuarded({
|
|
1773
|
+
recompute: update
|
|
1774
|
+
});
|
|
1759
1775
|
};
|
|
1760
1776
|
const imageValue = image ? handleImageAsset(image) : "";
|
|
1761
1777
|
return [templateReplace(content, data2), active$, visible$, onSelectWrapped, imageValue];
|
|
1762
1778
|
});
|
|
1763
1779
|
if (DEV3 && transformedChoices.length === 0) {
|
|
1764
|
-
throw new Error(
|
|
1780
|
+
throw new Error(
|
|
1781
|
+
`Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`
|
|
1782
|
+
);
|
|
1765
1783
|
}
|
|
1766
1784
|
ctx.clearBlockingActions("choice");
|
|
1767
1785
|
ctx.choices(templateReplace(question, data2), transformedChoices, (selected) => {
|
|
@@ -1816,7 +1834,7 @@ var novely = ({
|
|
|
1816
1834
|
if (DEV3 && variants[val].length === 0) {
|
|
1817
1835
|
throw new Error(`Attempt to go to empty variant "${val}"`);
|
|
1818
1836
|
}
|
|
1819
|
-
const stack = useStack(
|
|
1837
|
+
const stack = useStack(ctx);
|
|
1820
1838
|
stack.value[0].push(["condition", val], [null, 0]);
|
|
1821
1839
|
render(ctx);
|
|
1822
1840
|
}
|
|
@@ -1827,12 +1845,7 @@ var novely = ({
|
|
|
1827
1845
|
},
|
|
1828
1846
|
input({ ctx, data: data2, forward }, [question, onInput, setup]) {
|
|
1829
1847
|
ctx.clearBlockingActions("input");
|
|
1830
|
-
ctx.input(
|
|
1831
|
-
templateReplace(question, data2),
|
|
1832
|
-
onInput,
|
|
1833
|
-
setup || noop,
|
|
1834
|
-
forward
|
|
1835
|
-
);
|
|
1848
|
+
ctx.input(templateReplace(question, data2), onInput, setup || noop, forward);
|
|
1836
1849
|
},
|
|
1837
1850
|
custom({ ctx, push }, [fn]) {
|
|
1838
1851
|
if (fn.requireUserAction) {
|
|
@@ -1872,7 +1885,9 @@ var novely = ({
|
|
|
1872
1885
|
animateCharacter({ ctx, push }, [character, className]) {
|
|
1873
1886
|
const classes = className.split(" ");
|
|
1874
1887
|
if (DEV3 && classes.length === 0) {
|
|
1875
|
-
throw new Error(
|
|
1888
|
+
throw new Error(
|
|
1889
|
+
"Attempt to use AnimateCharacter without classes. Classes should be provided [https://novely.pages.dev/guide/actions/animateCharacter.html]"
|
|
1890
|
+
);
|
|
1876
1891
|
}
|
|
1877
1892
|
if (ctx.meta.preview) return;
|
|
1878
1893
|
ctx.character(character).animate(classes);
|
|
@@ -1906,7 +1921,9 @@ var novely = ({
|
|
|
1906
1921
|
},
|
|
1907
1922
|
preload({ ctx, push }, [source]) {
|
|
1908
1923
|
if (DEV3 && preloadAssets !== "lazy") {
|
|
1909
|
-
console.error(
|
|
1924
|
+
console.error(
|
|
1925
|
+
`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`
|
|
1926
|
+
);
|
|
1910
1927
|
}
|
|
1911
1928
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1912
1929
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
@@ -1952,21 +1969,15 @@ var novely = ({
|
|
|
1952
1969
|
interacted = value ? interacted + 1 : 0;
|
|
1953
1970
|
};
|
|
1954
1971
|
const templateReplace = (content, values) => {
|
|
1955
|
-
const {
|
|
1972
|
+
const {
|
|
1973
|
+
data: data2,
|
|
1974
|
+
meta: [lang]
|
|
1975
|
+
} = storageData.get();
|
|
1956
1976
|
const obj = values || data2;
|
|
1957
|
-
const str2 = flattenAllowedContent(
|
|
1958
|
-
!isFunction(content) && !isString(content) ? content[lang] : content,
|
|
1959
|
-
obj
|
|
1960
|
-
);
|
|
1977
|
+
const str2 = flattenAllowedContent(!isFunction(content) && !isString(content) ? content[lang] : content, obj);
|
|
1961
1978
|
const t2 = translation[lang];
|
|
1962
1979
|
const pluralRules = (t2.plural || t2.actions) && new Intl.PluralRules(t2.tag || lang);
|
|
1963
|
-
return replace(
|
|
1964
|
-
str2,
|
|
1965
|
-
obj,
|
|
1966
|
-
t2.plural,
|
|
1967
|
-
t2.actions,
|
|
1968
|
-
pluralRules
|
|
1969
|
-
);
|
|
1980
|
+
return replace(str2, obj, t2.plural, t2.actions, pluralRules);
|
|
1970
1981
|
};
|
|
1971
1982
|
const data = (value) => {
|
|
1972
1983
|
const _data = storageData.get().data;
|
|
@@ -1990,7 +2001,9 @@ var novely = ({
|
|
|
1990
2001
|
const setStorageData = (data2) => {
|
|
1991
2002
|
if (destroyed) {
|
|
1992
2003
|
if (DEV3) {
|
|
1993
|
-
throw new Error(
|
|
2004
|
+
throw new Error(
|
|
2005
|
+
`function \`setStorageData\` was called after novely instance was destroyed. Data is not updater nor synced after destroy.`
|
|
2006
|
+
);
|
|
1994
2007
|
}
|
|
1995
2008
|
return;
|
|
1996
2009
|
}
|
|
@@ -2050,7 +2063,7 @@ var novely = ({
|
|
|
2050
2063
|
* @example
|
|
2051
2064
|
* ```ts
|
|
2052
2065
|
* import type { ConditionParams, StateFunction } from '@novely/core';
|
|
2053
|
-
|
|
2066
|
+
*
|
|
2054
2067
|
* const conditionCheck = (state: StateFunction<ConditionParams<typeof engine.typeEssintials>>) => {
|
|
2055
2068
|
* return state.age >= 18;
|
|
2056
2069
|
* }
|