@patterkit/cli 0.3.7 → 0.3.9
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/cli.js +640 -336
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -105,7 +105,7 @@ var require_under_dash = __commonJS({
|
|
|
105
105
|
const bType = typeof b;
|
|
106
106
|
const aArray = Array.isArray(a);
|
|
107
107
|
const bArray = Array.isArray(b);
|
|
108
|
-
let
|
|
108
|
+
let keys2;
|
|
109
109
|
if (aType !== bType) {
|
|
110
110
|
return false;
|
|
111
111
|
}
|
|
@@ -123,11 +123,11 @@ var require_under_dash = __commonJS({
|
|
|
123
123
|
if (a === null || b === null) {
|
|
124
124
|
return a === b;
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
if (Object.keys(b).length !==
|
|
126
|
+
keys2 = Object.keys(a);
|
|
127
|
+
if (Object.keys(b).length !== keys2.length) {
|
|
128
128
|
return false;
|
|
129
129
|
}
|
|
130
|
-
for (const key2 of
|
|
130
|
+
for (const key2 of keys2) {
|
|
131
131
|
if (!b.hasOwnProperty(key2)) {
|
|
132
132
|
return false;
|
|
133
133
|
}
|
|
@@ -4908,11 +4908,11 @@ var require_stream_duplex = __commonJS({
|
|
|
4908
4908
|
"use strict";
|
|
4909
4909
|
var pna = require_process_nextick_args();
|
|
4910
4910
|
var objectKeys = Object.keys || function(obj2) {
|
|
4911
|
-
var
|
|
4911
|
+
var keys3 = [];
|
|
4912
4912
|
for (var key2 in obj2) {
|
|
4913
|
-
|
|
4913
|
+
keys3.push(key2);
|
|
4914
4914
|
}
|
|
4915
|
-
return
|
|
4915
|
+
return keys3;
|
|
4916
4916
|
};
|
|
4917
4917
|
module2.exports = Duplex;
|
|
4918
4918
|
var util2 = Object.create(require_util());
|
|
@@ -4921,13 +4921,13 @@ var require_stream_duplex = __commonJS({
|
|
|
4921
4921
|
var Writable = require_stream_writable();
|
|
4922
4922
|
util2.inherits(Duplex, Readable);
|
|
4923
4923
|
{
|
|
4924
|
-
|
|
4925
|
-
for (v = 0; v <
|
|
4926
|
-
method =
|
|
4924
|
+
keys2 = objectKeys(Writable.prototype);
|
|
4925
|
+
for (v = 0; v < keys2.length; v++) {
|
|
4926
|
+
method = keys2[v];
|
|
4927
4927
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
4928
4928
|
}
|
|
4929
4929
|
}
|
|
4930
|
-
var
|
|
4930
|
+
var keys2;
|
|
4931
4931
|
var method;
|
|
4932
4932
|
var v;
|
|
4933
4933
|
function Duplex(options) {
|
|
@@ -13820,14 +13820,14 @@ var require_buffer_list = __commonJS({
|
|
|
13820
13820
|
"../../node_modules/readable-stream/lib/internal/streams/buffer_list.js"(exports2, module2) {
|
|
13821
13821
|
"use strict";
|
|
13822
13822
|
function ownKeys2(object, enumerableOnly) {
|
|
13823
|
-
var
|
|
13823
|
+
var keys2 = Object.keys(object);
|
|
13824
13824
|
if (Object.getOwnPropertySymbols) {
|
|
13825
13825
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
13826
13826
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
13827
13827
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
13828
|
-
})),
|
|
13828
|
+
})), keys2.push.apply(keys2, symbols);
|
|
13829
13829
|
}
|
|
13830
|
-
return
|
|
13830
|
+
return keys2;
|
|
13831
13831
|
}
|
|
13832
13832
|
function _objectSpread(target) {
|
|
13833
13833
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -14747,22 +14747,22 @@ var require_stream_duplex2 = __commonJS({
|
|
|
14747
14747
|
"../../node_modules/readable-stream/lib/_stream_duplex.js"(exports2, module2) {
|
|
14748
14748
|
"use strict";
|
|
14749
14749
|
var objectKeys = Object.keys || function(obj2) {
|
|
14750
|
-
var
|
|
14751
|
-
for (var key2 in obj2)
|
|
14752
|
-
return
|
|
14750
|
+
var keys3 = [];
|
|
14751
|
+
for (var key2 in obj2) keys3.push(key2);
|
|
14752
|
+
return keys3;
|
|
14753
14753
|
};
|
|
14754
14754
|
module2.exports = Duplex;
|
|
14755
14755
|
var Readable = require_stream_readable2();
|
|
14756
14756
|
var Writable = require_stream_writable2();
|
|
14757
14757
|
require_inherits()(Duplex, Readable);
|
|
14758
14758
|
{
|
|
14759
|
-
|
|
14760
|
-
for (v = 0; v <
|
|
14761
|
-
method =
|
|
14759
|
+
keys2 = objectKeys(Writable.prototype);
|
|
14760
|
+
for (v = 0; v < keys2.length; v++) {
|
|
14761
|
+
method = keys2[v];
|
|
14762
14762
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
14763
14763
|
}
|
|
14764
14764
|
}
|
|
14765
|
-
var
|
|
14765
|
+
var keys2;
|
|
14766
14766
|
var method;
|
|
14767
14767
|
var v;
|
|
14768
14768
|
function Duplex(options) {
|
|
@@ -15141,14 +15141,14 @@ var require_from = __commonJS({
|
|
|
15141
15141
|
};
|
|
15142
15142
|
}
|
|
15143
15143
|
function ownKeys2(object, enumerableOnly) {
|
|
15144
|
-
var
|
|
15144
|
+
var keys2 = Object.keys(object);
|
|
15145
15145
|
if (Object.getOwnPropertySymbols) {
|
|
15146
15146
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
15147
15147
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
15148
15148
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
15149
|
-
})),
|
|
15149
|
+
})), keys2.push.apply(keys2, symbols);
|
|
15150
15150
|
}
|
|
15151
|
-
return
|
|
15151
|
+
return keys2;
|
|
15152
15152
|
}
|
|
15153
15153
|
function _objectSpread(target) {
|
|
15154
15154
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -29807,7 +29807,7 @@ var require_lodash2 = __commonJS({
|
|
|
29807
29807
|
return result;
|
|
29808
29808
|
}
|
|
29809
29809
|
function getAllKeys(object) {
|
|
29810
|
-
return baseGetAllKeys(object,
|
|
29810
|
+
return baseGetAllKeys(object, keys2, getSymbols);
|
|
29811
29811
|
}
|
|
29812
29812
|
function getMapData(map2, key2) {
|
|
29813
29813
|
var data = map2.__data__;
|
|
@@ -29929,7 +29929,7 @@ var require_lodash2 = __commonJS({
|
|
|
29929
29929
|
return value != null && typeof value == "object";
|
|
29930
29930
|
}
|
|
29931
29931
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
29932
|
-
function
|
|
29932
|
+
function keys2(object) {
|
|
29933
29933
|
return isArrayLike2(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
29934
29934
|
}
|
|
29935
29935
|
function stubArray() {
|
|
@@ -31263,7 +31263,7 @@ var require_lodash8 = __commonJS({
|
|
|
31263
31263
|
var baseEach = createBaseEach(baseForOwn);
|
|
31264
31264
|
var baseFor = createBaseFor();
|
|
31265
31265
|
function baseForOwn(object, iteratee) {
|
|
31266
|
-
return object && baseFor(object, iteratee,
|
|
31266
|
+
return object && baseFor(object, iteratee, keys2);
|
|
31267
31267
|
}
|
|
31268
31268
|
function baseGet(object, path) {
|
|
31269
31269
|
path = isKey(path, object) ? [path] : castPath(path);
|
|
@@ -31542,7 +31542,7 @@ var require_lodash8 = __commonJS({
|
|
|
31542
31542
|
return false;
|
|
31543
31543
|
}
|
|
31544
31544
|
function equalObjects(object, other, equalFunc, customizer, bitmask, stack2) {
|
|
31545
|
-
var isPartial = bitmask & PARTIAL_COMPARE_FLAG, objProps =
|
|
31545
|
+
var isPartial = bitmask & PARTIAL_COMPARE_FLAG, objProps = keys2(object), objLength = objProps.length, othProps = keys2(other), othLength = othProps.length;
|
|
31546
31546
|
if (objLength != othLength && !isPartial) {
|
|
31547
31547
|
return false;
|
|
31548
31548
|
}
|
|
@@ -31588,7 +31588,7 @@ var require_lodash8 = __commonJS({
|
|
|
31588
31588
|
return isKeyable(key2) ? data[typeof key2 == "string" ? "string" : "hash"] : data.map;
|
|
31589
31589
|
}
|
|
31590
31590
|
function getMatchData(object) {
|
|
31591
|
-
var result =
|
|
31591
|
+
var result = keys2(object), length = result.length;
|
|
31592
31592
|
while (length--) {
|
|
31593
31593
|
var key2 = result[length], value = object[key2];
|
|
31594
31594
|
result[length] = [key2, value, isStrictComparable(value)];
|
|
@@ -31768,7 +31768,7 @@ var require_lodash8 = __commonJS({
|
|
|
31768
31768
|
function hasIn(object, path) {
|
|
31769
31769
|
return object != null && hasPath(object, path, baseHasIn);
|
|
31770
31770
|
}
|
|
31771
|
-
function
|
|
31771
|
+
function keys2(object) {
|
|
31772
31772
|
return isArrayLike2(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
31773
31773
|
}
|
|
31774
31774
|
function identity(value) {
|
|
@@ -36918,9 +36918,9 @@ var require_legacy_streams = __commonJS({
|
|
|
36918
36918
|
this.mode = 438;
|
|
36919
36919
|
this.bufferSize = 64 * 1024;
|
|
36920
36920
|
options = options || {};
|
|
36921
|
-
var
|
|
36922
|
-
for (var index2 = 0, length =
|
|
36923
|
-
var key2 =
|
|
36921
|
+
var keys2 = Object.keys(options);
|
|
36922
|
+
for (var index2 = 0, length = keys2.length; index2 < length; index2++) {
|
|
36923
|
+
var key2 = keys2[index2];
|
|
36924
36924
|
this[key2] = options[key2];
|
|
36925
36925
|
}
|
|
36926
36926
|
if (this.encoding) this.setEncoding(this.encoding);
|
|
@@ -36966,9 +36966,9 @@ var require_legacy_streams = __commonJS({
|
|
|
36966
36966
|
this.mode = 438;
|
|
36967
36967
|
this.bytesWritten = 0;
|
|
36968
36968
|
options = options || {};
|
|
36969
|
-
var
|
|
36970
|
-
for (var index2 = 0, length =
|
|
36971
|
-
var key2 =
|
|
36969
|
+
var keys2 = Object.keys(options);
|
|
36970
|
+
for (var index2 = 0, length = keys2.length; index2 < length; index2++) {
|
|
36971
|
+
var key2 = keys2[index2];
|
|
36972
36972
|
this[key2] = options[key2];
|
|
36973
36973
|
}
|
|
36974
36974
|
if (this.start !== void 0) {
|
|
@@ -37987,11 +37987,11 @@ var require_stream_duplex3 = __commonJS({
|
|
|
37987
37987
|
"use strict";
|
|
37988
37988
|
var pna = require_process_nextick_args();
|
|
37989
37989
|
var objectKeys = Object.keys || function(obj2) {
|
|
37990
|
-
var
|
|
37990
|
+
var keys3 = [];
|
|
37991
37991
|
for (var key2 in obj2) {
|
|
37992
|
-
|
|
37992
|
+
keys3.push(key2);
|
|
37993
37993
|
}
|
|
37994
|
-
return
|
|
37994
|
+
return keys3;
|
|
37995
37995
|
};
|
|
37996
37996
|
module2.exports = Duplex;
|
|
37997
37997
|
var util2 = Object.create(require_util());
|
|
@@ -38000,13 +38000,13 @@ var require_stream_duplex3 = __commonJS({
|
|
|
38000
38000
|
var Writable = require_stream_writable3();
|
|
38001
38001
|
util2.inherits(Duplex, Readable);
|
|
38002
38002
|
{
|
|
38003
|
-
|
|
38004
|
-
for (v = 0; v <
|
|
38005
|
-
method =
|
|
38003
|
+
keys2 = objectKeys(Writable.prototype);
|
|
38004
|
+
for (v = 0; v < keys2.length; v++) {
|
|
38005
|
+
method = keys2[v];
|
|
38006
38006
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
38007
38007
|
}
|
|
38008
38008
|
}
|
|
38009
|
-
var
|
|
38009
|
+
var keys2;
|
|
38010
38010
|
var method;
|
|
38011
38011
|
var v;
|
|
38012
38012
|
function Duplex(options) {
|
|
@@ -39752,11 +39752,11 @@ var require_stream_duplex4 = __commonJS({
|
|
|
39752
39752
|
"use strict";
|
|
39753
39753
|
var pna = require_process_nextick_args();
|
|
39754
39754
|
var objectKeys = Object.keys || function(obj2) {
|
|
39755
|
-
var
|
|
39755
|
+
var keys3 = [];
|
|
39756
39756
|
for (var key2 in obj2) {
|
|
39757
|
-
|
|
39757
|
+
keys3.push(key2);
|
|
39758
39758
|
}
|
|
39759
|
-
return
|
|
39759
|
+
return keys3;
|
|
39760
39760
|
};
|
|
39761
39761
|
module2.exports = Duplex;
|
|
39762
39762
|
var util2 = Object.create(require_util());
|
|
@@ -39765,13 +39765,13 @@ var require_stream_duplex4 = __commonJS({
|
|
|
39765
39765
|
var Writable = require_stream_writable4();
|
|
39766
39766
|
util2.inherits(Duplex, Readable);
|
|
39767
39767
|
{
|
|
39768
|
-
|
|
39769
|
-
for (v = 0; v <
|
|
39770
|
-
method =
|
|
39768
|
+
keys2 = objectKeys(Writable.prototype);
|
|
39769
|
+
for (v = 0; v < keys2.length; v++) {
|
|
39770
|
+
method = keys2[v];
|
|
39771
39771
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
39772
39772
|
}
|
|
39773
39773
|
}
|
|
39774
|
-
var
|
|
39774
|
+
var keys2;
|
|
39775
39775
|
var method;
|
|
39776
39776
|
var v;
|
|
39777
39777
|
function Duplex(options) {
|
|
@@ -43509,10 +43509,10 @@ var require_glob = __commonJS({
|
|
|
43509
43509
|
if (add === null || typeof add !== "object") {
|
|
43510
43510
|
return origin;
|
|
43511
43511
|
}
|
|
43512
|
-
var
|
|
43513
|
-
var i =
|
|
43512
|
+
var keys2 = Object.keys(add);
|
|
43513
|
+
var i = keys2.length;
|
|
43514
43514
|
while (i--) {
|
|
43515
|
-
origin[
|
|
43515
|
+
origin[keys2[i]] = add[keys2[i]];
|
|
43516
43516
|
}
|
|
43517
43517
|
return origin;
|
|
43518
43518
|
}
|
|
@@ -49354,15 +49354,15 @@ var require_traverse = __commonJS({
|
|
|
49354
49354
|
if (modifiers.before) modifiers.before.call(state, state.node);
|
|
49355
49355
|
if (typeof state.node == "object" && state.node !== null && !state.circular) {
|
|
49356
49356
|
parents.push(state);
|
|
49357
|
-
var
|
|
49358
|
-
|
|
49357
|
+
var keys2 = Object.keys(state.node);
|
|
49358
|
+
keys2.forEach(function(key2, i2) {
|
|
49359
49359
|
path.push(key2);
|
|
49360
49360
|
if (modifiers.pre) modifiers.pre.call(state, state.node[key2], key2);
|
|
49361
49361
|
var child = walker(state.node[key2]);
|
|
49362
49362
|
if (immutable && Object.hasOwnProperty.call(state.node, key2)) {
|
|
49363
49363
|
state.node[key2] = child.node;
|
|
49364
49364
|
}
|
|
49365
|
-
child.isLast = i2 ==
|
|
49365
|
+
child.isLast = i2 == keys2.length - 1;
|
|
49366
49366
|
child.isFirst = i2 == 0;
|
|
49367
49367
|
if (modifiers.post) modifiers.post.call(state, child);
|
|
49368
49368
|
path.pop();
|
|
@@ -49742,12 +49742,12 @@ var require_vars = __commonJS({
|
|
|
49742
49742
|
module2.exports = function(store) {
|
|
49743
49743
|
function getset(name, value) {
|
|
49744
49744
|
var node = vars.store;
|
|
49745
|
-
var
|
|
49746
|
-
|
|
49745
|
+
var keys2 = name.split(".");
|
|
49746
|
+
keys2.slice(0, -1).forEach(function(k) {
|
|
49747
49747
|
if (node[k] === void 0) node[k] = {};
|
|
49748
49748
|
node = node[k];
|
|
49749
49749
|
});
|
|
49750
|
-
var key2 =
|
|
49750
|
+
var key2 = keys2[keys2.length - 1];
|
|
49751
49751
|
if (arguments.length == 1) {
|
|
49752
49752
|
return node[key2];
|
|
49753
49753
|
} else {
|
|
@@ -50282,14 +50282,14 @@ var require_util4 = __commonJS({
|
|
|
50282
50282
|
var ret2 = [];
|
|
50283
50283
|
var visitedKeys = /* @__PURE__ */ Object.create(null);
|
|
50284
50284
|
while (obj2 != null && !isExcludedProto(obj2)) {
|
|
50285
|
-
var
|
|
50285
|
+
var keys2;
|
|
50286
50286
|
try {
|
|
50287
|
-
|
|
50287
|
+
keys2 = getKeys(obj2);
|
|
50288
50288
|
} catch (e) {
|
|
50289
50289
|
return ret2;
|
|
50290
50290
|
}
|
|
50291
|
-
for (var i = 0; i <
|
|
50292
|
-
var key2 =
|
|
50291
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
50292
|
+
var key2 = keys2[i];
|
|
50293
50293
|
if (visitedKeys[key2]) continue;
|
|
50294
50294
|
visitedKeys[key2] = true;
|
|
50295
50295
|
var desc = Object.getOwnPropertyDescriptor(obj2, key2);
|
|
@@ -50326,9 +50326,9 @@ var require_util4 = __commonJS({
|
|
|
50326
50326
|
function isClass(fn) {
|
|
50327
50327
|
try {
|
|
50328
50328
|
if (typeof fn === "function") {
|
|
50329
|
-
var
|
|
50330
|
-
var hasMethods = es5.isES5 &&
|
|
50331
|
-
var hasMethodsOtherThanConstructor =
|
|
50329
|
+
var keys2 = es5.names(fn.prototype);
|
|
50330
|
+
var hasMethods = es5.isES5 && keys2.length > 1;
|
|
50331
|
+
var hasMethodsOtherThanConstructor = keys2.length > 0 && !(keys2.length === 1 && keys2[0] === "constructor");
|
|
50332
50332
|
var hasThisAssignmentAndStaticMethods = thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0;
|
|
50333
50333
|
if (hasMethods || hasMethodsOtherThanConstructor || hasThisAssignmentAndStaticMethods) {
|
|
50334
50334
|
return true;
|
|
@@ -50403,9 +50403,9 @@ var require_util4 = __commonJS({
|
|
|
50403
50403
|
return {}.toString.call(obj2);
|
|
50404
50404
|
}
|
|
50405
50405
|
function copyDescriptors(from, to, filter2) {
|
|
50406
|
-
var
|
|
50407
|
-
for (var i = 0; i <
|
|
50408
|
-
var key2 =
|
|
50406
|
+
var keys2 = es5.names(from);
|
|
50407
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
50408
|
+
var key2 = keys2[i];
|
|
50409
50409
|
if (filter2(key2)) {
|
|
50410
50410
|
try {
|
|
50411
50411
|
es5.defineProperty(to, key2, es5.getDescriptor(from, key2));
|
|
@@ -52207,9 +52207,9 @@ var require_catch_filter = __commonJS({
|
|
|
52207
52207
|
return tryCatch2(cb).call(boundTo, e);
|
|
52208
52208
|
}
|
|
52209
52209
|
} else if (util2.isObject(e)) {
|
|
52210
|
-
var
|
|
52211
|
-
for (var j = 0; j <
|
|
52212
|
-
var key2 =
|
|
52210
|
+
var keys2 = getKeys(item);
|
|
52211
|
+
for (var j = 0; j < keys2.length; ++j) {
|
|
52212
|
+
var key2 = keys2[j];
|
|
52213
52213
|
if (item[key2] != e[key2]) {
|
|
52214
52214
|
continue predicateLoop;
|
|
52215
52215
|
}
|
|
@@ -52245,9 +52245,9 @@ var require_nodeback = __commonJS({
|
|
|
52245
52245
|
ret2.name = obj2.name;
|
|
52246
52246
|
ret2.message = obj2.message;
|
|
52247
52247
|
ret2.stack = obj2.stack;
|
|
52248
|
-
var
|
|
52249
|
-
for (var i = 0; i <
|
|
52250
|
-
var key2 =
|
|
52248
|
+
var keys2 = es52.keys(obj2);
|
|
52249
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
52250
|
+
var key2 = keys2[i];
|
|
52251
52251
|
if (!rErrorKey.test(key2)) {
|
|
52252
52252
|
ret2[key2] = obj2[key2];
|
|
52253
52253
|
}
|
|
@@ -52993,9 +52993,9 @@ var require_call_get = __commonJS({
|
|
|
52993
52993
|
cache2[name] = ret2;
|
|
52994
52994
|
cache2[" size"]++;
|
|
52995
52995
|
if (cache2[" size"] > 512) {
|
|
52996
|
-
var
|
|
52997
|
-
for (var i = 0; i < 256; ++i) delete cache2[
|
|
52998
|
-
cache2[" size"] =
|
|
52996
|
+
var keys2 = Object.keys(cache2);
|
|
52997
|
+
for (var i = 0; i < 256; ++i) delete cache2[keys2[i]];
|
|
52998
|
+
cache2[" size"] = keys2.length - 256;
|
|
52999
52999
|
}
|
|
53000
53000
|
}
|
|
53001
53001
|
return ret2;
|
|
@@ -53714,10 +53714,10 @@ var require_promisify = __commonJS({
|
|
|
53714
53714
|
}
|
|
53715
53715
|
}
|
|
53716
53716
|
function promisifiableMethods(obj2, suffix, suffixRegexp, filter2) {
|
|
53717
|
-
var
|
|
53717
|
+
var keys2 = util2.inheritedDataKeys(obj2);
|
|
53718
53718
|
var ret2 = [];
|
|
53719
|
-
for (var i = 0; i <
|
|
53720
|
-
var key2 =
|
|
53719
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
53720
|
+
var key2 = keys2[i];
|
|
53721
53721
|
var value = obj2[key2];
|
|
53722
53722
|
var passesDefaultFilter = filter2 === defaultFilter ? true : defaultFilter(key2, value, obj2);
|
|
53723
53723
|
if (typeof value === "function" && !isPromisified(value) && !hasPromisified(obj2, key2, suffix) && filter2(key2, value, obj2, passesDefaultFilter)) {
|
|
@@ -53904,10 +53904,10 @@ var require_promisify = __commonJS({
|
|
|
53904
53904
|
if (!util2.isIdentifier(suffix)) {
|
|
53905
53905
|
throw new RangeError("suffix must be a valid identifier\n\n See http://goo.gl/MqrFmX\n");
|
|
53906
53906
|
}
|
|
53907
|
-
var
|
|
53908
|
-
for (var i = 0; i <
|
|
53909
|
-
var value = target[
|
|
53910
|
-
if (
|
|
53907
|
+
var keys2 = util2.inheritedDataKeys(target);
|
|
53908
|
+
for (var i = 0; i < keys2.length; ++i) {
|
|
53909
|
+
var value = target[keys2[i]];
|
|
53910
|
+
if (keys2[i] !== "constructor" && util2.isClass(value)) {
|
|
53911
53911
|
promisifyAll(
|
|
53912
53912
|
value.prototype,
|
|
53913
53913
|
suffix,
|
|
@@ -53967,11 +53967,11 @@ var require_props = __commonJS({
|
|
|
53967
53967
|
entries = mapToEntries(obj2);
|
|
53968
53968
|
isMap = true;
|
|
53969
53969
|
} else {
|
|
53970
|
-
var
|
|
53971
|
-
var len =
|
|
53970
|
+
var keys2 = es52.keys(obj2);
|
|
53971
|
+
var len = keys2.length;
|
|
53972
53972
|
entries = new Array(len * 2);
|
|
53973
53973
|
for (var i = 0; i < len; ++i) {
|
|
53974
|
-
var key2 =
|
|
53974
|
+
var key2 = keys2[i];
|
|
53975
53975
|
entries[i] = obj2[key2];
|
|
53976
53976
|
entries[i + len] = key2;
|
|
53977
53977
|
}
|
|
@@ -55796,11 +55796,11 @@ var require_stream_duplex5 = __commonJS({
|
|
|
55796
55796
|
"use strict";
|
|
55797
55797
|
var pna = require_process_nextick_args();
|
|
55798
55798
|
var objectKeys = Object.keys || function(obj2) {
|
|
55799
|
-
var
|
|
55799
|
+
var keys3 = [];
|
|
55800
55800
|
for (var key2 in obj2) {
|
|
55801
|
-
|
|
55801
|
+
keys3.push(key2);
|
|
55802
55802
|
}
|
|
55803
|
-
return
|
|
55803
|
+
return keys3;
|
|
55804
55804
|
};
|
|
55805
55805
|
module2.exports = Duplex;
|
|
55806
55806
|
var util2 = Object.create(require_util());
|
|
@@ -55809,13 +55809,13 @@ var require_stream_duplex5 = __commonJS({
|
|
|
55809
55809
|
var Writable = require_stream_writable5();
|
|
55810
55810
|
util2.inherits(Duplex, Readable);
|
|
55811
55811
|
{
|
|
55812
|
-
|
|
55813
|
-
for (v = 0; v <
|
|
55814
|
-
method =
|
|
55812
|
+
keys2 = objectKeys(Writable.prototype);
|
|
55813
|
+
for (v = 0; v < keys2.length; v++) {
|
|
55814
|
+
method = keys2[v];
|
|
55815
55815
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
55816
55816
|
}
|
|
55817
55817
|
}
|
|
55818
|
-
var
|
|
55818
|
+
var keys2;
|
|
55819
55819
|
var method;
|
|
55820
55820
|
var v;
|
|
55821
55821
|
function Duplex(options) {
|
|
@@ -57708,11 +57708,11 @@ var require_stream_duplex6 = __commonJS({
|
|
|
57708
57708
|
"use strict";
|
|
57709
57709
|
var pna = require_process_nextick_args();
|
|
57710
57710
|
var objectKeys = Object.keys || function(obj2) {
|
|
57711
|
-
var
|
|
57711
|
+
var keys3 = [];
|
|
57712
57712
|
for (var key2 in obj2) {
|
|
57713
|
-
|
|
57713
|
+
keys3.push(key2);
|
|
57714
57714
|
}
|
|
57715
|
-
return
|
|
57715
|
+
return keys3;
|
|
57716
57716
|
};
|
|
57717
57717
|
module2.exports = Duplex;
|
|
57718
57718
|
var util2 = Object.create(require_util());
|
|
@@ -57721,13 +57721,13 @@ var require_stream_duplex6 = __commonJS({
|
|
|
57721
57721
|
var Writable = require_stream_writable6();
|
|
57722
57722
|
util2.inherits(Duplex, Readable);
|
|
57723
57723
|
{
|
|
57724
|
-
|
|
57725
|
-
for (v = 0; v <
|
|
57726
|
-
method =
|
|
57724
|
+
keys2 = objectKeys(Writable.prototype);
|
|
57725
|
+
for (v = 0; v < keys2.length; v++) {
|
|
57726
|
+
method = keys2[v];
|
|
57727
57727
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
57728
57728
|
}
|
|
57729
57729
|
}
|
|
57730
|
-
var
|
|
57730
|
+
var keys2;
|
|
57731
57731
|
var method;
|
|
57732
57732
|
var v;
|
|
57733
57733
|
function Duplex(options) {
|
|
@@ -64001,7 +64001,7 @@ var require_fast_deep_equal = __commonJS({
|
|
|
64001
64001
|
if (a === b) return true;
|
|
64002
64002
|
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
64003
64003
|
if (a.constructor !== b.constructor) return false;
|
|
64004
|
-
var length, i,
|
|
64004
|
+
var length, i, keys2;
|
|
64005
64005
|
if (Array.isArray(a)) {
|
|
64006
64006
|
length = a.length;
|
|
64007
64007
|
if (length != b.length) return false;
|
|
@@ -64012,13 +64012,13 @@ var require_fast_deep_equal = __commonJS({
|
|
|
64012
64012
|
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
|
64013
64013
|
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
|
|
64014
64014
|
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
|
|
64015
|
-
|
|
64016
|
-
length =
|
|
64015
|
+
keys2 = Object.keys(a);
|
|
64016
|
+
length = keys2.length;
|
|
64017
64017
|
if (length !== Object.keys(b).length) return false;
|
|
64018
64018
|
for (i = length; i-- !== 0; )
|
|
64019
|
-
if (!Object.prototype.hasOwnProperty.call(b,
|
|
64019
|
+
if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false;
|
|
64020
64020
|
for (i = length; i-- !== 0; ) {
|
|
64021
|
-
var key2 =
|
|
64021
|
+
var key2 = keys2[i];
|
|
64022
64022
|
if (!equal(a[key2], b[key2])) return false;
|
|
64023
64023
|
}
|
|
64024
64024
|
return true;
|
|
@@ -191986,9 +191986,9 @@ var stringify = function stringify2(value, replacer2, space) {
|
|
|
191986
191986
|
stack2.push(value2);
|
|
191987
191987
|
let stepback = indent;
|
|
191988
191988
|
indent = indent + gap;
|
|
191989
|
-
let
|
|
191989
|
+
let keys2 = propertyList || Object.keys(value2);
|
|
191990
191990
|
let partial = [];
|
|
191991
|
-
for (const key2 of
|
|
191991
|
+
for (const key2 of keys2) {
|
|
191992
191992
|
const propertyString = serializeProperty(key2, value2);
|
|
191993
191993
|
if (propertyString !== void 0) {
|
|
191994
191994
|
let member = serializeKey(key2) + ":";
|
|
@@ -192151,8 +192151,8 @@ function tokenise(src) {
|
|
|
192151
192151
|
while (i < src.length && src[i] !== quote) {
|
|
192152
192152
|
if (src[i] === "\\" && i + 1 < src.length) {
|
|
192153
192153
|
i++;
|
|
192154
|
-
const
|
|
192155
|
-
s +=
|
|
192154
|
+
const esc3 = { n: "\n", t: " ", r: "\r", "\\": "\\", "'": "'", '"': '"' };
|
|
192155
|
+
s += esc3[src[i]] ?? src[i];
|
|
192156
192156
|
} else {
|
|
192157
192157
|
s += src[i];
|
|
192158
192158
|
}
|
|
@@ -193141,6 +193141,13 @@ function castStringKey(name) {
|
|
|
193141
193141
|
}
|
|
193142
193142
|
var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
|
|
193143
193143
|
var DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
193144
|
+
var SAVE_VERSION = 3;
|
|
193145
|
+
|
|
193146
|
+
// ../core/src/noderefs.ts
|
|
193147
|
+
var VISIT_FN_RE = /\b(patter_visits|patter_seen|visits|seen)\s*\(\s*(?:(['"])(.*?)\2|([A-Za-z_]\w*))\s*\)/g;
|
|
193148
|
+
function humanizeNodeRefs(cond, label) {
|
|
193149
|
+
return cond.replace(VISIT_FN_RE, (_m, fn, _q, quoted, bare) => `${fn}(${label(quoted ?? bare ?? "")})`);
|
|
193150
|
+
}
|
|
193144
193151
|
|
|
193145
193152
|
// ../core/src/serialize.ts
|
|
193146
193153
|
function canonicalStringify(value, opts) {
|
|
@@ -193160,10 +193167,10 @@ ${indent}]`;
|
|
|
193160
193167
|
}
|
|
193161
193168
|
if (typeof v === "object") {
|
|
193162
193169
|
const obj2 = v;
|
|
193163
|
-
const
|
|
193164
|
-
if (
|
|
193170
|
+
const keys2 = Object.keys(obj2).filter((k) => obj2[k] !== void 0).sort();
|
|
193171
|
+
if (keys2.length === 0) return "{}";
|
|
193165
193172
|
const next = indent + " ";
|
|
193166
|
-
const entries =
|
|
193173
|
+
const entries = keys2.map((k) => `${next}${JSON.stringify(k)}: ${write(obj2[k], next, tc)}`);
|
|
193167
193174
|
return `{
|
|
193168
193175
|
${entries.join(",\n")}${tail}
|
|
193169
193176
|
${indent}}`;
|
|
@@ -194040,6 +194047,12 @@ function checkDuplicateIds(root2, conflicts) {
|
|
|
194040
194047
|
var idMap = (nodes) => new Map(nodes.filter((n) => n.id).map((n) => [n.id, n]));
|
|
194041
194048
|
var arrEq = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
|
|
194042
194049
|
|
|
194050
|
+
// ../dialect/src/engine-scopes.ts
|
|
194051
|
+
var ENGINE_SCOPES = [
|
|
194052
|
+
{ token: "patter", engine: "Patterplay", means: "Patter's shared globals" },
|
|
194053
|
+
{ token: "story", engine: "Storylet Engine", means: "the Storylet Engine's shared @story properties" }
|
|
194054
|
+
];
|
|
194055
|
+
|
|
194043
194056
|
// ../dialect/src/index.ts
|
|
194044
194057
|
function host(h) {
|
|
194045
194058
|
return h.ctx.host ?? {};
|
|
@@ -194137,8 +194150,15 @@ var patterDialect = {
|
|
|
194137
194150
|
}
|
|
194138
194151
|
}
|
|
194139
194152
|
};
|
|
194140
|
-
|
|
194141
|
-
|
|
194153
|
+
var EXTERNAL_SCOPES = ENGINE_SCOPES.map((s) => s.token).filter((t) => t !== "patter" && t !== "scene");
|
|
194154
|
+
function withEngineScopes(spec) {
|
|
194155
|
+
const present = new Set((spec?.scopes ?? []).map((s) => s.token));
|
|
194156
|
+
const extra = EXTERNAL_SCOPES.filter((t) => !present.has(t)).map((token2) => ({ token: token2 }));
|
|
194157
|
+
return { version: spec?.version ?? 1, scopes: [...spec?.scopes ?? [], ...extra] };
|
|
194158
|
+
}
|
|
194159
|
+
function dialectWithForeignScopes(given) {
|
|
194160
|
+
const spec = withEngineScopes(given);
|
|
194161
|
+
if (spec.scopes.length === 0) return patterDialect;
|
|
194142
194162
|
const known = new Set(patterDialect.scopes.map((s) => s.token));
|
|
194143
194163
|
const extra = spec.scopes.filter((s) => !known.has(s.token)).map((s) => ({ token: s.token }));
|
|
194144
194164
|
if (extra.length === 0) return patterDialect;
|
|
@@ -194377,7 +194397,7 @@ function compileExpression(src, foreign) {
|
|
|
194377
194397
|
}
|
|
194378
194398
|
function validateConditions(input, options = {}) {
|
|
194379
194399
|
const issues = [];
|
|
194380
|
-
const foreign = options.foreignScopes;
|
|
194400
|
+
const foreign = withEngineScopes(options.foreignScopes);
|
|
194381
194401
|
const dialect = dialectWithForeignScopes(foreign);
|
|
194382
194402
|
const readOnly = readOnlyForeignTargets(foreign);
|
|
194383
194403
|
const opaqueForeign = opaqueForeignTokens(foreign);
|
|
@@ -194472,10 +194492,11 @@ function validateInterpolation(input, options = {}) {
|
|
|
194472
194492
|
const voiced = input.project.voiced ?? false;
|
|
194473
194493
|
const tables = (input.locales ?? []).map((l2) => ({ locale: l2.locale, strings: l2.strings }));
|
|
194474
194494
|
const defaultLocale = input.project.locales.default;
|
|
194475
|
-
const
|
|
194476
|
-
const
|
|
194495
|
+
const foreign = withEngineScopes(options.foreignScopes);
|
|
194496
|
+
const opaqueForeign = opaqueForeignTokens(foreign);
|
|
194497
|
+
const isScopeToken = scopeTokenTest(foreign);
|
|
194477
194498
|
for (const scene of input.scenes) {
|
|
194478
|
-
const schema = buildSchema(input.project, scene.sceneProps,
|
|
194499
|
+
const schema = buildSchema(input.project, scene.sceneProps, foreign);
|
|
194479
194500
|
const known = (ref) => {
|
|
194480
194501
|
const { scope, name } = splitRef(ref, isScopeToken);
|
|
194481
194502
|
if (opaqueForeign.has(scope)) return true;
|
|
@@ -194638,11 +194659,33 @@ function compileScene(scene, foreign) {
|
|
|
194638
194659
|
blocks: scene.blocks.map((b) => compileBlock(b, foreign))
|
|
194639
194660
|
};
|
|
194640
194661
|
}
|
|
194662
|
+
function externalScopesIn(scenes) {
|
|
194663
|
+
const found = /* @__PURE__ */ new Set();
|
|
194664
|
+
const external = new Set(EXTERNAL_SCOPES);
|
|
194665
|
+
const walk2 = (node) => {
|
|
194666
|
+
if (!Array.isArray(node) && (node === null || typeof node !== "object")) return;
|
|
194667
|
+
if (Array.isArray(node)) {
|
|
194668
|
+
if (node[0] === "sv" && typeof node[1] === "string" && external.has(node[1])) found.add(node[1]);
|
|
194669
|
+
for (const n of node) walk2(n);
|
|
194670
|
+
return;
|
|
194671
|
+
}
|
|
194672
|
+
const o = node;
|
|
194673
|
+
if (o["kind"] === "set" && typeof o["target"] === "string") {
|
|
194674
|
+
const head = o["target"].replace(/^@/, "").split(".")[0];
|
|
194675
|
+
if (o["target"].includes(".") && external.has(head)) found.add(head);
|
|
194676
|
+
}
|
|
194677
|
+
for (const v of Object.values(o)) walk2(v);
|
|
194678
|
+
};
|
|
194679
|
+
walk2(scenes);
|
|
194680
|
+
return [...found].sort();
|
|
194681
|
+
}
|
|
194641
194682
|
function exportBundle(input) {
|
|
194642
194683
|
const { project, scenes, locales = [], includeLocales } = input;
|
|
194643
194684
|
const foreignScopes = input.foreignScopes ?? hostScopesToSpec(project.scopeRegistry);
|
|
194685
|
+
const compileScopes = withEngineScopes(foreignScopes);
|
|
194644
194686
|
const scenesOut = {};
|
|
194645
|
-
for (const scene of scenes) scenesOut[scene.id] = compileScene(scene,
|
|
194687
|
+
for (const scene of scenes) scenesOut[scene.id] = compileScene(scene, compileScopes);
|
|
194688
|
+
const externalScopes = externalScopesIn(scenesOut);
|
|
194646
194689
|
const strings = {};
|
|
194647
194690
|
for (const loc of locales) {
|
|
194648
194691
|
if (includeLocales && !includeLocales.includes(loc.locale)) continue;
|
|
@@ -194698,7 +194741,9 @@ function exportBundle(input) {
|
|
|
194698
194741
|
// runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
|
|
194699
194742
|
...project.closedCaptions ? { closedCaptions: project.closedCaptions } : {},
|
|
194700
194743
|
scenes: scenesOut,
|
|
194701
|
-
strings
|
|
194744
|
+
strings,
|
|
194745
|
+
// Other engines' scopes the content names, so the engine can say when the game has not registered one.
|
|
194746
|
+
...externalScopes.length > 0 ? { externalScopes } : {}
|
|
194702
194747
|
};
|
|
194703
194748
|
}
|
|
194704
194749
|
|
|
@@ -195011,7 +195056,7 @@ function bundleOutputPath(loaded) {
|
|
|
195011
195056
|
}
|
|
195012
195057
|
|
|
195013
195058
|
// ../ops/src/playable-runtime.ts
|
|
195014
|
-
var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var V=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var ve=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var we=(n,e)=>{for(var t in e)V(n,t,{get:e[t],enumerable:!0})},xe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ve(e))!be.call(n,s)&&s!==t&&V(n,s,{get:()=>e[s],enumerable:!(r=ye(e,s))||r.enumerable});return n};var Ee=n=>xe(V({},"__esModule",{value:!0}),n);var Le={};we(Le,{Engine:()=>F,Flow:()=>C,buildTagIndex:()=>A,describeBundle:()=>ue,effectiveGameData:()=>fe,gameDataFields:()=>he,gameDataValue:()=>K});function w(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:w(n[2])};case"bin":return{kind:"binary",op:n[1],left:w(n[2]),right:w(n[3])};case"call":{let e=n.slice(2).map(w);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var l=class extends Error{constructor(e){super(e),this.name="EvalError"}};function B(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new l(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new l(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=M(a,e);if(c===void 0)throw new l("advance() needs a quality reference (@scope.name of a quality property)");let d=y(s(a),c,"advance");return c[Math.min(d+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new l(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new l("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new l(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new l(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'and\' requires boolean operands, left is ${typeof u}`);if(!u)return!1;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'and\' requires boolean operands, right is ${typeof f}`);return f}if(i.op==="or"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'or\' requires boolean operands, left is ${typeof u}`);if(u)return!0;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'or\' requires boolean operands, right is ${typeof f}`);return f}let o=s(i.left),a=s(i.right),c=M(i.left,e),d=M(i.right,e),p=c??d;if(p!==void 0){if(c&&d&&!ke(c,d)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new l(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return y(o,p,">")>y(a,p,">");case">=":return y(o,p,">=")>=y(a,p,">=");case"<":return y(o,p,"<")<y(a,p,"<");case"<=":return y(o,p,"<=")<=y(a,p,"<=");case"+":case"-":case"*":case"/":throw new l(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return Z(o,a);case"!=":return!Z(o,a);case">":return x(o,a,">"),o>a;case">=":return x(o,a,">="),o>=a;case"<":return x(o,a,"<"),o<a;case"<=":return x(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new l(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return x(o,a,"-"),o-a;case"*":return x(o,a,"*"),o*a;case"/":if(x(o,a,"/"),a===0)throw new l("division by zero");return o/a}}}};return s(n)}function Z(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;let t=[...n].sort(),r=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==r[s])return!1;return!0}return n===e}function x(n,e,t){if(typeof n!="number"||typeof e!="number")throw new l(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function M(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function y(n,e,t){if(typeof n!="string")throw new l(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new l(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var ke=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function I(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function j(n){let e=I(n);return{next(){e=e+1831565813>>>0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296},state(){return e}}}var Ce={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ie=[Ce];function Q(n,e,t){let r=t?.countingCalls??Ie;return P(n,t?.want??!0,e,r)}function P(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=P(n.left,e,t,r),i=P(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return P(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var b=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",this.seed(e)}seed(e){for(let t of e){let r=this.norm(t.name);this.decls.set(r,t),this.values[r]=structuredClone(t.default??E(t))}}get(e){return this.values[this.norm(e)]}set(e,t,r){let s=this.norm(e);if(!r?.host&&this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=t;for(let o of this.auditors)o(i);if(!i.silent)for(let o of this.subscribers)o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>ee(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm,pathPrefix:this.pathPrefix});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e){for(let[t,r]of Object.entries(e))this.values[this.norm(t)]=r}};function ee(n,e,t,r,s=""){let i=r??n.name.toLowerCase();return{name:i,path:s+i,type:n.type,value:e,default:n.default??E(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var $=1,D=class{scopes=new Map;defineOwned(e,t,r){return this.mountOwned(e,new b(t,{pathPrefix:r??`${e}.`}))}mountOwned(e,t){return this.assertFree(e),this.scopes.set(e,{kind:"owned",bag:t}),this}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,r=[],s=!0){this.assertFree(e);let i=new Map;for(let o of r)i.set(o.name.toLowerCase(),o);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:i,scopeWritable:s}),this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(r)return r.kind==="owned"?r.bag.get(t):r.resolver.get(t.toLowerCase())}set(e,t,r,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){try{i.bag.set(t,r,s?.host?{host:!0}:void 0)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let o=t.toLowerCase();if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes)if(r.kind==="owned")for(let s of r.bag.rows())e.push({scope:t,...s});else for(let s of r.decls.values())e.push({scope:t,...ee(s,r.resolver.get(s.name.toLowerCase()),this.foreignWritable(r,s.name.toLowerCase()),void 0,`${t}.`)});return e}toEvalContext(e){let t={};for(let[s,i]of this.scopes)t[s]=i.kind==="owned"?i.bag.values:i.resolver;let r=this.qualityLadders();return r.size===0?{scopes:t,host:e}:{scopes:t,host:e,qualities:(s,i)=>r.get(s)?.get(i.toLowerCase())}}qualityLadders(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];for(let i of s){if(i.type!=="quality"||i.stages===void 0)continue;let o=e.get(t);o||(o=new Map,e.set(t,o)),o.set(i.name.toLowerCase(),i.stages)}}return e}toSchema(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];if(s.length===0)continue;let i=new Map;for(let o of s)i.set(o.name.toLowerCase(),{type:o.type,enumValues:o.values,...o.stages!==void 0?{stages:o.stages}:{}});e.set(t,i)}return{properties:e}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());return e}load(e){for(let[t,r]of Object.entries(e)){let s=this.scopes.get(t);s?.kind==="owned"&&s.bag.load(r)}}saveFragment(){return{version:$,scopes:this.save()}}loadFragment(e){if(e.version!==$)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${$})`);this.load(e.scopes)}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function E(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??"";default:return!1}}function R(n){return n.ctx.host??{}}var q={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new l("random(a, b) requires exactly 2 arguments");let t=R(e).nextRandom;if(!t)throw new l("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new l("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new l("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:re("check_flags"),eval(n,e){let t=te(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:re("set_flags"),eval(n,e){let t=[...te(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("visits"),eval:(n,e)=>R(e).visits?.(O(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("seen"),eval:(n,e)=>(R(e).visits?.(O(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("patter_visits"),eval:(n,e)=>R(e).patterVisits?.(O(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("patter_seen"),eval:(n,e)=>(R(e).patterVisits?.(O(n,e,"patter_seen"))??0)>0}}};function H(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function O(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new l(`${t}(id) requires a string node id`);return r}function N(n){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function te(n,e,t){if(!n)throw new l(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new l(`${t}() first argument must be a flags property`)}function re(n){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var De=/^@[A-Za-z0-9_.]+$/;function*Re(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:De.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function Be(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function Pe(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function Oe(n){let e="",t=!1;for(let r of n){if(Pe(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function ne(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?Oe(r):n}function se(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Re(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":Be(s)}return t}function k(n,e){for(let t of n){e(t);let r=t.children;r&&k(r,e)}}function Ne(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function h(n){let e=n.gameId?.trim();return e||Ne(n.name)}function _(n){return`cast:${n}`}var U={open:"[",close:"]"},ie="SFX";function T(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function A(n){let e=new Map,t=(r,s)=>{let i=T([...s,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,T([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=T(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=T([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var oe=new WeakMap,F=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let d=new Map;for(let g of e.cast??[])g.displayName&&d.set(g.name,g.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let p=new Map,u=new Map,f=new Map;for(let[g,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(h(m),g);let v=new Map;for(let S of m.blocks)u.set(S.id,{sceneId:g}),f.set(S.id,S),v.set(h(S),S.id),k(S.children,X=>p.set(X.id,X));this.blockGameIdToId.set(g,v)}let J=e.properties??[],G=J.filter(g=>g.shared??!0).map(ce),me=J.filter(g=>!(g.shared??!0)).map(ce),Se=new Set(G.map(g=>g.name.toLowerCase())),L=new D().defineOwned("patter",G,"@patter."),z=new Set;if(t.world){let g=e.scopeRegistry?.scopes.find(v=>v.token==="world"),m=(g?.declarations??[]).map(le);L.defineForeign("world",t.world,m,g?.writable??!0),z.add("world")}for(let g of e.scopeRegistry?.scopes??[]){if(z.has(g.token))continue;let m=(g.declarations??[]).map(le);L.defineForeign(g.token,Te(g.declarations??[]),m,g.writable??!0)}let Y=new Map;for(let[g,m]of Object.entries(e.scenes)){let v=new Set((m.sceneProps??[]).filter(S=>S.shared??!1).map(S=>S.name.toLowerCase()));Y.set(g,v)}this.host={logEnabled:t.log??!1,emitEngine:(g,m,v)=>this.emitEngine(g,m,v),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:d,nodeIndex:p,blockIndex:u,blockById:f,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:A(e),shared:L,patterSharedDecls:G,patterLocalDecls:me,patterSharedNames:Se,sceneSharedNames:Y,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??U).open,captionClose:(e.closedCaptions??U).close,captionCharacter:e.closedCaptions?.character||ie,refSplitCache:new Map}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),s=new n(e,this.creationOptions);try{return s.loadGame(t),r(s)}catch{let i=new n(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let c=a.cursor.currentSceneId;try{i.openFlow(o,c!==null?{scene:c}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){let r=this.resolveSceneRef(t.scene),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new C(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.advanceToStop().played}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?h(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?h(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)ae(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return ae(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...h(e)?{gameId:h(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...h(t)?{gameId:h(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)k(r.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let s=this.host.defaultStrings[_(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}listBags(){let e=[{bag:this.host.shared.ownedBag("patter")}];for(let[t,r]of this.host.stageBags)e.push({bag:r,pathPrefix:`@scene:${t}.`});return e}closeFlow(e){this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.shared.reseedOwned("patter",this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear(),this.host.stageBags.clear()}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitShared(e);this.host.shared.set(r,s,t,{host:!0})}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),()=>this.engineTraceHandlers.delete(e)}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineLog.length,...r?{scene:r}:{}})}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:E(e),writable:e.writable??!0}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=H(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return this.host.shared.save()}load(e){this.host.shared.load(e)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:2,shared:this.host.shared.save(),sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:de(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,r.save()])),flows:e}}loadGame(e){if(e.version!==2)throw new Error(`unsupported save version: ${e.version}`);this.host.shared.load(e.shared),this.host.sharedVisits.clear();for(let[t,r]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(t,r);this.host.sharedSelectors.clear();for(let[t,r]of ge(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{})){let s=this.host.sceneSharedNames.get(t)??new Set,i=(this.host.bundle.scenes[t]?.sceneProps??[]).filter(a=>s.has(a.name.toLowerCase())),o=new b(i);o.load(r),this.host.stageBags.set(t,o)}this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let s=new C(t,this.host,this.defaultSeed);s.restore(r),this.flowsById.set(t,s)}}},C=class{id;host;local;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.shared.get("patter",e):this.local.get("patter",e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.shared.set("patter",e,t):this.local.set("patter",e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;return t===null?void 0:(this.host.sceneSharedNames.get(t)?.has(e)?this.host.stageBags.get(t):this.sceneBags.get(t))?.get(e)},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);s&&s.set(e,t)}};evalCtx;flowLog=[];flowSeq=0;constructor(e,t,r){this.id=e,this.host=t,this.rngState=I(r),this.local=this.freshLocal();let s={...t.shared.toEvalContext().scopes};s.patter=this.patterResolver,s.scene=this.sceneResolver,this.evalCtx={scopes:s,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0},qualities:(i,o)=>this.stagesFor(i,o)}}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}start(e,t){if(this.sceneBags.clear(),this.local=this.freshLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}goto(e,t){if(this.closed)return!1;if(e==="END")return this.started=!0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=this.host.sceneGameIdToId.get(e)??(this.host.bundle.scenes[e]?e:void 0);if(r===void 0)return!1;let s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===void 0)?!1:this.started?(this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.start(r,s),!0)}close(){this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end"};if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}let s=t.index;for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(this.host.logEnabled&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:r[t.index]?.id??null}),t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}listBags(){let e=[{bag:this.local.ownedBag("patter"),pathPrefix:`${this.id}/@patter.`}];for(let[t,r]of this.sceneBags)e.push({bag:r,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let s=t.byId.get(e);this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.shared.get(t,r)}setProperty(e,t){this.writeProperty(e,t,!0)}writeProperty(e,t,r){let{scope:s,name:i}=this.splitRef(e);if(s==="patter")this.patterResolver.set(i,t);else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(i,t)}else this.host.shared.set(s,i,t,r?{host:!0}:void 0)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,t.save()])),rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:de(this.selectors)}}}restore(e){this.rngState=I(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;if(this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,s])=>{let i=this.host.sceneSharedNames.get(r)??new Set,o=(this.host.bundle.scenes[r]?.sceneProps??[]).filter(c=>!i.has(c.name.toLowerCase())),a=new b(o);return a.load(s),[r,a]})),this.local=this.freshLocal(),this.local.load(e.scopes),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=ge(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter(c=>this.eligible(c)),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(r[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(r,i,a):s==="specificity"?this.pickSpecificity(r,i,a):this.pickSequential(r,i,a));default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(u=>u.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let u=e[s-1];return r.last=u.id,u}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,d=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&d>=c&&d++;let p=a[d];return a.splice(d,1),r.last=p,e.find(u=>u.id===p)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(p=>p.id));let d=new Set(r.bag);if(s=e.filter(p=>d.has(p.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(p=>p.id===r.last)??null:null}let i=-1,a=s.map(d=>{let p=this.specScore(d);return p>i&&(i=p),{c:d,s:p}}).filter(d=>d.s===i).map(d=>d.c),c;if(a.length===1)c=a[0];else{let d=r.last!==void 0?a.findIndex(u=>u.id===r.last):-1,p=Math.floor(this.rng()*(d>=0?a.length-1:a.length));d>=0&&p>=d&&p++,c=a[p]}return t!=="repeat"&&(r.bag=r.bag.filter(d=>d!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return Q(e,s=>pe(B(s,this.evalCtx,q)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[]){let r=this.evalExpr(t.value),s=this.host.logEnabled?this.getProperty(t.target):void 0;this.writeProperty(t.target,r,!1),this.emit({type:"write",target:t.target,value:r,...s!==void 0?{prev:s}:{}})}}eligible(e){return e.condition?pe(this.evalExpr(e.condition)):!0}evalExpr(e){return B(this.conditionAst(e),this.evalCtx,q)}conditionAst(e){let t=oe.get(e);return t||(t=w(e.ast),oe.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=j(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return se(e,t=>this.getProperty(t))}stripCaptions(e){return ne(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return k(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=_(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){let t=this.host.refSplitCache.get(e);return t||(t=H(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new D().defineOwned("patter",this.host.patterLocalDecls,"@patter.")}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set,r=e.sceneProps??[];this.sceneBags.has(e.id)||this.sceneBags.set(e.id,new b(r.filter(s=>!t.has(s.name.toLowerCase())))),this.host.stageBags.has(e.id)||this.host.stageBags.set(e.id,new b(r.filter(s=>t.has(s.name.toLowerCase()))));for(let s of e.sceneProps??[]){if(!s.temporary)continue;let i=s.name.toLowerCase(),o=t.has(i)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);o&&o.set(i,E(s))}}};function ae(n,e){k(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function de(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function ge(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ce(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function le(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Te(n){let e=r=>r.toLowerCase(),t=new Map;for(let r of n)t.set(e(r.name),E(r));return{get:r=>t.get(e(r)),set:(r,s)=>{t.set(e(r),s)}}}function pe(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Ae=(n,e)=>n.shared??e;function W(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Ae(n,e)}}function Fe(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ge(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ue(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=h(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:h(c),name:c.name}))});for(let c of o.blocks)Ge(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>W(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>W(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(Fe)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>W(o,!0)),scene:r},gameData:i,counts:e}}function he(n,e){return n.gameDataFields?.[e]??[]}function K(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function fe(n,e){let t={};for(let r of n){let s=K(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return Ee(Le);})();\n';
|
|
195059
|
+
var PLAYABLE_RUNTIME_JS = 'var Patterplay=(()=>{var q=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var Ne=(n,e)=>{for(var t in e)q(n,t,{get:e[t],enumerable:!0})},Fe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Be(e))!Pe.call(n,s)&&s!==t&&q(n,s,{get:()=>e[s],enumerable:!(r=Oe(e,s))||r.enumerable});return n};var Te=n=>Fe(q({},"__esModule",{value:!0}),n);var Qe={};Ne(Qe,{Engine:()=>$,Flow:()=>D,buildTagIndex:()=>M,describeBundle:()=>ke,effectiveGameData:()=>Ie,gameDataFields:()=>Ce,gameDataValue:()=>Q});function E(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:E(n[2])};case"bin":return{kind:"binary",op:n[1],left:E(n[2]),right:E(n[3])};case"call":{let e=n.slice(2).map(E);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var p=class extends Error{constructor(e){super(e),this.name="EvalError"}};function F(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new p(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new p(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=_(a,e);if(c===void 0)throw new p("advance() needs a quality reference (@scope.name of a quality property)");let l=w(s(a),c,"advance");return c[Math.min(l+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new p(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new p("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new p(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new p(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let u=s(i.left);if(typeof u!="boolean")throw new p(`\'and\' requires boolean operands, left is ${typeof u}`);if(!u)return!1;let S=s(i.right);if(typeof S!="boolean")throw new p(`\'and\' requires boolean operands, right is ${typeof S}`);return S}if(i.op==="or"){let u=s(i.left);if(typeof u!="boolean")throw new p(`\'or\' requires boolean operands, left is ${typeof u}`);if(u)return!0;let S=s(i.right);if(typeof S!="boolean")throw new p(`\'or\' requires boolean operands, right is ${typeof S}`);return S}let o=s(i.left),a=s(i.right),c=_(i.left,e),l=_(i.right,e),d=c??l;if(d!==void 0){if(c&&l&&!Ae(c,l)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new p(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return w(o,d,">")>w(a,d,">");case">=":return w(o,d,">=")>=w(a,d,">=");case"<":return w(o,d,"<")<w(a,d,"<");case"<=":return w(o,d,"<=")<=w(a,d,"<=");case"+":case"-":case"*":case"/":throw new p(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return se(o,a);case"!=":return!se(o,a);case">":return k(o,a,">"),o>a;case">=":return k(o,a,">="),o>=a;case"<":return k(o,a,"<"),o<a;case"<=":return k(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new p(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return k(o,a,"-"),o-a;case"*":return k(o,a,"*"),o*a;case"/":if(k(o,a,"/"),a===0)throw new p("division by zero");return o/a}}}};return s(n)}function se(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;let t=[...n].sort(),r=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==r[s])return!1;return!0}return n===e}function k(n,e,t){if(typeof n!="number"||typeof e!="number")throw new p(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function _(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function w(n,e,t){if(typeof n!="string")throw new p(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new p(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var Ae=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function R(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function H(n){let e=R(n);return{next(){e=e+1831565813>>>0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296},state(){return e}}}var Ge={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ve=[Ge];function ie(n,e,t){let r=t?.countingCalls??Ve;return T(n,t?.want??!0,e,r)}function T(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=T(n.left,e,t,r),i=T(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return T(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var b=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",this.seed(e)}seed(e){for(let t of e){let r=this.norm(t.name);this.decls.set(r,t),this.values[r]=structuredClone(t.default??O(t))}}get(e){return this.values[this.norm(e)]}normalise(e){return this.norm(e)}set(e,t,r){let s=this.norm(e);if(!r?.host&&this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=t;for(let o of this.auditors)o(i);if(!i.silent)for(let o of this.subscribers)o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>ae(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm,pathPrefix:this.pathPrefix});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e){for(let[t,r]of Object.entries(e))this.values[this.norm(t)]=r}};function ae(n,e,t,r,s=""){let i=r??n.name.toLowerCase();return{name:i,path:s+i,type:n.type,value:e,default:n.default??O(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var Le=n=>n.toLowerCase(),U=1,A=class{scopes=new Map;parked=new Map;rev=0;get revision(){return this.rev}defineOwned(e,t,r){let s=typeof r=="string"?{pathPrefix:r}:r??{},i=new b(t,{pathPrefix:s.pathPrefix??`${e}.`,...s.normalise?{normalise:s.normalise}:{}});return this.mountOwned(e,i,s.owner!==void 0?{owner:s.owner}:void 0)}mountOwned(e,t,r){this.assertFree(e,r?.owner),this.scopes.set(e,{kind:"owned",bag:t,...r?.owner!==void 0?{owner:r.owner}:{}}),this.rev++;let s=this.parked.get(e);return s&&(t.load(s),this.parked.delete(e)),this}remove(e,t){let r=this.scopes.get(e);if(!r)throw new Error(`unknown scope \'@${e}\'`);return t?.keep&&r.kind==="owned"&&this.parked.set(e,r.bag.save()),this.scopes.delete(e),this.rev++,this}discardParked(e){if(e===void 0)this.parked.clear();else for(let t of[...this.parked.keys()])t.startsWith(e)&&this.parked.delete(t);return this}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,r=[],s=!0){let i=typeof s=="boolean"?{writable:s}:s;this.assertFree(e,i.owner);let o=i.normalise??Le,a=new Map;for(let c of r)a.set(o(c.name),c);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:a,scopeWritable:i.writable??!0,norm:o,...i.owner!==void 0?{owner:i.owner}:{}}),this.rev++,this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(r)return r.kind==="owned"?r.bag.get(t):r.resolver.get(r.norm(t))}set(e,t,r,s){let i=this.scopes.get(e);if(!i)throw new Error(`unknown scope \'@${e}\'`);if(i.kind==="owned"){try{i.bag.set(t,r,s?.host?{host:!0}:void 0)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let o=i.norm(t);if(!i.resolver.set)throw new Error(`\'@${e}.${t}\' is read-only`);if(!s?.host&&!this.foreignWritable(i,o))throw new Error(`\'@${e}.${t}\' is read-only`);i.resolver.set(o,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes){let s=r.owner!==void 0?{owner:r.owner}:{};if(r.kind==="owned")for(let i of r.bag.rows())e.push({scope:t,...s,...i});else for(let[i,o]of r.decls)e.push({scope:t,...s,...ae(o,r.resolver.get(i),this.foreignWritable(r,i),i,`${t}.`)})}return e}toEvalContext(e,t){let r=this.view(t?.aliases),s={};for(let[o,a]of r)s[o]=a.kind==="owned"?a.bag.values:a.resolver;let i=this.qualityLadders(r);return i.size===0?{scopes:s,host:e}:{scopes:s,host:e,qualities:(o,a)=>{let c=r.get(o);return c?i.get(o)?.get(Me(c)(a)):void 0}}}view(e){let t=new Map(this.scopes);for(let[r,s]of Object.entries(e??{})){let i=this.scopes.get(s);if(!i)throw new Error(`alias \'@${r}\' names \'${s}\', which is not registered`);t.set(r,i)}return t}qualityLadders(e){let t=new Map;for(let[r,s]of e)for(let[i,o]of oe(s)){if(o.type!=="quality"||o.stages===void 0)continue;let a=t.get(r);a||(a=new Map,t.set(r,a)),a.set(i,o.stages)}return t}toSchema(e){let t=new Map;for(let[r,s]of this.view(e?.aliases)){let i=oe(s);if(i.length===0)continue;let o=new Map;for(let[a,c]of i)o.set(a,{type:c.type,enumValues:c.values,...c.stages!==void 0?{stages:c.stages}:{}});t.set(r,o)}return{properties:t}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());for(let[t,r]of this.parked)e[t]=structuredClone(r);return e}load(e,t){t?.keepParked||this.parked.clear();for(let[r,s]of Object.entries(e)){let i=this.scopes.get(r);i?.kind==="owned"?i.bag.load(s):i||this.parked.set(r,structuredClone(s))}}saveFragment(){return{version:U,scopes:this.save()}}loadFragment(e){if(e.version!==U)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${U})`);this.load(e.scopes)}assertFree(e,t){let r=this.scopes.get(e);if(!r)return;let s=r.owner!==void 0?` by ${r.owner}`:"",i=t!==void 0?` (wanted by ${t})`:"";throw new Error(`scope \'@${e}\' is already registered${s}${i}`)}};function oe(n){return n.kind==="foreign"?[...n.decls.entries()]:n.bag.declarations().map(e=>[n.bag.normalise(e.name),e])}function Me(n){return n.kind==="foreign"?n.norm:e=>n.bag.normalise(e)}function O(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??"";default:return!1}}var ce=[{token:"patter",engine:"Patterplay",means:"Patter\'s shared globals"},{token:"story",engine:"Storylet Engine",means:"the Storylet Engine\'s shared @story properties"}];function B(n){return n.ctx.host??{}}var W={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new p("random(a, b) requires exactly 2 arguments");let t=B(e).nextRandom;if(!t)throw new p("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new p("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new p("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:pe("check_flags"),eval(n,e){let t=le(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new p("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:pe("set_flags"),eval(n,e){let t=[...le(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new p("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:V("visits"),eval:(n,e)=>B(e).visits?.(G(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:V("seen"),eval:(n,e)=>(B(e).visits?.(G(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:V("patter_visits"),eval:(n,e)=>B(e).patterVisits?.(G(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:V("patter_seen"),eval:(n,e)=>(B(e).patterVisits?.(G(n,e,"patter_seen"))??0)>0}}},ut=ce.map(n=>n.token).filter(n=>n!=="patter"&&n!=="scene");function de(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function G(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new p(`${t}(id) requires a string node id`);return r}function V(n){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function le(n,e,t){if(!n)throw new p(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new p(`${t}() first argument must be a flags property`)}function pe(n){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var $e=/^@[A-Za-z0-9_.]+$/;function*je(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:$e.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function qe(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function _e(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function He(n){let e="",t=!1;for(let r of n){if(_e(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function ge(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?He(r):n}function ue(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of je(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":qe(s)}return t}function C(n,e){for(let t of n){e(t);let r=t.children;r&&C(r,e)}}function Ue(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function m(n){let e=n.gameId?.trim();return e||Ue(n.name)}function K(n){return`cast:${n}`}var J={open:"[",close:"]"},he="SFX";var z=3;function L(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function M(n){let e=new Map,t=(r,s)=>{let i=L([...s,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,L([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=L(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=L([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var fe=new WeakMap,I="Patter",P=n=>n.replace(/%/g,"%25").replace(/\\//g,"%2F"),me=Symbol("ownsRegistry"),v={stage:n=>`patter/scene/${P(n)}`,flow:n=>`patter/flow/${P(n)}/`,flowGlobals:n=>`patter/flow/${P(n)}/patter`,flowScene:(n,e)=>`patter/flow/${P(n)}/scene/${P(e)}`},$=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let l=new Map;for(let g of e.cast??[])g.displayName&&l.set(g.name,g.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let d=new Map,u=new Map,S=new Map;for(let[g,h]of Object.entries(e.scenes)){this.sceneGameIdToId.set(m(h),g);let y=new Map;for(let f of h.blocks)u.set(f.id,{sceneId:g}),S.set(f.id,f),y.set(m(f),f.id),C(f.children,ne=>d.set(ne.id,ne));this.blockGameIdToId.set(g,y)}let X=e.properties??[],j=X.filter(g=>g.shared??!0).map(ye),De=X.filter(g=>!(g.shared??!0)).map(ye),Re=new Set(j.map(g=>g.name.toLowerCase())),x=t.registry??new A,Z=!t.registry||t[me]===!0,ee=new b(j,{pathPrefix:"@patter."}),te=[],N=[];try{x.mountOwned("patter",ee,{owner:I}),N.push("patter");let g=new Set;if(t.world){let h=e.scopeRegistry?.scopes.find(f=>f.token==="world"),y=(h?.declarations??[]).map(xe);x.defineForeign("world",t.world,y,{writable:h?.writable??!0,owner:I}),N.push("world"),g.add("world")}for(let h of Z?e.scopeRegistry?.scopes??[]:[]){if(g.has(h.token)||x.has(h.token))continue;let y=(h.declarations??[]).map(f=>We(f,h.writable));x.defineOwned(h.token,y,{owner:I}),N.push(h.token),te.push(h.token)}}catch(g){for(let h of N)x.remove(h,{keep:!0});throw g}let re=new Map;for(let[g,h]of Object.entries(e.scenes)){let y=new Set((h.sceneProps??[]).filter(f=>f.shared??!1).map(f=>f.name.toLowerCase()));re.set(g,y)}this.host={logEnabled:t.log??!1,emitEngine:(g,h,y)=>this.emitEngine(g,h,y),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:l,nodeIndex:d,blockIndex:u,blockById:S,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:M(e),registry:x,ownsRegistry:Z,patterBag:ee,hostScopes:te,patterSharedDecls:j,patterLocalDecls:De,patterSharedNames:Re,sceneSharedNames:re,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??J).open,captionClose:(e.closedCaptions??J).close,captionCharacter:e.closedCaptions?.character||he,refSplitCache:new Map,refSplitRevision:x.revision}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=o=>(o.setLocale(this.currentLocale),o.setClosedCaptions(this.host.captionsOn),o),s=()=>new n(e,{...this.creationOptions,registry:this.host.registry,[me]:this.host.ownsRegistry});this.release(!0);let i=s();try{return i.loadGame(t),r(i)}catch{i.release(!0);let o=s();for(let[a,c]of Object.entries(t.flows)){let l=c.cursor.currentSceneId;try{o.openFlow(a,l!==null?{scene:l}:{})}catch{}}return r(o)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){this.assertExternalScopes();let r=this.resolveSceneRef(t.scene),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new D(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.advanceToStop().played}assertExternalScopes(){for(let e of this.host.bundle.externalScopes??[])if(!this.host.registry.has(e))throw new Error(`this content names @${e}, which no engine on this registry registered: give every engine the game\'s one registry`)}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?m(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?m(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)Se(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return Se(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...m(e)?{gameId:m(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...m(t)?{gameId:m(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)C(r.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let s=this.host.defaultStrings[K(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}listBags(){let e=[{bag:this.host.patterBag}];for(let[t,r]of this.host.stageBags)e.push({bag:r,pathPrefix:`@scene:${t}.`});return e}closeFlow(e){this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.patterBag.reseed(this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear();for(let e of this.host.stageBags.keys())this.host.registry.remove(v.stage(e));this.host.stageBags.clear(),this.host.registry.discardParked("patter/")}release(e){for(let r of this.flowsById.values())r.releaseBags(e),r.close();this.flowsById.clear();let t=this.host.registry;for(let r of this.host.stageBags.keys())t.remove(v.stage(r),{keep:e});this.host.stageBags.clear();for(let r of["patter",...this.host.hostScopes])t.has(r)&&t.remove(r,{keep:e});this.creationOptions.world&&t.has("world")&&t.remove("world")}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.registry.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitShared(e);this.host.registry.set(r,s,t,{host:!0})}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),()=>this.engineTraceHandlers.delete(e)}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineLog.length,...r?{scene:r}:{}})}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:O(e),writable:e.writable??!0}))}splitShared(e){let t=Ee(this.host,e);if(t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return{patter:this.host.patterBag.save()}}load(e){e.patter&&this.host.patterBag.load(e.patter)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:z,...this.host.ownsRegistry?{registry:this.host.registry.save()}:{},sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:we(this.host.sharedSelectors),flows:e}}loadGame(e){let t=e.version;if(t!==2&&t!==z)throw new Error(`unsupported save version: ${String(t)}`);this.assertExternalScopes();let r=this.host.registry;for(let[i,o]of this.flowsById)o.releaseBags(i in e.flows),o.close();this.flowsById.clear();for(let i of this.host.stageBags.keys())r.remove(v.stage(i),{keep:!0});this.host.stageBags.clear();let s=e.version===2?Ke(e):e.registry;s&&(this.host.ownsRegistry?r.load(s):r.load(s,{keepParked:!0})),this.host.sharedVisits.clear();for(let[i,o]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(i,o);this.host.sharedSelectors.clear();for(let[i,o]of be(e.sharedSelectors))this.host.sharedSelectors.set(i,o);for(let[i,o]of Object.entries(e.flows)){let a=new D(i,this.host,this.defaultSeed);a.restore(o),this.flowsById.set(i,a)}}},D=class{id;host;local;registered=new Set;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.patterBag.get(e):this.local.get(e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.registry.set("patter",e,t):this.local.set(e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;if(t!==null)return this.sceneBagFor(t,e)?.get(e)},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.sceneBagFor(r,e);s&&s.set(e,t)}};evalCtx;ctxRevision=-1;registryQualities;flowLog=[];flowSeq=0;constructor(e,t,r){this.id=e,this.host=t,this.rngState=R(r),this.local=this.newLocal(),this.evalCtx={scopes:{},host:{nextRandom:this.rng,visits:s=>this.visitCounts.get(s)??0,patterVisits:s=>this.host.sharedVisits.get(s)??0},qualities:(s,i)=>this.stagesFor(s,i)}}context(){let e=this.host.registry;if(e.revision!==this.ctxRevision){let t=e.toEvalContext(),r=this.evalCtx.scopes;for(let s of Object.keys(r))delete r[s];Object.assign(r,t.scopes),r.patter=this.patterResolver,r.scene=this.sceneResolver,this.registryQualities=t.qualities,this.ctxRevision=e.revision}return this.evalCtx}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return this.registryQualities?.(e,t)??s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}start(e,t){if(this.releaseBags(!1),this.host.registry.discardParked(v.flow(this.id)),this.mountLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}goto(e,t){if(this.closed)return!1;if(e==="END")return this.started=!0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=this.host.sceneGameIdToId.get(e)??(this.host.bundle.scenes[e]?e:void 0);if(r===void 0)return!1;let s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===void 0)?!1:this.started?(this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.start(r,s),!0)}close(){this.releaseBags(!1),this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end"};if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}let s=t.index;for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(this.host.logEnabled&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:r[t.index]?.id??null}),t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}listBags(){let e=[{bag:this.local,pathPrefix:`${this.id}/@patter.`}];for(let[t,r]of this.sceneBags)e.push({bag:r,pathPrefix:`${this.id}/@scene:${t}.`});return e}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let s=t.byId.get(e);this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.registry.get(t,r)}setProperty(e,t){this.writeProperty(e,t,!0)}writeProperty(e,t,r){let{scope:s,name:i}=this.splitRef(e);if(s==="patter")this.patterResolver.set(i,t);else if(s==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(i,t)}else this.host.registry.set(s,i,t,r?{host:!0}:void 0)}snapshot(){return{rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:we(this.selectors)}}}restore(e){this.rngState=R(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.releaseBags(!1),this.mountLocal();for(let r of new Set([t.currentSceneId,...this.stack.map(s=>s.sceneId)]))r!==null&&this.host.bundle.scenes[r]&&this.ensureSceneBags(r);if(this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=be(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter(c=>this.eligible(c)),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(r[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(r,i,a):s==="specificity"?this.pickSpecificity(r,i,a):this.pickSequential(r,i,a));default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(u=>u.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let u=e[s-1];return r.last=u.id,u}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,l=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&l>=c&&l++;let d=a[l];return a.splice(l,1),r.last=d,e.find(u=>u.id===d)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(d=>d.id));let l=new Set(r.bag);if(s=e.filter(d=>l.has(d.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(d=>d.id===r.last)??null:null}let i=-1,a=s.map(l=>{let d=this.specScore(l);return d>i&&(i=d),{c:l,s:d}}).filter(l=>l.s===i).map(l=>l.c),c;if(a.length===1)c=a[0];else{let l=r.last!==void 0?a.findIndex(u=>u.id===r.last):-1,d=Math.floor(this.rng()*(l>=0?a.length-1:a.length));l>=0&&d>=l&&d++,c=a[d]}return t!=="repeat"&&(r.bag=r.bag.filter(l=>l!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return ie(e,s=>ve(F(s,this.context(),W)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[]){let r=this.evalExpr(t.value),s=this.host.logEnabled?this.getProperty(t.target):void 0;this.writeProperty(t.target,r,!1),this.emit({type:"write",target:t.target,value:r,...s!==void 0?{prev:s}:{}})}}eligible(e){return e.condition?ve(this.evalExpr(e.condition)):!0}evalExpr(e){return F(this.conditionAst(e),this.context(),W)}conditionAst(e){let t=fe.get(e);return t||(t=E(e.ast),fe.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=H(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return ue(e,t=>this.getProperty(t))}stripCaptions(e){return ge(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return C(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=K(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){return Ee(this.host,e)}newLocal(){return new b(this.host.patterLocalDecls,{pathPrefix:"@patter."})}mountLocal(){this.local=this.newLocal();let e=v.flowGlobals(this.id);this.host.registry.mountOwned(e,this.local,{owner:I}),this.registered.add(e)}releaseBags(e){for(let t of this.registered)this.host.registry.remove(t,{keep:e});this.registered.clear(),this.sceneBags.clear()}sceneBagFor(e,t){if(this.host.bundle.scenes[e])return this.ensureSceneBags(e),this.host.sceneSharedNames.get(e)?.has(t.toLowerCase())?this.host.stageBags.get(e):this.sceneBags.get(e)}ensureSceneBags(e){let t=this.host.sceneSharedNames.get(e)??new Set,r=this.host.bundle.scenes[e]?.sceneProps??[];if(!this.sceneBags.has(e)){let s=new b(r.filter(o=>!t.has(o.name.toLowerCase())),{pathPrefix:"@scene."}),i=v.flowScene(this.id,e);this.host.registry.mountOwned(i,s,{owner:I}),this.registered.add(i),this.sceneBags.set(e,s)}if(!this.host.stageBags.has(e)){let s=new b(r.filter(i=>t.has(i.name.toLowerCase())),{pathPrefix:"@scene."});this.host.registry.mountOwned(v.stage(e),s,{owner:I}),this.host.stageBags.set(e,s)}}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;this.ensureSceneBags(e.id);for(let r of e.sceneProps??[]){if(!r.temporary)continue;let s=r.name.toLowerCase(),i=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);i&&i.set(s,O(r))}}};function Se(n,e){C(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function we(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function be(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ye(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function xe(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function We(n,e){let t=xe(n),r=n.writable??e;return r===void 0?t:{...t,writable:r}}function Ee(n,e){n.refSplitRevision!==n.registry.revision&&(n.refSplitCache.clear(),n.refSplitRevision=n.registry.revision);let t=n.refSplitCache.get(e);return t||(t=de(e,r=>r==="scene"||n.registry.has(r)||(n.bundle.externalScopes?.includes(r)??!1)),n.refSplitCache.set(e,t)),t}function Ke(n){let e={};n.shared?.patter&&(e.patter=n.shared.patter);for(let[t,r]of Object.entries(n.stageBags??{}))e[v.stage(t)]=r;for(let[t,r]of Object.entries(n.flows??{})){r.scopes?.patter&&(e[v.flowGlobals(t)]=r.scopes.patter);for(let[s,i]of Object.entries(r.sceneBags??{}))e[v.flowScene(t,s)]=i}return e}function ve(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Je=(n,e)=>n.shared??e;function Y(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Je(n,e)}}function ze(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ye(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ke(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=m(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:m(c),name:c.name}))});for(let c of o.blocks)Ye(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>Y(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>Y(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(ze)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>Y(o,!0)),scene:r},gameData:i,counts:e}}function Ce(n,e){return n.gameDataFields?.[e]??[]}function Q(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function Ie(n,e){let t={};for(let r of n){let s=Q(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return Te(Qe);})();\n';
|
|
195015
195060
|
|
|
195016
195061
|
// ../ops/src/export-html.ts
|
|
195017
195062
|
var esc = (s) => s.replace(/[&<>]/g, (c2) => ({ "&": "&", "<": "<", ">": ">" })[c2]);
|
|
@@ -195278,6 +195323,13 @@ var PropertyBag = class _PropertyBag {
|
|
|
195278
195323
|
get(name) {
|
|
195279
195324
|
return this.values[this.norm(name)];
|
|
195280
195325
|
}
|
|
195326
|
+
/** A name as this bag keys it: its normalisation policy applied. The registry
|
|
195327
|
+
* uses it to key quality ladders and the validation schema the bag's own way,
|
|
195328
|
+
* so a case-significant (identity) bag is not quietly folded to lower case
|
|
195329
|
+
* one layer up. */
|
|
195330
|
+
normalise(name) {
|
|
195331
|
+
return this.norm(name);
|
|
195332
|
+
}
|
|
195281
195333
|
/** Write a property. Engine writes (the default) notify subscribers;
|
|
195282
195334
|
* pass `silent: true` for a host write, which reaches only the audit
|
|
195283
195335
|
* hook. Throws on a read-only property unless the caller says it is the
|
|
@@ -195361,25 +195413,82 @@ function rowFor(d, value, writable, name, pathPrefix = "") {
|
|
|
195361
195413
|
writable: writable ?? d.writable ?? true
|
|
195362
195414
|
};
|
|
195363
195415
|
}
|
|
195416
|
+
var lowerCase = (name) => name.toLowerCase();
|
|
195364
195417
|
var SAVE_FRAGMENT_VERSION = 1;
|
|
195365
195418
|
var ScopeRegistry = class {
|
|
195366
195419
|
scopes = /* @__PURE__ */ new Map();
|
|
195420
|
+
/** Values loaded for keys nobody has registered yet, waiting to be claimed. */
|
|
195421
|
+
parked = /* @__PURE__ */ new Map();
|
|
195422
|
+
rev = 0;
|
|
195423
|
+
/**
|
|
195424
|
+
* A counter that moves whenever a scope is registered or removed, and at no
|
|
195425
|
+
* other time: it starts at 0 and each registration or removal adds 1. Values
|
|
195426
|
+
* changing does not move it. A caller that caches a context built by
|
|
195427
|
+
* `toEvalContext()` rebuilds it when this moves, because the context's set of
|
|
195428
|
+
* scopes is fixed when it is built while the values it reads stay live.
|
|
195429
|
+
*/
|
|
195430
|
+
get revision() {
|
|
195431
|
+
return this.rev;
|
|
195432
|
+
}
|
|
195367
195433
|
/**
|
|
195368
195434
|
* Register a scope this registry **owns and stores**. Its bag is seeded from
|
|
195369
195435
|
* each declaration's `default` (or a type default). Owned scopes are
|
|
195370
195436
|
* type-checked (declarations) and serialized by `save`/`load`.
|
|
195437
|
+
*
|
|
195438
|
+
* The third argument may be the path prefix alone (the pre-0.7 form) or an
|
|
195439
|
+
* options object.
|
|
195371
195440
|
*/
|
|
195372
|
-
defineOwned(token2, declarations,
|
|
195373
|
-
|
|
195441
|
+
defineOwned(token2, declarations, opts) {
|
|
195442
|
+
const o = typeof opts === "string" ? { pathPrefix: opts } : opts ?? {};
|
|
195443
|
+
const bag = new PropertyBag(declarations, {
|
|
195444
|
+
pathPrefix: o.pathPrefix ?? `${token2}.`,
|
|
195445
|
+
...o.normalise ? { normalise: o.normalise } : {}
|
|
195446
|
+
});
|
|
195447
|
+
return this.mountOwned(token2, bag, o.owner !== void 0 ? { owner: o.owner } : void 0);
|
|
195374
195448
|
}
|
|
195375
195449
|
/**
|
|
195376
|
-
* Attach an EXISTING bag as an owned scope
|
|
195377
|
-
*
|
|
195378
|
-
*
|
|
195450
|
+
* Attach an EXISTING bag as an owned scope: an engine (or a host) holds the
|
|
195451
|
+
* bag and this registry reads, writes, lists and saves it like its own.
|
|
195452
|
+
*
|
|
195453
|
+
* If values were loaded for this key before anyone registered it, the bag
|
|
195454
|
+
* claims them now: laid over its seeded defaults by the bag's own `load` rule.
|
|
195379
195455
|
*/
|
|
195380
|
-
mountOwned(token2, bag) {
|
|
195381
|
-
this.assertFree(token2);
|
|
195382
|
-
this.scopes.set(token2, { kind: "owned", bag });
|
|
195456
|
+
mountOwned(token2, bag, opts) {
|
|
195457
|
+
this.assertFree(token2, opts?.owner);
|
|
195458
|
+
this.scopes.set(token2, { kind: "owned", bag, ...opts?.owner !== void 0 ? { owner: opts.owner } : {} });
|
|
195459
|
+
this.rev++;
|
|
195460
|
+
const waiting = this.parked.get(token2);
|
|
195461
|
+
if (waiting) {
|
|
195462
|
+
bag.load(waiting);
|
|
195463
|
+
this.parked.delete(token2);
|
|
195464
|
+
}
|
|
195465
|
+
return this;
|
|
195466
|
+
}
|
|
195467
|
+
/**
|
|
195468
|
+
* Unregister a scope. With `{ keep: true }` an owned scope's values are parked
|
|
195469
|
+
* and handed back when the same key is next registered, which is how a live
|
|
195470
|
+
* reload hands an engine's state to its replacement. Throws on an unknown key.
|
|
195471
|
+
*/
|
|
195472
|
+
remove(token2, opts) {
|
|
195473
|
+
const e = this.scopes.get(token2);
|
|
195474
|
+
if (!e) throw new Error(`unknown scope '@${token2}'`);
|
|
195475
|
+
if (opts?.keep && e.kind === "owned") this.parked.set(token2, e.bag.save());
|
|
195476
|
+
this.scopes.delete(token2);
|
|
195477
|
+
this.rev++;
|
|
195478
|
+
return this;
|
|
195479
|
+
}
|
|
195480
|
+
/**
|
|
195481
|
+
* Drop parked values nobody claimed. Parked values are kept in the next save by
|
|
195482
|
+
* default, so nothing loaded is lost to a flow or deck that simply has not
|
|
195483
|
+
* reopened yet; a game that knows they are dead drops them here.
|
|
195484
|
+
*
|
|
195485
|
+
* With a `prefix`, only keys starting with it are dropped: an engine resetting
|
|
195486
|
+
* itself drops its own instance keys (`my-engine/`) and leaves every other
|
|
195487
|
+
* engine's alone.
|
|
195488
|
+
*/
|
|
195489
|
+
discardParked(prefix) {
|
|
195490
|
+
if (prefix === void 0) this.parked.clear();
|
|
195491
|
+
else for (const key2 of [...this.parked.keys()]) if (key2.startsWith(prefix)) this.parked.delete(key2);
|
|
195383
195492
|
return this;
|
|
195384
195493
|
}
|
|
195385
195494
|
/** An owned scope's bag (subscribe, audit, rows live there). */
|
|
@@ -195405,11 +195514,21 @@ var ScopeRegistry = class {
|
|
|
195405
195514
|
* `declarations` (optional, e.g. imported from a `scopeRegistrySpec`) are used
|
|
195406
195515
|
* only for validation; omit them for an opaque scope.
|
|
195407
195516
|
*/
|
|
195408
|
-
defineForeign(token2, resolver, declarations = [],
|
|
195409
|
-
|
|
195517
|
+
defineForeign(token2, resolver, declarations = [], opts = true) {
|
|
195518
|
+
const o = typeof opts === "boolean" ? { writable: opts } : opts;
|
|
195519
|
+
this.assertFree(token2, o.owner);
|
|
195520
|
+
const norm = o.normalise ?? lowerCase;
|
|
195410
195521
|
const decls = /* @__PURE__ */ new Map();
|
|
195411
|
-
for (const d of declarations) decls.set(d.name
|
|
195412
|
-
this.scopes.set(token2, {
|
|
195522
|
+
for (const d of declarations) decls.set(norm(d.name), d);
|
|
195523
|
+
this.scopes.set(token2, {
|
|
195524
|
+
kind: "foreign",
|
|
195525
|
+
resolver,
|
|
195526
|
+
decls,
|
|
195527
|
+
scopeWritable: o.writable ?? true,
|
|
195528
|
+
norm,
|
|
195529
|
+
...o.owner !== void 0 ? { owner: o.owner } : {}
|
|
195530
|
+
});
|
|
195531
|
+
this.rev++;
|
|
195413
195532
|
return this;
|
|
195414
195533
|
}
|
|
195415
195534
|
has(token2) {
|
|
@@ -195419,7 +195538,7 @@ var ScopeRegistry = class {
|
|
|
195419
195538
|
get(scope, name) {
|
|
195420
195539
|
const e = this.scopes.get(scope);
|
|
195421
195540
|
if (!e) return void 0;
|
|
195422
|
-
return e.kind === "owned" ? e.bag.get(name) : e.resolver.get(
|
|
195541
|
+
return e.kind === "owned" ? e.bag.get(name) : e.resolver.get(e.norm(name));
|
|
195423
195542
|
}
|
|
195424
195543
|
/** Write a property (an ENGINE write: the bag's subscribers fire; use
|
|
195425
195544
|
* the bag directly for silent host writes). Throws on an unknown scope.
|
|
@@ -195441,7 +195560,7 @@ var ScopeRegistry = class {
|
|
|
195441
195560
|
}
|
|
195442
195561
|
return;
|
|
195443
195562
|
}
|
|
195444
|
-
const n =
|
|
195563
|
+
const n = e.norm(name);
|
|
195445
195564
|
if (!e.resolver.set) throw new Error(`'@${scope}.${name}' is read-only`);
|
|
195446
195565
|
if (!opts?.host && !this.foreignWritable(e, n)) throw new Error(`'@${scope}.${name}' is read-only`);
|
|
195447
195566
|
e.resolver.set(n, value);
|
|
@@ -195456,19 +195575,15 @@ var ScopeRegistry = class {
|
|
|
195456
195575
|
listProperties() {
|
|
195457
195576
|
const out = [];
|
|
195458
195577
|
for (const [token2, e] of this.scopes) {
|
|
195578
|
+
const owner = e.owner !== void 0 ? { owner: e.owner } : {};
|
|
195459
195579
|
if (e.kind === "owned") {
|
|
195460
|
-
for (const row of e.bag.rows()) out.push({ scope: token2, ...row });
|
|
195580
|
+
for (const row of e.bag.rows()) out.push({ scope: token2, ...owner, ...row });
|
|
195461
195581
|
} else {
|
|
195462
|
-
for (const d of e.decls
|
|
195582
|
+
for (const [n, d] of e.decls) {
|
|
195463
195583
|
out.push({
|
|
195464
195584
|
scope: token2,
|
|
195465
|
-
...
|
|
195466
|
-
|
|
195467
|
-
e.resolver.get(d.name.toLowerCase()),
|
|
195468
|
-
this.foreignWritable(e, d.name.toLowerCase()),
|
|
195469
|
-
void 0,
|
|
195470
|
-
`${token2}.`
|
|
195471
|
-
)
|
|
195585
|
+
...owner,
|
|
195586
|
+
...rowFor(d, e.resolver.get(n), this.foreignWritable(e, n), n, `${token2}.`)
|
|
195472
195587
|
});
|
|
195473
195588
|
}
|
|
195474
195589
|
}
|
|
@@ -195480,31 +195595,48 @@ var ScopeRegistry = class {
|
|
|
195480
195595
|
* bags, foreign scopes as their resolvers. `host` carries dialect-function
|
|
195481
195596
|
* callbacks (PRNG, tag lookups) and is passed through untouched.
|
|
195482
195597
|
*/
|
|
195483
|
-
toEvalContext(host2) {
|
|
195598
|
+
toEvalContext(host2, opts) {
|
|
195599
|
+
const view = this.view(opts?.aliases);
|
|
195484
195600
|
const scopes = {};
|
|
195485
|
-
for (const [token2, e] of
|
|
195486
|
-
|
|
195487
|
-
}
|
|
195488
|
-
const qualities = this.qualityLadders();
|
|
195601
|
+
for (const [token2, e] of view) scopes[token2] = e.kind === "owned" ? e.bag.values : e.resolver;
|
|
195602
|
+
const qualities = this.qualityLadders(view);
|
|
195489
195603
|
return qualities.size === 0 ? { scopes, host: host2 } : {
|
|
195490
195604
|
scopes,
|
|
195491
195605
|
host: host2,
|
|
195492
|
-
qualities: (scope, name) =>
|
|
195606
|
+
qualities: (scope, name) => {
|
|
195607
|
+
const e = view.get(scope);
|
|
195608
|
+
return e ? qualities.get(scope)?.get(normOf(e)(name)) : void 0;
|
|
195609
|
+
}
|
|
195493
195610
|
};
|
|
195494
195611
|
}
|
|
195495
|
-
/**
|
|
195496
|
-
|
|
195612
|
+
/**
|
|
195613
|
+
* The scopes an expression sees: every registered key under its own token,
|
|
195614
|
+
* then each alias token pointing at its key's entry (an alias shadows a key of
|
|
195615
|
+
* the same name). Keys an engine uses for instance bags (`engine/flow-2/...`)
|
|
195616
|
+
* are not valid expression tokens, so they are present but unreachable.
|
|
195617
|
+
*/
|
|
195618
|
+
view(aliases) {
|
|
195619
|
+
const out = new Map(this.scopes);
|
|
195620
|
+
for (const [token2, key2] of Object.entries(aliases ?? {})) {
|
|
195621
|
+
const e = this.scopes.get(key2);
|
|
195622
|
+
if (!e) throw new Error(`alias '@${token2}' names '${key2}', which is not registered`);
|
|
195623
|
+
out.set(token2, e);
|
|
195624
|
+
}
|
|
195625
|
+
return out;
|
|
195626
|
+
}
|
|
195627
|
+
/** Every quality declaration's ladder, keyed scope token then name (the
|
|
195628
|
+
* scope's own normalisation). */
|
|
195629
|
+
qualityLadders(view) {
|
|
195497
195630
|
const out = /* @__PURE__ */ new Map();
|
|
195498
|
-
for (const [token2, e] of
|
|
195499
|
-
const
|
|
195500
|
-
for (const d of decls) {
|
|
195631
|
+
for (const [token2, e] of view) {
|
|
195632
|
+
for (const [n, d] of declsOf(e)) {
|
|
195501
195633
|
if (d.type !== "quality" || d.stages === void 0) continue;
|
|
195502
195634
|
let m = out.get(token2);
|
|
195503
195635
|
if (!m) {
|
|
195504
195636
|
m = /* @__PURE__ */ new Map();
|
|
195505
195637
|
out.set(token2, m);
|
|
195506
195638
|
}
|
|
195507
|
-
m.set(
|
|
195639
|
+
m.set(n, d.stages);
|
|
195508
195640
|
}
|
|
195509
195641
|
}
|
|
195510
195642
|
return out;
|
|
@@ -195512,15 +195644,17 @@ var ScopeRegistry = class {
|
|
|
195512
195644
|
/**
|
|
195513
195645
|
* Build the `ExpressionSchema` expr's validator consumes. Scopes with no
|
|
195514
195646
|
* declarations are **omitted** (opaque - references into them are not flagged);
|
|
195515
|
-
* declared scopes contribute their property types for validation.
|
|
195647
|
+
* declared scopes contribute their property types for validation. Aliases
|
|
195648
|
+
* apply as they do to `toEvalContext`, so a condition written against `@scene`
|
|
195649
|
+
* validates against the instance bag the engine names.
|
|
195516
195650
|
*/
|
|
195517
|
-
toSchema() {
|
|
195651
|
+
toSchema(opts) {
|
|
195518
195652
|
const properties = /* @__PURE__ */ new Map();
|
|
195519
|
-
for (const [token2, e] of this.
|
|
195520
|
-
const decls =
|
|
195653
|
+
for (const [token2, e] of this.view(opts?.aliases)) {
|
|
195654
|
+
const decls = declsOf(e);
|
|
195521
195655
|
if (decls.length === 0) continue;
|
|
195522
195656
|
const m = /* @__PURE__ */ new Map();
|
|
195523
|
-
for (const d of decls) m.set(
|
|
195657
|
+
for (const [n, d] of decls) m.set(n, {
|
|
195524
195658
|
type: d.type,
|
|
195525
195659
|
enumValues: d.values,
|
|
195526
195660
|
...d.stages !== void 0 ? { stages: d.stages } : {}
|
|
@@ -195529,40 +195663,78 @@ var ScopeRegistry = class {
|
|
|
195529
195663
|
}
|
|
195530
195664
|
return { properties };
|
|
195531
195665
|
}
|
|
195532
|
-
/** Serialize **owned** scopes
|
|
195533
|
-
*
|
|
195534
|
-
*
|
|
195535
|
-
*
|
|
195666
|
+
/** Serialize **owned** scopes (foreign scopes are the game's, and the game
|
|
195667
|
+
* saves them), as bare bags keyed by token, plus any values still parked, so
|
|
195668
|
+
* a save taken before every engine has re-registered loses nothing. The
|
|
195669
|
+
* registry knows nothing about game saves: a game embeds this in its own. */
|
|
195536
195670
|
save() {
|
|
195537
195671
|
const out = {};
|
|
195538
195672
|
for (const [token2, e] of this.scopes) if (e.kind === "owned") out[token2] = e.bag.save();
|
|
195673
|
+
for (const [token2, vals] of this.parked) out[token2] = structuredClone(vals);
|
|
195539
195674
|
return out;
|
|
195540
195675
|
}
|
|
195541
|
-
/**
|
|
195542
|
-
*
|
|
195543
|
-
|
|
195676
|
+
/**
|
|
195677
|
+
* Restore from a `save` blob. An owned scope lays its section over its current
|
|
195678
|
+
* values (the bag's `load` rule). A section for a key nobody has registered
|
|
195679
|
+
* yet is PARKED and handed over when that key registers, so a game can load
|
|
195680
|
+
* its registry before its engines have reopened their flows or decks. A
|
|
195681
|
+
* section for a foreign scope is ignored: those values are the game's.
|
|
195682
|
+
*
|
|
195683
|
+
* A load replaces whatever was parked before it: it is a whole restore, and
|
|
195684
|
+
* residue from an earlier load must not leak into this one.
|
|
195685
|
+
*
|
|
195686
|
+
* Changed in 0.7.0: sections for unregistered keys used to be dropped.
|
|
195687
|
+
*/
|
|
195688
|
+
load(blob, opts) {
|
|
195689
|
+
if (!opts?.keepParked) this.parked.clear();
|
|
195544
195690
|
for (const [token2, vals] of Object.entries(blob)) {
|
|
195545
195691
|
const e = this.scopes.get(token2);
|
|
195546
195692
|
if (e?.kind === "owned") e.bag.load(vals);
|
|
195693
|
+
else if (!e) this.parked.set(token2, structuredClone(vals));
|
|
195547
195694
|
}
|
|
195548
195695
|
}
|
|
195549
|
-
/**
|
|
195550
|
-
*
|
|
195551
|
-
*
|
|
195696
|
+
/**
|
|
195697
|
+
* `save()` wrapped with a version stamp.
|
|
195698
|
+
*
|
|
195699
|
+
* @deprecated Versioning belongs to the save that embeds the values; no
|
|
195700
|
+
* engine ever called this. Embed `save()` in your own versioned save.
|
|
195701
|
+
* Removed at the next breaking release.
|
|
195702
|
+
*/
|
|
195552
195703
|
saveFragment() {
|
|
195553
195704
|
return { version: SAVE_FRAGMENT_VERSION, scopes: this.save() };
|
|
195554
195705
|
}
|
|
195555
|
-
/**
|
|
195706
|
+
/**
|
|
195707
|
+
* Restore from a versioned fragment; an unsupported version throws.
|
|
195708
|
+
*
|
|
195709
|
+
* @deprecated See `saveFragment`. Removed at the next breaking release.
|
|
195710
|
+
*/
|
|
195556
195711
|
loadFragment(fragment) {
|
|
195557
195712
|
if (fragment.version !== SAVE_FRAGMENT_VERSION) {
|
|
195558
195713
|
throw new Error(`unsupported owned-state fragment version ${fragment.version} (supported: ${SAVE_FRAGMENT_VERSION})`);
|
|
195559
195714
|
}
|
|
195560
195715
|
this.load(fragment.scopes);
|
|
195561
195716
|
}
|
|
195562
|
-
|
|
195563
|
-
|
|
195717
|
+
/**
|
|
195718
|
+
* A token is taken once. There is no reserved-token list: a clash surfaces
|
|
195719
|
+
* here, the moment a game combines its engines, which is the only moment
|
|
195720
|
+
* anyone knows which engines are present. With owners recorded the error says
|
|
195721
|
+
* whose token it already is.
|
|
195722
|
+
*/
|
|
195723
|
+
assertFree(token2, owner) {
|
|
195724
|
+
const e = this.scopes.get(token2);
|
|
195725
|
+
if (!e) return;
|
|
195726
|
+
const by = e.owner !== void 0 ? ` by ${e.owner}` : "";
|
|
195727
|
+
const wants = owner !== void 0 ? ` (wanted by ${owner})` : "";
|
|
195728
|
+
throw new Error(`scope '@${token2}' is already registered${by}${wants}`);
|
|
195564
195729
|
}
|
|
195565
195730
|
};
|
|
195731
|
+
function declsOf(e) {
|
|
195732
|
+
if (e.kind === "foreign") return [...e.decls.entries()];
|
|
195733
|
+
return e.bag.declarations().map((d) => [e.bag.normalise(d.name), d]);
|
|
195734
|
+
}
|
|
195735
|
+
function normOf(e) {
|
|
195736
|
+
return e.kind === "foreign" ? e.norm : (n) => e.bag.normalise(n);
|
|
195737
|
+
}
|
|
195566
195738
|
function defaultFor(d) {
|
|
195567
195739
|
if (d.default !== void 0) return d.default;
|
|
195568
195740
|
switch (d.type) {
|
|
@@ -195624,6 +195796,19 @@ function buildTagIndex(bundle) {
|
|
|
195624
195796
|
|
|
195625
195797
|
// ../runtime/src/engine.ts
|
|
195626
195798
|
var astCache = /* @__PURE__ */ new WeakMap();
|
|
195799
|
+
var OWNER = "Patter";
|
|
195800
|
+
var esc2 = (id) => id.replace(/%/g, "%25").replace(/\//g, "%2F");
|
|
195801
|
+
var OWNS_REGISTRY = /* @__PURE__ */ Symbol("ownsRegistry");
|
|
195802
|
+
var keys = {
|
|
195803
|
+
/** A scene's SHARED `@scene` props (one bag per scene, every flow's). */
|
|
195804
|
+
stage: (sceneId) => `patter/scene/${esc2(sceneId)}`,
|
|
195805
|
+
/** Everything one flow registers starts with this. */
|
|
195806
|
+
flow: (flowId) => `patter/flow/${esc2(flowId)}/`,
|
|
195807
|
+
/** A flow's NOT-shared `@patter` globals. */
|
|
195808
|
+
flowGlobals: (flowId) => `patter/flow/${esc2(flowId)}/patter`,
|
|
195809
|
+
/** A flow's NOT-shared `@scene` props for one scene. */
|
|
195810
|
+
flowScene: (flowId, sceneId) => `patter/flow/${esc2(flowId)}/scene/${esc2(sceneId)}`
|
|
195811
|
+
};
|
|
195627
195812
|
var Engine = class _Engine {
|
|
195628
195813
|
host;
|
|
195629
195814
|
defaultSeed;
|
|
@@ -195683,18 +195868,32 @@ var Engine = class _Engine {
|
|
|
195683
195868
|
const patterSharedDecls = props.filter((p) => p.shared ?? true).map(toDecl);
|
|
195684
195869
|
const patterLocalDecls = props.filter((p) => !(p.shared ?? true)).map(toDecl);
|
|
195685
195870
|
const patterSharedNames = new Set(patterSharedDecls.map((d) => d.name.toLowerCase()));
|
|
195686
|
-
const
|
|
195687
|
-
const
|
|
195688
|
-
|
|
195689
|
-
|
|
195690
|
-
|
|
195691
|
-
|
|
195692
|
-
|
|
195693
|
-
|
|
195694
|
-
|
|
195695
|
-
if (
|
|
195696
|
-
|
|
195697
|
-
|
|
195871
|
+
const registry = options.registry ?? new ScopeRegistry();
|
|
195872
|
+
const ownsRegistry = !options.registry || options[OWNS_REGISTRY] === true;
|
|
195873
|
+
const patterBag = new PropertyBag(patterSharedDecls, { pathPrefix: "@patter." });
|
|
195874
|
+
const hostScopes = [];
|
|
195875
|
+
const registered = [];
|
|
195876
|
+
try {
|
|
195877
|
+
registry.mountOwned("patter", patterBag, { owner: OWNER });
|
|
195878
|
+
registered.push("patter");
|
|
195879
|
+
const hostBound = /* @__PURE__ */ new Set();
|
|
195880
|
+
if (options.world) {
|
|
195881
|
+
const worldSpec = bundle.scopeRegistry?.scopes.find((s) => s.token === "world");
|
|
195882
|
+
const decls = (worldSpec?.declarations ?? []).map(toForeignDecl);
|
|
195883
|
+
registry.defineForeign("world", options.world, decls, { writable: worldSpec?.writable ?? true, owner: OWNER });
|
|
195884
|
+
registered.push("world");
|
|
195885
|
+
hostBound.add("world");
|
|
195886
|
+
}
|
|
195887
|
+
for (const spec of ownsRegistry ? bundle.scopeRegistry?.scopes ?? [] : []) {
|
|
195888
|
+
if (hostBound.has(spec.token) || registry.has(spec.token)) continue;
|
|
195889
|
+
const decls = (spec.declarations ?? []).map((d) => selfBackedDecl(d, spec.writable));
|
|
195890
|
+
registry.defineOwned(spec.token, decls, { owner: OWNER });
|
|
195891
|
+
registered.push(spec.token);
|
|
195892
|
+
hostScopes.push(spec.token);
|
|
195893
|
+
}
|
|
195894
|
+
} catch (e) {
|
|
195895
|
+
for (const k of registered) registry.remove(k, { keep: true });
|
|
195896
|
+
throw e;
|
|
195698
195897
|
}
|
|
195699
195898
|
const sceneSharedNames = /* @__PURE__ */ new Map();
|
|
195700
195899
|
for (const [sceneId, scene] of Object.entries(bundle.scenes)) {
|
|
@@ -195716,7 +195915,10 @@ var Engine = class _Engine {
|
|
|
195716
195915
|
blockGameIdToId: this.blockGameIdToId,
|
|
195717
195916
|
// same instances the engine resolves with
|
|
195718
195917
|
tagIndex: buildTagIndex(bundle),
|
|
195719
|
-
|
|
195918
|
+
registry,
|
|
195919
|
+
ownsRegistry,
|
|
195920
|
+
patterBag,
|
|
195921
|
+
hostScopes,
|
|
195720
195922
|
patterSharedDecls,
|
|
195721
195923
|
patterLocalDecls,
|
|
195722
195924
|
patterSharedNames,
|
|
@@ -195733,7 +195935,8 @@ var Engine = class _Engine {
|
|
|
195733
195935
|
captionClose: (bundle.closedCaptions ?? DEFAULT_CAPTION_DELIMITERS).close,
|
|
195734
195936
|
captionCharacter: bundle.closedCaptions?.character || DEFAULT_CAPTION_CHARACTER,
|
|
195735
195937
|
// absent/empty -> SFX
|
|
195736
|
-
refSplitCache: /* @__PURE__ */ new Map()
|
|
195938
|
+
refSplitCache: /* @__PURE__ */ new Map(),
|
|
195939
|
+
refSplitRevision: registry.revision
|
|
195737
195940
|
};
|
|
195738
195941
|
}
|
|
195739
195942
|
/** The active locale (string + character-name lookups resolve in it). */
|
|
@@ -195778,10 +195981,12 @@ var Engine = class _Engine {
|
|
|
195778
195981
|
* content-drift policy (§9.8) resolves edits under the cursor: stack frames re-find their next
|
|
195779
195982
|
* child by id, drifted options drop, a vanished snippet is skipped.
|
|
195780
195983
|
*
|
|
195781
|
-
* Returns the REPLACEMENT engine
|
|
195782
|
-
*
|
|
195783
|
-
*
|
|
195784
|
-
*
|
|
195984
|
+
* Returns the REPLACEMENT engine, on the same registry. This one hands its bags over (each is
|
|
195985
|
+
* removed from the registry with its values kept, and the replacement claims them as it
|
|
195986
|
+
* registers), its flows are closed, and it should be discarded. Hosts re-bind their flow handles
|
|
195987
|
+
* via `next.getFlow(id)`. If the restore throws (defensive - §9.8 makes this unreachable for
|
|
195988
|
+
* ordinary edits), the swap falls back to a fresh engine with each saved flow restarted from the
|
|
195989
|
+
* top of the scene it was in; the shared properties carry over.
|
|
195785
195990
|
*/
|
|
195786
195991
|
hotSwap(bundle) {
|
|
195787
195992
|
const snapshot = this.saveGame();
|
|
@@ -195790,12 +195995,19 @@ var Engine = class _Engine {
|
|
|
195790
195995
|
next2.setClosedCaptions(this.host.captionsOn);
|
|
195791
195996
|
return next2;
|
|
195792
195997
|
};
|
|
195793
|
-
const
|
|
195998
|
+
const make = () => new _Engine(bundle, {
|
|
195999
|
+
...this.creationOptions,
|
|
196000
|
+
registry: this.host.registry,
|
|
196001
|
+
[OWNS_REGISTRY]: this.host.ownsRegistry
|
|
196002
|
+
});
|
|
196003
|
+
this.release(true);
|
|
196004
|
+
const next = make();
|
|
195794
196005
|
try {
|
|
195795
196006
|
next.loadGame(snapshot);
|
|
195796
196007
|
return carryOver(next);
|
|
195797
196008
|
} catch {
|
|
195798
|
-
|
|
196009
|
+
next.release(true);
|
|
196010
|
+
const fresh = make();
|
|
195799
196011
|
for (const [id, f] of Object.entries(snapshot.flows)) {
|
|
195800
196012
|
const sceneId = f.cursor.currentSceneId;
|
|
195801
196013
|
try {
|
|
@@ -195834,6 +196046,7 @@ var Engine = class _Engine {
|
|
|
195834
196046
|
* call to reach for when you want a speaker's variation state to carry on.
|
|
195835
196047
|
*/
|
|
195836
196048
|
openFlow(id, opts = {}) {
|
|
196049
|
+
this.assertExternalScopes();
|
|
195837
196050
|
const sceneId = this.resolveSceneRef(opts.scene);
|
|
195838
196051
|
const blockId = this.resolveBlockRef(sceneId, opts.block);
|
|
195839
196052
|
this.flowsById.get(id)?.close();
|
|
@@ -195873,6 +196086,17 @@ var Engine = class _Engine {
|
|
|
195873
196086
|
}
|
|
195874
196087
|
return existing.advanceToStop().played;
|
|
195875
196088
|
}
|
|
196089
|
+
/** Content that names another engine's scope (`@story.act`) runs only where that engine is on this
|
|
196090
|
+
* registry: without it every read would answer false and every write fail, so the flow is refused as
|
|
196091
|
+
* it opens (or the save as it loads), before anything changes. By then a game has built all of its
|
|
196092
|
+
* engines, whatever order it built them in. The same message on every runtime. */
|
|
196093
|
+
assertExternalScopes() {
|
|
196094
|
+
for (const token2 of this.host.bundle.externalScopes ?? []) {
|
|
196095
|
+
if (!this.host.registry.has(token2)) {
|
|
196096
|
+
throw new Error(`this content names @${token2}, which no engine on this registry registered: give every engine the game's one registry`);
|
|
196097
|
+
}
|
|
196098
|
+
}
|
|
196099
|
+
}
|
|
195876
196100
|
/** Resolve a scene reference (a gameId address OR an internal id) to its internal id. */
|
|
195877
196101
|
resolveSceneRef(ref) {
|
|
195878
196102
|
if (ref == null) return void 0;
|
|
@@ -196058,7 +196282,7 @@ var Engine = class _Engine {
|
|
|
196058
196282
|
* loadGame() replaces every bag, so re-enumerate after a load.
|
|
196059
196283
|
*/
|
|
196060
196284
|
listBags() {
|
|
196061
|
-
const mounts = [{ bag: this.host.
|
|
196285
|
+
const mounts = [{ bag: this.host.patterBag }];
|
|
196062
196286
|
for (const [sceneId, bag] of this.host.stageBags) mounts.push({ bag, pathPrefix: `@scene:${sceneId}.` });
|
|
196063
196287
|
return mounts;
|
|
196064
196288
|
}
|
|
@@ -196077,15 +196301,31 @@ var Engine = class _Engine {
|
|
|
196077
196301
|
reset() {
|
|
196078
196302
|
for (const flow of this.flowsById.values()) flow.close();
|
|
196079
196303
|
this.flowsById.clear();
|
|
196080
|
-
this.host.
|
|
196304
|
+
this.host.patterBag.reseed(this.host.patterSharedDecls);
|
|
196081
196305
|
this.host.sharedVisits.clear();
|
|
196082
196306
|
this.host.sharedSelectors.clear();
|
|
196307
|
+
for (const s of this.host.stageBags.keys()) this.host.registry.remove(keys.stage(s));
|
|
196083
196308
|
this.host.stageBags.clear();
|
|
196309
|
+
this.host.registry.discardParked("patter/");
|
|
196310
|
+
}
|
|
196311
|
+
/** Remove every bag this engine registered, keeping the values parked when `keep` (a live reload
|
|
196312
|
+
* handing its state to a replacement), and close its flows. The engine is inert afterwards. */
|
|
196313
|
+
release(keep) {
|
|
196314
|
+
for (const flow of this.flowsById.values()) {
|
|
196315
|
+
flow.releaseBags(keep);
|
|
196316
|
+
flow.close();
|
|
196317
|
+
}
|
|
196318
|
+
this.flowsById.clear();
|
|
196319
|
+
const reg = this.host.registry;
|
|
196320
|
+
for (const s of this.host.stageBags.keys()) reg.remove(keys.stage(s), { keep });
|
|
196321
|
+
this.host.stageBags.clear();
|
|
196322
|
+
for (const t of ["patter", ...this.host.hostScopes]) if (reg.has(t)) reg.remove(t, { keep });
|
|
196323
|
+
if (this.creationOptions.world && reg.has("world")) reg.remove("world");
|
|
196084
196324
|
}
|
|
196085
196325
|
/** Read a shared (`@patter` / foreign) property by ref. `@scene` refs are rejected (flow-level). */
|
|
196086
196326
|
getProperty(ref) {
|
|
196087
196327
|
const { scope, name } = this.splitShared(ref);
|
|
196088
|
-
return this.host.
|
|
196328
|
+
return this.host.registry.get(scope, name);
|
|
196089
196329
|
}
|
|
196090
196330
|
/** Write a shared (`@patter` / foreign) property by ref. `@scene` refs are rejected (flow-level).
|
|
196091
196331
|
*
|
|
@@ -196096,7 +196336,7 @@ var Engine = class _Engine {
|
|
|
196096
196336
|
* were each refused the one property they existed to move.) */
|
|
196097
196337
|
setProperty(ref, value) {
|
|
196098
196338
|
const { scope, name } = this.splitShared(ref);
|
|
196099
|
-
this.host.
|
|
196339
|
+
this.host.registry.set(scope, name, value, { host: true });
|
|
196100
196340
|
}
|
|
196101
196341
|
/** The shared `@patter` properties, for a live state inspector: each with its ref, type, current
|
|
196102
196342
|
* value, declared default (for reset), and enum options. Mirrors the Unity / Godot ports. */
|
|
@@ -196143,54 +196383,66 @@ var Engine = class _Engine {
|
|
|
196143
196383
|
// @scene is scene-namespaced and needs a flow's current scene - silently
|
|
196144
196384
|
// routing it into the shared bag (as a junk "scene.x" key) was a trap.
|
|
196145
196385
|
splitShared(ref) {
|
|
196146
|
-
|
|
196147
|
-
if (!split) {
|
|
196148
|
-
split = splitRef(ref, (t) => t === "scene" || this.host.shared.has(t));
|
|
196149
|
-
this.host.refSplitCache.set(ref, split);
|
|
196150
|
-
}
|
|
196386
|
+
const split = splitHostRef(this.host, ref);
|
|
196151
196387
|
if (split.scope === "scene") {
|
|
196152
196388
|
throw new Error(`'${ref}': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);
|
|
196153
196389
|
}
|
|
196154
196390
|
return split;
|
|
196155
196391
|
}
|
|
196156
|
-
/**
|
|
196392
|
+
/** The shared `@patter` values alone, as `{ patter: {...} }`.
|
|
196393
|
+
* @deprecated The registry holds every property now: a game saves `registry.save()` once, and a
|
|
196394
|
+
* standalone engine's `saveGame()` carries its registry's values. Removed at the next breaking release. */
|
|
196157
196395
|
save() {
|
|
196158
|
-
return this.host.
|
|
196396
|
+
return { patter: this.host.patterBag.save() };
|
|
196159
196397
|
}
|
|
196160
|
-
/**
|
|
196398
|
+
/** Lay a `{ patter: {...} }` section over the shared `@patter` values; anything else is ignored.
|
|
196399
|
+
* @deprecated See `save`. Removed at the next breaking release. */
|
|
196161
196400
|
load(blob) {
|
|
196162
|
-
this.host.
|
|
196401
|
+
if (blob.patter) this.host.patterBag.load(blob.patter);
|
|
196163
196402
|
}
|
|
196164
|
-
/** Snapshot the whole game
|
|
196403
|
+
/** Snapshot the whole game's NON-property state: visit counts, shared selector cursors, and every
|
|
196404
|
+
* live flow's cursor and PRNG. The property values are the registry's: a standalone engine (one that
|
|
196405
|
+
* made its own registry) carries them here under `registry`; a game that passed a registry saves it
|
|
196406
|
+
* once itself, beside each engine's `saveGame()`. */
|
|
196165
196407
|
saveGame() {
|
|
196166
196408
|
const flows = {};
|
|
196167
196409
|
for (const [id, flow] of this.flowsById) flows[id] = flow.snapshot();
|
|
196168
196410
|
return {
|
|
196169
|
-
version:
|
|
196170
|
-
|
|
196411
|
+
version: SAVE_VERSION,
|
|
196412
|
+
...this.host.ownsRegistry ? { registry: this.host.registry.save() } : {},
|
|
196171
196413
|
sharedVisits: Object.fromEntries(this.host.sharedVisits),
|
|
196172
196414
|
sharedSelectors: serialiseSelectors(this.host.sharedSelectors),
|
|
196173
|
-
stageBags: Object.fromEntries([...this.host.stageBags].map(([s, bag]) => [s, bag.save()])),
|
|
196174
196415
|
flows
|
|
196175
196416
|
};
|
|
196176
196417
|
}
|
|
196177
|
-
/**
|
|
196418
|
+
/**
|
|
196419
|
+
* Restore a `saveGame()`: visit counts, shared selector cursors, and every flow. Property values come
|
|
196420
|
+
* from the registry. A save that carries them (a standalone engine's, or a version 2 save from before
|
|
196421
|
+
* the registry held them) has them moved into the registry here; otherwise the game loads its
|
|
196422
|
+
* registry itself, before or after this call. Either order works: this engine's bags are handed back
|
|
196423
|
+
* to the registry (values kept) and the restored flows claim them as they register.
|
|
196424
|
+
*/
|
|
196178
196425
|
loadGame(save) {
|
|
196179
|
-
|
|
196180
|
-
|
|
196426
|
+
const version2 = save.version;
|
|
196427
|
+
if (version2 !== 2 && version2 !== SAVE_VERSION) throw new Error(`unsupported save version: ${String(version2)}`);
|
|
196428
|
+
this.assertExternalScopes();
|
|
196429
|
+
const reg = this.host.registry;
|
|
196430
|
+
for (const [id, flow] of this.flowsById) {
|
|
196431
|
+
flow.releaseBags(id in save.flows);
|
|
196432
|
+
flow.close();
|
|
196433
|
+
}
|
|
196434
|
+
this.flowsById.clear();
|
|
196435
|
+
for (const s of this.host.stageBags.keys()) reg.remove(keys.stage(s), { keep: true });
|
|
196436
|
+
this.host.stageBags.clear();
|
|
196437
|
+
const values = save.version === 2 ? sectionsFromV2(save) : save.registry;
|
|
196438
|
+
if (values) {
|
|
196439
|
+
if (this.host.ownsRegistry) reg.load(values);
|
|
196440
|
+
else reg.load(values, { keepParked: true });
|
|
196441
|
+
}
|
|
196181
196442
|
this.host.sharedVisits.clear();
|
|
196182
196443
|
for (const [id, n] of Object.entries(save.sharedVisits ?? {})) this.host.sharedVisits.set(id, n);
|
|
196183
196444
|
this.host.sharedSelectors.clear();
|
|
196184
196445
|
for (const [id, st] of deserialiseSelectors(save.sharedSelectors)) this.host.sharedSelectors.set(id, st);
|
|
196185
|
-
this.host.stageBags.clear();
|
|
196186
|
-
for (const [s, values] of Object.entries(save.stageBags ?? {})) {
|
|
196187
|
-
const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
|
|
196188
|
-
const decls = (this.host.bundle.scenes[s]?.sceneProps ?? []).filter((d) => shared.has(d.name.toLowerCase()));
|
|
196189
|
-
const bag = new PropertyBag(decls);
|
|
196190
|
-
bag.load(values);
|
|
196191
|
-
this.host.stageBags.set(s, bag);
|
|
196192
|
-
}
|
|
196193
|
-
this.flowsById.clear();
|
|
196194
196446
|
for (const [id, snap] of Object.entries(save.flows)) {
|
|
196195
196447
|
const flow = new Flow(id, this.host, this.defaultSeed);
|
|
196196
196448
|
flow.restore(snap);
|
|
@@ -196202,7 +196454,9 @@ var Flow = class {
|
|
|
196202
196454
|
id;
|
|
196203
196455
|
host;
|
|
196204
196456
|
local;
|
|
196205
|
-
//
|
|
196457
|
+
// the NOT-shared `@patter` globals (this flow's copy), keys.flowGlobals
|
|
196458
|
+
/** The registry keys this flow has registered (its globals and each scene bag). */
|
|
196459
|
+
registered = /* @__PURE__ */ new Set();
|
|
196206
196460
|
rngState;
|
|
196207
196461
|
// Execution cursor. The `stack` is the continuation stack: each frame is a
|
|
196208
196462
|
// position within a block's children (the top frame is the active block run;
|
|
@@ -196227,40 +196481,44 @@ var Flow = class {
|
|
|
196227
196481
|
/** Per-node entry counts for this flow (node id -> times entered). */
|
|
196228
196482
|
visitCounts = /* @__PURE__ */ new Map();
|
|
196229
196483
|
// Per-flow halves of the two scopes. The NOT-shared `@patter` globals live in
|
|
196230
|
-
// `local
|
|
196231
|
-
//
|
|
196232
|
-
//
|
|
196233
|
-
// resolver presents one merged scope, routing each property
|
|
196234
|
-
// declared `shared` flag
|
|
196484
|
+
// `local`; the NOT-shared `@scene` props live in `sceneBags` (namespaced per
|
|
196485
|
+
// scene; they PERSIST across re-entries, spec §7). The SHARED halves live on the
|
|
196486
|
+
// host (`host.patterBag` / `host.stageBags`). All of them are registered in the
|
|
196487
|
+
// game's registry. Each resolver presents one merged scope, routing each property
|
|
196488
|
+
// to its half by the declared `shared` flag: that split is why `@patter` and
|
|
196489
|
+
// `@scene` are composed here rather than aliased to a single registry key.
|
|
196235
196490
|
/** This flow's per-scene LOCAL scene props; see FlowHost.stageBags. */
|
|
196236
196491
|
sceneBags = /* @__PURE__ */ new Map();
|
|
196237
196492
|
patterResolver = {
|
|
196238
|
-
get: (n) => this.host.patterSharedNames.has(n) ? this.host.
|
|
196493
|
+
get: (n) => this.host.patterSharedNames.has(n) ? this.host.patterBag.get(n) : this.local.get(n),
|
|
196239
196494
|
set: (n, v) => {
|
|
196240
|
-
if (this.host.patterSharedNames.has(n)) this.host.
|
|
196241
|
-
else this.local.set(
|
|
196495
|
+
if (this.host.patterSharedNames.has(n)) this.host.registry.set("patter", n, v);
|
|
196496
|
+
else this.local.set(n, v);
|
|
196242
196497
|
}
|
|
196243
196498
|
};
|
|
196244
196499
|
sceneResolver = {
|
|
196245
196500
|
get: (n) => {
|
|
196246
196501
|
const s = this.currentSceneId;
|
|
196247
196502
|
if (s === null) return void 0;
|
|
196248
|
-
|
|
196249
|
-
return bag?.get(n);
|
|
196503
|
+
return this.sceneBagFor(s, n)?.get(n);
|
|
196250
196504
|
},
|
|
196251
196505
|
set: (n, v) => {
|
|
196252
196506
|
const s = this.currentSceneId;
|
|
196253
196507
|
if (s === null) return;
|
|
196254
|
-
const bag = this.
|
|
196508
|
+
const bag = this.sceneBagFor(s, n);
|
|
196255
196509
|
if (bag) bag.set(n, v);
|
|
196256
196510
|
}
|
|
196257
196511
|
};
|
|
196258
|
-
// The eval context is built
|
|
196259
|
-
//
|
|
196260
|
-
//
|
|
196261
|
-
//
|
|
196262
|
-
//
|
|
196512
|
+
// The eval context is built once and REFRESHED only when the registry's set of
|
|
196513
|
+
// scopes moves (its `revision`): every constituent resolves live state at call
|
|
196514
|
+
// time (bags mutate in place per scoperegistry's contract; patter/scene route
|
|
196515
|
+
// through this flow's resolvers, which read the current `local`/`sceneBags`/
|
|
196516
|
+
// `currentSceneId`; the host callbacks read current flow fields), but another
|
|
196517
|
+
// engine registering `@story` after this flow opened must still be readable.
|
|
196518
|
+
// Rebuilding it per evaluation was the engine's hottest allocation.
|
|
196263
196519
|
evalCtx;
|
|
196520
|
+
ctxRevision = -1;
|
|
196521
|
+
registryQualities;
|
|
196264
196522
|
flowLog = [];
|
|
196265
196523
|
/** Monotonic across the flow's life; survives clearLog so two reads agree on order. */
|
|
196266
196524
|
flowSeq = 0;
|
|
@@ -196268,12 +196526,9 @@ var Flow = class {
|
|
|
196268
196526
|
this.id = id;
|
|
196269
196527
|
this.host = host2;
|
|
196270
196528
|
this.rngState = toUint32(seed);
|
|
196271
|
-
this.local = this.
|
|
196272
|
-
const scopes = { ...host2.shared.toEvalContext().scopes };
|
|
196273
|
-
scopes["patter"] = this.patterResolver;
|
|
196274
|
-
scopes["scene"] = this.sceneResolver;
|
|
196529
|
+
this.local = this.newLocal();
|
|
196275
196530
|
this.evalCtx = {
|
|
196276
|
-
scopes,
|
|
196531
|
+
scopes: {},
|
|
196277
196532
|
host: {
|
|
196278
196533
|
nextRandom: this.rng,
|
|
196279
196534
|
visits: (id2) => this.visitCounts.get(id2) ?? 0,
|
|
@@ -196286,6 +196541,21 @@ var Flow = class {
|
|
|
196286
196541
|
qualities: (scope, name) => this.stagesFor(scope, name)
|
|
196287
196542
|
};
|
|
196288
196543
|
}
|
|
196544
|
+
/** The eval context, its scopes refreshed if the registry's set of scopes has moved since. */
|
|
196545
|
+
context() {
|
|
196546
|
+
const reg = this.host.registry;
|
|
196547
|
+
if (reg.revision !== this.ctxRevision) {
|
|
196548
|
+
const base = reg.toEvalContext();
|
|
196549
|
+
const scopes = this.evalCtx.scopes;
|
|
196550
|
+
for (const k of Object.keys(scopes)) delete scopes[k];
|
|
196551
|
+
Object.assign(scopes, base.scopes);
|
|
196552
|
+
scopes["patter"] = this.patterResolver;
|
|
196553
|
+
scopes["scene"] = this.sceneResolver;
|
|
196554
|
+
this.registryQualities = base.qualities;
|
|
196555
|
+
this.ctxRevision = reg.revision;
|
|
196556
|
+
}
|
|
196557
|
+
return this.evalCtx;
|
|
196558
|
+
}
|
|
196289
196559
|
/** The stage ladder of `@scope.name` when it is a declared quality, else undefined. Names compare
|
|
196290
196560
|
* lowercase, as the compiler emits references (the selfBackedResolver lesson). */
|
|
196291
196561
|
stagesFor(scope, name) {
|
|
@@ -196298,13 +196568,14 @@ var Flow = class {
|
|
|
196298
196568
|
const scene = this.currentSceneId != null ? this.host.bundle.scenes[this.currentSceneId] : void 0;
|
|
196299
196569
|
return fromDecls(scene?.sceneProps);
|
|
196300
196570
|
}
|
|
196301
|
-
return fromDecls(this.host.bundle.scopeRegistry?.scopes.find((s) => s.token === scope)?.declarations);
|
|
196571
|
+
return this.registryQualities?.(scope, name) ?? fromDecls(this.host.bundle.scopeRegistry?.scopes.find((s) => s.token === scope)?.declarations);
|
|
196302
196572
|
}
|
|
196303
196573
|
// -- Host API -------------------------------------------------------------
|
|
196304
196574
|
/** Begin this flow at a scene (and optionally a specific block within it). */
|
|
196305
196575
|
start(sceneId, blockId) {
|
|
196306
|
-
this.
|
|
196307
|
-
this.
|
|
196576
|
+
this.releaseBags(false);
|
|
196577
|
+
this.host.registry.discardParked(keys.flow(this.id));
|
|
196578
|
+
this.mountLocal();
|
|
196308
196579
|
this.selectors.clear();
|
|
196309
196580
|
this.visitCounts.clear();
|
|
196310
196581
|
this.stack = [];
|
|
@@ -196404,6 +196675,7 @@ var Flow = class {
|
|
|
196404
196675
|
* cannot quietly mutate the world. Terminal: unlike ending, a close is never revived.
|
|
196405
196676
|
*/
|
|
196406
196677
|
close() {
|
|
196678
|
+
this.releaseBags(false);
|
|
196407
196679
|
this.closed = true;
|
|
196408
196680
|
this.flowEnded = true;
|
|
196409
196681
|
this.stack = [];
|
|
@@ -196513,7 +196785,7 @@ var Flow = class {
|
|
|
196513
196785
|
* halves are the Engine's listBags.
|
|
196514
196786
|
*/
|
|
196515
196787
|
listBags() {
|
|
196516
|
-
const mounts = [{ bag: this.local
|
|
196788
|
+
const mounts = [{ bag: this.local, pathPrefix: `${this.id}/@patter.` }];
|
|
196517
196789
|
for (const [sceneId, bag] of this.sceneBags) mounts.push({ bag, pathPrefix: `${this.id}/@scene:${sceneId}.` });
|
|
196518
196790
|
return mounts;
|
|
196519
196791
|
}
|
|
@@ -196561,7 +196833,7 @@ var Flow = class {
|
|
|
196561
196833
|
const { scope, name } = this.splitRef(ref);
|
|
196562
196834
|
if (scope === "patter") return this.patterResolver.get(name);
|
|
196563
196835
|
if (scope === "scene") return this.sceneResolver.get(name);
|
|
196564
|
-
return this.host.
|
|
196836
|
+
return this.host.registry.get(scope, name);
|
|
196565
196837
|
}
|
|
196566
196838
|
/** Write a property by ref (routed by scope, then by the property's `shared` flag). The GAME's
|
|
196567
196839
|
* surface: it writes with host authority, so a `writable: false` host declaration does not refuse
|
|
@@ -196579,16 +196851,13 @@ var Flow = class {
|
|
|
196579
196851
|
if (this.currentSceneId === null) throw new Error(`'${ref}': the flow has not entered a scene yet`);
|
|
196580
196852
|
this.sceneResolver.set(name, value);
|
|
196581
196853
|
} else {
|
|
196582
|
-
this.host.
|
|
196854
|
+
this.host.registry.set(scope, name, value, host2 ? { host: true } : void 0);
|
|
196583
196855
|
}
|
|
196584
196856
|
}
|
|
196585
196857
|
// -- Save / restore (engine-driven) --------------------------------------
|
|
196586
|
-
/** @internal Snapshot this flow's cursor +
|
|
196858
|
+
/** @internal Snapshot this flow's cursor + PRNG + visits. Its properties are the registry's. */
|
|
196587
196859
|
snapshot() {
|
|
196588
196860
|
return {
|
|
196589
|
-
scopes: this.local.save(),
|
|
196590
|
-
// owned scope "patter" = the NOT-shared globals (@scene saved separately)
|
|
196591
|
-
sceneBags: Object.fromEntries([...this.sceneBags].map(([s, bag]) => [s, bag.save()])),
|
|
196592
196861
|
rngState: this.rngState,
|
|
196593
196862
|
visits: Object.fromEntries(this.visitCounts),
|
|
196594
196863
|
cursor: {
|
|
@@ -196626,15 +196895,11 @@ var Flow = class {
|
|
|
196626
196895
|
}
|
|
196627
196896
|
return { ...frame };
|
|
196628
196897
|
});
|
|
196629
|
-
this.
|
|
196630
|
-
|
|
196631
|
-
|
|
196632
|
-
|
|
196633
|
-
|
|
196634
|
-
return [s, bag];
|
|
196635
|
-
}));
|
|
196636
|
-
this.local = this.freshLocal();
|
|
196637
|
-
this.local.load(snap.scopes);
|
|
196898
|
+
this.releaseBags(false);
|
|
196899
|
+
this.mountLocal();
|
|
196900
|
+
for (const s of /* @__PURE__ */ new Set([c2.currentSceneId, ...this.stack.map((f) => f.sceneId)])) {
|
|
196901
|
+
if (s !== null && this.host.bundle.scenes[s]) this.ensureSceneBags(s);
|
|
196902
|
+
}
|
|
196638
196903
|
this.activeSnippet = null;
|
|
196639
196904
|
if (c2.activeSnippetId !== null) {
|
|
196640
196905
|
const node = this.host.nodeIndex.get(c2.activeSnippetId);
|
|
@@ -196905,7 +197170,7 @@ var Flow = class {
|
|
|
196905
197170
|
* node (comparisons, scoped vars, literals, other calls) is an atom, evaluated whole.
|
|
196906
197171
|
*/
|
|
196907
197172
|
matchedSpec(node, want) {
|
|
196908
|
-
const evalTruthy = (n) => truthy(evaluate(n, this.
|
|
197173
|
+
const evalTruthy = (n) => truthy(evaluate(n, this.context(), patterDialect));
|
|
196909
197174
|
return matchedSpecificity(node, evalTruthy, { want });
|
|
196910
197175
|
}
|
|
196911
197176
|
/** A selector's cursor state - shared across flows (`group.shared`) or this flow's own. */
|
|
@@ -196932,7 +197197,7 @@ var Flow = class {
|
|
|
196932
197197
|
return truthy(this.evalExpr(node.condition));
|
|
196933
197198
|
}
|
|
196934
197199
|
evalExpr(expr) {
|
|
196935
|
-
return evaluate(this.conditionAst(expr), this.
|
|
197200
|
+
return evaluate(this.conditionAst(expr), this.context(), patterDialect);
|
|
196936
197201
|
}
|
|
196937
197202
|
/** The deserialised (in-memory) AST for an expression, cached per Expression. Shared by the
|
|
196938
197203
|
* evaluator and the Best-match specificity walker so both work off one parse. */
|
|
@@ -197057,18 +197322,51 @@ var Flow = class {
|
|
|
197057
197322
|
const key2 = castStringKey(character);
|
|
197058
197323
|
return this.host.strings[key2] ?? this.host.defaultStrings[key2] ?? this.host.castDisplay.get(character);
|
|
197059
197324
|
}
|
|
197060
|
-
/** Split a ref into scope + name. Tokens: `@scene`,
|
|
197325
|
+
/** Split a ref into scope + name. Tokens: `@scene`, registered tokens, else `@patter` (incl. bare `@name`). */
|
|
197061
197326
|
splitRef(ref) {
|
|
197062
|
-
|
|
197063
|
-
|
|
197064
|
-
|
|
197065
|
-
|
|
197066
|
-
}
|
|
197067
|
-
|
|
197327
|
+
return splitHostRef(this.host, ref);
|
|
197328
|
+
}
|
|
197329
|
+
/** A fresh, unregistered bag for the NOT-shared `@patter` globals (the shared ones live on the host). */
|
|
197330
|
+
newLocal() {
|
|
197331
|
+
return new PropertyBag(this.host.patterLocalDecls, { pathPrefix: "@patter." });
|
|
197332
|
+
}
|
|
197333
|
+
/** Register a fresh globals bag under this flow's key; it claims any values waiting there. */
|
|
197334
|
+
mountLocal() {
|
|
197335
|
+
this.local = this.newLocal();
|
|
197336
|
+
const key2 = keys.flowGlobals(this.id);
|
|
197337
|
+
this.host.registry.mountOwned(key2, this.local, { owner: OWNER });
|
|
197338
|
+
this.registered.add(key2);
|
|
197339
|
+
}
|
|
197340
|
+
/** @internal Remove every bag this flow registered; with `keep`, their values wait in the registry for
|
|
197341
|
+
* the flow that replaces this one. Engine-driven (close, loadGame, hotSwap). */
|
|
197342
|
+
releaseBags(keep) {
|
|
197343
|
+
for (const key2 of this.registered) this.host.registry.remove(key2, { keep });
|
|
197344
|
+
this.registered.clear();
|
|
197345
|
+
this.sceneBags.clear();
|
|
197068
197346
|
}
|
|
197069
|
-
/** The
|
|
197070
|
-
|
|
197071
|
-
|
|
197347
|
+
/** The bag a `@scene` property of scene `s` lives in (stage or this flow's), made if missing. */
|
|
197348
|
+
sceneBagFor(s, name) {
|
|
197349
|
+
if (!this.host.bundle.scenes[s]) return void 0;
|
|
197350
|
+
this.ensureSceneBags(s);
|
|
197351
|
+
return this.host.sceneSharedNames.get(s)?.has(name.toLowerCase()) ? this.host.stageBags.get(s) : this.sceneBags.get(s);
|
|
197352
|
+
}
|
|
197353
|
+
/** Make (and register) scene `s`'s stage bag and this flow's bag for it, if not made yet. A bag made
|
|
197354
|
+
* here claims whatever values the registry holds for its key: that is how a loaded save reaches it. */
|
|
197355
|
+
ensureSceneBags(s) {
|
|
197356
|
+
const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
|
|
197357
|
+
const props = this.host.bundle.scenes[s]?.sceneProps ?? [];
|
|
197358
|
+
if (!this.sceneBags.has(s)) {
|
|
197359
|
+
const bag = new PropertyBag(props.filter((d) => !shared.has(d.name.toLowerCase())), { pathPrefix: "@scene." });
|
|
197360
|
+
const key2 = keys.flowScene(this.id, s);
|
|
197361
|
+
this.host.registry.mountOwned(key2, bag, { owner: OWNER });
|
|
197362
|
+
this.registered.add(key2);
|
|
197363
|
+
this.sceneBags.set(s, bag);
|
|
197364
|
+
}
|
|
197365
|
+
if (!this.host.stageBags.has(s)) {
|
|
197366
|
+
const bag = new PropertyBag(props.filter((d) => shared.has(d.name.toLowerCase())), { pathPrefix: "@scene." });
|
|
197367
|
+
this.host.registry.mountOwned(keys.stage(s), bag, { owner: OWNER });
|
|
197368
|
+
this.host.stageBags.set(s, bag);
|
|
197369
|
+
}
|
|
197072
197370
|
}
|
|
197073
197371
|
/**
|
|
197074
197372
|
* Seed a scene's `@scene` props (spec §7). The not-shared props seed THIS flow's
|
|
@@ -197079,13 +197377,7 @@ var Flow = class {
|
|
|
197079
197377
|
*/
|
|
197080
197378
|
seedScene(scene) {
|
|
197081
197379
|
const shared = this.host.sceneSharedNames.get(scene.id) ?? /* @__PURE__ */ new Set();
|
|
197082
|
-
|
|
197083
|
-
if (!this.sceneBags.has(scene.id)) {
|
|
197084
|
-
this.sceneBags.set(scene.id, new PropertyBag(props.filter((d) => !shared.has(d.name.toLowerCase()))));
|
|
197085
|
-
}
|
|
197086
|
-
if (!this.host.stageBags.has(scene.id)) {
|
|
197087
|
-
this.host.stageBags.set(scene.id, new PropertyBag(props.filter((d) => shared.has(d.name.toLowerCase()))));
|
|
197088
|
-
}
|
|
197380
|
+
this.ensureSceneBags(scene.id);
|
|
197089
197381
|
for (const decl of scene.sceneProps ?? []) {
|
|
197090
197382
|
if (!decl.temporary) continue;
|
|
197091
197383
|
const name = decl.name.toLowerCase();
|
|
@@ -197131,16 +197423,32 @@ function toDecl(decl) {
|
|
|
197131
197423
|
function toForeignDecl(decl) {
|
|
197132
197424
|
return { name: decl.name, type: decl.type, values: decl.values, stages: decl.stages, default: decl.default, writable: decl.writable };
|
|
197133
197425
|
}
|
|
197134
|
-
function
|
|
197135
|
-
const
|
|
197136
|
-
const
|
|
197137
|
-
|
|
197138
|
-
|
|
197139
|
-
|
|
197140
|
-
|
|
197141
|
-
|
|
197142
|
-
|
|
197143
|
-
}
|
|
197426
|
+
function selfBackedDecl(decl, scopeWritable) {
|
|
197427
|
+
const d = toForeignDecl(decl);
|
|
197428
|
+
const writable = decl.writable ?? scopeWritable;
|
|
197429
|
+
return writable === void 0 ? d : { ...d, writable };
|
|
197430
|
+
}
|
|
197431
|
+
function splitHostRef(host2, ref) {
|
|
197432
|
+
if (host2.refSplitRevision !== host2.registry.revision) {
|
|
197433
|
+
host2.refSplitCache.clear();
|
|
197434
|
+
host2.refSplitRevision = host2.registry.revision;
|
|
197435
|
+
}
|
|
197436
|
+
let hit = host2.refSplitCache.get(ref);
|
|
197437
|
+
if (!hit) {
|
|
197438
|
+
hit = splitRef(ref, (t) => t === "scene" || host2.registry.has(t) || (host2.bundle.externalScopes?.includes(t) ?? false));
|
|
197439
|
+
host2.refSplitCache.set(ref, hit);
|
|
197440
|
+
}
|
|
197441
|
+
return hit;
|
|
197442
|
+
}
|
|
197443
|
+
function sectionsFromV2(save) {
|
|
197444
|
+
const out = {};
|
|
197445
|
+
if (save.shared?.patter) out["patter"] = save.shared.patter;
|
|
197446
|
+
for (const [s, v] of Object.entries(save.stageBags ?? {})) out[keys.stage(s)] = v;
|
|
197447
|
+
for (const [id, f] of Object.entries(save.flows ?? {})) {
|
|
197448
|
+
if (f.scopes?.patter) out[keys.flowGlobals(id)] = f.scopes.patter;
|
|
197449
|
+
for (const [s, v] of Object.entries(f.sceneBags ?? {})) out[keys.flowScene(id, s)] = v;
|
|
197450
|
+
}
|
|
197451
|
+
return out;
|
|
197144
197452
|
}
|
|
197145
197453
|
function truthy(v) {
|
|
197146
197454
|
if (typeof v === "boolean") return v;
|
|
@@ -198535,10 +198843,6 @@ function colourIndex(name) {
|
|
|
198535
198843
|
function characterColour(name) {
|
|
198536
198844
|
return CHAR_PALETTE[colourIndex(name)];
|
|
198537
198845
|
}
|
|
198538
|
-
var VISIT_FN_RE = /\b(patter_visits|patter_seen|visits|seen)\s*\(\s*(['"])(.*?)\2\s*\)/g;
|
|
198539
|
-
function humanizeCondition(cond, label) {
|
|
198540
|
-
return cond.replace(VISIT_FN_RE, (_m, fn, _q, id) => `${fn}(${label(id)})`);
|
|
198541
|
-
}
|
|
198542
198846
|
var MARKUP_RE = /<(b|i|bi)>([\s\S]*?)<\/\1>/g;
|
|
198543
198847
|
var INTERP_RE = /\{@[^}]*\}/g;
|
|
198544
198848
|
function textRuns(text) {
|
|
@@ -198613,7 +198917,7 @@ function runScriptDoc(loaded) {
|
|
|
198613
198917
|
blockName.set(block.id, block.name);
|
|
198614
198918
|
}
|
|
198615
198919
|
}
|
|
198616
|
-
const humanize = (cond) =>
|
|
198920
|
+
const humanize = (cond) => humanizeNodeRefs(cond, (id) => blockName.get(id) ?? sceneOf.get(id) ?? id);
|
|
198617
198921
|
const els = [];
|
|
198618
198922
|
const textOf = (id) => source2[id] ?? "";
|
|
198619
198923
|
const jumpText = (j) => {
|
|
@@ -198710,8 +199014,8 @@ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
|
198710
199014
|
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
198711
199015
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
198712
199016
|
var __copyProps2 = (to, from, except, desc) => {
|
|
198713
|
-
if (from && typeof from === "object" || typeof from === "function") for (var
|
|
198714
|
-
key2 =
|
|
199017
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys2 = __getOwnPropNames2(from), i = 0, n = keys2.length, key2; i < n; i++) {
|
|
199018
|
+
key2 = keys2[i];
|
|
198715
199019
|
if (!__hasOwnProp2.call(to, key2) && key2 !== except) __defProp2(to, key2, {
|
|
198716
199020
|
get: ((k) => from[k]).bind(null, key2),
|
|
198717
199021
|
enumerable: !(desc = __getOwnPropDesc2(from, key2)) || desc.enumerable
|
|
@@ -199167,10 +199471,10 @@ var require_events = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
|
199167
199471
|
return this;
|
|
199168
199472
|
}
|
|
199169
199473
|
if (arguments.length === 0) {
|
|
199170
|
-
var
|
|
199474
|
+
var keys2 = Object.keys(events);
|
|
199171
199475
|
var key2;
|
|
199172
|
-
for (i = 0; i <
|
|
199173
|
-
key2 =
|
|
199476
|
+
for (i = 0; i < keys2.length; ++i) {
|
|
199477
|
+
key2 = keys2[i];
|
|
199174
199478
|
if (key2 === "removeListener") continue;
|
|
199175
199479
|
this.removeAllListeners(key2);
|
|
199176
199480
|
}
|
|
@@ -201783,9 +202087,9 @@ var require_isBufferBrowser = /* @__PURE__ */ __commonJSMin(((exports2, module2)
|
|
|
201783
202087
|
var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
201784
202088
|
init_dist();
|
|
201785
202089
|
var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors2(obj2) {
|
|
201786
|
-
var
|
|
202090
|
+
var keys2 = Object.keys(obj2);
|
|
201787
202091
|
var descriptors = {};
|
|
201788
|
-
for (var i = 0; i <
|
|
202092
|
+
for (var i = 0; i < keys2.length; i++) descriptors[keys2[i]] = Object.getOwnPropertyDescriptor(obj2, keys2[i]);
|
|
201789
202093
|
return descriptors;
|
|
201790
202094
|
};
|
|
201791
202095
|
var formatRegExp = /%[sdj%]/g;
|
|
@@ -201921,11 +202225,11 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201921
202225
|
}
|
|
201922
202226
|
var primitive = formatPrimitive(ctx, value);
|
|
201923
202227
|
if (primitive) return primitive;
|
|
201924
|
-
var
|
|
201925
|
-
var visibleKeys = arrayToHash(
|
|
201926
|
-
if (ctx.showHidden)
|
|
201927
|
-
if (isError2(value) && (
|
|
201928
|
-
if (
|
|
202228
|
+
var keys2 = Object.keys(value);
|
|
202229
|
+
var visibleKeys = arrayToHash(keys2);
|
|
202230
|
+
if (ctx.showHidden) keys2 = Object.getOwnPropertyNames(value);
|
|
202231
|
+
if (isError2(value) && (keys2.indexOf("message") >= 0 || keys2.indexOf("description") >= 0)) return formatError(value);
|
|
202232
|
+
if (keys2.length === 0) {
|
|
201929
202233
|
if (isFunction(value)) {
|
|
201930
202234
|
var name = value.name ? ": " + value.name : "";
|
|
201931
202235
|
return ctx.stylize("[Function" + name + "]", "special");
|
|
@@ -201943,13 +202247,13 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201943
202247
|
if (isRegExp(value)) base = " " + RegExp.prototype.toString.call(value);
|
|
201944
202248
|
if (isDate(value)) base = " " + Date.prototype.toUTCString.call(value);
|
|
201945
202249
|
if (isError2(value)) base = " " + formatError(value);
|
|
201946
|
-
if (
|
|
202250
|
+
if (keys2.length === 0 && (!array || value.length == 0)) return braces[0] + base + braces[1];
|
|
201947
202251
|
if (recurseTimes < 0) if (isRegExp(value)) return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
|
201948
202252
|
else return ctx.stylize("[Object]", "special");
|
|
201949
202253
|
ctx.seen.push(value);
|
|
201950
202254
|
var output;
|
|
201951
|
-
if (array) output = formatArray(ctx, value, recurseTimes, visibleKeys,
|
|
201952
|
-
else output =
|
|
202255
|
+
if (array) output = formatArray(ctx, value, recurseTimes, visibleKeys, keys2);
|
|
202256
|
+
else output = keys2.map(function(key2) {
|
|
201953
202257
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key2, array);
|
|
201954
202258
|
});
|
|
201955
202259
|
ctx.seen.pop();
|
|
@@ -201968,11 +202272,11 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
201968
202272
|
function formatError(value) {
|
|
201969
202273
|
return "[" + Error.prototype.toString.call(value) + "]";
|
|
201970
202274
|
}
|
|
201971
|
-
function formatArray(ctx, value, recurseTimes, visibleKeys,
|
|
202275
|
+
function formatArray(ctx, value, recurseTimes, visibleKeys, keys2) {
|
|
201972
202276
|
var output = [];
|
|
201973
202277
|
for (var i = 0, l2 = value.length; i < l2; ++i) if (hasOwnProperty(value, String(i))) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
|
|
201974
202278
|
else output.push("");
|
|
201975
|
-
|
|
202279
|
+
keys2.forEach(function(key2) {
|
|
201976
202280
|
if (!key2.match(/^\d+$/)) output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key2, true));
|
|
201977
202281
|
});
|
|
201978
202282
|
return output;
|
|
@@ -202115,9 +202419,9 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
202115
202419
|
exports2.inherits = require_inherits_browser2();
|
|
202116
202420
|
exports2._extend = function(origin, add) {
|
|
202117
202421
|
if (!add || !isObject3(add)) return origin;
|
|
202118
|
-
var
|
|
202119
|
-
var i =
|
|
202120
|
-
while (i--) origin[
|
|
202422
|
+
var keys2 = Object.keys(add);
|
|
202423
|
+
var i = keys2.length;
|
|
202424
|
+
while (i--) origin[keys2[i]] = add[keys2[i]];
|
|
202121
202425
|
return origin;
|
|
202122
202426
|
};
|
|
202123
202427
|
function hasOwnProperty(obj2, prop) {
|
|
@@ -202199,14 +202503,14 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
|
|
|
202199
202503
|
}));
|
|
202200
202504
|
var require_buffer_list2 = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
202201
202505
|
function ownKeys2(object, enumerableOnly) {
|
|
202202
|
-
var
|
|
202506
|
+
var keys2 = Object.keys(object);
|
|
202203
202507
|
if (Object.getOwnPropertySymbols) {
|
|
202204
202508
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
202205
202509
|
enumerableOnly && (symbols = symbols.filter(function(sym) {
|
|
202206
202510
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
202207
|
-
})),
|
|
202511
|
+
})), keys2.push.apply(keys2, symbols);
|
|
202208
202512
|
}
|
|
202209
|
-
return
|
|
202513
|
+
return keys2;
|
|
202210
202514
|
}
|
|
202211
202515
|
function _objectSpread(target) {
|
|
202212
202516
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -203054,17 +203358,17 @@ var require__stream_writable = /* @__PURE__ */ __commonJSMin(((exports2, module2
|
|
|
203054
203358
|
var require__stream_duplex = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
|
|
203055
203359
|
init_dist();
|
|
203056
203360
|
var objectKeys = Object.keys || function(obj2) {
|
|
203057
|
-
var
|
|
203058
|
-
for (var key2 in obj2)
|
|
203059
|
-
return
|
|
203361
|
+
var keys3 = [];
|
|
203362
|
+
for (var key2 in obj2) keys3.push(key2);
|
|
203363
|
+
return keys3;
|
|
203060
203364
|
};
|
|
203061
203365
|
module2.exports = Duplex;
|
|
203062
203366
|
var Readable = require__stream_readable();
|
|
203063
203367
|
var Writable = require__stream_writable();
|
|
203064
203368
|
require_inherits_browser2()(Duplex, Readable);
|
|
203065
|
-
var
|
|
203066
|
-
for (var v = 0; v <
|
|
203067
|
-
var method =
|
|
203369
|
+
var keys2 = objectKeys(Writable.prototype);
|
|
203370
|
+
for (var v = 0; v < keys2.length; v++) {
|
|
203371
|
+
var method = keys2[v];
|
|
203068
203372
|
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
|
|
203069
203373
|
}
|
|
203070
203374
|
function Duplex(options) {
|
|
@@ -217471,12 +217775,12 @@ var Bitfield = class extends Base {
|
|
|
217471
217775
|
size() {
|
|
217472
217776
|
return this.type.size();
|
|
217473
217777
|
}
|
|
217474
|
-
encode(stream2,
|
|
217778
|
+
encode(stream2, keys2) {
|
|
217475
217779
|
let val = 0;
|
|
217476
217780
|
for (let i = 0; i < this.flags.length; i++) {
|
|
217477
217781
|
const flag = this.flags[i];
|
|
217478
217782
|
if (flag != null) {
|
|
217479
|
-
if (
|
|
217783
|
+
if (keys2[flag]) {
|
|
217480
217784
|
val |= 1 << i;
|
|
217481
217785
|
}
|
|
217482
217786
|
}
|
|
@@ -238873,8 +239177,8 @@ function parsePropertyQuery(query) {
|
|
|
238873
239177
|
if (!m) return null;
|
|
238874
239178
|
const prop = m[1];
|
|
238875
239179
|
const value = m[2].replace(/^[\s=<>!]+/, "").replace(/^["']|["']$/g, "").trim().toLowerCase() || void 0;
|
|
238876
|
-
const
|
|
238877
|
-
const regexes = prop.includes(".") ? [new RegExp(`@${
|
|
239180
|
+
const esc3 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
239181
|
+
const regexes = prop.includes(".") ? [new RegExp(`@${esc3(prop)}\\b`, "i")] : [new RegExp(`@${esc3(prop)}\\b`, "i"), new RegExp(`@patter\\.${esc3(prop)}\\b`, "i")];
|
|
238878
239182
|
return { regexes, value };
|
|
238879
239183
|
}
|
|
238880
239184
|
var indexCache = null;
|
|
@@ -240969,7 +241273,7 @@ function writeTextFiles(files, encoding = "utf8") {
|
|
|
240969
241273
|
// package.json
|
|
240970
241274
|
var package_default = {
|
|
240971
241275
|
name: "@patterkit/cli",
|
|
240972
|
-
version: "0.3.
|
|
241276
|
+
version: "0.3.9",
|
|
240973
241277
|
description: "The `patter` CLI: validate, format, export, and play a Patter project.",
|
|
240974
241278
|
type: "module",
|
|
240975
241279
|
license: "MIT",
|
|
@@ -240998,8 +241302,8 @@ var package_default = {
|
|
|
240998
241302
|
"build:standalone:others": "node scripts/build-standalone.mjs --targets=linux-x64,linux-arm64,windows-x64"
|
|
240999
241303
|
},
|
|
241000
241304
|
dependencies: {
|
|
241001
|
-
"@patterkit/core": "0.2.
|
|
241002
|
-
"@patterkit/ops": "0.7.
|
|
241305
|
+
"@patterkit/core": "0.2.5",
|
|
241306
|
+
"@patterkit/ops": "0.7.7",
|
|
241003
241307
|
"@wildwinter/simple-vc-lib": "^0.4.1"
|
|
241004
241308
|
}
|
|
241005
241309
|
};
|