@craftrpgs/cli 0.2.0 → 0.2.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/bin.js +1404 -259
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -6301,7 +6301,7 @@ var require_ajv = __commonJS(function(exports, module) {
|
|
|
6301
6301
|
} });
|
|
6302
6302
|
});
|
|
6303
6303
|
|
|
6304
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6304
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/identity.js
|
|
6305
6305
|
var require_identity = __commonJS(function(exports) {
|
|
6306
6306
|
var ALIAS = Symbol.for("yaml.alias");
|
|
6307
6307
|
var DOC = Symbol.for("yaml.document");
|
|
@@ -6355,7 +6355,7 @@ var require_identity = __commonJS(function(exports) {
|
|
|
6355
6355
|
exports.isSeq = isSeq;
|
|
6356
6356
|
});
|
|
6357
6357
|
|
|
6358
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6358
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/visit.js
|
|
6359
6359
|
var require_visit = __commonJS(function(exports) {
|
|
6360
6360
|
var identity = require_identity();
|
|
6361
6361
|
var BREAK = Symbol("break visit");
|
|
@@ -6510,7 +6510,7 @@ var require_visit = __commonJS(function(exports) {
|
|
|
6510
6510
|
exports.visitAsync = visitAsync;
|
|
6511
6511
|
});
|
|
6512
6512
|
|
|
6513
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6513
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/doc/directives.js
|
|
6514
6514
|
var require_directives = __commonJS(function(exports) {
|
|
6515
6515
|
var identity = require_identity();
|
|
6516
6516
|
var visit = require_visit();
|
|
@@ -6662,7 +6662,7 @@ var require_directives = __commonJS(function(exports) {
|
|
|
6662
6662
|
exports.Directives = Directives;
|
|
6663
6663
|
});
|
|
6664
6664
|
|
|
6665
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6665
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/doc/anchors.js
|
|
6666
6666
|
var require_anchors = __commonJS(function(exports) {
|
|
6667
6667
|
var identity = require_identity();
|
|
6668
6668
|
var visit = require_visit();
|
|
@@ -6724,7 +6724,7 @@ var require_anchors = __commonJS(function(exports) {
|
|
|
6724
6724
|
exports.findNewAnchor = findNewAnchor;
|
|
6725
6725
|
});
|
|
6726
6726
|
|
|
6727
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6727
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/doc/applyReviver.js
|
|
6728
6728
|
var require_applyReviver = __commonJS(function(exports) {
|
|
6729
6729
|
function applyReviver(reviver, obj, key, val) {
|
|
6730
6730
|
if (val && typeof val === "object") {
|
|
@@ -6771,7 +6771,7 @@ var require_applyReviver = __commonJS(function(exports) {
|
|
|
6771
6771
|
exports.applyReviver = applyReviver;
|
|
6772
6772
|
});
|
|
6773
6773
|
|
|
6774
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6774
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/toJS.js
|
|
6775
6775
|
var require_toJS = __commonJS(function(exports) {
|
|
6776
6776
|
var identity = require_identity();
|
|
6777
6777
|
function toJS(value, arg, ctx) {
|
|
@@ -6798,7 +6798,7 @@ var require_toJS = __commonJS(function(exports) {
|
|
|
6798
6798
|
exports.toJS = toJS;
|
|
6799
6799
|
});
|
|
6800
6800
|
|
|
6801
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6801
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/Node.js
|
|
6802
6802
|
var require_Node = __commonJS(function(exports) {
|
|
6803
6803
|
var applyReviver = require_applyReviver();
|
|
6804
6804
|
var identity = require_identity();
|
|
@@ -6835,7 +6835,7 @@ var require_Node = __commonJS(function(exports) {
|
|
|
6835
6835
|
exports.NodeBase = NodeBase;
|
|
6836
6836
|
});
|
|
6837
6837
|
|
|
6838
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6838
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/Alias.js
|
|
6839
6839
|
var require_Alias = __commonJS(function(exports) {
|
|
6840
6840
|
var anchors = require_anchors();
|
|
6841
6841
|
var visit = require_visit();
|
|
@@ -6854,6 +6854,8 @@ var require_Alias = __commonJS(function(exports) {
|
|
|
6854
6854
|
});
|
|
6855
6855
|
}
|
|
6856
6856
|
resolve(doc, ctx) {
|
|
6857
|
+
if (ctx?.maxAliasCount === 0)
|
|
6858
|
+
throw new ReferenceError("Alias resolution is disabled");
|
|
6857
6859
|
let nodes;
|
|
6858
6860
|
if (ctx?.aliasResolveCache) {
|
|
6859
6861
|
nodes = ctx.aliasResolveCache;
|
|
@@ -6943,7 +6945,7 @@ var require_Alias = __commonJS(function(exports) {
|
|
|
6943
6945
|
exports.Alias = Alias;
|
|
6944
6946
|
});
|
|
6945
6947
|
|
|
6946
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6948
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/Scalar.js
|
|
6947
6949
|
var require_Scalar = __commonJS(function(exports) {
|
|
6948
6950
|
var identity = require_identity();
|
|
6949
6951
|
var Node = require_Node();
|
|
@@ -6971,7 +6973,7 @@ var require_Scalar = __commonJS(function(exports) {
|
|
|
6971
6973
|
exports.isScalarValue = isScalarValue;
|
|
6972
6974
|
});
|
|
6973
6975
|
|
|
6974
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
6976
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/doc/createNode.js
|
|
6975
6977
|
var require_createNode = __commonJS(function(exports) {
|
|
6976
6978
|
var Alias = require_Alias();
|
|
6977
6979
|
var identity = require_identity();
|
|
@@ -7043,7 +7045,7 @@ var require_createNode = __commonJS(function(exports) {
|
|
|
7043
7045
|
exports.createNode = createNode;
|
|
7044
7046
|
});
|
|
7045
7047
|
|
|
7046
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7048
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/Collection.js
|
|
7047
7049
|
var require_Collection = __commonJS(function(exports) {
|
|
7048
7050
|
var createNode = require_createNode();
|
|
7049
7051
|
var identity = require_identity();
|
|
@@ -7158,7 +7160,7 @@ var require_Collection = __commonJS(function(exports) {
|
|
|
7158
7160
|
exports.isEmptyPath = isEmptyPath;
|
|
7159
7161
|
});
|
|
7160
7162
|
|
|
7161
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7163
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyComment.js
|
|
7162
7164
|
var require_stringifyComment = __commonJS(function(exports) {
|
|
7163
7165
|
var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
|
|
7164
7166
|
function indentComment(comment, indent) {
|
|
@@ -7175,7 +7177,7 @@ var require_stringifyComment = __commonJS(function(exports) {
|
|
|
7175
7177
|
exports.stringifyComment = stringifyComment;
|
|
7176
7178
|
});
|
|
7177
7179
|
|
|
7178
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7180
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/foldFlowLines.js
|
|
7179
7181
|
var require_foldFlowLines = __commonJS(function(exports) {
|
|
7180
7182
|
var FOLD_FLOW = "flow";
|
|
7181
7183
|
var FOLD_BLOCK = "block";
|
|
@@ -7312,7 +7314,7 @@ ${indent}${text.slice(fold + 1, end)}`;
|
|
|
7312
7314
|
exports.foldFlowLines = foldFlowLines;
|
|
7313
7315
|
});
|
|
7314
7316
|
|
|
7315
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7317
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyString.js
|
|
7316
7318
|
var require_stringifyString = __commonJS(function(exports) {
|
|
7317
7319
|
var Scalar = require_Scalar();
|
|
7318
7320
|
var foldFlowLines = require_foldFlowLines();
|
|
@@ -7610,7 +7612,7 @@ ${indent}`);
|
|
|
7610
7612
|
exports.stringifyString = stringifyString;
|
|
7611
7613
|
});
|
|
7612
7614
|
|
|
7613
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7615
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringify.js
|
|
7614
7616
|
var require_stringify = __commonJS(function(exports) {
|
|
7615
7617
|
var anchors = require_anchors();
|
|
7616
7618
|
var identity = require_identity();
|
|
@@ -7731,7 +7733,7 @@ ${ctx.indent}${str}`;
|
|
|
7731
7733
|
exports.stringify = stringify;
|
|
7732
7734
|
});
|
|
7733
7735
|
|
|
7734
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7736
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyPair.js
|
|
7735
7737
|
var require_stringifyPair = __commonJS(function(exports) {
|
|
7736
7738
|
var identity = require_identity();
|
|
7737
7739
|
var Scalar = require_Scalar();
|
|
@@ -7867,7 +7869,7 @@ ${ctx.indent}`;
|
|
|
7867
7869
|
exports.stringifyPair = stringifyPair;
|
|
7868
7870
|
});
|
|
7869
7871
|
|
|
7870
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7872
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/log.js
|
|
7871
7873
|
var require_log = __commonJS(function(exports) {
|
|
7872
7874
|
var node_process = __require("process");
|
|
7873
7875
|
function debug(logLevel, ...messages) {
|
|
@@ -7886,7 +7888,7 @@ var require_log = __commonJS(function(exports) {
|
|
|
7886
7888
|
exports.warn = warn;
|
|
7887
7889
|
});
|
|
7888
7890
|
|
|
7889
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7891
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/merge.js
|
|
7890
7892
|
var require_merge = __commonJS(function(exports) {
|
|
7891
7893
|
var identity = require_identity();
|
|
7892
7894
|
var Scalar = require_Scalar();
|
|
@@ -7903,18 +7905,18 @@ var require_merge = __commonJS(function(exports) {
|
|
|
7903
7905
|
};
|
|
7904
7906
|
var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
|
|
7905
7907
|
function addMergeToJSMap(ctx, map, value) {
|
|
7906
|
-
|
|
7907
|
-
if (identity.isSeq(
|
|
7908
|
-
for (const it of
|
|
7908
|
+
const source = resolveAliasValue(ctx, value);
|
|
7909
|
+
if (identity.isSeq(source))
|
|
7910
|
+
for (const it of source.items)
|
|
7909
7911
|
mergeValue(ctx, map, it);
|
|
7910
|
-
else if (Array.isArray(
|
|
7911
|
-
for (const it of
|
|
7912
|
+
else if (Array.isArray(source))
|
|
7913
|
+
for (const it of source)
|
|
7912
7914
|
mergeValue(ctx, map, it);
|
|
7913
7915
|
else
|
|
7914
|
-
mergeValue(ctx, map,
|
|
7916
|
+
mergeValue(ctx, map, source);
|
|
7915
7917
|
}
|
|
7916
7918
|
function mergeValue(ctx, map, value) {
|
|
7917
|
-
const source = ctx
|
|
7919
|
+
const source = resolveAliasValue(ctx, value);
|
|
7918
7920
|
if (!identity.isMap(source))
|
|
7919
7921
|
throw new Error("Merge sources must be maps or map aliases");
|
|
7920
7922
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
@@ -7935,12 +7937,15 @@ var require_merge = __commonJS(function(exports) {
|
|
|
7935
7937
|
}
|
|
7936
7938
|
return map;
|
|
7937
7939
|
}
|
|
7940
|
+
function resolveAliasValue(ctx, value) {
|
|
7941
|
+
return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
|
|
7942
|
+
}
|
|
7938
7943
|
exports.addMergeToJSMap = addMergeToJSMap;
|
|
7939
7944
|
exports.isMergeKey = isMergeKey;
|
|
7940
7945
|
exports.merge = merge;
|
|
7941
7946
|
});
|
|
7942
7947
|
|
|
7943
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
7948
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/addPairToJSMap.js
|
|
7944
7949
|
var require_addPairToJSMap = __commonJS(function(exports) {
|
|
7945
7950
|
var log = require_log();
|
|
7946
7951
|
var merge = require_merge();
|
|
@@ -8001,7 +8006,7 @@ var require_addPairToJSMap = __commonJS(function(exports) {
|
|
|
8001
8006
|
exports.addPairToJSMap = addPairToJSMap;
|
|
8002
8007
|
});
|
|
8003
8008
|
|
|
8004
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8009
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/Pair.js
|
|
8005
8010
|
var require_Pair = __commonJS(function(exports) {
|
|
8006
8011
|
var createNode = require_createNode();
|
|
8007
8012
|
var stringifyPair = require_stringifyPair();
|
|
@@ -8039,7 +8044,7 @@ var require_Pair = __commonJS(function(exports) {
|
|
|
8039
8044
|
exports.createPair = createPair;
|
|
8040
8045
|
});
|
|
8041
8046
|
|
|
8042
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8047
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyCollection.js
|
|
8043
8048
|
var require_stringifyCollection = __commonJS(function(exports) {
|
|
8044
8049
|
var identity = require_identity();
|
|
8045
8050
|
var stringify = require_stringify();
|
|
@@ -8191,7 +8196,7 @@ ${indent}${end}`;
|
|
|
8191
8196
|
exports.stringifyCollection = stringifyCollection;
|
|
8192
8197
|
});
|
|
8193
8198
|
|
|
8194
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8199
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/YAMLMap.js
|
|
8195
8200
|
var require_YAMLMap = __commonJS(function(exports) {
|
|
8196
8201
|
var stringifyCollection = require_stringifyCollection();
|
|
8197
8202
|
var addPairToJSMap = require_addPairToJSMap();
|
|
@@ -8318,7 +8323,7 @@ var require_YAMLMap = __commonJS(function(exports) {
|
|
|
8318
8323
|
exports.findPair = findPair;
|
|
8319
8324
|
});
|
|
8320
8325
|
|
|
8321
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8326
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/common/map.js
|
|
8322
8327
|
var require_map = __commonJS(function(exports) {
|
|
8323
8328
|
var identity = require_identity();
|
|
8324
8329
|
var YAMLMap = require_YAMLMap();
|
|
@@ -8337,7 +8342,7 @@ var require_map = __commonJS(function(exports) {
|
|
|
8337
8342
|
exports.map = map;
|
|
8338
8343
|
});
|
|
8339
8344
|
|
|
8340
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8345
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/nodes/YAMLSeq.js
|
|
8341
8346
|
var require_YAMLSeq = __commonJS(function(exports) {
|
|
8342
8347
|
var createNode = require_createNode();
|
|
8343
8348
|
var stringifyCollection = require_stringifyCollection();
|
|
@@ -8430,7 +8435,7 @@ var require_YAMLSeq = __commonJS(function(exports) {
|
|
|
8430
8435
|
exports.YAMLSeq = YAMLSeq;
|
|
8431
8436
|
});
|
|
8432
8437
|
|
|
8433
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8438
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/common/seq.js
|
|
8434
8439
|
var require_seq = __commonJS(function(exports) {
|
|
8435
8440
|
var identity = require_identity();
|
|
8436
8441
|
var YAMLSeq = require_YAMLSeq();
|
|
@@ -8449,7 +8454,7 @@ var require_seq = __commonJS(function(exports) {
|
|
|
8449
8454
|
exports.seq = seq;
|
|
8450
8455
|
});
|
|
8451
8456
|
|
|
8452
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8457
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/common/string.js
|
|
8453
8458
|
var require_string = __commonJS(function(exports) {
|
|
8454
8459
|
var stringifyString = require_stringifyString();
|
|
8455
8460
|
var string = {
|
|
@@ -8465,7 +8470,7 @@ var require_string = __commonJS(function(exports) {
|
|
|
8465
8470
|
exports.string = string;
|
|
8466
8471
|
});
|
|
8467
8472
|
|
|
8468
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8473
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/common/null.js
|
|
8469
8474
|
var require_null = __commonJS(function(exports) {
|
|
8470
8475
|
var Scalar = require_Scalar();
|
|
8471
8476
|
var nullTag = {
|
|
@@ -8480,7 +8485,7 @@ var require_null = __commonJS(function(exports) {
|
|
|
8480
8485
|
exports.nullTag = nullTag;
|
|
8481
8486
|
});
|
|
8482
8487
|
|
|
8483
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8488
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/core/bool.js
|
|
8484
8489
|
var require_bool = __commonJS(function(exports) {
|
|
8485
8490
|
var Scalar = require_Scalar();
|
|
8486
8491
|
var boolTag = {
|
|
@@ -8501,7 +8506,7 @@ var require_bool = __commonJS(function(exports) {
|
|
|
8501
8506
|
exports.boolTag = boolTag;
|
|
8502
8507
|
});
|
|
8503
8508
|
|
|
8504
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8509
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyNumber.js
|
|
8505
8510
|
var require_stringifyNumber = __commonJS(function(exports) {
|
|
8506
8511
|
function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
8507
8512
|
if (typeof value === "bigint")
|
|
@@ -8510,7 +8515,7 @@ var require_stringifyNumber = __commonJS(function(exports) {
|
|
|
8510
8515
|
if (!isFinite(num))
|
|
8511
8516
|
return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
|
|
8512
8517
|
let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
|
8513
|
-
if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") &&
|
|
8518
|
+
if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
|
|
8514
8519
|
let i = n.indexOf(".");
|
|
8515
8520
|
if (i < 0) {
|
|
8516
8521
|
i = n.length;
|
|
@@ -8525,7 +8530,7 @@ var require_stringifyNumber = __commonJS(function(exports) {
|
|
|
8525
8530
|
exports.stringifyNumber = stringifyNumber;
|
|
8526
8531
|
});
|
|
8527
8532
|
|
|
8528
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8533
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/core/float.js
|
|
8529
8534
|
var require_float = __commonJS(function(exports) {
|
|
8530
8535
|
var Scalar = require_Scalar();
|
|
8531
8536
|
var stringifyNumber = require_stringifyNumber();
|
|
@@ -8568,7 +8573,7 @@ var require_float = __commonJS(function(exports) {
|
|
|
8568
8573
|
exports.floatNaN = floatNaN;
|
|
8569
8574
|
});
|
|
8570
8575
|
|
|
8571
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8576
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/core/int.js
|
|
8572
8577
|
var require_int = __commonJS(function(exports) {
|
|
8573
8578
|
var stringifyNumber = require_stringifyNumber();
|
|
8574
8579
|
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
|
@@ -8610,7 +8615,7 @@ var require_int = __commonJS(function(exports) {
|
|
|
8610
8615
|
exports.intOct = intOct;
|
|
8611
8616
|
});
|
|
8612
8617
|
|
|
8613
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8618
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/core/schema.js
|
|
8614
8619
|
var require_schema = __commonJS(function(exports) {
|
|
8615
8620
|
var map = require_map();
|
|
8616
8621
|
var _null = require_null();
|
|
@@ -8635,7 +8640,7 @@ var require_schema = __commonJS(function(exports) {
|
|
|
8635
8640
|
exports.schema = schema;
|
|
8636
8641
|
});
|
|
8637
8642
|
|
|
8638
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8643
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/json/schema.js
|
|
8639
8644
|
var require_schema2 = __commonJS(function(exports) {
|
|
8640
8645
|
var Scalar = require_Scalar();
|
|
8641
8646
|
var map = require_map();
|
|
@@ -8699,7 +8704,7 @@ var require_schema2 = __commonJS(function(exports) {
|
|
|
8699
8704
|
exports.schema = schema;
|
|
8700
8705
|
});
|
|
8701
8706
|
|
|
8702
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8707
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/binary.js
|
|
8703
8708
|
var require_binary = __commonJS(function(exports) {
|
|
8704
8709
|
var node_buffer = __require("buffer");
|
|
8705
8710
|
var Scalar = require_Scalar();
|
|
@@ -8754,7 +8759,7 @@ var require_binary = __commonJS(function(exports) {
|
|
|
8754
8759
|
exports.binary = binary;
|
|
8755
8760
|
});
|
|
8756
8761
|
|
|
8757
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8762
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
|
|
8758
8763
|
var require_pairs = __commonJS(function(exports) {
|
|
8759
8764
|
var identity = require_identity();
|
|
8760
8765
|
var Pair = require_Pair();
|
|
@@ -8829,7 +8834,7 @@ ${cn.comment}` : item.comment;
|
|
|
8829
8834
|
exports.resolvePairs = resolvePairs;
|
|
8830
8835
|
});
|
|
8831
8836
|
|
|
8832
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8837
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/omap.js
|
|
8833
8838
|
var require_omap = __commonJS(function(exports) {
|
|
8834
8839
|
var identity = require_identity();
|
|
8835
8840
|
var toJS = require_toJS();
|
|
@@ -8901,7 +8906,7 @@ var require_omap = __commonJS(function(exports) {
|
|
|
8901
8906
|
exports.omap = omap;
|
|
8902
8907
|
});
|
|
8903
8908
|
|
|
8904
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8909
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/bool.js
|
|
8905
8910
|
var require_bool2 = __commonJS(function(exports) {
|
|
8906
8911
|
var Scalar = require_Scalar();
|
|
8907
8912
|
function boolStringify({ value, source }, ctx) {
|
|
@@ -8930,7 +8935,7 @@ var require_bool2 = __commonJS(function(exports) {
|
|
|
8930
8935
|
exports.trueTag = trueTag;
|
|
8931
8936
|
});
|
|
8932
8937
|
|
|
8933
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8938
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/float.js
|
|
8934
8939
|
var require_float2 = __commonJS(function(exports) {
|
|
8935
8940
|
var Scalar = require_Scalar();
|
|
8936
8941
|
var stringifyNumber = require_stringifyNumber();
|
|
@@ -8976,7 +8981,7 @@ var require_float2 = __commonJS(function(exports) {
|
|
|
8976
8981
|
exports.floatNaN = floatNaN;
|
|
8977
8982
|
});
|
|
8978
8983
|
|
|
8979
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
8984
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/int.js
|
|
8980
8985
|
var require_int2 = __commonJS(function(exports) {
|
|
8981
8986
|
var stringifyNumber = require_stringifyNumber();
|
|
8982
8987
|
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
|
@@ -9052,7 +9057,7 @@ var require_int2 = __commonJS(function(exports) {
|
|
|
9052
9057
|
exports.intOct = intOct;
|
|
9053
9058
|
});
|
|
9054
9059
|
|
|
9055
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9060
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/set.js
|
|
9056
9061
|
var require_set = __commonJS(function(exports) {
|
|
9057
9062
|
var identity = require_identity();
|
|
9058
9063
|
var Pair = require_Pair();
|
|
@@ -9135,7 +9140,7 @@ var require_set = __commonJS(function(exports) {
|
|
|
9135
9140
|
exports.set = set;
|
|
9136
9141
|
});
|
|
9137
9142
|
|
|
9138
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9143
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
|
|
9139
9144
|
var require_timestamp = __commonJS(function(exports) {
|
|
9140
9145
|
var stringifyNumber = require_stringifyNumber();
|
|
9141
9146
|
function parseSexagesimal(str, asBigInt) {
|
|
@@ -9217,7 +9222,7 @@ var require_timestamp = __commonJS(function(exports) {
|
|
|
9217
9222
|
exports.timestamp = timestamp;
|
|
9218
9223
|
});
|
|
9219
9224
|
|
|
9220
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9225
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/yaml-1.1/schema.js
|
|
9221
9226
|
var require_schema3 = __commonJS(function(exports) {
|
|
9222
9227
|
var map = require_map();
|
|
9223
9228
|
var _null = require_null();
|
|
@@ -9258,7 +9263,7 @@ var require_schema3 = __commonJS(function(exports) {
|
|
|
9258
9263
|
exports.schema = schema;
|
|
9259
9264
|
});
|
|
9260
9265
|
|
|
9261
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9266
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/tags.js
|
|
9262
9267
|
var require_tags = __commonJS(function(exports) {
|
|
9263
9268
|
var map = require_map();
|
|
9264
9269
|
var _null = require_null();
|
|
@@ -9349,7 +9354,7 @@ var require_tags = __commonJS(function(exports) {
|
|
|
9349
9354
|
exports.getTags = getTags;
|
|
9350
9355
|
});
|
|
9351
9356
|
|
|
9352
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9357
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/schema/Schema.js
|
|
9353
9358
|
var require_Schema = __commonJS(function(exports) {
|
|
9354
9359
|
var identity = require_identity();
|
|
9355
9360
|
var map = require_map();
|
|
@@ -9379,7 +9384,7 @@ var require_Schema = __commonJS(function(exports) {
|
|
|
9379
9384
|
exports.Schema = Schema;
|
|
9380
9385
|
});
|
|
9381
9386
|
|
|
9382
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9387
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/stringify/stringifyDocument.js
|
|
9383
9388
|
var require_stringifyDocument = __commonJS(function(exports) {
|
|
9384
9389
|
var identity = require_identity();
|
|
9385
9390
|
var stringify = require_stringify();
|
|
@@ -9459,7 +9464,7 @@ var require_stringifyDocument = __commonJS(function(exports) {
|
|
|
9459
9464
|
exports.stringifyDocument = stringifyDocument;
|
|
9460
9465
|
});
|
|
9461
9466
|
|
|
9462
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9467
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/doc/Document.js
|
|
9463
9468
|
var require_Document = __commonJS(function(exports) {
|
|
9464
9469
|
var Alias = require_Alias();
|
|
9465
9470
|
var Collection = require_Collection();
|
|
@@ -9694,7 +9699,7 @@ var require_Document = __commonJS(function(exports) {
|
|
|
9694
9699
|
exports.Document = Document;
|
|
9695
9700
|
});
|
|
9696
9701
|
|
|
9697
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9702
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/errors.js
|
|
9698
9703
|
var require_errors2 = __commonJS(function(exports) {
|
|
9699
9704
|
class YAMLError extends Error {
|
|
9700
9705
|
constructor(name, pos, code, message) {
|
|
@@ -9759,7 +9764,7 @@ ${pointer}
|
|
|
9759
9764
|
exports.prettifyError = prettifyError;
|
|
9760
9765
|
});
|
|
9761
9766
|
|
|
9762
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9767
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-props.js
|
|
9763
9768
|
var require_resolve_props = __commonJS(function(exports) {
|
|
9764
9769
|
function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
|
|
9765
9770
|
let spaceBefore = false;
|
|
@@ -9889,7 +9894,7 @@ var require_resolve_props = __commonJS(function(exports) {
|
|
|
9889
9894
|
exports.resolveProps = resolveProps;
|
|
9890
9895
|
});
|
|
9891
9896
|
|
|
9892
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9897
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/util-contains-newline.js
|
|
9893
9898
|
var require_util_contains_newline = __commonJS(function(exports) {
|
|
9894
9899
|
function containsNewline(key) {
|
|
9895
9900
|
if (!key)
|
|
@@ -9929,7 +9934,7 @@ var require_util_contains_newline = __commonJS(function(exports) {
|
|
|
9929
9934
|
exports.containsNewline = containsNewline;
|
|
9930
9935
|
});
|
|
9931
9936
|
|
|
9932
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9937
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/util-flow-indent-check.js
|
|
9933
9938
|
var require_util_flow_indent_check = __commonJS(function(exports) {
|
|
9934
9939
|
var utilContainsNewline = require_util_contains_newline();
|
|
9935
9940
|
function flowIndentCheck(indent, fc, onError) {
|
|
@@ -9944,7 +9949,7 @@ var require_util_flow_indent_check = __commonJS(function(exports) {
|
|
|
9944
9949
|
exports.flowIndentCheck = flowIndentCheck;
|
|
9945
9950
|
});
|
|
9946
9951
|
|
|
9947
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9952
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/util-map-includes.js
|
|
9948
9953
|
var require_util_map_includes = __commonJS(function(exports) {
|
|
9949
9954
|
var identity = require_identity();
|
|
9950
9955
|
function mapIncludes(ctx, items, search) {
|
|
@@ -9957,7 +9962,7 @@ var require_util_map_includes = __commonJS(function(exports) {
|
|
|
9957
9962
|
exports.mapIncludes = mapIncludes;
|
|
9958
9963
|
});
|
|
9959
9964
|
|
|
9960
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
9965
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-block-map.js
|
|
9961
9966
|
var require_resolve_block_map = __commonJS(function(exports) {
|
|
9962
9967
|
var Pair = require_Pair();
|
|
9963
9968
|
var YAMLMap = require_YAMLMap();
|
|
@@ -10064,7 +10069,7 @@ var require_resolve_block_map = __commonJS(function(exports) {
|
|
|
10064
10069
|
exports.resolveBlockMap = resolveBlockMap;
|
|
10065
10070
|
});
|
|
10066
10071
|
|
|
10067
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10072
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-block-seq.js
|
|
10068
10073
|
var require_resolve_block_seq = __commonJS(function(exports) {
|
|
10069
10074
|
var YAMLSeq = require_YAMLSeq();
|
|
10070
10075
|
var resolveProps = require_resolve_props();
|
|
@@ -10112,7 +10117,7 @@ var require_resolve_block_seq = __commonJS(function(exports) {
|
|
|
10112
10117
|
exports.resolveBlockSeq = resolveBlockSeq;
|
|
10113
10118
|
});
|
|
10114
10119
|
|
|
10115
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10120
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-end.js
|
|
10116
10121
|
var require_resolve_end = __commonJS(function(exports) {
|
|
10117
10122
|
function resolveEnd(end, offset, reqSpace, onError) {
|
|
10118
10123
|
let comment = "";
|
|
@@ -10152,7 +10157,7 @@ var require_resolve_end = __commonJS(function(exports) {
|
|
|
10152
10157
|
exports.resolveEnd = resolveEnd;
|
|
10153
10158
|
});
|
|
10154
10159
|
|
|
10155
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10160
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-flow-collection.js
|
|
10156
10161
|
var require_resolve_flow_collection = __commonJS(function(exports) {
|
|
10157
10162
|
var identity = require_identity();
|
|
10158
10163
|
var Pair = require_Pair();
|
|
@@ -10343,7 +10348,7 @@ var require_resolve_flow_collection = __commonJS(function(exports) {
|
|
|
10343
10348
|
exports.resolveFlowCollection = resolveFlowCollection;
|
|
10344
10349
|
});
|
|
10345
10350
|
|
|
10346
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10351
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/compose-collection.js
|
|
10347
10352
|
var require_compose_collection = __commonJS(function(exports) {
|
|
10348
10353
|
var identity = require_identity();
|
|
10349
10354
|
var Scalar = require_Scalar();
|
|
@@ -10405,7 +10410,7 @@ var require_compose_collection = __commonJS(function(exports) {
|
|
|
10405
10410
|
exports.composeCollection = composeCollection;
|
|
10406
10411
|
});
|
|
10407
10412
|
|
|
10408
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10413
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-block-scalar.js
|
|
10409
10414
|
var require_resolve_block_scalar = __commonJS(function(exports) {
|
|
10410
10415
|
var Scalar = require_Scalar();
|
|
10411
10416
|
function resolveBlockScalar(ctx, scalar, onError) {
|
|
@@ -10598,7 +10603,7 @@ var require_resolve_block_scalar = __commonJS(function(exports) {
|
|
|
10598
10603
|
exports.resolveBlockScalar = resolveBlockScalar;
|
|
10599
10604
|
});
|
|
10600
10605
|
|
|
10601
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10606
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/resolve-flow-scalar.js
|
|
10602
10607
|
var require_resolve_flow_scalar = __commonJS(function(exports) {
|
|
10603
10608
|
var Scalar = require_Scalar();
|
|
10604
10609
|
var resolveEnd = require_resolve_end();
|
|
@@ -10735,7 +10740,7 @@ var require_resolve_flow_scalar = __commonJS(function(exports) {
|
|
|
10735
10740
|
while (next === " " || next === "\t")
|
|
10736
10741
|
next = source[++i + 1];
|
|
10737
10742
|
} else if (next === "x" || next === "u" || next === "U") {
|
|
10738
|
-
const length =
|
|
10743
|
+
const length = next === "x" ? 2 : next === "u" ? 4 : 8;
|
|
10739
10744
|
res += parseCharCode(source, i + 1, length, onError);
|
|
10740
10745
|
i += length;
|
|
10741
10746
|
} else {
|
|
@@ -10804,17 +10809,18 @@ var require_resolve_flow_scalar = __commonJS(function(exports) {
|
|
|
10804
10809
|
const cc = source.substr(offset, length);
|
|
10805
10810
|
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
|
|
10806
10811
|
const code = ok ? parseInt(cc, 16) : NaN;
|
|
10807
|
-
|
|
10812
|
+
try {
|
|
10813
|
+
return String.fromCodePoint(code);
|
|
10814
|
+
} catch {
|
|
10808
10815
|
const raw = source.substr(offset - 2, length + 2);
|
|
10809
10816
|
onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
|
|
10810
10817
|
return raw;
|
|
10811
10818
|
}
|
|
10812
|
-
return String.fromCodePoint(code);
|
|
10813
10819
|
}
|
|
10814
10820
|
exports.resolveFlowScalar = resolveFlowScalar;
|
|
10815
10821
|
});
|
|
10816
10822
|
|
|
10817
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10823
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/compose-scalar.js
|
|
10818
10824
|
var require_compose_scalar = __commonJS(function(exports) {
|
|
10819
10825
|
var identity = require_identity();
|
|
10820
10826
|
var Scalar = require_Scalar();
|
|
@@ -10892,7 +10898,7 @@ var require_compose_scalar = __commonJS(function(exports) {
|
|
|
10892
10898
|
exports.composeScalar = composeScalar;
|
|
10893
10899
|
});
|
|
10894
10900
|
|
|
10895
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10901
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/util-empty-scalar-position.js
|
|
10896
10902
|
var require_util_empty_scalar_position = __commonJS(function(exports) {
|
|
10897
10903
|
function emptyScalarPosition(offset, before, pos) {
|
|
10898
10904
|
if (before) {
|
|
@@ -10919,7 +10925,7 @@ var require_util_empty_scalar_position = __commonJS(function(exports) {
|
|
|
10919
10925
|
exports.emptyScalarPosition = emptyScalarPosition;
|
|
10920
10926
|
});
|
|
10921
10927
|
|
|
10922
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
10928
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/compose-node.js
|
|
10923
10929
|
var require_compose_node = __commonJS(function(exports) {
|
|
10924
10930
|
var Alias = require_Alias();
|
|
10925
10931
|
var identity = require_identity();
|
|
@@ -11022,7 +11028,7 @@ var require_compose_node = __commonJS(function(exports) {
|
|
|
11022
11028
|
exports.composeNode = composeNode;
|
|
11023
11029
|
});
|
|
11024
11030
|
|
|
11025
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11031
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/compose-doc.js
|
|
11026
11032
|
var require_compose_doc = __commonJS(function(exports) {
|
|
11027
11033
|
var Document = require_Document();
|
|
11028
11034
|
var composeNode = require_compose_node();
|
|
@@ -11062,7 +11068,7 @@ var require_compose_doc = __commonJS(function(exports) {
|
|
|
11062
11068
|
exports.composeDoc = composeDoc;
|
|
11063
11069
|
});
|
|
11064
11070
|
|
|
11065
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11071
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/compose/composer.js
|
|
11066
11072
|
var require_composer = __commonJS(function(exports) {
|
|
11067
11073
|
var node_process = __require("process");
|
|
11068
11074
|
var directives = require_directives();
|
|
@@ -11251,7 +11257,7 @@ ${end.comment}` : end.comment;
|
|
|
11251
11257
|
exports.Composer = Composer;
|
|
11252
11258
|
});
|
|
11253
11259
|
|
|
11254
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11260
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/cst-scalar.js
|
|
11255
11261
|
var require_cst_scalar = __commonJS(function(exports) {
|
|
11256
11262
|
var resolveBlockScalar = require_resolve_block_scalar();
|
|
11257
11263
|
var resolveFlowScalar = require_resolve_flow_scalar();
|
|
@@ -11441,7 +11447,7 @@ var require_cst_scalar = __commonJS(function(exports) {
|
|
|
11441
11447
|
exports.setScalarValue = setScalarValue;
|
|
11442
11448
|
});
|
|
11443
11449
|
|
|
11444
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11450
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/cst-stringify.js
|
|
11445
11451
|
var require_cst_stringify = __commonJS(function(exports) {
|
|
11446
11452
|
var stringify = (cst) => ("type" in cst) ? stringifyToken(cst) : stringifyItem(cst);
|
|
11447
11453
|
function stringifyToken(token) {
|
|
@@ -11499,7 +11505,7 @@ var require_cst_stringify = __commonJS(function(exports) {
|
|
|
11499
11505
|
exports.stringify = stringify;
|
|
11500
11506
|
});
|
|
11501
11507
|
|
|
11502
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11508
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/cst-visit.js
|
|
11503
11509
|
var require_cst_visit = __commonJS(function(exports) {
|
|
11504
11510
|
var BREAK = Symbol("break visit");
|
|
11505
11511
|
var SKIP = Symbol("skip children");
|
|
@@ -11558,7 +11564,7 @@ var require_cst_visit = __commonJS(function(exports) {
|
|
|
11558
11564
|
exports.visit = visit;
|
|
11559
11565
|
});
|
|
11560
11566
|
|
|
11561
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11567
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/cst.js
|
|
11562
11568
|
var require_cst = __commonJS(function(exports) {
|
|
11563
11569
|
var cstScalar = require_cst_scalar();
|
|
11564
11570
|
var cstStringify = require_cst_stringify();
|
|
@@ -11659,7 +11665,7 @@ var require_cst = __commonJS(function(exports) {
|
|
|
11659
11665
|
exports.tokenType = tokenType;
|
|
11660
11666
|
});
|
|
11661
11667
|
|
|
11662
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
11668
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/lexer.js
|
|
11663
11669
|
var require_lexer = __commonJS(function(exports) {
|
|
11664
11670
|
var cst = require_cst();
|
|
11665
11671
|
function isEmpty(ch) {
|
|
@@ -12245,7 +12251,7 @@ var require_lexer = __commonJS(function(exports) {
|
|
|
12245
12251
|
exports.Lexer = Lexer;
|
|
12246
12252
|
});
|
|
12247
12253
|
|
|
12248
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
12254
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/line-counter.js
|
|
12249
12255
|
var require_line_counter = __commonJS(function(exports) {
|
|
12250
12256
|
class LineCounter {
|
|
12251
12257
|
constructor() {
|
|
@@ -12273,7 +12279,7 @@ var require_line_counter = __commonJS(function(exports) {
|
|
|
12273
12279
|
exports.LineCounter = LineCounter;
|
|
12274
12280
|
});
|
|
12275
12281
|
|
|
12276
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
12282
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/parse/parser.js
|
|
12277
12283
|
var require_parser = __commonJS(function(exports) {
|
|
12278
12284
|
var node_process = __require("process");
|
|
12279
12285
|
var cst = require_cst();
|
|
@@ -13122,7 +13128,7 @@ var require_parser = __commonJS(function(exports) {
|
|
|
13122
13128
|
exports.Parser = Parser;
|
|
13123
13129
|
});
|
|
13124
13130
|
|
|
13125
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
13131
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/public-api.js
|
|
13126
13132
|
var require_public_api = __commonJS(function(exports) {
|
|
13127
13133
|
var composer = require_composer();
|
|
13128
13134
|
var Document = require_Document();
|
|
@@ -17851,6 +17857,9 @@ function contentTypeForContentExtension(extension) {
|
|
|
17851
17857
|
// ../shared/src/constants/gm-engine.ts
|
|
17852
17858
|
var GM_ENGINES = ["v1", "v2"];
|
|
17853
17859
|
|
|
17860
|
+
// ../shared/src/game-time.ts
|
|
17861
|
+
var TIME_TRACKER_KEY = "time";
|
|
17862
|
+
|
|
17854
17863
|
// ../shared/src/platform-instructions.ts
|
|
17855
17864
|
var PLATFORM_INSTRUCTIONS = [
|
|
17856
17865
|
{
|
|
@@ -17864,53 +17873,65 @@ var PLATFORM_INSTRUCTIONS = [
|
|
|
17864
17873
|
}
|
|
17865
17874
|
},
|
|
17866
17875
|
{
|
|
17867
|
-
id: "
|
|
17868
|
-
revision:
|
|
17876
|
+
id: "only-the-story",
|
|
17877
|
+
revision: 1,
|
|
17869
17878
|
instruction: {
|
|
17870
|
-
name: "
|
|
17879
|
+
name: "Only the story",
|
|
17871
17880
|
when: "always",
|
|
17872
17881
|
section: "Narration",
|
|
17873
|
-
body: "
|
|
17882
|
+
body: "Everything you write outside tool calls is the story the player reads. Never mention your tools, what you look up or record, the current state, trackers, or what you will roll or do next, and never step out of the story to speak as yourself unless the player asks you something out of character. Anything that is not story goes in a hidden note."
|
|
17874
17883
|
}
|
|
17875
17884
|
},
|
|
17876
17885
|
{
|
|
17877
|
-
id: "
|
|
17886
|
+
id: "rolls",
|
|
17878
17887
|
revision: 2,
|
|
17879
17888
|
instruction: {
|
|
17880
|
-
name: "
|
|
17889
|
+
name: "Rolls",
|
|
17881
17890
|
when: "always",
|
|
17882
|
-
section: "
|
|
17883
|
-
body:
|
|
17891
|
+
section: "Rules",
|
|
17892
|
+
body: "When something attempted could fail, roll for it, against a difficulty taken from the files when they set one. The player's dice appear only when you call the tool for their roll: never ask the player to roll in your narration."
|
|
17884
17893
|
}
|
|
17885
17894
|
},
|
|
17886
17895
|
{
|
|
17887
|
-
id: "
|
|
17896
|
+
id: "each-turn",
|
|
17888
17897
|
revision: 1,
|
|
17889
17898
|
instruction: {
|
|
17890
|
-
name: "
|
|
17899
|
+
name: "Each turn",
|
|
17891
17900
|
when: "always",
|
|
17892
17901
|
section: "Narration",
|
|
17893
|
-
body: `
|
|
17902
|
+
body: `Resolve what the player did, then let the people present react from what they want. End each reply on something concrete in front of the player's character that they must answer: someone speaks or acts to them, a threat moves, a choice with a cost. Never end on stillness, a summary or a bare "What do you do?".`
|
|
17894
17903
|
}
|
|
17895
17904
|
},
|
|
17896
17905
|
{
|
|
17897
|
-
id: "
|
|
17898
|
-
revision:
|
|
17906
|
+
id: "places-not-squares",
|
|
17907
|
+
revision: 3,
|
|
17899
17908
|
instruction: {
|
|
17900
|
-
name: "
|
|
17901
|
-
when: "
|
|
17902
|
-
|
|
17903
|
-
|
|
17909
|
+
name: "Places, not squares",
|
|
17910
|
+
when: "situational",
|
|
17911
|
+
trigger: "When someone moves within the scene, or a fight is on",
|
|
17912
|
+
section: "Narration",
|
|
17913
|
+
body: `Never write grid squares or coordinates in the story ("moves to G5", "the goblin at I14"): they are for the current state and your tool calls, and the map shows where everyone stands. Say where someone goes by what is there and how far: "walks over to the well", "ducks behind the overturned cart", "closes to within a sword's reach of the bandit".`
|
|
17914
|
+
}
|
|
17915
|
+
},
|
|
17916
|
+
{
|
|
17917
|
+
id: "travel-times",
|
|
17918
|
+
revision: 2,
|
|
17919
|
+
instruction: {
|
|
17920
|
+
name: "Journeys, not timetables",
|
|
17921
|
+
when: "situational",
|
|
17922
|
+
trigger: "When the party travels somewhere, or the player asks how far or how long a way is",
|
|
17923
|
+
section: "Narration",
|
|
17924
|
+
body: `research() gives exact distances and travel times ("about 2.8 km north, ~35 min on foot"). They keep the world consistent and belong in your tool calls (how much time passes), not recited in the story: "You walk 35 minutes to the butcher's shop" reads like a timetable. Tell the way as the character lives it: "a short walk across the market square", "the sun is well up by the time you reach the butcher's", "half a day's ride along the coast road". Give a figure only when it matters to the moment (a deadline, a chase, a choice between routes) or the player asks, and then say it the way a person would: "a good half hour", "a couple of miles".`
|
|
17904
17925
|
}
|
|
17905
17926
|
},
|
|
17906
17927
|
{
|
|
17907
17928
|
id: "combat-tracker",
|
|
17908
|
-
revision:
|
|
17929
|
+
revision: 8,
|
|
17909
17930
|
instruction: {
|
|
17910
17931
|
name: "Combat tracker",
|
|
17911
17932
|
when: "always",
|
|
17912
17933
|
section: "Rules",
|
|
17913
|
-
body: `When the fight is over (every foe down, fled or surrendered, or the fighting stops), end it: "
|
|
17934
|
+
body: `read() the Running a fight procedure (<procedures>) as the fight starts, and run the fight by it. Everyone fighting, companions and allies included, has a place in the turn order. When the fight is over (every foe down, fled or surrendered, or the fighting stops), end it: {"id": "current-state", "op": "remove", "field": "trackers", "value": "Combat"}.`,
|
|
17914
17935
|
tracker: {
|
|
17915
17936
|
key: "fight",
|
|
17916
17937
|
start: {
|
|
@@ -17926,18 +17947,18 @@ var PLATFORM_INSTRUCTIONS = [
|
|
|
17926
17947
|
},
|
|
17927
17948
|
starts: "when-started",
|
|
17928
17949
|
trigger: "a fight begins",
|
|
17929
|
-
when: "a fighter's turn ends
|
|
17950
|
+
when: "a fighter's turn ends"
|
|
17930
17951
|
}
|
|
17931
17952
|
}
|
|
17932
17953
|
},
|
|
17933
17954
|
{
|
|
17934
17955
|
id: "objectives-tracker",
|
|
17935
|
-
revision:
|
|
17956
|
+
revision: 5,
|
|
17936
17957
|
instruction: {
|
|
17937
17958
|
name: "Objectives",
|
|
17938
17959
|
when: "always",
|
|
17939
17960
|
section: "Rules",
|
|
17940
|
-
body: `The party's objectives are one list for the whole game: what they are working toward beyond this scene. Add one
|
|
17961
|
+
body: `The party's objectives are one list for the whole game: what they are working toward beyond this scene. Add one worded as the party knows it then, short, one step to an objective: {"id": "current-state", "op": "add", "field": "trackers[Objectives].items", "value": "Find Item A"}. A job with several steps they already know (go somewhere, learn something, report back) is one objective per step, in order, each an add of its own ("Get into Place A", "Find Item A", "Bring Item A to Character B"), never one item joined with "and" or "then", so each is marked done when it happens. Mark one done or failed when the story settles it: {"id": "current-state", "op": "set", "field": "trackers[Objectives].items[Find Item A]", "value": "done"}. Steps they do not know yet are never written ahead of the story: they come as objectives of their own when the story gives them. One that runs over time (keep watch, log every contact) is done only when its end comes.`,
|
|
17941
17962
|
tracker: {
|
|
17942
17963
|
key: "objectives",
|
|
17943
17964
|
start: {
|
|
@@ -17951,19 +17972,19 @@ var PLATFORM_INSTRUCTIONS = [
|
|
|
17951
17972
|
question: "In `earlier`, `player_turn` or `narration`, has the party been given an objective, something they are now working toward beyond this scene, that {tracker} does not hold under any wording?",
|
|
17952
17973
|
yes: 'Yes: an order or an assignment handed to them (they act on it or do not refuse it), a request or a job they take on, or a goal they set themselves that will outlast this scene ("Find what woke the Sleeper", "Get the ledger to the Abbot", "Learn who signed the panel"), and nothing in {tracker} says it.',
|
|
17953
17974
|
no: "No: {tracker} already holds it, however worded; or it is only floated, refused or still being weighed; or it is only what this scene is for, the next move (go to the archives, ask the clerk, cross the yard), or something done in the same moment.",
|
|
17954
|
-
remind: `
|
|
17975
|
+
remind: `The story gave the party an objective the current state's Objectives list does not hold: add it as the party knows it now, short, one step to an objective, {"id": "current-state", "op": "add", "field": "trackers[Objectives].items", "value": "<the objective>"}`
|
|
17955
17976
|
}
|
|
17956
17977
|
}
|
|
17957
17978
|
}
|
|
17958
17979
|
},
|
|
17959
17980
|
{
|
|
17960
17981
|
id: "party-tracker",
|
|
17961
|
-
revision:
|
|
17982
|
+
revision: 4,
|
|
17962
17983
|
instruction: {
|
|
17963
17984
|
name: "Party",
|
|
17964
17985
|
when: "always",
|
|
17965
17986
|
section: "Rules",
|
|
17966
|
-
body: `The Party is everyone who travels and acts with the player's character as one of them: the player's character, who is always in it, and the companions who have joined. Add someone when they join
|
|
17987
|
+
body: `The Party is everyone who travels and acts with the player's character as one of them: the player's character, who is always in it, and the companions who have joined. Add someone when they join, {"id": "current-state", "op": "add", "field": "trackers[Party].records", "value": "Character B"}, and remove them the same way when they leave, part ways for good or die. Someone who only helps for a while (a guide for the afternoon, a guard who fights beside them once) is not in it unless the story has them join.`,
|
|
17967
17988
|
tracker: {
|
|
17968
17989
|
key: "party",
|
|
17969
17990
|
start: {
|
|
@@ -17984,61 +18005,19 @@ var PLATFORM_INSTRUCTIONS = [
|
|
|
17984
18005
|
question: "In `earlier`, `player_turn` or `narration`, has someone joined the party (now travelling and acting with the player's character as one of them) or left it, that {tracker} does not show?",
|
|
17985
18006
|
yes: `Yes: someone agrees to come along, is taken on, or sets out with them as one of the group ("I'll come with you", hired for the journey, rescued and staying with them); or someone {tracker} lists leaves, parts ways for good, is left behind or dies.`,
|
|
17986
18007
|
no: "No: {tracker} already shows who is in the party; or someone only helps for a moment, offers to come but has not joined, or is only met, fought beside or travelled near.",
|
|
17987
|
-
remind: `
|
|
18008
|
+
remind: `Someone joined or left the party and the current state's Party does not show it: add or remove them, {"id": "current-state", "op": "add", "field": "trackers[Party].records", "value": "<their name>"}`
|
|
17988
18009
|
}
|
|
17989
18010
|
}
|
|
17990
18011
|
}
|
|
17991
18012
|
},
|
|
17992
|
-
{
|
|
17993
|
-
id: "death-saves-tracker",
|
|
17994
|
-
revision: 3,
|
|
17995
|
-
instruction: {
|
|
17996
|
-
name: "Death saves",
|
|
17997
|
-
when: "always",
|
|
17998
|
-
section: "Rules",
|
|
17999
|
-
body: `Only for a world whose rules have the dying roll to stay alive. Each save is a roll on their turn: the player's for their character, yours for anyone else. Record each one as it lands ("Death saves for Sara": "Successes +1", "Death saves for Sara": "Failures +1"). When they stabilize, are healed or die, end it ("Death saves for Sara": "End").`,
|
|
18000
|
-
tracker: {
|
|
18001
|
-
key: "death-saves",
|
|
18002
|
-
start: {
|
|
18003
|
-
name: "Death saves",
|
|
18004
|
-
fields: [
|
|
18005
|
-
{
|
|
18006
|
-
kind: "count",
|
|
18007
|
-
label: "Successes",
|
|
18008
|
-
value: 0,
|
|
18009
|
-
min: 0,
|
|
18010
|
-
max: 3,
|
|
18011
|
-
tone: "good",
|
|
18012
|
-
display: "pips",
|
|
18013
|
-
at: { "3": "Stable" }
|
|
18014
|
-
},
|
|
18015
|
-
{
|
|
18016
|
-
kind: "count",
|
|
18017
|
-
label: "Failures",
|
|
18018
|
-
value: 0,
|
|
18019
|
-
min: 0,
|
|
18020
|
-
max: 3,
|
|
18021
|
-
tone: "bad",
|
|
18022
|
-
display: "pips",
|
|
18023
|
-
at: { "3": "Dies" }
|
|
18024
|
-
}
|
|
18025
|
-
]
|
|
18026
|
-
},
|
|
18027
|
-
starts: "when-started",
|
|
18028
|
-
trigger: "someone falls dying, and the world's rules have them roll to stay alive",
|
|
18029
|
-
perPerson: true,
|
|
18030
|
-
when: "they make a death save"
|
|
18031
|
-
}
|
|
18032
|
-
}
|
|
18033
|
-
},
|
|
18034
18013
|
{
|
|
18035
18014
|
id: "time-tracker",
|
|
18036
|
-
revision:
|
|
18015
|
+
revision: 6,
|
|
18037
18016
|
instruction: {
|
|
18038
18017
|
name: "Time",
|
|
18039
18018
|
when: "always",
|
|
18040
18019
|
section: "Rules",
|
|
18041
|
-
body: `The
|
|
18020
|
+
body: `The in-game time is the current state's "time", and only you move it: nothing moves it after the turn. Whenever the story takes time worth counting, move it in the update() for that stretch of story, beside its other changes. With nothing else to record, the time is still an update() of its own. A line or two of talk needs no record. Tell it in the story once, as the time it is now ("It is now dusk"), never "a while later". Narrate the hour, the light and what is open from the current state's time, never from a guess.`,
|
|
18042
18021
|
tracker: {
|
|
18043
18022
|
key: "time",
|
|
18044
18023
|
start: {
|
|
@@ -18053,29 +18032,38 @@ var PLATFORM_INSTRUCTIONS = [
|
|
|
18053
18032
|
},
|
|
18054
18033
|
{
|
|
18055
18034
|
id: "player-moves",
|
|
18056
|
-
revision:
|
|
18035
|
+
revision: 5,
|
|
18057
18036
|
instruction: {
|
|
18058
18037
|
name: "Player moves",
|
|
18059
18038
|
when: "situational",
|
|
18060
18039
|
trigger: "When the player's character moves: walks somewhere, closes in, backs off, takes cover or follows someone",
|
|
18061
18040
|
section: "Rules",
|
|
18062
|
-
body: `When the move is one they can make,
|
|
18041
|
+
body: `When the move is one they can make, record where the player's character ends up with update(): {"id": "current-state", "op": "set", "field": "people[Character A].position", "value": "30 ft away from Lookout 1"}.`
|
|
18063
18042
|
}
|
|
18064
18043
|
},
|
|
18065
18044
|
{
|
|
18066
|
-
id: "
|
|
18067
|
-
revision:
|
|
18045
|
+
id: "fight-procedure",
|
|
18046
|
+
revision: 5,
|
|
18068
18047
|
instruction: {
|
|
18069
|
-
name: "
|
|
18070
|
-
when: "
|
|
18071
|
-
|
|
18072
|
-
|
|
18048
|
+
name: "Running a fight",
|
|
18049
|
+
when: "procedure",
|
|
18050
|
+
trigger: "When a fight starts, and on its turns while it runs",
|
|
18051
|
+
pruning: "on-compaction",
|
|
18052
|
+
section: "Rules",
|
|
18053
|
+
body: `A fight runs on its turn order (the Trackers procedure says how a turn order works). Start it as the fight starts, with everyone taking part, as its line under "Trackers this game keeps" shows, and give each NPC in it a side if theirs is not set (People on the map). Pass the turn as each one ends, and play each turn as the fighter the turn order gives it to.
|
|
18054
|
+
|
|
18055
|
+
Turns. Every NPC's turn is yours to play, an ally's too (a companion travelling with the party): their move, their roll, what it did, then on to the next. Stop for the player only on the player's character's turn.
|
|
18056
|
+
|
|
18057
|
+
Reach. A melee attack needs its target within reach, so close the distance first, as a move.
|
|
18058
|
+
|
|
18059
|
+
Stats. As the fight starts, show the stat it turns on under the tokens (hit points as a bar, hidden for enemies), and give each extra in the fight that stat as a detail (People on the map says how). Work out who goes down from the numbers.
|
|
18060
|
+
|
|
18061
|
+
Table talk. Talk at the table as a game master running a fight would, as much as the moment needs: hand the turn over ("Character B's up.", "Character A, it's your turn. What do you do?"), say how a roll went and what it did ("Seventeen: that hits, for seven damage."), give the logistics a choice turns on (who is in reach, how far, who is flanked, what a move would provoke), and say how hurt someone looks ("he's barely standing") rather than their hit points left. Table talk is not narrating your process; your own bookkeeping stays unsaid.`
|
|
18073
18062
|
}
|
|
18074
18063
|
}
|
|
18075
18064
|
];
|
|
18076
18065
|
var RESPONSE_LENGTH = "Response length";
|
|
18077
18066
|
var LONG_TRAVEL = "Long-distance travel";
|
|
18078
|
-
var STORY_PACING_KEY = "platform-story-pacing";
|
|
18079
18067
|
var PLATFORM_OPTIONS = [
|
|
18080
18068
|
{
|
|
18081
18069
|
revision: 3,
|
|
@@ -18129,58 +18117,7 @@ var PLATFORM_OPTIONS = [
|
|
|
18129
18117
|
}
|
|
18130
18118
|
},
|
|
18131
18119
|
{
|
|
18132
|
-
revision:
|
|
18133
|
-
option: {
|
|
18134
|
-
key: STORY_PACING_KEY,
|
|
18135
|
-
label: "Story pacing",
|
|
18136
|
-
description: "How hard the Game Master pushes the story forward.",
|
|
18137
|
-
kind: "one",
|
|
18138
|
-
default: ["driven"],
|
|
18139
|
-
choices: [
|
|
18140
|
-
{
|
|
18141
|
-
key: "driven",
|
|
18142
|
-
label: "Driven",
|
|
18143
|
-
description: "Something moves every turn.",
|
|
18144
|
-
instructions: [
|
|
18145
|
-
{
|
|
18146
|
-
when: "always",
|
|
18147
|
-
body: `Each turn, something moves on besides what the player did: a clock, a threat, a rumour, someone who has been waiting.
|
|
18148
|
-
|
|
18149
|
-
End each reply on something concrete in front of the player's character that they must answer: someone speaks or acts to them, an offer, a threat that moves, a choice with a cost, time running short. Never end on stillness ("the room is quiet"), a summary, or a bare "What do you do?".`
|
|
18150
|
-
}
|
|
18151
|
-
]
|
|
18152
|
-
},
|
|
18153
|
-
{
|
|
18154
|
-
key: "player-lead",
|
|
18155
|
-
label: "Player Lead",
|
|
18156
|
-
description: "Pushes when you push, lingers when you linger.",
|
|
18157
|
-
instructions: [
|
|
18158
|
-
{
|
|
18159
|
-
when: "always",
|
|
18160
|
-
body: `Match the pace to the player's. When they act, press on: consequences land and the people present push back. When they talk, look around or take their time, stay in the moment with them and bring in nothing new unless a thread already in motion arrives.
|
|
18161
|
-
|
|
18162
|
-
End each reply on something in front of the player's character to answer: someone's reply or reaction, an invitation, a choice. Never end on stillness ("the room is quiet"), a summary, or a bare "What do you do?".`
|
|
18163
|
-
}
|
|
18164
|
-
]
|
|
18165
|
-
},
|
|
18166
|
-
{
|
|
18167
|
-
key: "slice-of-life",
|
|
18168
|
-
label: "Slice of life",
|
|
18169
|
-
description: "Time to talk and explore; no trouble unless you look for it.",
|
|
18170
|
-
instructions: [
|
|
18171
|
-
{
|
|
18172
|
-
when: "always",
|
|
18173
|
-
body: `Let scenes breathe. Spend the reply on the people and the place: conversation, small gestures, how somewhere looks, sounds and smells. Bring in no new threat, deadline or twist: trouble comes only when the player goes looking for it, or from something the story already set in motion.
|
|
18174
|
-
|
|
18175
|
-
End each reply on something open in front of the player's character, however quiet the moment: someone speaks to them or catches their eye, an invitation, a small detail worth a closer look. Never end on stillness ("there is room to eat in peace"), a summary, or a bare "What do you do?".`
|
|
18176
|
-
}
|
|
18177
|
-
]
|
|
18178
|
-
}
|
|
18179
|
-
]
|
|
18180
|
-
}
|
|
18181
|
-
},
|
|
18182
|
-
{
|
|
18183
|
-
revision: 1,
|
|
18120
|
+
revision: 2,
|
|
18184
18121
|
option: {
|
|
18185
18122
|
key: "platform-long-distance-travel",
|
|
18186
18123
|
label: LONG_TRAVEL,
|
|
@@ -18201,7 +18138,7 @@ End each reply on something open in front of the player's character, however qui
|
|
|
18201
18138
|
instructions: [
|
|
18202
18139
|
{
|
|
18203
18140
|
when: "always",
|
|
18204
|
-
body:
|
|
18141
|
+
body: "When the party travels somewhere far (a trip of hours or more), take them straight there in the same reply: set place to where they are going, never travel, and inc time by how long the trip took; sum up the trip in a sentence or two (how long it took, how the way went), and go on from the arrival. When the player set out from the map, tell the arrival the same way."
|
|
18205
18142
|
}
|
|
18206
18143
|
]
|
|
18207
18144
|
},
|
|
@@ -18212,7 +18149,7 @@ End each reply on something open in front of the player's character, however qui
|
|
|
18212
18149
|
instructions: [
|
|
18213
18150
|
{
|
|
18214
18151
|
when: "always",
|
|
18215
|
-
body: `When the party travels somewhere far (a trip of hours or more), play it as a journey to where the player said they are going. Set out first
|
|
18152
|
+
body: `When the party travels somewhere far (a trip of hours or more), play it as a journey to where the player said they are going. Set out first, setting travel to that place with the way and how long it takes ({"to": "place-b#2f4b9e10", "via": "the coast road", "takes": "about three days"}), then tell the way in stages over several replies, for as long as the distance really takes: the road and the weather, rests and camps, people and trouble met on the way, with the time moving as it would. The party stays on the road the whole time: a camp, a rest or someone met is told there, with the time it takes, never as a place of its own. Keep heading for the place the player named unless they change course, and set place to it only once the way has been travelled. When the player set out from the map, they are already on the way: go on with the journey.`
|
|
18216
18153
|
}
|
|
18217
18154
|
]
|
|
18218
18155
|
}
|
|
@@ -18236,9 +18173,6 @@ function sameJson(a, b) {
|
|
|
18236
18173
|
return JSON.stringify(sortedKeys(a)) === JSON.stringify(sortedKeys(b));
|
|
18237
18174
|
}
|
|
18238
18175
|
|
|
18239
|
-
// ../shared/src/game-time.ts
|
|
18240
|
-
var TIME_TRACKER_KEY = "time";
|
|
18241
|
-
|
|
18242
18176
|
// ../shared/src/trackers.ts
|
|
18243
18177
|
var TRACKER_TONES = ["good", "bad"];
|
|
18244
18178
|
var TRACKER_ITEM_STATES = ["open", "done", "failed"];
|
|
@@ -18267,6 +18201,7 @@ var TRACKER_LIMITS = {
|
|
|
18267
18201
|
};
|
|
18268
18202
|
var labelSchema = string2().trim().max(TRACKER_LIMITS.label).nullish();
|
|
18269
18203
|
var hiddenSchema = boolean2().nullish();
|
|
18204
|
+
var turnStampSchema = number2().int().nonnegative().nullish().catch(null);
|
|
18270
18205
|
var refSchema = object({
|
|
18271
18206
|
name: string2().trim().min(1).max(TRACKER_LIMITS.name),
|
|
18272
18207
|
file: string2().nullish()
|
|
@@ -18395,7 +18330,9 @@ var trackerShapeSchema = object({
|
|
|
18395
18330
|
lasts: _enum(TRACKER_LASTS).nullish(),
|
|
18396
18331
|
from: string2().nullish(),
|
|
18397
18332
|
since: string2().nullish(),
|
|
18398
|
-
changed: string2().nullish()
|
|
18333
|
+
changed: string2().nullish(),
|
|
18334
|
+
sinceTurn: turnStampSchema,
|
|
18335
|
+
changedTurn: turnStampSchema
|
|
18399
18336
|
});
|
|
18400
18337
|
function isObject2(value) {
|
|
18401
18338
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -18440,7 +18377,13 @@ var TRACKER_DEFINITION_LIMITS = {
|
|
|
18440
18377
|
};
|
|
18441
18378
|
var trackerDefinitionSchema = object({
|
|
18442
18379
|
key: string2().trim().min(1).max(TRACKER_DEFINITION_LIMITS.key).regex(/^[a-z0-9][a-z0-9-]*$/, "Keys are lowercase letters, digits and -"),
|
|
18443
|
-
start: trackerShapeSchema.omit({
|
|
18380
|
+
start: trackerShapeSchema.omit({
|
|
18381
|
+
since: true,
|
|
18382
|
+
changed: true,
|
|
18383
|
+
sinceTurn: true,
|
|
18384
|
+
changedTurn: true,
|
|
18385
|
+
from: true
|
|
18386
|
+
}),
|
|
18444
18387
|
starts: _enum(TRACKER_STARTS),
|
|
18445
18388
|
when: string2().trim().max(TRACKER_DEFINITION_LIMITS.when).nullish(),
|
|
18446
18389
|
updates: _enum(TRACKER_UPDATES).nullish(),
|
|
@@ -18458,6 +18401,11 @@ var NUMBER_KINDS = new Set(["count", "clock", "scale"]);
|
|
|
18458
18401
|
function isNumberField(field) {
|
|
18459
18402
|
return NUMBER_KINDS.has(field.kind);
|
|
18460
18403
|
}
|
|
18404
|
+
var QUOTED_PAIR = String.raw`"[^"\n]*"\s*:\s*"[^"\n]*"`;
|
|
18405
|
+
var QUOTED_ASIDE_RE = new RegExp(String.raw`\s*\([^()]*${QUOTED_PAIR}[^()]*\)`, "g");
|
|
18406
|
+
var QUOTED_PAIRS_RE = new RegExp(String.raw`:?\s*${QUOTED_PAIR}(?:\s*,\s*${QUOTED_PAIR})*`, "g");
|
|
18407
|
+
var EXAMPLE_PERSON = "Character A";
|
|
18408
|
+
var EXAMPLE_ORDER = { [EXAMPLE_PERSON]: 18, "Lookout 1": 12 };
|
|
18461
18409
|
var ARTICLE_RE = /^(?:the|a|an)\s+/;
|
|
18462
18410
|
var POSSESSIVE_RE = /['’]s\b/g;
|
|
18463
18411
|
var NON_WORD_RE = /[^\p{L}\p{N}]+/gu;
|
|
@@ -18564,6 +18512,8 @@ function trackerDefinitionProblem(definition) {
|
|
|
18564
18512
|
var GAME_OPTION_INSTRUCTION_NAME_MAX_LENGTH = 120;
|
|
18565
18513
|
var GAME_OPTION_INSTRUCTION_BODY_MAX_LENGTH = 2000;
|
|
18566
18514
|
var GAME_OPTION_SITUATIONAL_BODY_MAX_LENGTH = 1000;
|
|
18515
|
+
var GAME_OPTION_PROCEDURE_BODY_MAX_LENGTH = 1e4;
|
|
18516
|
+
var GAME_OPTION_STORED_BODY_MAX_LENGTH = 12000;
|
|
18567
18517
|
var GAME_OPTION_LABEL_MAX_LENGTH = 60;
|
|
18568
18518
|
var GAME_OPTION_DESCRIPTION_MAX_LENGTH = 200;
|
|
18569
18519
|
var GAME_OPTION_KEY_MAX_LENGTH = 60;
|
|
@@ -18573,16 +18523,26 @@ var GAME_OPTION_MAX_CHOICES = 8;
|
|
|
18573
18523
|
var GAME_OPTIONS_MAX_INSTRUCTIONS = 200;
|
|
18574
18524
|
var GAME_OPTIONS_MAX_ALWAYS_LENGTH = 1e4;
|
|
18575
18525
|
var GAME_OPTIONS_MAX_SITUATIONAL = 100;
|
|
18576
|
-
var
|
|
18526
|
+
var GAME_OPTIONS_MAX_PROCEDURES = 25;
|
|
18527
|
+
var GAME_OPTION_INSTRUCTION_WHEN = [
|
|
18528
|
+
"always",
|
|
18529
|
+
"situational",
|
|
18530
|
+
"procedure"
|
|
18531
|
+
];
|
|
18532
|
+
var GAME_OPTION_PROCEDURE_PRUNING = [
|
|
18533
|
+
"after-use",
|
|
18534
|
+
"on-compaction"
|
|
18535
|
+
];
|
|
18577
18536
|
var GAME_OPTION_KINDS = ["one", "several", "toggle"];
|
|
18578
18537
|
var keySchema = string2().trim().min(1).max(GAME_OPTION_KEY_MAX_LENGTH).regex(/^[a-z0-9][a-z0-9-]*$/, "Keys are lowercase letters, digits and -");
|
|
18579
18538
|
var GAME_OPTION_SECTION_MAX_LENGTH = 40;
|
|
18580
18539
|
var GAME_OPTIONS_MAX_SECTIONS = 30;
|
|
18581
18540
|
var gameOptionInstructionSchema = object({
|
|
18582
18541
|
name: string2().trim().max(GAME_OPTION_INSTRUCTION_NAME_MAX_LENGTH).optional(),
|
|
18583
|
-
body: string2().trim().min(1).max(
|
|
18542
|
+
body: string2().trim().min(1).max(GAME_OPTION_STORED_BODY_MAX_LENGTH),
|
|
18584
18543
|
when: _enum(GAME_OPTION_INSTRUCTION_WHEN),
|
|
18585
18544
|
trigger: string2().trim().max(GAME_OPTION_INSTRUCTION_NAME_MAX_LENGTH).optional(),
|
|
18545
|
+
pruning: _enum(GAME_OPTION_PROCEDURE_PRUNING).optional(),
|
|
18586
18546
|
section: string2().trim().max(GAME_OPTION_SECTION_MAX_LENGTH).optional(),
|
|
18587
18547
|
tracker: trackerDefinitionSchema.optional(),
|
|
18588
18548
|
platform: string2().max(GAME_OPTION_KEY_MAX_LENGTH).optional()
|
|
@@ -18655,7 +18615,28 @@ function sectionsOf(options) {
|
|
|
18655
18615
|
].map((name) => name.trim()).filter(Boolean);
|
|
18656
18616
|
return [...new Set(names)];
|
|
18657
18617
|
}
|
|
18658
|
-
function
|
|
18618
|
+
function instructionBodyMax(instruction) {
|
|
18619
|
+
if (instruction.when === "procedure") {
|
|
18620
|
+
return GAME_OPTION_PROCEDURE_BODY_MAX_LENGTH;
|
|
18621
|
+
}
|
|
18622
|
+
return instruction.when === "situational" && !instruction.tracker ? GAME_OPTION_SITUATIONAL_BODY_MAX_LENGTH : GAME_OPTION_INSTRUCTION_BODY_MAX_LENGTH;
|
|
18623
|
+
}
|
|
18624
|
+
function bodyLengthProblem(instruction) {
|
|
18625
|
+
const max = instructionBodyMax(instruction);
|
|
18626
|
+
const has = instruction.body.length;
|
|
18627
|
+
if (has <= max) {
|
|
18628
|
+
return null;
|
|
18629
|
+
}
|
|
18630
|
+
if (instruction.when === "procedure") {
|
|
18631
|
+
return `it is a procedure, so its text is at most ${max} characters (it has ${has}). Trim it, or split it into procedures for its parts.`;
|
|
18632
|
+
}
|
|
18633
|
+
if (instruction.when === "situational" && !instruction.tracker) {
|
|
18634
|
+
return `it is situational, so its text is at most ${max} characters (it has ${has}). Trim it, or make it a procedure: a procedure holds up to ${GAME_OPTION_PROCEDURE_BODY_MAX_LENGTH} characters, read whole when its moment comes.`;
|
|
18635
|
+
}
|
|
18636
|
+
const kind = instruction.tracker ? "a tracker's rules" : "always on";
|
|
18637
|
+
return `it is ${kind}, so its text is at most ${max} characters (it has ${has}). Trim it, or make the part for one moment situational or a procedure.`;
|
|
18638
|
+
}
|
|
18639
|
+
function instructionProblem(instruction, base, bodyLengths) {
|
|
18659
18640
|
if (instruction.tracker) {
|
|
18660
18641
|
const problem = trackerDefinitionProblem(instruction.tracker);
|
|
18661
18642
|
if (problem) {
|
|
@@ -18668,25 +18649,45 @@ function instructionProblem(instruction, base) {
|
|
|
18668
18649
|
if (base && instruction.when === "always" && !instruction.name?.trim()) {
|
|
18669
18650
|
return "an always instruction needs a title.";
|
|
18670
18651
|
}
|
|
18671
|
-
if (instruction.when === "
|
|
18672
|
-
|
|
18652
|
+
if (instruction.when === "procedure") {
|
|
18653
|
+
if (instruction.tracker) {
|
|
18654
|
+
return `"${instruction.name?.trim() || instructionTrigger(instruction)}" is a procedure, which can't define a tracker: make the tracker its own instruction.`;
|
|
18655
|
+
}
|
|
18656
|
+
if (!instruction.trigger?.trim()) {
|
|
18657
|
+
return "a procedure needs to say when to use it.";
|
|
18658
|
+
}
|
|
18659
|
+
if (base && !instruction.name?.trim()) {
|
|
18660
|
+
return "a procedure needs a title.";
|
|
18661
|
+
}
|
|
18662
|
+
}
|
|
18663
|
+
const long = bodyLengthProblem(instruction);
|
|
18664
|
+
if (bodyLengths && long) {
|
|
18665
|
+
return `"${instruction.name?.trim() || instructionTrigger(instruction)}": ${long}`;
|
|
18673
18666
|
}
|
|
18674
18667
|
return null;
|
|
18675
18668
|
}
|
|
18676
|
-
function gameOptionsProblem(options) {
|
|
18677
|
-
const baseProblem = options.instructions.map((instruction) => instructionProblem(instruction, true)).find(Boolean);
|
|
18669
|
+
function gameOptionsProblem(options, { bodyLengths = true } = {}) {
|
|
18670
|
+
const baseProblem = options.instructions.map((instruction) => instructionProblem(instruction, true, bodyLengths)).find(Boolean);
|
|
18678
18671
|
if (baseProblem) {
|
|
18679
18672
|
return `In the base instructions, ${baseProblem}`;
|
|
18680
18673
|
}
|
|
18681
18674
|
for (const option of options.options) {
|
|
18682
18675
|
for (const choice of option.choices) {
|
|
18683
|
-
const problem = choice.instructions.map((instruction) => instructionProblem(instruction, false)).find(Boolean);
|
|
18676
|
+
const problem = choice.instructions.map((instruction) => instructionProblem(instruction, false, bodyLengths)).find(Boolean);
|
|
18684
18677
|
if (problem) {
|
|
18685
18678
|
return `In "${option.label} · ${choice.label}", ${problem}`;
|
|
18686
18679
|
}
|
|
18687
18680
|
}
|
|
18688
18681
|
}
|
|
18689
|
-
return trackerKeysProblem(options) ?? gameOptionsStructureProblem(options) ?? gameOptionsLimitProblem(options);
|
|
18682
|
+
return craftTimeProblem(options) ?? trackerKeysProblem(options) ?? gameOptionsStructureProblem(options) ?? gameOptionsLimitProblem(options);
|
|
18683
|
+
}
|
|
18684
|
+
var TIME_TRACKER_ID = "time-tracker";
|
|
18685
|
+
function craftTimeProblem(options) {
|
|
18686
|
+
const time = options.instructions.find((instruction) => instruction.platform === TIME_TRACKER_ID);
|
|
18687
|
+
if (!time || time.tracker?.key === TIME_TRACKER_KEY) {
|
|
18688
|
+
return null;
|
|
18689
|
+
}
|
|
18690
|
+
return `Craft's Time tracker ("${time.name}") must keep its tracker with the key "${TIME_TRACKER_KEY}": code moves the clock by that key. Reword its name, rules and trigger, or turn it off.`;
|
|
18690
18691
|
}
|
|
18691
18692
|
function trackerKeysProblem(options) {
|
|
18692
18693
|
const lists = [
|
|
@@ -18754,14 +18755,67 @@ function gameOptionsLimitProblem(options) {
|
|
|
18754
18755
|
if (situational > GAME_OPTIONS_MAX_SITUATIONAL) {
|
|
18755
18756
|
return `One game can have up to ${situational} situational instructions; the limit is ${GAME_OPTIONS_MAX_SITUATIONAL}.`;
|
|
18756
18757
|
}
|
|
18758
|
+
const procedures = worstCaseProcedureCount(options);
|
|
18759
|
+
if (procedures > GAME_OPTIONS_MAX_PROCEDURES) {
|
|
18760
|
+
return `One game can have up to ${procedures} procedures; the limit is ${GAME_OPTIONS_MAX_PROCEDURES}, Craft's included. Merge some, or make the short ones situational.`;
|
|
18761
|
+
}
|
|
18757
18762
|
return null;
|
|
18758
18763
|
}
|
|
18759
18764
|
var gameOptionsSchema = storedGameOptionsShape.superRefine((options, ctx) => {
|
|
18760
|
-
const
|
|
18765
|
+
for (const { path, instruction } of storedInstructions(options)) {
|
|
18766
|
+
const long = bodyLengthProblem(instruction);
|
|
18767
|
+
if (long) {
|
|
18768
|
+
ctx.addIssue({
|
|
18769
|
+
code: "custom",
|
|
18770
|
+
path: [...path, "body"],
|
|
18771
|
+
message: long
|
|
18772
|
+
});
|
|
18773
|
+
}
|
|
18774
|
+
}
|
|
18775
|
+
const problem = gameOptionsProblem(withPlatform(options), {
|
|
18776
|
+
bodyLengths: false
|
|
18777
|
+
});
|
|
18761
18778
|
if (problem) {
|
|
18762
18779
|
ctx.addIssue({ code: "custom", message: problem });
|
|
18763
18780
|
}
|
|
18764
18781
|
});
|
|
18782
|
+
function storedInstructions(options) {
|
|
18783
|
+
const found = [];
|
|
18784
|
+
const choicesOf = (path, choices) => {
|
|
18785
|
+
choices.forEach((choice, c) => {
|
|
18786
|
+
choice.instructions.forEach((instruction, i) => {
|
|
18787
|
+
found.push({
|
|
18788
|
+
path: [...path, "choices", c, "instructions", i],
|
|
18789
|
+
instruction
|
|
18790
|
+
});
|
|
18791
|
+
});
|
|
18792
|
+
});
|
|
18793
|
+
};
|
|
18794
|
+
options.instructions.forEach((instruction, i) => {
|
|
18795
|
+
if ("body" in instruction) {
|
|
18796
|
+
found.push({ path: ["instructions", i], instruction });
|
|
18797
|
+
}
|
|
18798
|
+
});
|
|
18799
|
+
options.options.forEach((option, o) => {
|
|
18800
|
+
if ("choices" in option) {
|
|
18801
|
+
choicesOf(["options", o], option.choices);
|
|
18802
|
+
}
|
|
18803
|
+
});
|
|
18804
|
+
for (const [id, override] of Object.entries(options.platform?.instructions ?? {})) {
|
|
18805
|
+
if ("body" in override) {
|
|
18806
|
+
found.push({
|
|
18807
|
+
path: ["platform", "instructions", id],
|
|
18808
|
+
instruction: override
|
|
18809
|
+
});
|
|
18810
|
+
}
|
|
18811
|
+
}
|
|
18812
|
+
for (const [key, override] of Object.entries(options.platform?.options ?? {})) {
|
|
18813
|
+
if ("choices" in override) {
|
|
18814
|
+
choicesOf(["platform", "options", key], override.choices);
|
|
18815
|
+
}
|
|
18816
|
+
}
|
|
18817
|
+
return found;
|
|
18818
|
+
}
|
|
18765
18819
|
var storedGameOptionsSchema = storedGameOptionsShape.superRefine((options, ctx) => {
|
|
18766
18820
|
const problem = gameOptionsStructureProblem(withPlatform(options));
|
|
18767
18821
|
if (problem) {
|
|
@@ -19058,18 +19112,26 @@ function worstCaseAlwaysLength(options) {
|
|
|
19058
19112
|
function worstCaseSituationalCount(options) {
|
|
19059
19113
|
return worstCase(options, situationalCount);
|
|
19060
19114
|
}
|
|
19115
|
+
function procedureCount(instructions, _place) {
|
|
19116
|
+
return instructions.filter((instruction) => instruction.when === "procedure").length;
|
|
19117
|
+
}
|
|
19118
|
+
function worstCaseProcedureCount(options) {
|
|
19119
|
+
return worstCase(options, procedureCount);
|
|
19120
|
+
}
|
|
19061
19121
|
|
|
19062
19122
|
// ../shared/src/gm-tool-settings.ts
|
|
19063
19123
|
var gmToolSettingsInputSchema = object({
|
|
19064
19124
|
askPlayerToRoll: boolean2().optional(),
|
|
19065
19125
|
askUserQuestion: boolean2().optional(),
|
|
19066
19126
|
generateNames: boolean2().optional(),
|
|
19127
|
+
gmExpressions: boolean2().optional(),
|
|
19067
19128
|
research: boolean2().optional()
|
|
19068
19129
|
}).strict();
|
|
19069
19130
|
var gmToolSettingsSchema = object({
|
|
19070
19131
|
askPlayerToRoll: boolean2(),
|
|
19071
19132
|
askUserQuestion: boolean2(),
|
|
19072
19133
|
generateNames: boolean2(),
|
|
19134
|
+
gmExpressions: boolean2(),
|
|
19073
19135
|
research: boolean2()
|
|
19074
19136
|
}).strict();
|
|
19075
19137
|
|
|
@@ -28150,6 +28212,9 @@ function sanitizeVfsPathForDisk(path) {
|
|
|
28150
28212
|
return path.split("/").map((segment) => segment === "" ? "" : sanitizeVfsSegmentForDisk(segment)).join("/");
|
|
28151
28213
|
}
|
|
28152
28214
|
|
|
28215
|
+
// ../shared/src/files/file-handle.ts
|
|
28216
|
+
var QUOTES = new Set(['"', "'", "“", "”", "‘", "’", "«", "»"]);
|
|
28217
|
+
|
|
28153
28218
|
// ../shared/src/files/file-reference-content.ts
|
|
28154
28219
|
var STATE_PATH_LEADING_SLASH_RE = /^\/+/;
|
|
28155
28220
|
var STATE_PATH_ARRAY_INDEX_RE = /\[(?:\d+|\*)\]/g;
|
|
@@ -28373,13 +28438,13 @@ function referenceDisplayValue(value, qualify) {
|
|
|
28373
28438
|
}
|
|
28374
28439
|
return value;
|
|
28375
28440
|
}
|
|
28376
|
-
function projectFileContentReferencesForEditing(content, schema, layout) {
|
|
28377
|
-
return projectValue(content, asSchemaNode(schema), referenceHintsFromLayout(layout), "");
|
|
28441
|
+
function projectFileContentReferencesForEditing(content, schema, layout, display) {
|
|
28442
|
+
return projectValue(content, asSchemaNode(schema), referenceHintsFromLayout(layout), "", display);
|
|
28378
28443
|
}
|
|
28379
|
-
function projectValue(value, schema, hints, path) {
|
|
28444
|
+
function projectValue(value, schema, hints, path, display) {
|
|
28380
28445
|
const directTargets = directReferenceTargets(schema, hints, path);
|
|
28381
28446
|
if (directTargets.length > 0) {
|
|
28382
|
-
return referenceDisplayValue(value, directTargets.length > 1);
|
|
28447
|
+
return display?.(value) ?? referenceDisplayValue(value, directTargets.length > 1);
|
|
28383
28448
|
}
|
|
28384
28449
|
const itemSchema = schemaItems(schema);
|
|
28385
28450
|
if (Array.isArray(value)) {
|
|
@@ -28387,9 +28452,9 @@ function projectValue(value, schema, hints, path) {
|
|
|
28387
28452
|
const itemTargets = arrayItemReferenceTargets(schema, itemSchema, hints, path);
|
|
28388
28453
|
if (itemTargets.length > 0) {
|
|
28389
28454
|
const referenceSchema = referenceSchemaForTargets(itemSchema, itemTargets);
|
|
28390
|
-
return value.map((item) => projectValue(item, referenceSchema, hints, itemPath));
|
|
28455
|
+
return value.map((item) => projectValue(item, referenceSchema, hints, itemPath, display));
|
|
28391
28456
|
}
|
|
28392
|
-
return itemSchema || hintHasPathPrefix(hints, itemPath) ? value.map((item) => projectValue(item, itemSchema, hints, itemPath)) : value;
|
|
28457
|
+
return itemSchema || hintHasPathPrefix(hints, itemPath) ? value.map((item) => projectValue(item, itemSchema, hints, itemPath, display)) : value;
|
|
28393
28458
|
}
|
|
28394
28459
|
const properties = schemaProperties2(schema);
|
|
28395
28460
|
if (isRecord5(value) && (properties || hintHasPathPrefix(hints, path))) {
|
|
@@ -28401,7 +28466,7 @@ function projectValue(value, schema, hints, path) {
|
|
|
28401
28466
|
if (!(childSchema || hintHasPathPrefix(hints, childPath))) {
|
|
28402
28467
|
continue;
|
|
28403
28468
|
}
|
|
28404
|
-
const projected = projectValue(childValue, asSchemaNode(childSchema), hints, childPath);
|
|
28469
|
+
const projected = projectValue(childValue, asSchemaNode(childSchema), hints, childPath, display);
|
|
28405
28470
|
if (projected !== childValue) {
|
|
28406
28471
|
changed = true;
|
|
28407
28472
|
next[key] = projected;
|
|
@@ -28621,6 +28686,14 @@ var fileContentBaseSchema = object({
|
|
|
28621
28686
|
description: string2().optional(),
|
|
28622
28687
|
image: preprocess((value) => value === null ? undefined : value, imageObjectSchema.optional())
|
|
28623
28688
|
}).passthrough();
|
|
28689
|
+
var IMAGE_URL_KEYS = new Set([
|
|
28690
|
+
"url",
|
|
28691
|
+
"backgroundRemovedUrl",
|
|
28692
|
+
"overlayUrl",
|
|
28693
|
+
"posterUrl",
|
|
28694
|
+
"mp4Url",
|
|
28695
|
+
"webmUrl"
|
|
28696
|
+
]);
|
|
28624
28697
|
var IMAGE_OBJECT_JSON_SCHEMA = {
|
|
28625
28698
|
type: "object",
|
|
28626
28699
|
format: "image",
|
|
@@ -29985,7 +30058,7 @@ function defineCatalog(schema, catalog) {
|
|
|
29985
30058
|
return schema.createCatalog(catalog);
|
|
29986
30059
|
}
|
|
29987
30060
|
|
|
29988
|
-
// ../../node_modules/.bun/@json-render+react@0.19.0+
|
|
30061
|
+
// ../../node_modules/.bun/@json-render+react@0.19.0+a3a949af4499b2f6/node_modules/@json-render/react/dist/chunk-WYDS23XB.mjs
|
|
29989
30062
|
var schema = defineSchema((s) => ({
|
|
29990
30063
|
spec: s.object({
|
|
29991
30064
|
root: s.string(),
|
|
@@ -30040,7 +30113,7 @@ var schema = defineSchema((s) => ({
|
|
|
30040
30113
|
]
|
|
30041
30114
|
});
|
|
30042
30115
|
|
|
30043
|
-
// ../../node_modules/.bun/@json-render+shadcn@0.19.0+
|
|
30116
|
+
// ../../node_modules/.bun/@json-render+shadcn@0.19.0+c4b94aca9866a541/node_modules/@json-render/shadcn/dist/chunk-L37EOULD.mjs
|
|
30044
30117
|
var validationCheckSchema = array(object({
|
|
30045
30118
|
type: string2(),
|
|
30046
30119
|
message: string2(),
|
|
@@ -30415,6 +30488,372 @@ var shadcnComponentDefinitions = {
|
|
|
30415
30488
|
}
|
|
30416
30489
|
};
|
|
30417
30490
|
|
|
30491
|
+
// ../shared/src/json-render/card-catalog.ts
|
|
30492
|
+
var SCRIPT_CARD_TONES = [
|
|
30493
|
+
"neutral",
|
|
30494
|
+
"success",
|
|
30495
|
+
"failure",
|
|
30496
|
+
"critical",
|
|
30497
|
+
"fumble",
|
|
30498
|
+
"partial",
|
|
30499
|
+
"info",
|
|
30500
|
+
"magic"
|
|
30501
|
+
];
|
|
30502
|
+
var SCRIPT_CARD_ICONS = [
|
|
30503
|
+
"sword",
|
|
30504
|
+
"swords",
|
|
30505
|
+
"shield",
|
|
30506
|
+
"heart",
|
|
30507
|
+
"skull",
|
|
30508
|
+
"coins",
|
|
30509
|
+
"scroll",
|
|
30510
|
+
"sparkles",
|
|
30511
|
+
"flame",
|
|
30512
|
+
"snowflake",
|
|
30513
|
+
"droplet",
|
|
30514
|
+
"dice",
|
|
30515
|
+
"key",
|
|
30516
|
+
"lock",
|
|
30517
|
+
"eye",
|
|
30518
|
+
"moon",
|
|
30519
|
+
"sun",
|
|
30520
|
+
"tent",
|
|
30521
|
+
"crown",
|
|
30522
|
+
"gem",
|
|
30523
|
+
"flask",
|
|
30524
|
+
"book",
|
|
30525
|
+
"target",
|
|
30526
|
+
"zap",
|
|
30527
|
+
"trophy",
|
|
30528
|
+
"users",
|
|
30529
|
+
"user",
|
|
30530
|
+
"map",
|
|
30531
|
+
"compass",
|
|
30532
|
+
"wand",
|
|
30533
|
+
"star",
|
|
30534
|
+
"check",
|
|
30535
|
+
"x",
|
|
30536
|
+
"hourglass",
|
|
30537
|
+
"footprints",
|
|
30538
|
+
"hammer",
|
|
30539
|
+
"cpu",
|
|
30540
|
+
"brain",
|
|
30541
|
+
"vote",
|
|
30542
|
+
"bag",
|
|
30543
|
+
"feather",
|
|
30544
|
+
"ghost",
|
|
30545
|
+
"leaf",
|
|
30546
|
+
"anchor",
|
|
30547
|
+
"castle",
|
|
30548
|
+
"music",
|
|
30549
|
+
"message",
|
|
30550
|
+
"alert",
|
|
30551
|
+
"info",
|
|
30552
|
+
"plus",
|
|
30553
|
+
"minus",
|
|
30554
|
+
"arrow"
|
|
30555
|
+
];
|
|
30556
|
+
var DEFAULT_SLOT = ["default"];
|
|
30557
|
+
var tone = optional(nullable(_enum(SCRIPT_CARD_TONES)));
|
|
30558
|
+
var ICON_NAME_RE = /^[a-z][a-z-]*$/;
|
|
30559
|
+
var KNOWN_ICONS = new Set(SCRIPT_CARD_ICONS);
|
|
30560
|
+
var icon = optional(nullable(string2().max(16).refine((name) => !ICON_NAME_RE.test(name) || KNOWN_ICONS.has(name), {
|
|
30561
|
+
message: `not a card icon; use one of ${SCRIPT_CARD_ICONS.join(", ")}, or an emoji`
|
|
30562
|
+
})));
|
|
30563
|
+
var SCRIPT_CARD_COLORS = [
|
|
30564
|
+
"red",
|
|
30565
|
+
"orange",
|
|
30566
|
+
"gold",
|
|
30567
|
+
"green",
|
|
30568
|
+
"teal",
|
|
30569
|
+
"blue",
|
|
30570
|
+
"violet",
|
|
30571
|
+
"pink"
|
|
30572
|
+
];
|
|
30573
|
+
var text = optional(nullable(string2()));
|
|
30574
|
+
var num = optional(nullable(number2()));
|
|
30575
|
+
var className = optional(nullable(string2()));
|
|
30576
|
+
var value = optional(nullable(union([string2(), number2()])));
|
|
30577
|
+
var TONE_DOC = `tone is one of ${SCRIPT_CARD_TONES.map((t) => `"${t}"`).join(", ")}: success emerald, failure rose, critical gold, fumble red, partial amber, info sky, magic violet.`;
|
|
30578
|
+
var ICON_DOC = `icon names a game icon (${SCRIPT_CARD_ICONS.join(", ")}) or is a short text such as an emoji.`;
|
|
30579
|
+
var DIE_DOC = `Each die is { sides, value, kept, tone, color, label, exploded }: sides 4, 6, 8, 10, 12, 20 or 100 draws that die's shape (any other is a square); value is its face, a number or a short text ("+", "−" and " " for Fate dice, "?" for a die players don't see); kept: false strikes it out (the low die of advantage, a pool's dropped dice); a kept d20's natural 20 glows gold and its natural 1 breaks; tone gives it a meaning (a Blades pool's highest die "partial"), while color only colors it (${SCRIPT_CARD_COLORS.join(", ")}: "orange" for fire); label is a word under it ("fire", "hope"); exploded: true marks a die that exploded.`;
|
|
30580
|
+
var scriptCardComponents = {
|
|
30581
|
+
Frame: {
|
|
30582
|
+
props: object({
|
|
30583
|
+
eyebrow: text,
|
|
30584
|
+
title: text,
|
|
30585
|
+
subtitle: text,
|
|
30586
|
+
icon,
|
|
30587
|
+
image: text,
|
|
30588
|
+
tag: text,
|
|
30589
|
+
tone,
|
|
30590
|
+
className
|
|
30591
|
+
}),
|
|
30592
|
+
slots: DEFAULT_SLOT,
|
|
30593
|
+
description: `Only in a script's card: the card's shell. A header (an icon or a portrait image, a small eyebrow line above the title such as "Attack" or "Shop", the title, a subtitle) and its children stacked below. The frame stays neutral and tone tints its icon; only "critical" (a gold rule and a foil sweep) and "fumble" (a red rule) mark the frame itself, so save them for a natural 20 or 1. image is a portrait URL in place of the icon (a merchant, a speaker). tag is a small label at the header's end ("Live", "Secret"). Keep eyebrow to two short parts ("Longsword · advantage"); put mechanics such as a roll's position in Tags. Put an Actions element last among its children for a footer of Buttons. ${TONE_DOC} ${ICON_DOC}`,
|
|
30594
|
+
example: {
|
|
30595
|
+
eyebrow: "Attack",
|
|
30596
|
+
title: "Brom swings at the goblin",
|
|
30597
|
+
subtitle: "Longsword · advantage",
|
|
30598
|
+
icon: "sword",
|
|
30599
|
+
tone: "success"
|
|
30600
|
+
}
|
|
30601
|
+
},
|
|
30602
|
+
Actions: {
|
|
30603
|
+
props: object({
|
|
30604
|
+
align: optional(nullable(_enum(["start", "end", "stretch"]))),
|
|
30605
|
+
className
|
|
30606
|
+
}),
|
|
30607
|
+
slots: DEFAULT_SLOT,
|
|
30608
|
+
description: `Only in a script's card: a row of Buttons. Last inside a Frame it is the frame's footer, set apart by a rule; elsewhere it is a plain row. align "stretch" gives each Button an equal share.`,
|
|
30609
|
+
example: { align: "start" }
|
|
30610
|
+
},
|
|
30611
|
+
Dice: {
|
|
30612
|
+
props: object({
|
|
30613
|
+
dice: array(unknown()),
|
|
30614
|
+
size: optional(nullable(_enum(["sm", "md", "lg"]))),
|
|
30615
|
+
className
|
|
30616
|
+
}),
|
|
30617
|
+
description: `Only in a script's card: dice as they landed, each drawn as its own shape with its face. ${DIE_DOC}`,
|
|
30618
|
+
example: {
|
|
30619
|
+
dice: [
|
|
30620
|
+
{ sides: 20, value: 17 },
|
|
30621
|
+
{ sides: 20, value: 6, kept: false }
|
|
30622
|
+
],
|
|
30623
|
+
size: "md"
|
|
30624
|
+
}
|
|
30625
|
+
},
|
|
30626
|
+
Roll: {
|
|
30627
|
+
props: object({
|
|
30628
|
+
label: text,
|
|
30629
|
+
dice: array(unknown()),
|
|
30630
|
+
modifiers: optional(nullable(array(unknown()))),
|
|
30631
|
+
total: value,
|
|
30632
|
+
target: optional(nullable(object({ label: text, value }).passthrough())),
|
|
30633
|
+
outcome: optional(nullable(object({ text, tone }).passthrough())),
|
|
30634
|
+
className
|
|
30635
|
+
}),
|
|
30636
|
+
description: `Only in a script's card: one roll read as a whole: its dice, what was added, the total large, what it was against and the verdict as a stamp. dice as in Dice (${DIE_DOC}). modifiers is [{ value, label }] ({ value: 5, label: "STR" }). target is { label, value } ("AC", 15; "DC", 13). outcome is { text, tone } ("Hit" success, "Critical" critical, "Miss" failure, "Mixed" partial). The total is written by the script; the card doesn't add it up. A lone die with nothing added is its own total: it shows large with the verdict beside it. With a numeric target the card shows how far the roll beat or missed it, except on a natural 20 or 1.`,
|
|
30637
|
+
example: {
|
|
30638
|
+
label: "Attack roll",
|
|
30639
|
+
dice: [{ sides: 20, value: 17 }],
|
|
30640
|
+
modifiers: [{ value: 5, label: "STR" }],
|
|
30641
|
+
total: 22,
|
|
30642
|
+
target: { label: "AC", value: 15 },
|
|
30643
|
+
outcome: { text: "Hit", tone: "success" }
|
|
30644
|
+
}
|
|
30645
|
+
},
|
|
30646
|
+
Hero: {
|
|
30647
|
+
props: object({
|
|
30648
|
+
value: union([string2(), number2()]),
|
|
30649
|
+
label: text,
|
|
30650
|
+
unit: text,
|
|
30651
|
+
caption: text,
|
|
30652
|
+
icon,
|
|
30653
|
+
tone,
|
|
30654
|
+
className
|
|
30655
|
+
}),
|
|
30656
|
+
description: `Only in a script's card: the moment's one big number without dice: a level reached (label "Level", value 4), experience earned ("+450", unit "XP"), gold found, damage dealt, days left. tone "critical" celebrates it in gold with a burst (a level up, a milestone); other tones tint it. caption is a small line under the number. ${ICON_DOC}`,
|
|
30657
|
+
example: {
|
|
30658
|
+
label: "Level",
|
|
30659
|
+
value: 4,
|
|
30660
|
+
icon: "star",
|
|
30661
|
+
tone: "critical",
|
|
30662
|
+
caption: "Fighter · 2,700 XP"
|
|
30663
|
+
}
|
|
30664
|
+
},
|
|
30665
|
+
Outcome: {
|
|
30666
|
+
props: object({
|
|
30667
|
+
title: string2(),
|
|
30668
|
+
text,
|
|
30669
|
+
icon,
|
|
30670
|
+
tone,
|
|
30671
|
+
className
|
|
30672
|
+
}),
|
|
30673
|
+
description: `Only in a script's card: what happened, in words, as a band across the card: "The goblin falls", "Poisoned for 1 hour". title is the headline (keep it under about 60 characters: it shows two lines at most), text the detail under it. ${TONE_DOC}`,
|
|
30674
|
+
example: {
|
|
30675
|
+
title: "Poisoned for 1 hour",
|
|
30676
|
+
text: "Disadvantage on attack rolls and ability checks.",
|
|
30677
|
+
icon: "flask",
|
|
30678
|
+
tone: "failure"
|
|
30679
|
+
}
|
|
30680
|
+
},
|
|
30681
|
+
Meter: {
|
|
30682
|
+
props: object({
|
|
30683
|
+
label: text,
|
|
30684
|
+
value: number2(),
|
|
30685
|
+
max: number2(),
|
|
30686
|
+
min: num,
|
|
30687
|
+
from: num,
|
|
30688
|
+
icon,
|
|
30689
|
+
tone: optional(nullable(_enum([...SCRIPT_CARD_TONES, "health"]))),
|
|
30690
|
+
display: optional(nullable(_enum(["bar", "boxes", "pips"]))),
|
|
30691
|
+
better: optional(nullable(_enum(["higher", "lower"]))),
|
|
30692
|
+
caption: text,
|
|
30693
|
+
valueLabel: text,
|
|
30694
|
+
minLabel: text,
|
|
30695
|
+
maxLabel: text,
|
|
30696
|
+
hideValue: optional(nullable(boolean2())),
|
|
30697
|
+
className
|
|
30698
|
+
}),
|
|
30699
|
+
description: `Only in a script's card: a value against its max: hit points, mana, experience, a trace, votes in. from is where it was before this run: a loss drains and leaves an outlined ghost of what was lost (health shows a skull at zero), a gain glows, and the change shows signed beside the value. tone "health" (the default) goes green, amber, red as it empties; any other tone fixes the color. display "boxes" or "pips" draws one cell per point (supplies, death saves; up to 20); pips with an icon draw that icon in each (hearts, skulls). min below zero makes it two-sided around a centre tick (faction standing −5 to +5, sanity); valueLabel names where it stands ("Friendly"); minLabel and maxLabel label the ends (put them on the last of a group). better: "lower" when going up is bad (a trace, an alarm). caption is a small line under it. hideValue hides the numbers (an enemy's health). ${TONE_DOC}`,
|
|
30700
|
+
example: {
|
|
30701
|
+
label: "Hit points",
|
|
30702
|
+
value: 9,
|
|
30703
|
+
from: 21,
|
|
30704
|
+
max: 32,
|
|
30705
|
+
icon: "heart"
|
|
30706
|
+
}
|
|
30707
|
+
},
|
|
30708
|
+
Changes: {
|
|
30709
|
+
props: object({
|
|
30710
|
+
items: array(unknown()),
|
|
30711
|
+
className
|
|
30712
|
+
}),
|
|
30713
|
+
description: `Only in a script's card: what this run changed, a row each: { label, from, to, delta, unit, icon, detail, tone, better }. from → to shows before and after; delta is the signed difference (worked out from numbers when left out); a row with only delta reads "Gold −25 gp"; a row with only to reads as something gained ("New feature: Second Wind"). A row that didn't change is left out. Going up is green unless better is "lower"; tone "success" or "failure" overrides it. ${ICON_DOC}`,
|
|
30714
|
+
example: {
|
|
30715
|
+
items: [
|
|
30716
|
+
{ label: "Hit point maximum", from: 32, to: 41, icon: "heart" },
|
|
30717
|
+
{ label: "Gold", delta: -25, unit: "gp", icon: "coins" }
|
|
30718
|
+
]
|
|
30719
|
+
}
|
|
30720
|
+
},
|
|
30721
|
+
Facts: {
|
|
30722
|
+
props: object({
|
|
30723
|
+
items: array(unknown()),
|
|
30724
|
+
layout: optional(nullable(_enum(["inline", "grid"]))),
|
|
30725
|
+
columns: num,
|
|
30726
|
+
className
|
|
30727
|
+
}),
|
|
30728
|
+
description: `Only in a script's card: short label/value pairs, [{ label, value, tone }]: DC 15 · Range 60 ft · Save WIS. layout "inline" (the default) runs them on one wrapping line; "grid" sets them in cells with the value large (columns, 2 to 4).`,
|
|
30729
|
+
example: {
|
|
30730
|
+
items: [
|
|
30731
|
+
{ label: "DC", value: 15 },
|
|
30732
|
+
{ label: "Range", value: "60 ft" }
|
|
30733
|
+
],
|
|
30734
|
+
layout: "inline"
|
|
30735
|
+
}
|
|
30736
|
+
},
|
|
30737
|
+
Tags: {
|
|
30738
|
+
props: object({
|
|
30739
|
+
items: array(unknown()),
|
|
30740
|
+
className
|
|
30741
|
+
}),
|
|
30742
|
+
description: `Only in a script's card: small pills for conditions, damage types, traits: [{ text, tone, icon }] or plain strings. ${TONE_DOC}`,
|
|
30743
|
+
example: {
|
|
30744
|
+
items: [{ text: "Poisoned", tone: "fumble", icon: "flask" }, "Prone"]
|
|
30745
|
+
}
|
|
30746
|
+
},
|
|
30747
|
+
Roster: {
|
|
30748
|
+
props: object({
|
|
30749
|
+
items: array(unknown()),
|
|
30750
|
+
numbered: optional(nullable(boolean2())),
|
|
30751
|
+
tone,
|
|
30752
|
+
className
|
|
30753
|
+
}),
|
|
30754
|
+
description: `Only in a script's card: people in order: initiative, a party at rest, who voted. Each is { name, subtitle, image, value, valueLabel, dice, modifier, meter: { value, max }, tags, tone, state, you }: image is a portrait URL; without one the game shows the person's own portrait when it knows them by name (the player, a character, an extra), else initials; value is a number at the row's end with valueLabel under it ("19", "init"); dice ([{ sides, value, kept }], up to 3, as Dice takes them) show small before the value with modifier ("+2") between, for a roster of rolls such as initiative; meter is a thin health bar; state "current" lights the row (whose turn it is), "done" and "down" dim it ("down" strikes the name and shows a skull); you: true marks the player's own row. numbered shows 1, 2, 3. tone is the current row's accent (violet by default); an entry's own tone tints its initials ("failure" for enemies).`,
|
|
30755
|
+
example: {
|
|
30756
|
+
numbered: true,
|
|
30757
|
+
items: [
|
|
30758
|
+
{
|
|
30759
|
+
name: "Sera",
|
|
30760
|
+
subtitle: "Ranger",
|
|
30761
|
+
dice: [{ sides: 20, value: 16 }],
|
|
30762
|
+
modifier: "+3",
|
|
30763
|
+
value: 19,
|
|
30764
|
+
valueLabel: "init"
|
|
30765
|
+
},
|
|
30766
|
+
{ name: "Goblin", value: 8, tone: "failure", state: "down" }
|
|
30767
|
+
]
|
|
30768
|
+
}
|
|
30769
|
+
},
|
|
30770
|
+
RollTable: {
|
|
30771
|
+
props: object({
|
|
30772
|
+
rows: array(unknown()),
|
|
30773
|
+
landed: num,
|
|
30774
|
+
rolled: value,
|
|
30775
|
+
sides: num,
|
|
30776
|
+
className
|
|
30777
|
+
}),
|
|
30778
|
+
description: `Only in a script's card: a table of ranges with the row the roll landed on lit: a random encounter table, a move's bands (10+ / 7–9 / 6−), a percentile ladder. rows is [{ range, label, text, tone }]; landed is the index of the row that came up (0 first); rolled is the number shown on it; with sides (20) it shows as that die. text shows only on the landed row, so keep each label short and put what it means in text. ${TONE_DOC}`,
|
|
30779
|
+
example: {
|
|
30780
|
+
rows: [
|
|
30781
|
+
{ range: "10+", label: "You do it", tone: "success" },
|
|
30782
|
+
{ range: "7–9", label: "You stumble", tone: "partial" },
|
|
30783
|
+
{ range: "6−", label: "The GM makes a move", tone: "failure" }
|
|
30784
|
+
],
|
|
30785
|
+
landed: 1,
|
|
30786
|
+
rolled: 8
|
|
30787
|
+
}
|
|
30788
|
+
},
|
|
30789
|
+
Steps: {
|
|
30790
|
+
props: object({
|
|
30791
|
+
items: array(unknown()),
|
|
30792
|
+
direction: optional(nullable(_enum(["vertical", "horizontal"]))),
|
|
30793
|
+
tone,
|
|
30794
|
+
className
|
|
30795
|
+
}),
|
|
30796
|
+
description: `Only in a script's card: stages in order: a level up's choices, a ritual, clues found, a journey's legs. items is [{ label, detail, status }] with status "done", "current", "failed" or "todo" (the default). direction "horizontal" fits up to five short labels on one line. tone is the current stage's accent (violet by default).`,
|
|
30797
|
+
example: {
|
|
30798
|
+
items: [
|
|
30799
|
+
{ label: "Roll hit points", status: "done" },
|
|
30800
|
+
{ label: "Choose a feat", status: "current" },
|
|
30801
|
+
{ label: "Review your sheet" }
|
|
30802
|
+
]
|
|
30803
|
+
}
|
|
30804
|
+
},
|
|
30805
|
+
Log: {
|
|
30806
|
+
props: object({
|
|
30807
|
+
items: array(unknown()),
|
|
30808
|
+
className
|
|
30809
|
+
}),
|
|
30810
|
+
description: `Only in a script's card: what happened, line by line: a contest's rounds, a fight's blows, tries at a lock. items is [{ label, text, detail, tone }] or plain strings; label is a short marker ("R1", "Try 2"); detail is a small breakdown after the line ("16+5 · 9+4"); tone success or critical marks the line with a check, failure or fumble with a cross. ${TONE_DOC}`,
|
|
30811
|
+
example: {
|
|
30812
|
+
items: [
|
|
30813
|
+
{ label: "R1", text: "21 vs 13", tone: "success" },
|
|
30814
|
+
{ label: "R2", text: "9 vs 18", tone: "failure" }
|
|
30815
|
+
]
|
|
30816
|
+
}
|
|
30817
|
+
},
|
|
30818
|
+
Currency: {
|
|
30819
|
+
props: object({
|
|
30820
|
+
amounts: array(unknown()),
|
|
30821
|
+
label: text,
|
|
30822
|
+
signed: optional(nullable(boolean2())),
|
|
30823
|
+
className
|
|
30824
|
+
}),
|
|
30825
|
+
description: `Only in a script's card: money as coins: [{ amount, unit, color }]. Units pp, gp, ep, sp and cp draw as platinum, gold, electrum, silver and copper coins; any other unit ("credits", "crowns") draws a plain coin, or one of color. signed: true shows amounts as changes, +14 green and −3 red. label is a small word before them ("Your purse").`,
|
|
30826
|
+
example: {
|
|
30827
|
+
label: "Your purse",
|
|
30828
|
+
amounts: [
|
|
30829
|
+
{ amount: 23, unit: "gp" },
|
|
30830
|
+
{ amount: 7, unit: "sp" }
|
|
30831
|
+
]
|
|
30832
|
+
}
|
|
30833
|
+
},
|
|
30834
|
+
Versus: {
|
|
30835
|
+
props: object({
|
|
30836
|
+
left: object({}).passthrough(),
|
|
30837
|
+
right: object({}).passthrough(),
|
|
30838
|
+
winner: optional(nullable(_enum(["left", "right"]))),
|
|
30839
|
+
label: text,
|
|
30840
|
+
className
|
|
30841
|
+
}),
|
|
30842
|
+
description: `Only in a script's card: two sides head to head: a contest, an opposed check, a duel. left and right are { name, image, detail, value }: value is the score or roll shown large, detail a line under the name ("+5"). winner "left" or "right" crowns that side and dims the other; leave it out while it's undecided. label is a small line under "VS" ("best of 3").`,
|
|
30843
|
+
example: {
|
|
30844
|
+
left: { name: "Brom", detail: "+5", value: 2 },
|
|
30845
|
+
right: { name: "Old Hask", detail: "+4", value: 1 },
|
|
30846
|
+
winner: "left",
|
|
30847
|
+
label: "best of 3"
|
|
30848
|
+
}
|
|
30849
|
+
}
|
|
30850
|
+
};
|
|
30851
|
+
var SCRIPT_CARD_ONLY_COMPONENTS = new Set([
|
|
30852
|
+
"FileTiles",
|
|
30853
|
+
"Button",
|
|
30854
|
+
...Object.keys(scriptCardComponents)
|
|
30855
|
+
]);
|
|
30856
|
+
|
|
30418
30857
|
// ../shared/src/json-render/catalog.ts
|
|
30419
30858
|
var {
|
|
30420
30859
|
Separator,
|
|
@@ -30474,7 +30913,7 @@ var extendedShadcnComponents = {
|
|
|
30474
30913
|
Stack: {
|
|
30475
30914
|
props: object({
|
|
30476
30915
|
direction: nullable(_enum(["horizontal", "vertical"])),
|
|
30477
|
-
gap: nullable(_enum(["sm", "md", "lg", "none"])),
|
|
30916
|
+
gap: nullable(_enum(["xs", "sm", "md", "lg", "none"])),
|
|
30478
30917
|
align: nullable(_enum(["start", "center", "end", "stretch"])),
|
|
30479
30918
|
justify: nullable(_enum(["start", "center", "end", "between", "around"])),
|
|
30480
30919
|
wrap: nullable(boolean2()),
|
|
@@ -30491,7 +30930,7 @@ var extendedShadcnComponents = {
|
|
|
30491
30930
|
Grid: {
|
|
30492
30931
|
props: object({
|
|
30493
30932
|
columns: nullable(number2()),
|
|
30494
|
-
gap: nullable(_enum(["sm", "md", "lg"])),
|
|
30933
|
+
gap: nullable(_enum(["xs", "sm", "md", "lg"])),
|
|
30495
30934
|
bgColor: nullable(string2()),
|
|
30496
30935
|
bgImage: bgImageProp,
|
|
30497
30936
|
bgImageFit: bgImageFitEnum,
|
|
@@ -30704,6 +31143,48 @@ var craftComponents = {
|
|
|
30704
31143
|
bgColor: null
|
|
30705
31144
|
}
|
|
30706
31145
|
},
|
|
31146
|
+
FileTiles: {
|
|
31147
|
+
props: object({
|
|
31148
|
+
files: array(unknown()),
|
|
31149
|
+
size: nullable(_enum(["sm", "md", "lg"])),
|
|
31150
|
+
layout: nullable(_enum(["grid", "list", "row"])),
|
|
31151
|
+
emptyText: nullable(string2()),
|
|
31152
|
+
shown: nullable(number2().int().min(1)),
|
|
31153
|
+
moreLabel: nullable(string2()),
|
|
31154
|
+
moreLayout: nullable(_enum(["grid", "list", "row"])),
|
|
31155
|
+
className: classNameProp
|
|
31156
|
+
}),
|
|
31157
|
+
description: `Only in a script's card: a grid of the world's files, each its picture and name, opening the file on a tap in play. files lists them by id (a handle's $id, or the handle itself), or as { file, detail, badge, button } for a tile with a line under its name, a badge on its picture and a button that runs one of the script's actions ({ label, press: { action, params, confirm }, disabled, reason }). Craft fills in each name and picture after the run and leaves out any that aren't in the game. layout is how the tiles sit: "grid" (the default), "list" (a row per file, its button at the end: for comparing many, like prices) or "row" (one line that scrolls sideways, keeping the story in view). size is the tile size, "md" by default; a grid's columns follow the size and the screen. shown keeps the set to that many tiles, with a button (moreLabel, "See all" by default) that opens every tile in a window players can scroll and search, laid out as moreLayout (the card's layout by default, a grid for a row).`,
|
|
31158
|
+
example: {
|
|
31159
|
+
files: [],
|
|
31160
|
+
size: "md",
|
|
31161
|
+
layout: "grid",
|
|
31162
|
+
emptyText: null,
|
|
31163
|
+
shown: null,
|
|
31164
|
+
moreLabel: null,
|
|
31165
|
+
moreLayout: null
|
|
31166
|
+
}
|
|
31167
|
+
},
|
|
31168
|
+
Button: {
|
|
31169
|
+
props: object({
|
|
31170
|
+
label: string2(),
|
|
31171
|
+
variant: nullable(_enum(["default", "secondary", "outline", "danger", "choice"])),
|
|
31172
|
+
disabled: nullable(boolean2()),
|
|
31173
|
+
icon: optional(nullable(string2().max(16))),
|
|
31174
|
+
description: optional(nullable(string2())),
|
|
31175
|
+
meta: optional(nullable(union([string2(), number2()]))),
|
|
31176
|
+
selected: optional(nullable(boolean2())),
|
|
31177
|
+
reason: optional(nullable(string2())),
|
|
31178
|
+
turn: optional(nullable(string2().max(200))),
|
|
31179
|
+
className: classNameProp
|
|
31180
|
+
}),
|
|
31181
|
+
description: `Only in a script's card: a button that runs what its element's on.press names. One of the script's actions ({ action: "buy", params: { item: "silver-ring" } }) changes the game's files and redraws the card; setState, pushState and removeState change the card's own state. disabled (often a $cond) greys it out, and reason says why ("Need 27 gp"). variant "default" is the card's one primary action, "secondary" the rest, "danger" for something that can't be undone. variant "choice" draws it as an option row, full width: icon, label, description under it, meta at its end (a price, a tally: "5 gp", "2 votes"). Set selected (often a $cond on the card's state) when the choices are a pick among them: a check shows on the picked one. Once the pick is made and the card redraws, keep selected and set disabled on every choice: the chosen row stays bright with a check and the rest fade. icon names a card icon (sword, shield, heart, coins, flask…) or is an emoji. meta also shows after a plain Button's label. When its action starts the next turn (startsTurn on the action), the press is sent as the player's turn in the Button's label, or in turn when set: words that read as what the player does, for a Confirm whose label says nothing of the pick (often a $template on the card's state).`,
|
|
31182
|
+
example: {
|
|
31183
|
+
label: "Buy · 15 gp",
|
|
31184
|
+
variant: "secondary",
|
|
31185
|
+
disabled: null
|
|
31186
|
+
}
|
|
31187
|
+
},
|
|
30707
31188
|
ReferenceValue: {
|
|
30708
31189
|
props: object({
|
|
30709
31190
|
source: unknown(),
|
|
@@ -31256,7 +31737,8 @@ var craftCatalog = defineCatalog(schema, {
|
|
|
31256
31737
|
Avatar: withClassNameProp(Avatar),
|
|
31257
31738
|
Alert: withClassNameProp(Alert),
|
|
31258
31739
|
...extendedShadcnComponents,
|
|
31259
|
-
...craftComponents
|
|
31740
|
+
...craftComponents,
|
|
31741
|
+
...scriptCardComponents
|
|
31260
31742
|
},
|
|
31261
31743
|
actions: {}
|
|
31262
31744
|
});
|
|
@@ -31682,6 +32164,14 @@ function getCatalogPropSchemas(componentType) {
|
|
|
31682
32164
|
}
|
|
31683
32165
|
return props.shape;
|
|
31684
32166
|
}
|
|
32167
|
+
function catalogPropValueProblem(componentType, propKey, value) {
|
|
32168
|
+
const fieldSchema = getCatalogPropSchemas(componentType)?.[propKey];
|
|
32169
|
+
if (!isPropFieldSchema(fieldSchema)) {
|
|
32170
|
+
return null;
|
|
32171
|
+
}
|
|
32172
|
+
const parsed = fieldSchema.safeParse(value);
|
|
32173
|
+
return parsed.success ? null : parsed.error?.issues?.[0]?.message ?? "does not match the schema";
|
|
32174
|
+
}
|
|
31685
32175
|
function isCatalogComponentType(componentType) {
|
|
31686
32176
|
return Object.hasOwn(craftCatalog.data.components, componentType);
|
|
31687
32177
|
}
|
|
@@ -31822,6 +32312,9 @@ function collectJsonRenderLayoutCatalogIssues(input) {
|
|
|
31822
32312
|
for (const [key, element] of Object.entries(parsed.elements)) {
|
|
31823
32313
|
if (isRecord10(element)) {
|
|
31824
32314
|
collectElementCatalogIssues(key, element, issues);
|
|
32315
|
+
if (typeof element.type === "string" && SCRIPT_CARD_ONLY_COMPONENTS.has(element.type)) {
|
|
32316
|
+
issues.push(`Element "${key}" is a ${element.type}, which only a script's card can use.`);
|
|
32317
|
+
}
|
|
31825
32318
|
}
|
|
31826
32319
|
}
|
|
31827
32320
|
for (const [sectionId, section] of Object.entries(layoutSectionsFromSpec(parsed))) {
|
|
@@ -31980,10 +32473,14 @@ function findScriptFileType(types, key) {
|
|
|
31980
32473
|
var SCRIPT_SOURCE_MAX_LENGTH = 64 * 1024;
|
|
31981
32474
|
var SCRIPT_DESCRIPTION_MAX_LENGTH = 1000;
|
|
31982
32475
|
var SCRIPT_WHEN_MAX_LENGTH = 500;
|
|
32476
|
+
var SCRIPT_AFTER_MAX_LENGTH = 500;
|
|
31983
32477
|
var SCRIPT_MEMORY_LIMIT_BYTES = 16 * 1024 * 1024;
|
|
31984
32478
|
var SCRIPT_RESULT_MAX_BYTES = 64 * 1024;
|
|
32479
|
+
var SCRIPT_CARD_MAX_BYTES = 16 * 1024;
|
|
32480
|
+
var SCRIPT_MAX_ACTIONS = 20;
|
|
32481
|
+
var SCRIPT_CARD_STATE_MAX_BYTES = 4 * 1024;
|
|
31985
32482
|
var SCRIPT_LOG_MAX_BYTES = 16 * 1024;
|
|
31986
|
-
var SCRIPT_MAX_PER_CONTAINER =
|
|
32483
|
+
var SCRIPT_MAX_PER_CONTAINER = 30;
|
|
31987
32484
|
|
|
31988
32485
|
// ../shared/src/scripts/name.ts
|
|
31989
32486
|
var SCRIPT_FILE_SUFFIX_RE = /\.script(\.js)?$/i;
|
|
@@ -32003,6 +32500,44 @@ function scriptFunctionName(fileName) {
|
|
|
32003
32500
|
return LEADING_DIGIT_RE.test(name) ? `_${name}` : name;
|
|
32004
32501
|
}
|
|
32005
32502
|
|
|
32503
|
+
// ../shared/src/scripts/card.ts
|
|
32504
|
+
var SCRIPT_CARD_EXCLUDED_COMPONENTS = new Set([
|
|
32505
|
+
"Include",
|
|
32506
|
+
"SectionSwitch",
|
|
32507
|
+
"FileReferenceGrid",
|
|
32508
|
+
"PageReferenceGrid",
|
|
32509
|
+
"ReferenceValue",
|
|
32510
|
+
"TurnTracker",
|
|
32511
|
+
"Select",
|
|
32512
|
+
"VoiceSelect"
|
|
32513
|
+
]);
|
|
32514
|
+
var SCRIPT_CARD_STATE_ACTIONS = new Set([
|
|
32515
|
+
"setState",
|
|
32516
|
+
"pushState",
|
|
32517
|
+
"removeState"
|
|
32518
|
+
]);
|
|
32519
|
+
var SCRIPT_CARD_RESERVED_ACTIONS = new Set([
|
|
32520
|
+
...SCRIPT_CARD_STATE_ACTIONS,
|
|
32521
|
+
"validateForm"
|
|
32522
|
+
]);
|
|
32523
|
+
var BINDING_KEYS = new Set([
|
|
32524
|
+
"action",
|
|
32525
|
+
"params",
|
|
32526
|
+
"confirm",
|
|
32527
|
+
"onSuccess",
|
|
32528
|
+
"onError",
|
|
32529
|
+
"preventDefault"
|
|
32530
|
+
]);
|
|
32531
|
+
var TILE_KEYS = new Set(["file", "detail", "badge", "button"]);
|
|
32532
|
+
var TILE_BUTTON_KEYS = new Set([
|
|
32533
|
+
"label",
|
|
32534
|
+
"press",
|
|
32535
|
+
"disabled",
|
|
32536
|
+
"reason",
|
|
32537
|
+
"variant"
|
|
32538
|
+
]);
|
|
32539
|
+
var TILE_BUTTON_VARIANTS = new Set(["default", "secondary", "outline"]);
|
|
32540
|
+
|
|
32006
32541
|
// ../shared/src/scripts/types.ts
|
|
32007
32542
|
var SCRIPT_FIELD_TYPES = [
|
|
32008
32543
|
"string",
|
|
@@ -32013,6 +32548,7 @@ var SCRIPT_FIELD_TYPES = [
|
|
|
32013
32548
|
"object"
|
|
32014
32549
|
];
|
|
32015
32550
|
var SCRIPT_VISIBILITIES = ["gm", "player"];
|
|
32551
|
+
var SCRIPT_CARD_ORDERS = ["together", "card-first"];
|
|
32016
32552
|
|
|
32017
32553
|
// ../shared/src/scripts/fields.ts
|
|
32018
32554
|
var FIELD_NAME_RE = /^[A-Za-z_$][\w$]*$/;
|
|
@@ -32243,10 +32779,16 @@ var BANNED_MEMBER_NAMES2 = new Set(["__proto__", "constructor", "prototype"]);
|
|
|
32243
32779
|
var DEFINITION_KEYS = new Set([
|
|
32244
32780
|
"description",
|
|
32245
32781
|
"when",
|
|
32782
|
+
"after",
|
|
32246
32783
|
"input",
|
|
32247
32784
|
"run",
|
|
32248
|
-
"visibility"
|
|
32785
|
+
"visibility",
|
|
32786
|
+
"cardOrder",
|
|
32787
|
+
"waitsForPlayer",
|
|
32788
|
+
"card",
|
|
32789
|
+
"actions"
|
|
32249
32790
|
]);
|
|
32791
|
+
var ACTION_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
|
|
32250
32792
|
var ACORN_POSITION_SUFFIX_RE = /\s*\(\d+:\d+\)$/;
|
|
32251
32793
|
|
|
32252
32794
|
class LiteralError extends Error {
|
|
@@ -32335,6 +32877,23 @@ function stringOption(property, key, maxLength, diagnostics) {
|
|
|
32335
32877
|
throw error;
|
|
32336
32878
|
}
|
|
32337
32879
|
}
|
|
32880
|
+
function cardOrderOption(property, diagnostics) {
|
|
32881
|
+
const value = property.value.type === "Literal" ? property.value.value : undefined;
|
|
32882
|
+
const order = SCRIPT_CARD_ORDERS.find((option) => option === value);
|
|
32883
|
+
if (!order) {
|
|
32884
|
+
diagnostics.push(at(property.value, 'cardOrder is "together" (the card shows with what the run did on the map, the default) or "card-first" (the card shows first, then the map plays)'));
|
|
32885
|
+
return "together";
|
|
32886
|
+
}
|
|
32887
|
+
return order;
|
|
32888
|
+
}
|
|
32889
|
+
function booleanOption(property, key, diagnostics) {
|
|
32890
|
+
const value = property.value.type === "Literal" ? property.value.value : undefined;
|
|
32891
|
+
if (typeof value !== "boolean") {
|
|
32892
|
+
diagnostics.push(at(property.value, `${key} is true or false`));
|
|
32893
|
+
return false;
|
|
32894
|
+
}
|
|
32895
|
+
return value;
|
|
32896
|
+
}
|
|
32338
32897
|
function visibilityOption(property, diagnostics) {
|
|
32339
32898
|
const value = property.value.type === "Literal" ? property.value.value : undefined;
|
|
32340
32899
|
const visibility = SCRIPT_VISIBILITIES.find((option) => option === value);
|
|
@@ -32358,14 +32917,193 @@ function checkRun(property, diagnostics) {
|
|
|
32358
32917
|
}
|
|
32359
32918
|
return { ok: true, usesGame: value.params.length >= 2 };
|
|
32360
32919
|
}
|
|
32920
|
+
function checkCard(property, diagnostics) {
|
|
32921
|
+
const value = property.value;
|
|
32922
|
+
if (value.type !== "FunctionExpression" && value.type !== "ArrowFunctionExpression") {
|
|
32923
|
+
diagnostics.push(at(value, "card must be a function: card(result, input) { return { root, elements } }"));
|
|
32924
|
+
return false;
|
|
32925
|
+
}
|
|
32926
|
+
if (value.generator) {
|
|
32927
|
+
diagnostics.push(at(property, "card can't be a generator"));
|
|
32928
|
+
}
|
|
32929
|
+
if (value.params.length > 2) {
|
|
32930
|
+
diagnostics.push(at(value, "card takes the result and the input: card(result, input)"));
|
|
32931
|
+
}
|
|
32932
|
+
checkCardLiterals(value, diagnostics);
|
|
32933
|
+
return true;
|
|
32934
|
+
}
|
|
32935
|
+
function actionFields(node, name, diagnostics) {
|
|
32936
|
+
let value = {};
|
|
32937
|
+
try {
|
|
32938
|
+
value = literalValue(node);
|
|
32939
|
+
} catch (error) {
|
|
32940
|
+
if (!(error instanceof LiteralError)) {
|
|
32941
|
+
throw error;
|
|
32942
|
+
}
|
|
32943
|
+
diagnostics.push(at(error.node, `actions.${name}.input: ${error.message}`));
|
|
32944
|
+
}
|
|
32945
|
+
const { fields, errors } = readScriptFields(value);
|
|
32946
|
+
for (const error of errors) {
|
|
32947
|
+
diagnostics.push(at(node, `actions.${name}.input: ${error}`));
|
|
32948
|
+
}
|
|
32949
|
+
return { fields, inputSchema: fieldsToJsonSchema(fields) };
|
|
32950
|
+
}
|
|
32951
|
+
function checkActions(property, diagnostics) {
|
|
32952
|
+
const actions = {};
|
|
32953
|
+
if (property.value.type !== "ObjectExpression") {
|
|
32954
|
+
diagnostics.push(at(property.value, "actions must be an object: actions: { buy: { input: { ... }, run(input, { game, result }) { ... } } }"));
|
|
32955
|
+
return actions;
|
|
32956
|
+
}
|
|
32957
|
+
for (const entry of property.value.properties) {
|
|
32958
|
+
if (entry.type !== "Property" || entry.computed) {
|
|
32959
|
+
diagnostics.push(at(entry, "Write each action out by name; no ...spread"));
|
|
32960
|
+
continue;
|
|
32961
|
+
}
|
|
32962
|
+
const name = propertyKey(entry);
|
|
32963
|
+
if (name === null || !ACTION_NAME_RE.test(name)) {
|
|
32964
|
+
diagnostics.push(at(entry.key, "An action's name is a plain name, like buy or takeFeat"));
|
|
32965
|
+
continue;
|
|
32966
|
+
}
|
|
32967
|
+
if (SCRIPT_CARD_RESERVED_ACTIONS.has(name)) {
|
|
32968
|
+
diagnostics.push(at(entry.key, `${name} is one of the card's own actions; give this action another name`));
|
|
32969
|
+
continue;
|
|
32970
|
+
}
|
|
32971
|
+
if (name in actions) {
|
|
32972
|
+
diagnostics.push(at(entry.key, `There are two actions named ${name}`));
|
|
32973
|
+
continue;
|
|
32974
|
+
}
|
|
32975
|
+
if (entry.value.type !== "ObjectExpression") {
|
|
32976
|
+
diagnostics.push(at(entry.value, `actions.${name} must be an object: { input: { ... }, run(input, { game, result }) { ... } }`));
|
|
32977
|
+
continue;
|
|
32978
|
+
}
|
|
32979
|
+
let definition = {
|
|
32980
|
+
fields: {},
|
|
32981
|
+
inputSchema: fieldsToJsonSchema({})
|
|
32982
|
+
};
|
|
32983
|
+
let hasRun = false;
|
|
32984
|
+
let startsTurn = false;
|
|
32985
|
+
for (const part of entry.value.properties) {
|
|
32986
|
+
const key = part.type === "Property" ? propertyKey(part) : null;
|
|
32987
|
+
if (part.type !== "Property" || key === "input") {
|
|
32988
|
+
if (part.type === "Property") {
|
|
32989
|
+
definition = actionFields(part.value, name, diagnostics);
|
|
32990
|
+
} else {
|
|
32991
|
+
diagnostics.push(at(part, "Write the action out; no ...spread"));
|
|
32992
|
+
}
|
|
32993
|
+
continue;
|
|
32994
|
+
}
|
|
32995
|
+
if (key === "startsTurn") {
|
|
32996
|
+
startsTurn = booleanOption(part, `actions.${name}.startsTurn`, diagnostics);
|
|
32997
|
+
continue;
|
|
32998
|
+
}
|
|
32999
|
+
if (key !== "run") {
|
|
33000
|
+
diagnostics.push(at(part.key, `actions.${name} takes input, run and startsTurn${key ? `, not "${key}"` : ""}`));
|
|
33001
|
+
continue;
|
|
33002
|
+
}
|
|
33003
|
+
const value = part.value;
|
|
33004
|
+
if (value.type !== "FunctionExpression" && value.type !== "ArrowFunctionExpression") {
|
|
33005
|
+
diagnostics.push(at(value, `actions.${name}.run must be a function: run(input, { game, result }) { ... }`));
|
|
33006
|
+
continue;
|
|
33007
|
+
}
|
|
33008
|
+
if (value.generator) {
|
|
33009
|
+
diagnostics.push(at(part, `actions.${name}.run can't be a generator`));
|
|
33010
|
+
}
|
|
33011
|
+
if (value.params.length > 2) {
|
|
33012
|
+
diagnostics.push(at(value, `actions.${name}.run takes the input and the context: run(input, { game, result })`));
|
|
33013
|
+
}
|
|
33014
|
+
hasRun = true;
|
|
33015
|
+
}
|
|
33016
|
+
if (!hasRun) {
|
|
33017
|
+
diagnostics.push(at(entry, `actions.${name} needs run(input, { game, result }) { ... }`));
|
|
33018
|
+
}
|
|
33019
|
+
actions[name] = startsTurn ? { ...definition, startsTurn } : definition;
|
|
33020
|
+
}
|
|
33021
|
+
if (Object.keys(actions).length > SCRIPT_MAX_ACTIONS) {
|
|
33022
|
+
diagnostics.push(at(property.value, `A script can have at most ${SCRIPT_MAX_ACTIONS} actions; this one has ${Object.keys(actions).length}`));
|
|
33023
|
+
}
|
|
33024
|
+
return actions;
|
|
33025
|
+
}
|
|
33026
|
+
function propertyNamed(node, name) {
|
|
33027
|
+
for (const property of node.properties) {
|
|
33028
|
+
if (property.type === "Property" && propertyKey(property) === name) {
|
|
33029
|
+
return property;
|
|
33030
|
+
}
|
|
33031
|
+
}
|
|
33032
|
+
return null;
|
|
33033
|
+
}
|
|
33034
|
+
function writtenValues(node) {
|
|
33035
|
+
if (node.type === "Literal") {
|
|
33036
|
+
const value = node.value;
|
|
33037
|
+
return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" ? [[value, node]] : [];
|
|
33038
|
+
}
|
|
33039
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0) {
|
|
33040
|
+
return [[node.quasis[0]?.value.cooked ?? "", node]];
|
|
33041
|
+
}
|
|
33042
|
+
if (node.type === "ConditionalExpression") {
|
|
33043
|
+
return [
|
|
33044
|
+
...writtenValues(node.consequent),
|
|
33045
|
+
...writtenValues(node.alternate)
|
|
33046
|
+
];
|
|
33047
|
+
}
|
|
33048
|
+
if (node.type === "LogicalExpression" && (node.operator === "||" || node.operator === "??")) {
|
|
33049
|
+
return writtenValues(node.right);
|
|
33050
|
+
}
|
|
33051
|
+
return [];
|
|
33052
|
+
}
|
|
33053
|
+
function checkCardLiterals(card, diagnostics) {
|
|
33054
|
+
walk2(card, (node) => {
|
|
33055
|
+
if (node.type !== "ObjectExpression") {
|
|
33056
|
+
return;
|
|
33057
|
+
}
|
|
33058
|
+
const typeProperty = propertyNamed(node, "type");
|
|
33059
|
+
const props = propertyNamed(node, "props");
|
|
33060
|
+
if (!(typeProperty && (props || propertyNamed(node, "children")))) {
|
|
33061
|
+
return;
|
|
33062
|
+
}
|
|
33063
|
+
const [written] = writtenValues(typeProperty.value);
|
|
33064
|
+
const componentType = written?.[0];
|
|
33065
|
+
if (typeof componentType !== "string") {
|
|
33066
|
+
return;
|
|
33067
|
+
}
|
|
33068
|
+
if (SCRIPT_CARD_EXCLUDED_COMPONENTS.has(componentType)) {
|
|
33069
|
+
diagnostics.push(at(typeProperty.value, `A card can't use ${componentType}`));
|
|
33070
|
+
return;
|
|
33071
|
+
}
|
|
33072
|
+
if (!isCatalogComponentType(componentType)) {
|
|
33073
|
+
diagnostics.push(at(typeProperty.value, `${componentType} isn't a component; see the layout component table`));
|
|
33074
|
+
return;
|
|
33075
|
+
}
|
|
33076
|
+
if (props?.value.type !== "ObjectExpression") {
|
|
33077
|
+
return;
|
|
33078
|
+
}
|
|
33079
|
+
for (const prop of props.value.properties) {
|
|
33080
|
+
const propKey = prop.type === "Property" ? propertyKey(prop) : null;
|
|
33081
|
+
if (!(prop.type === "Property" && propKey)) {
|
|
33082
|
+
continue;
|
|
33083
|
+
}
|
|
33084
|
+
for (const [value, valueNode] of writtenValues(prop.value)) {
|
|
33085
|
+
const problem = catalogPropValueProblem(componentType, propKey, value);
|
|
33086
|
+
if (problem) {
|
|
33087
|
+
diagnostics.push(at(valueNode, `${componentType} ${propKey} can't be ${JSON.stringify(value)}: ${problem}`));
|
|
33088
|
+
}
|
|
33089
|
+
}
|
|
33090
|
+
}
|
|
33091
|
+
});
|
|
33092
|
+
}
|
|
32361
33093
|
function readDefinition(options, diagnostics) {
|
|
32362
33094
|
let description = null;
|
|
32363
33095
|
let when = null;
|
|
33096
|
+
let after = null;
|
|
32364
33097
|
let visibility = "gm";
|
|
33098
|
+
let cardOrder = "together";
|
|
33099
|
+
let waitsForPlayer = false;
|
|
32365
33100
|
let fieldsValue = {};
|
|
32366
33101
|
let fieldsNode = options;
|
|
32367
33102
|
let hasRun = false;
|
|
32368
33103
|
let usesGame = false;
|
|
33104
|
+
let hasCard = false;
|
|
33105
|
+
let actions = {};
|
|
33106
|
+
let actionsNode = null;
|
|
32369
33107
|
for (const property of options.properties) {
|
|
32370
33108
|
if (property.type !== "Property") {
|
|
32371
33109
|
diagnostics.push(at(property, "Write defineScript()'s options out; no ...spread"));
|
|
@@ -32377,15 +33115,26 @@ function readDefinition(options, diagnostics) {
|
|
|
32377
33115
|
continue;
|
|
32378
33116
|
}
|
|
32379
33117
|
if (key === null || !DEFINITION_KEYS.has(key)) {
|
|
32380
|
-
diagnostics.push(at(property.key, `defineScript() takes description, when, input, run and
|
|
33118
|
+
diagnostics.push(at(property.key, `defineScript() takes description, when, after, input, run, visibility, waitsForPlayer, cardOrder, card and actions${key ? `, not "${key}"` : ""}`));
|
|
32381
33119
|
continue;
|
|
32382
33120
|
}
|
|
32383
33121
|
if (key === "description") {
|
|
32384
33122
|
description = stringOption(property, key, SCRIPT_DESCRIPTION_MAX_LENGTH, diagnostics);
|
|
32385
33123
|
} else if (key === "when") {
|
|
32386
33124
|
when = stringOption(property, key, SCRIPT_WHEN_MAX_LENGTH, diagnostics) || null;
|
|
33125
|
+
} else if (key === "after") {
|
|
33126
|
+
after = stringOption(property, key, SCRIPT_AFTER_MAX_LENGTH, diagnostics) || null;
|
|
32387
33127
|
} else if (key === "visibility") {
|
|
32388
33128
|
visibility = visibilityOption(property, diagnostics);
|
|
33129
|
+
} else if (key === "cardOrder") {
|
|
33130
|
+
cardOrder = cardOrderOption(property, diagnostics);
|
|
33131
|
+
} else if (key === "waitsForPlayer") {
|
|
33132
|
+
waitsForPlayer = booleanOption(property, key, diagnostics);
|
|
33133
|
+
} else if (key === "card") {
|
|
33134
|
+
hasCard = checkCard(property, diagnostics);
|
|
33135
|
+
} else if (key === "actions") {
|
|
33136
|
+
actions = checkActions(property, diagnostics);
|
|
33137
|
+
actionsNode = property.key;
|
|
32389
33138
|
} else if (key === "input") {
|
|
32390
33139
|
fieldsNode = property.value;
|
|
32391
33140
|
try {
|
|
@@ -32409,6 +33158,9 @@ function readDefinition(options, diagnostics) {
|
|
|
32409
33158
|
if (!hasRun) {
|
|
32410
33159
|
diagnostics.push(at(options, "defineScript() needs run(input) { ... } (or run(input, { game }) to read and change files)"));
|
|
32411
33160
|
}
|
|
33161
|
+
if (actionsNode && !(hasCard && visibility === "player")) {
|
|
33162
|
+
diagnostics.push(at(actionsNode, 'actions run from Buttons on the card players see: give the script card(result, input) and visibility: "player"'));
|
|
33163
|
+
}
|
|
32412
33164
|
const { fields, errors } = readScriptFields(fieldsValue);
|
|
32413
33165
|
for (const error of errors) {
|
|
32414
33166
|
diagnostics.push(at(fieldsNode, error));
|
|
@@ -32419,10 +33171,15 @@ function readDefinition(options, diagnostics) {
|
|
|
32419
33171
|
return {
|
|
32420
33172
|
description,
|
|
32421
33173
|
when,
|
|
33174
|
+
after,
|
|
32422
33175
|
visibility,
|
|
33176
|
+
cardOrder,
|
|
33177
|
+
waitsForPlayer,
|
|
32423
33178
|
fields,
|
|
32424
33179
|
inputSchema: fieldsToJsonSchema(fields),
|
|
32425
|
-
usesGame
|
|
33180
|
+
usesGame,
|
|
33181
|
+
hasCard,
|
|
33182
|
+
actions
|
|
32426
33183
|
};
|
|
32427
33184
|
}
|
|
32428
33185
|
function isAstNode2(value) {
|
|
@@ -32595,7 +33352,7 @@ function definitionCall(declaration, diagnostics) {
|
|
|
32595
33352
|
}
|
|
32596
33353
|
const [options, ...extra] = call.arguments;
|
|
32597
33354
|
if (!options || options.type !== "ObjectExpression" || extra.length > 0) {
|
|
32598
|
-
diagnostics.push(at(call, "defineScript() takes one object: { description, when, input, run, visibility }"));
|
|
33355
|
+
diagnostics.push(at(call, "defineScript() takes one object: { description, when, input, run, visibility, cardOrder, card, actions }"));
|
|
32599
33356
|
return null;
|
|
32600
33357
|
}
|
|
32601
33358
|
return options;
|
|
@@ -33619,10 +34376,89 @@ var ARRIVAL_KEYS = new Set([
|
|
|
33619
34376
|
"details",
|
|
33620
34377
|
"hidden"
|
|
33621
34378
|
]);
|
|
33622
|
-
var STAMPS = new Set(["since", "changed"]);
|
|
34379
|
+
var STAMPS = new Set(["since", "changed", "sinceTurn", "changedTurn"]);
|
|
33623
34380
|
// ../shared/src/scripts/input.ts
|
|
33624
34381
|
var import_ajv2 = __toESM(require_ajv());
|
|
33625
34382
|
var compiled = new WeakMap;
|
|
34383
|
+
// ../shared/src/scene-looks.ts
|
|
34384
|
+
var ROLL_KINDS = [
|
|
34385
|
+
"attack",
|
|
34386
|
+
"damage",
|
|
34387
|
+
"heal",
|
|
34388
|
+
"save",
|
|
34389
|
+
"check",
|
|
34390
|
+
"contest",
|
|
34391
|
+
"chance"
|
|
34392
|
+
];
|
|
34393
|
+
var DELIVERIES = [
|
|
34394
|
+
"strike",
|
|
34395
|
+
"claw",
|
|
34396
|
+
"shot",
|
|
34397
|
+
"thrown",
|
|
34398
|
+
"bolt",
|
|
34399
|
+
"beam",
|
|
34400
|
+
"arc",
|
|
34401
|
+
"wave",
|
|
34402
|
+
"spray",
|
|
34403
|
+
"burst",
|
|
34404
|
+
"touch"
|
|
34405
|
+
];
|
|
34406
|
+
var PROJECTILES = [
|
|
34407
|
+
"shaft",
|
|
34408
|
+
"blade",
|
|
34409
|
+
"ball",
|
|
34410
|
+
"slug",
|
|
34411
|
+
"missile",
|
|
34412
|
+
"bead",
|
|
34413
|
+
"line",
|
|
34414
|
+
"swarm"
|
|
34415
|
+
];
|
|
34416
|
+
var ELEMENTS = [
|
|
34417
|
+
"physical",
|
|
34418
|
+
"fire",
|
|
34419
|
+
"cold",
|
|
34420
|
+
"lightning",
|
|
34421
|
+
"acid",
|
|
34422
|
+
"poison",
|
|
34423
|
+
"shadow",
|
|
34424
|
+
"light",
|
|
34425
|
+
"mind",
|
|
34426
|
+
"arcane",
|
|
34427
|
+
"sonic",
|
|
34428
|
+
"nature",
|
|
34429
|
+
"life"
|
|
34430
|
+
];
|
|
34431
|
+
var APPROACHES = [
|
|
34432
|
+
"sneak",
|
|
34433
|
+
"notice",
|
|
34434
|
+
"search",
|
|
34435
|
+
"read",
|
|
34436
|
+
"persuade",
|
|
34437
|
+
"deceive",
|
|
34438
|
+
"intimidate",
|
|
34439
|
+
"perform",
|
|
34440
|
+
"force",
|
|
34441
|
+
"agility",
|
|
34442
|
+
"endure",
|
|
34443
|
+
"know",
|
|
34444
|
+
"tinker",
|
|
34445
|
+
"tend",
|
|
34446
|
+
"wild",
|
|
34447
|
+
"magic"
|
|
34448
|
+
];
|
|
34449
|
+
var REACTIONS = [
|
|
34450
|
+
"alert",
|
|
34451
|
+
"question",
|
|
34452
|
+
"love",
|
|
34453
|
+
"anger",
|
|
34454
|
+
"fear",
|
|
34455
|
+
"joy",
|
|
34456
|
+
"sleep",
|
|
34457
|
+
"idea",
|
|
34458
|
+
"sad",
|
|
34459
|
+
"silence"
|
|
34460
|
+
];
|
|
34461
|
+
var BLOW_KINDS = new Set(["attack", "damage", "heal"]);
|
|
33626
34462
|
// ../shared/src/scripts/script-types.ts
|
|
33627
34463
|
var SCRIPT_TYPES_COMPILER_OPTIONS = {
|
|
33628
34464
|
target: "ES2022",
|
|
@@ -33656,6 +34492,7 @@ var HANDLE_MEMBER_NAMES = new Set([
|
|
|
33656
34492
|
"$path",
|
|
33657
34493
|
"$fileTypeSlug"
|
|
33658
34494
|
]);
|
|
34495
|
+
var union2 = (list) => list.map((entry) => JSON.stringify(entry)).join(" | ");
|
|
33659
34496
|
var PRELUDE = `/** A reference to another file, as a reference field stores it. */
|
|
33660
34497
|
interface StoredReference {
|
|
33661
34498
|
readonly slug: string;
|
|
@@ -33761,6 +34598,10 @@ interface CurrentStatePerson {
|
|
|
33761
34598
|
readonly hidden: CurrentStateHidden | null;
|
|
33762
34599
|
/** An extra's own state (hp, conditions); someone with a file keeps theirs in it. */
|
|
33763
34600
|
readonly details: { readonly [detail: string]: string | number | boolean };
|
|
34601
|
+
/** The map square(s) they stand on ("M13", "J9–K10"); null off a grid or with no token. */
|
|
34602
|
+
readonly square: string | null;
|
|
34603
|
+
/** Feet to everyone else here with a token, by name, as the map measures it; null off a map. */
|
|
34604
|
+
readonly distances: { readonly [name: string]: number } | null;
|
|
33764
34605
|
}
|
|
33765
34606
|
|
|
33766
34607
|
/** A file or person a tracker points at, by name; its file is filled in by the game. */
|
|
@@ -33913,8 +34754,75 @@ interface CurrentStateChange {
|
|
|
33913
34754
|
/** The current state: the scene the GM keeps. */
|
|
33914
34755
|
interface GameCurrentState {
|
|
33915
34756
|
get(): Promise<CurrentState>;
|
|
33916
|
-
/**
|
|
33917
|
-
|
|
34757
|
+
/**
|
|
34758
|
+
* Checks the change (an error says what's wrong, with error.code) and
|
|
34759
|
+
* returns the current state with it. options.show is where what it makes
|
|
34760
|
+
* shows (an HP change's row, someone going down): see Show.
|
|
34761
|
+
*/
|
|
34762
|
+
update(change: CurrentStateChange, options?: { show?: Show }): Promise<CurrentState>;
|
|
34763
|
+
}
|
|
34764
|
+
|
|
34765
|
+
/**
|
|
34766
|
+
* Where a roll, an effect, a reaction or a current-state change shows:
|
|
34767
|
+
* "all" (the default) on the map and as its row in the story; "map" on the
|
|
34768
|
+
* map only, when the script's own card tells it in the story; "none"
|
|
34769
|
+
* nowhere (it still happens: the dice decide, the state changes).
|
|
34770
|
+
*/
|
|
34771
|
+
type Show = "all" | "map" | "none";
|
|
34772
|
+
|
|
34773
|
+
/** How a moment looks on the map (knowledge/map-language.md). */
|
|
34774
|
+
interface MomentLook {
|
|
34775
|
+
/** How it travels from who it comes from to who it lands on. */
|
|
34776
|
+
delivery?: ${union2(DELIVERIES)};
|
|
34777
|
+
/** What the eye sees flying, for a shot, a throw or a bolt: a javelin is "shaft", a pistol "slug". */
|
|
34778
|
+
projectile?: ${union2(PROJECTILES)};
|
|
34779
|
+
element?: ${union2(ELEMENTS)};
|
|
34780
|
+
}
|
|
34781
|
+
|
|
34782
|
+
/** What game.roll() takes besides the dice. */
|
|
34783
|
+
interface RollOptions extends MomentLook {
|
|
34784
|
+
/** Who rolls, by their current-state name; leave out for a roll no one in the scene makes. */
|
|
34785
|
+
by?: string;
|
|
34786
|
+
/** Who it is at or for: the target, or everyone an area catches. */
|
|
34787
|
+
at?: string | readonly string[];
|
|
34788
|
+
/** What the roll is for, a few words ("Scimitar attack"). */
|
|
34789
|
+
reason?: string;
|
|
34790
|
+
/** The number it is against: 14, or { value: 14, label: "AC 14" }. */
|
|
34791
|
+
against?: number | { value: number; label?: string; succeedsOn?: "or_higher" | "or_lower" };
|
|
34792
|
+
/** What kind of roll the map shows. */
|
|
34793
|
+
kind?: ${union2(ROLL_KINDS)};
|
|
34794
|
+
approach?: ${union2(APPROACHES)};
|
|
34795
|
+
/** Where the roll shows: "all" (the default), "map" (no row in the story) or "none". */
|
|
34796
|
+
show?: Show;
|
|
34797
|
+
}
|
|
34798
|
+
|
|
34799
|
+
/** What game.roll() returns: the total, every face, and the kept d20 face when there is one. */
|
|
34800
|
+
interface RollResult {
|
|
34801
|
+
total: number;
|
|
34802
|
+
faces: number[];
|
|
34803
|
+
/** The kept face of the first d20, for natural 1s and 20s. */
|
|
34804
|
+
natural?: number;
|
|
34805
|
+
dice: string;
|
|
34806
|
+
}
|
|
34807
|
+
|
|
34808
|
+
/** What game.effect() takes: something landing on people with no roll of its own. */
|
|
34809
|
+
interface EffectOptions extends MomentLook {
|
|
34810
|
+
/** Who it comes from; leave out when it comes from the place itself. */
|
|
34811
|
+
from?: string;
|
|
34812
|
+
/** Who it lands on. */
|
|
34813
|
+
at: string | readonly string[];
|
|
34814
|
+
/** What happened, a few words for the caption ("Scimitar hits"). */
|
|
34815
|
+
what: string;
|
|
34816
|
+
/** Where it shows: "all" (the default), "map" (no row in the story) or "none". */
|
|
34817
|
+
show?: Show;
|
|
34818
|
+
}
|
|
34819
|
+
|
|
34820
|
+
/** What game.react() takes: someone visibly reacting, a bead over their head. */
|
|
34821
|
+
interface ReactOptions {
|
|
34822
|
+
who: string;
|
|
34823
|
+
as: ${union2(REACTIONS)};
|
|
34824
|
+
/** Where it shows: "all" (the default), "map" or "none". */
|
|
34825
|
+
show?: Show;
|
|
33918
34826
|
}
|
|
33919
34827
|
|
|
33920
34828
|
/** run()'s second argument. */
|
|
@@ -33927,6 +34835,34 @@ interface ScriptContext {
|
|
|
33927
34835
|
readonly game: Game;
|
|
33928
34836
|
}
|
|
33929
34837
|
|
|
34838
|
+
/** An action's second argument: the game, and the card's last result. */
|
|
34839
|
+
interface ScriptActionContext {
|
|
34840
|
+
/** The world's files, as run() gets them; every change saves together or none does. */
|
|
34841
|
+
readonly game: Game;
|
|
34842
|
+
/** What the card was last drawn from: run()'s result, or the last action's. Read-only. */
|
|
34843
|
+
readonly result: any;
|
|
34844
|
+
}
|
|
34845
|
+
|
|
34846
|
+
/** Something a card's Button can run: \`on: { press: { action: "buy", params: { ... } } }\`. */
|
|
34847
|
+
interface ScriptAction {
|
|
34848
|
+
/** The fields a tap passes as params, by name. */
|
|
34849
|
+
input?: { [field: string]: ScriptInputField };
|
|
34850
|
+
/**
|
|
34851
|
+
* Runs on a tap. Check what the tap asks against the result and the files
|
|
34852
|
+
* (never trust params for a price), throw to refuse with a reason the card
|
|
34853
|
+
* shows, and return the card's next result (or nothing to keep it).
|
|
34854
|
+
*/
|
|
34855
|
+
run(input: any, context: ScriptActionContext): unknown;
|
|
34856
|
+
/**
|
|
34857
|
+
* Start the Game Master's next turn once a press works (default false),
|
|
34858
|
+
* with the pressed Button's label as the player's turn: for a pick-one
|
|
34859
|
+
* choice that moves the story on. Only while the card is the newest thing
|
|
34860
|
+
* in the story, and only the first such press on it. Leave it off for an
|
|
34861
|
+
* action players press many times, like a shop's Buy.
|
|
34862
|
+
*/
|
|
34863
|
+
startsTurn?: boolean;
|
|
34864
|
+
}
|
|
34865
|
+
|
|
33930
34866
|
/** One input field: a small JSON Schema. Required unless optional or given a default. */
|
|
33931
34867
|
interface ScriptInputField {
|
|
33932
34868
|
type: "string" | "number" | "integer" | "boolean" | "array" | "object";
|
|
@@ -33950,12 +34886,71 @@ interface ScriptDefinition {
|
|
|
33950
34886
|
description: string;
|
|
33951
34887
|
/** When the Game Master should run it. */
|
|
33952
34888
|
when?: string;
|
|
34889
|
+
/**
|
|
34890
|
+
* What in the story has it run after the Game Master tells it (opt in):
|
|
34891
|
+
* a check after each turn asks whether the turn met it, and runs the
|
|
34892
|
+
* script if so. For scripts the story doesn't wait on, like advancing a
|
|
34893
|
+
* clock or awarding XP, never ones that decide what happens.
|
|
34894
|
+
*/
|
|
34895
|
+
after?: string;
|
|
33953
34896
|
/** Who sees it run in play: the GM alone (the default) or the players too. */
|
|
33954
34897
|
visibility?: "gm" | "player";
|
|
34898
|
+
/**
|
|
34899
|
+
* Where the card players see goes beside what the run did on the map:
|
|
34900
|
+
* "together" (the default) shows it with that moment, its result as the
|
|
34901
|
+
* blow lands; "card-first" shows the card first, then the map plays (a
|
|
34902
|
+
* table roll, then the bandits it called up stepping out).
|
|
34903
|
+
*/
|
|
34904
|
+
cardOrder?: "together" | "card-first";
|
|
34905
|
+
/**
|
|
34906
|
+
* End the Game Master's turn as soon as this script has run (default
|
|
34907
|
+
* false): the GM writes nothing after it, and the player answers next.
|
|
34908
|
+
* For scripts that wait on the player, like a shop whose card they buy from.
|
|
34909
|
+
*/
|
|
34910
|
+
waitsForPlayer?: boolean;
|
|
33955
34911
|
/** The input fields, by name. */
|
|
33956
34912
|
input?: { [field: string]: ScriptInputField };
|
|
33957
34913
|
/** Runs the script. May be async; return plain JSON. */
|
|
33958
34914
|
run(input: any, context: ScriptContext): unknown;
|
|
34915
|
+
/**
|
|
34916
|
+
* The script's own card: what players see where it ran (with visibility
|
|
34917
|
+
* "player") and the editor's test run shows. Gets run()'s result and the
|
|
34918
|
+
* input; returns a json-render spec, { root, elements }, whose props can
|
|
34919
|
+
* bind { "$state": "/result/..." }. Return null for the default card.
|
|
34920
|
+
*/
|
|
34921
|
+
card?(result: any, input: any): ScriptCardSpec | null | undefined;
|
|
34922
|
+
/**
|
|
34923
|
+
* What the card's Buttons can run, by name. Each changes the game's files
|
|
34924
|
+
* when a player taps it and returns the card's next result; the card is
|
|
34925
|
+
* drawn again from it, for every player. Needs card and visibility "player".
|
|
34926
|
+
*/
|
|
34927
|
+
actions?: { [name: string]: ScriptAction };
|
|
34928
|
+
}
|
|
34929
|
+
|
|
34930
|
+
/** What a press runs: one of the script's actions, or a change to the card's own state. */
|
|
34931
|
+
interface ScriptCardBinding {
|
|
34932
|
+
action: string;
|
|
34933
|
+
params?: { [param: string]: unknown };
|
|
34934
|
+
confirm?: { title: string; message: string; confirmLabel?: string; cancelLabel?: string; variant?: "default" | "danger" };
|
|
34935
|
+
onSuccess?: { set: { [statePath: string]: unknown } };
|
|
34936
|
+
onError?: { set: { [statePath: string]: unknown } };
|
|
34937
|
+
}
|
|
34938
|
+
|
|
34939
|
+
/** A json-render spec: the root element's key and every element by key. */
|
|
34940
|
+
interface ScriptCardSpec {
|
|
34941
|
+
root: string;
|
|
34942
|
+
elements: {
|
|
34943
|
+
[key: string]: {
|
|
34944
|
+
type: string;
|
|
34945
|
+
props?: { [prop: string]: unknown };
|
|
34946
|
+
children?: string[];
|
|
34947
|
+
/** What a tap runs: { press: { action: "buy", params: { item: "rope" } } }. */
|
|
34948
|
+
on?: { press: ScriptCardBinding | ScriptCardBinding[] };
|
|
34949
|
+
[key: string]: unknown;
|
|
34950
|
+
};
|
|
34951
|
+
};
|
|
34952
|
+
/** The card's own state as it starts, for picks a Button then confirms (not /result or /viewer). */
|
|
34953
|
+
state?: { [key: string]: unknown };
|
|
33959
34954
|
}
|
|
33960
34955
|
|
|
33961
34956
|
declare function defineScript(definition: ScriptDefinition): ScriptDefinition;
|
|
@@ -34359,6 +35354,34 @@ function renderGame(declared) {
|
|
|
34359
35354
|
" * the way somewhere, at a place with no file, or outside a game.",
|
|
34360
35355
|
" */",
|
|
34361
35356
|
" currentLocation(options?: { include?: true | readonly string[] }): Promise<AnyFile | null>;",
|
|
35357
|
+
" /**",
|
|
35358
|
+
" * The character of whoever caused this run: who tapped the card's Button,",
|
|
35359
|
+
" * or whose message started the GM's turn. Null with no one (a test run",
|
|
35360
|
+
" * with no character picked), so check it.",
|
|
35361
|
+
" */",
|
|
35362
|
+
" player(options?: { include?: true | readonly string[] }): Promise<AnyFile | null>;",
|
|
35363
|
+
" /**",
|
|
35364
|
+
" * Rolls dice and shows the roll on the map and in the story, with its",
|
|
35365
|
+
' * dice card, where the script made it: game.roll("1d20+5", { by: "Goblin 1",',
|
|
35366
|
+
' * at: "Riven", reason: "Scimitar attack", against: { value: 14, label: "AC 14" } }).',
|
|
35367
|
+
" */",
|
|
35368
|
+
" roll(dice: string, options?: RollOptions): Promise<RollResult>;",
|
|
35369
|
+
" /**",
|
|
35370
|
+
" * Asks the player to roll for their own character, and answers with their",
|
|
35371
|
+
' * dice as roll() does: game.askPlayerToRoll("1d20+5", { by: "Riven",',
|
|
35372
|
+
' * at: "Goblin 1", reason: "Longsword attack", against: { value: 13, label: "AC 13" } }).',
|
|
35373
|
+
" * In a game the run stops here and the GM's reply ends with the dice in",
|
|
35374
|
+
" * front of the player; once they roll, the run starts over with the same",
|
|
35375
|
+
" * input, its earlier roll() calls give back the same dice, and this call",
|
|
35376
|
+
" * answers with the player's roll. Nothing the run did before it is kept",
|
|
35377
|
+
" * until then. Let a WAITING_FOR_PLAYER error through a catch. Where no",
|
|
35378
|
+
" * player is asked (a test run, the assistant) the dice are rolled for them.",
|
|
35379
|
+
" */",
|
|
35380
|
+
" askPlayerToRoll(dice: string, options?: RollOptions): Promise<RollResult>;",
|
|
35381
|
+
" /** Shows something landing on people with no roll: an auto-hit, a hazard, a spell's effect. */",
|
|
35382
|
+
" effect(options: EffectOptions): Promise<void>;",
|
|
35383
|
+
" /** Shows someone reacting: a bead over their head. */",
|
|
35384
|
+
" react(options: ReactOptions): Promise<void>;",
|
|
34362
35385
|
" /** The world's file types. */",
|
|
34363
35386
|
" fileTypes(): FileTypes;",
|
|
34364
35387
|
" /**",
|
|
@@ -34715,7 +35738,7 @@ function coerceOptionalString(value) {
|
|
|
34715
35738
|
return typeof value === "string" ? value : String(value);
|
|
34716
35739
|
}
|
|
34717
35740
|
|
|
34718
|
-
// ../../node_modules/.bun/yaml@2.8.
|
|
35741
|
+
// ../../node_modules/.bun/yaml@2.8.4/node_modules/yaml/dist/index.js
|
|
34719
35742
|
var composer = require_composer();
|
|
34720
35743
|
var Document = require_Document();
|
|
34721
35744
|
var Schema = require_Schema();
|
|
@@ -37411,7 +38434,7 @@ async function refreshWorkspaceScriptTypes({
|
|
|
37411
38434
|
// package.json
|
|
37412
38435
|
var package_default = {
|
|
37413
38436
|
name: "@craftrpgs/cli",
|
|
37414
|
-
version: "0.2.0",
|
|
38437
|
+
version: "0.2.2-alpha.0",
|
|
37415
38438
|
description: "Sync Craft projects with a local folder — clone, edit with any coding agent, push back.",
|
|
37416
38439
|
license: "UNLICENSED",
|
|
37417
38440
|
homepage: "https://craftrpgs.com",
|
|
@@ -38490,7 +39513,7 @@ async function promptForBase({
|
|
|
38490
39513
|
rl.close();
|
|
38491
39514
|
}
|
|
38492
39515
|
}
|
|
38493
|
-
// ../../node_modules/.bun/uuid@11.1.
|
|
39516
|
+
// ../../node_modules/.bun/uuid@11.1.1/node_modules/uuid/dist/esm/rng.js
|
|
38494
39517
|
import { randomFillSync } from "crypto";
|
|
38495
39518
|
var rnds8Pool = new Uint8Array(256);
|
|
38496
39519
|
var poolPtr = rnds8Pool.length;
|
|
@@ -38502,7 +39525,7 @@ function rng() {
|
|
|
38502
39525
|
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
38503
39526
|
}
|
|
38504
39527
|
|
|
38505
|
-
// ../../node_modules/.bun/uuid@11.1.
|
|
39528
|
+
// ../../node_modules/.bun/uuid@11.1.1/node_modules/uuid/dist/esm/stringify.js
|
|
38506
39529
|
var byteToHex = [];
|
|
38507
39530
|
for (let i = 0;i < 256; ++i) {
|
|
38508
39531
|
byteToHex.push((i + 256).toString(16).slice(1));
|
|
@@ -38511,7 +39534,7 @@ function unsafeStringify(arr, offset = 0) {
|
|
|
38511
39534
|
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
38512
39535
|
}
|
|
38513
39536
|
|
|
38514
|
-
// ../../node_modules/.bun/uuid@11.1.
|
|
39537
|
+
// ../../node_modules/.bun/uuid@11.1.1/node_modules/uuid/dist/esm/v7.js
|
|
38515
39538
|
var _state = {};
|
|
38516
39539
|
function v7(options, buf, offset) {
|
|
38517
39540
|
let bytes;
|
|
@@ -40683,7 +41706,7 @@ var MAP_USAGE = `Usage: craft map get <location-path> [--json]
|
|
|
40683
41706
|
` + ` craft map set <location-path> --file <map.json>
|
|
40684
41707
|
` + `
|
|
40685
41708
|
` + "The map JSON is the stored MapData shape; in `set` input, areas/points may\n" + 'use `"link": "<workspace path | slug.type | referenceId>"` instead of\n' + `fileReferenceId, and element ids are minted when omitted. An element's
|
|
40686
|
-
` + '`exit` (a door, stairs, a road to another location) takes `"to"` as a\n' + "workspace path too; no `to` is the way out to the parent map. `get` prints\n" + `links and exit targets as workspace paths. Read
|
|
41709
|
+
` + '`exit` (a door, stairs, a road to another location) takes `"to"` as a\n' + "workspace path too; no `to` is the way out to the parent map, and\n" + "`arriveAt` is the id of the pin or area it comes out at on that map. `get` prints\n" + `links and exit targets as workspace paths. Read
|
|
40687
41710
|
` + `.craft/instructions/authoring-maps.md for the format and
|
|
40688
41711
|
` + ".craft/instructions/linking-locations.md for exits.";
|
|
40689
41712
|
async function runMap(argv) {
|
|
@@ -41749,6 +42772,12 @@ function collectAgentFileMentionAliases(markdown) {
|
|
|
41749
42772
|
function stripDiacritics(value) {
|
|
41750
42773
|
return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
|
|
41751
42774
|
}
|
|
42775
|
+
function matchesOutsideMarkdownCode(markdown, regex) {
|
|
42776
|
+
return collectRegexMatchesOutsideProtectedRanges(markdown, regex);
|
|
42777
|
+
}
|
|
42778
|
+
function replaceOutsideMarkdownCode(markdown, regex, replace) {
|
|
42779
|
+
return replaceRegexMatchesOutsideProtectedRanges(markdown, regex, replace);
|
|
42780
|
+
}
|
|
41752
42781
|
function collectRegexMatchesOutsideProtectedRanges(markdown, regex) {
|
|
41753
42782
|
const protectedRanges = collectMarkdownProtectedRanges(markdown);
|
|
41754
42783
|
const matches = [];
|
|
@@ -41764,6 +42793,26 @@ function collectRegexMatchesOutsideProtectedRanges(markdown, regex) {
|
|
|
41764
42793
|
}
|
|
41765
42794
|
return matches;
|
|
41766
42795
|
}
|
|
42796
|
+
function replaceRegexMatchesOutsideProtectedRanges(markdown, regex, replace) {
|
|
42797
|
+
const protectedRanges = collectMarkdownProtectedRanges(markdown);
|
|
42798
|
+
let output = "";
|
|
42799
|
+
let lastIndex = 0;
|
|
42800
|
+
regex.lastIndex = 0;
|
|
42801
|
+
let match = regex.exec(markdown);
|
|
42802
|
+
while (match !== null) {
|
|
42803
|
+
const start = match.index;
|
|
42804
|
+
const end = start + match[0].length;
|
|
42805
|
+
if (rangeOverlapsAny({ start, end }, protectedRanges)) {
|
|
42806
|
+
match = regex.exec(markdown);
|
|
42807
|
+
continue;
|
|
42808
|
+
}
|
|
42809
|
+
output += markdown.slice(lastIndex, start);
|
|
42810
|
+
output += replace(match);
|
|
42811
|
+
lastIndex = end;
|
|
42812
|
+
match = regex.exec(markdown);
|
|
42813
|
+
}
|
|
42814
|
+
return output + markdown.slice(lastIndex);
|
|
42815
|
+
}
|
|
41767
42816
|
function collectMarkdownProtectedRanges(markdown) {
|
|
41768
42817
|
const ranges = [];
|
|
41769
42818
|
collectFencedCodeRanges(markdown, ranges);
|
|
@@ -46122,15 +47171,111 @@ var sceneHeadingProps = object({
|
|
|
46122
47171
|
});
|
|
46123
47172
|
|
|
46124
47173
|
// ../shared/src/gm-narration/clean-narration-text.ts
|
|
46125
|
-
var
|
|
47174
|
+
var POSTPROCESSING_MARKER = "STARTING POSTPROCESSING";
|
|
47175
|
+
var WHITESPACE_CHAR_RE = /\s/;
|
|
47176
|
+
var DIVIDER_LINE_END_RE = /[ \t]*\n/y;
|
|
46126
47177
|
var TRANSLATED_POSTPROCESSING_MARKER_RE = /(?:\n?---[ \t]*\r?\n)?^[ \t]*(?:`{3,}[ \t]*)?\\?(?:-{3,}|\*{2})[ \t]*(?:正在)?(?:开始后处理|開始後處理)[ \t]*(?:-{3,}|\*{2})?[ \t]*\r?$/gm;
|
|
47178
|
+
function isWhitespaceAt(text, index) {
|
|
47179
|
+
const char = text[index];
|
|
47180
|
+
return char !== undefined && WHITESPACE_CHAR_RE.test(char);
|
|
47181
|
+
}
|
|
47182
|
+
function markerPrefixStart(text, floor, markerAt) {
|
|
47183
|
+
let start = markerAt;
|
|
47184
|
+
while (start > floor && isWhitespaceAt(text, start - 1)) {
|
|
47185
|
+
start--;
|
|
47186
|
+
}
|
|
47187
|
+
while (start > floor && text[start - 1] === "-") {
|
|
47188
|
+
start--;
|
|
47189
|
+
}
|
|
47190
|
+
while (start > floor && text[start - 1] === "*") {
|
|
47191
|
+
start--;
|
|
47192
|
+
}
|
|
47193
|
+
while (start > floor && isWhitespaceAt(text, start - 1)) {
|
|
47194
|
+
start--;
|
|
47195
|
+
}
|
|
47196
|
+
if (start - 3 >= floor && text.startsWith("---", start - 3)) {
|
|
47197
|
+
DIVIDER_LINE_END_RE.lastIndex = start;
|
|
47198
|
+
if (DIVIDER_LINE_END_RE.test(text)) {
|
|
47199
|
+
start -= 3;
|
|
47200
|
+
if (start > floor && text[start - 1] === `
|
|
47201
|
+
`) {
|
|
47202
|
+
start--;
|
|
47203
|
+
}
|
|
47204
|
+
}
|
|
47205
|
+
}
|
|
47206
|
+
return start;
|
|
47207
|
+
}
|
|
46127
47208
|
function stripGmPostprocessingMarkers(text) {
|
|
46128
|
-
|
|
47209
|
+
let stripped = "";
|
|
47210
|
+
let keepFrom = 0;
|
|
47211
|
+
let markerAt = text.indexOf(POSTPROCESSING_MARKER);
|
|
47212
|
+
while (markerAt >= 0) {
|
|
47213
|
+
stripped += text.slice(keepFrom, markerPrefixStart(text, keepFrom, markerAt));
|
|
47214
|
+
const lineEnd = text.indexOf(`
|
|
47215
|
+
`, markerAt + POSTPROCESSING_MARKER.length);
|
|
47216
|
+
keepFrom = lineEnd < 0 ? text.length : lineEnd;
|
|
47217
|
+
markerAt = text.indexOf(POSTPROCESSING_MARKER, keepFrom);
|
|
47218
|
+
}
|
|
47219
|
+
stripped += text.slice(keepFrom);
|
|
47220
|
+
return stripped.replace(TRANSLATED_POSTPROCESSING_MARKER_RE, "");
|
|
47221
|
+
}
|
|
47222
|
+
var HIDDEN_TAG_NAMES = "hidden-note|note-to-self|[a-z]+-hidden|hidden-[a-z]+|askPlayerToRoll|gmRollDice|askUserQuestion";
|
|
47223
|
+
var HIDDEN_NOTE_TAG_RE = new RegExp(`<(\\/?)(${HIDDEN_TAG_NAMES})>`, "gi");
|
|
47224
|
+
var HIDDEN_NOTE_OPEN_RE = new RegExp(`<(?:${HIDDEN_TAG_NAMES})>`, "i");
|
|
47225
|
+
var HIDDEN_NOTE_EDGE_TAGS_RE = new RegExp(`^<(?:${HIDDEN_TAG_NAMES})>|<\\/(?:${HIDDEN_TAG_NAMES})>$`, "gi");
|
|
47226
|
+
|
|
47227
|
+
// ../shared/src/gm-narration/narration-links.ts
|
|
47228
|
+
var NARRATION_LINK_RE = /!?\[([^[\]\n]{0,200}(?:\n[^[\]\n]{0,200})?)\]\([ \t]{0,16}(?:\n[ \t]{0,16})?(?:<([^<>\n]{0,256})>|([^\s()<>]{0,256}))(?:[ \t\n]{1,16}(?:"[^"\n]{0,200}"|'[^'\n]{0,200}'|\([^()\n]{0,200}\)))?[ \t]{0,16}(?:\n[ \t]{0,16})?\)/gu;
|
|
47229
|
+
var UNFINISHED_LINK_RE = /!?\[(?=[^[]*$)([^[\]\n]{0,200}(?:\n[^[\]\n]{0,200})?)(\](?:\([^)]{0,300})?)?$/gu;
|
|
47230
|
+
var LEFTOVER_TARGET_RE = /\]\([ \t]{0,16}<?[\p{L}\p{N}_-]{0,80}#[0-9a-fA-F]{6,8}>?(?:[ \t]{1,16}[^)\n]{0,200})?\)/gu;
|
|
47231
|
+
var WEB_TARGET_RE = /^https?:\/\//i;
|
|
47232
|
+
function narrationLinks(text, { streaming = false } = {}) {
|
|
47233
|
+
if (!text.includes("[")) {
|
|
47234
|
+
return [];
|
|
47235
|
+
}
|
|
47236
|
+
const links = matchesOutsideMarkdownCode(text, NARRATION_LINK_RE).map((match) => ({
|
|
47237
|
+
words: match[1] ?? "",
|
|
47238
|
+
target: (match[2] ?? match[3] ?? "").trim(),
|
|
47239
|
+
image: match[0].startsWith("!"),
|
|
47240
|
+
start: match.index,
|
|
47241
|
+
end: match.index + match[0].length
|
|
47242
|
+
}));
|
|
47243
|
+
const [tail] = matchesOutsideMarkdownCode(text, UNFINISHED_LINK_RE);
|
|
47244
|
+
if (tail && tail.index >= (links.at(-1)?.end ?? 0) && (tail[2] !== "]" || streaming)) {
|
|
47245
|
+
links.push({
|
|
47246
|
+
words: tail[1] ?? "",
|
|
47247
|
+
target: null,
|
|
47248
|
+
image: tail[0].startsWith("!"),
|
|
47249
|
+
start: tail.index,
|
|
47250
|
+
end: text.length
|
|
47251
|
+
});
|
|
47252
|
+
}
|
|
47253
|
+
return links;
|
|
47254
|
+
}
|
|
47255
|
+
function drawnAsWords(link) {
|
|
47256
|
+
return link.image || link.target === null || !WEB_TARGET_RE.test(link.target);
|
|
47257
|
+
}
|
|
47258
|
+
function narrationLinkWords(text) {
|
|
47259
|
+
let words = text;
|
|
47260
|
+
const links = narrationLinks(text).filter(drawnAsWords);
|
|
47261
|
+
if (links.length > 0) {
|
|
47262
|
+
words = "";
|
|
47263
|
+
let at = 0;
|
|
47264
|
+
for (const link of links) {
|
|
47265
|
+
words += text.slice(at, link.start) + link.words;
|
|
47266
|
+
at = link.end;
|
|
47267
|
+
}
|
|
47268
|
+
words += text.slice(at);
|
|
47269
|
+
}
|
|
47270
|
+
return words.includes("](") ? replaceOutsideMarkdownCode(words, LEFTOVER_TARGET_RE, () => "]") : words;
|
|
46129
47271
|
}
|
|
47272
|
+
var NO_LINKS = new Map;
|
|
47273
|
+
var linksByMessage = new WeakMap;
|
|
46130
47274
|
|
|
46131
47275
|
// ../shared/src/tts/text.ts
|
|
46132
47276
|
function cleanTextForTTS(text) {
|
|
46133
|
-
|
|
47277
|
+
const withoutPictures = stripGmPostprocessingMarkers(text).replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, "$1").replace(/!\[.*?\]\(.*?\)/g, "");
|
|
47278
|
+
return narrationLinkWords(withoutPictures).replace(/\[([^\]]+)\]\(.*?\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/(\*{3}|_{3})(.+?)\1/g, "$2").replace(/(\*{2}|_{2})(.+?)\1/g, "$2").replace(/(?<!\w)(\*|_)(.+?)\1(?!\w)/g, "$2").replace(/~~(.+?)~~/g, "$1").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}\s*$/gm, "").replace(/^[\t ]*[-*+]\s+/gm, "").replace(/^[\t ]*\d+\.\s+/gm, "").replace(/<[^>]+>/g, "").replace(/\n{2,}/g, " ").replace(/\n/g, " ").replace(/ {2,}/g, " ").trim();
|
|
46134
47279
|
}
|
|
46135
47280
|
function hashTtsSegmentText(text) {
|
|
46136
47281
|
let hash = 2166136261;
|