@fuaran-ui/ops 0.9.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -80,10 +80,11 @@ var formatFiniteDouble = (n) => {
80
80
  return neg ? "-" + out : out;
81
81
  };
82
82
  var num = (n) => {
83
- if (Number.isNaN(n)) return '"NaN"';
84
- if (n === Infinity) return '"Infinity"';
85
- if (n === -Infinity) return '"-Infinity"';
86
- return formatFiniteDouble(n);
83
+ const v = Number(n);
84
+ if (Number.isNaN(v)) return '"NaN"';
85
+ if (v === Infinity) return '"Infinity"';
86
+ if (v === -Infinity) return '"-Infinity"';
87
+ return formatFiniteDouble(v);
87
88
  };
88
89
  var bool = (b) => b ? "true" : "false";
89
90
  var jObject = (fields) => {
@@ -483,7 +484,9 @@ var action = (a) => {
483
484
  case "CommitLocal":
484
485
  return caseObj("CommitLocal", [["nodeId", str(a.nodeId)]]);
485
486
  case "WriteToClipboard":
486
- return caseObj("WriteToClipboard", [["text", str(a.text)]]);
487
+ return caseObj("WriteToClipboard", [["text", textSource(a.text)]]);
488
+ case "Print":
489
+ return caseObj("Print", []);
487
490
  case "ReadFileBody":
488
491
  return caseObj("ReadFileBody", [
489
492
  ["encoding", str(a.encoding)],
@@ -593,6 +596,9 @@ var pushWeightOptional = (fields, w) => {
593
596
  var pushEmphasisOptional = (fields, e) => {
594
597
  if (e !== "Normal") fields.push(["emphasis", str(e)]);
595
598
  };
599
+ var pushTrendPolarityOptional = (fields, p) => {
600
+ if (p !== "HigherIsBetter") fields.push(["trendPolarity", str(p)]);
601
+ };
596
602
  var pushCellFormatOptional = (fields, key, f) => {
597
603
  if (f.kind !== "None") fields.push([key, cellFormat(f)]);
598
604
  };
@@ -610,6 +616,7 @@ var metricSpec = (s) => {
610
616
  pushEmphasisOptional(fields, s.emphasis);
611
617
  if (s.trend !== void 0) fields.push(["trend", binding(s.trend)]);
612
618
  if (s.trendFormat !== void 0) fields.push(["trendFormat", cellFormat(s.trendFormat)]);
619
+ pushTrendPolarityOptional(fields, s.trendPolarity);
613
620
  if (s.icon !== void 0) fields.push(["icon", str(s.icon)]);
614
621
  if (s.subtext !== void 0) fields.push(["subtext", textSource(s.subtext)]);
615
622
  return jObject(fields);
@@ -656,11 +663,76 @@ var linkSpec = (s) => {
656
663
  if (s.protection !== void 0) fields.push(["protection", str(s.protection)]);
657
664
  return jObject(fields);
658
665
  };
659
- var imageSpec = (s) => jObject([
660
- ["alt", textSource(s.alt)],
661
- ["src", binding(s.src)],
662
- ["variant", str(s.variant)]
666
+ var srcSetEntry = (e) => jObject([
667
+ ["src", binding(e.src)],
668
+ ["width", num(e.width)]
663
669
  ]);
670
+ var imageSpec = (s) => {
671
+ const fields = [
672
+ ["alt", textSource(s.alt)],
673
+ ["src", binding(s.src)],
674
+ ["variant", str(s.variant)]
675
+ ];
676
+ if (s.fit !== "Natural") fields.push(["fit", str(s.fit)]);
677
+ if (s.aspectRatio !== "Natural") fields.push(["aspectRatio", str(s.aspectRatio)]);
678
+ if (s.loading !== "Eager") fields.push(["loading", str(s.loading)]);
679
+ if (s.caption !== void 0) fields.push(["caption", textSource(s.caption)]);
680
+ if (s.srcSet.length > 0) fields.push(["srcSet", jArray(s.srcSet.map(srcSetEntry))]);
681
+ if (s.expandable) fields.push(["expandable", bool(true)]);
682
+ return jObject(fields);
683
+ };
684
+ var mediaKind = (k) => {
685
+ if (k.$type === "Audio") return caseObj("Audio", []);
686
+ const fields = [];
687
+ if (k.autoplay) fields.push(["autoplay", bool(true)]);
688
+ if (k.poster !== void 0) fields.push(["poster", binding(k.poster)]);
689
+ return caseObj("Video", fields);
690
+ };
691
+ var mediaSpec = (s) => {
692
+ const fields = [];
693
+ if (!s.controls) fields.push(["controls", bool(false)]);
694
+ fields.push(["kind", mediaKind(s.kind)]);
695
+ fields.push(["label", textSource(s.label)]);
696
+ if (s.loop) fields.push(["loop", bool(true)]);
697
+ fields.push(["src", binding(s.src)]);
698
+ if (s.tracks.length > 0) fields.push(["tracks", jArray(s.tracks.map(trackEntry))]);
699
+ if (s.transcript !== void 0) fields.push(["transcript", textSource(s.transcript)]);
700
+ return jObject(fields);
701
+ };
702
+ var trackEntry = (t) => {
703
+ const fields = [];
704
+ if (t.default) fields.push(["default", bool(true)]);
705
+ fields.push(["kind", str(t.kind)]);
706
+ fields.push(["label", textSource(t.label)]);
707
+ fields.push(["src", binding(t.src)]);
708
+ fields.push(["srcLang", str(t.srcLang)]);
709
+ return jObject(fields);
710
+ };
711
+ var treeSpec = (s) => {
712
+ const fields = [["items", jArray(s.items.map(treeItem))]];
713
+ if (s.expandedStateKey !== void 0) fields.push(["expandedStateKey", str(s.expandedStateKey)]);
714
+ if (s.onSelect !== void 0) fields.push(["onSelect", CLOSURE]);
715
+ if (s.selectionStateKey !== void 0)
716
+ fields.push(["selectionStateKey", str(s.selectionStateKey)]);
717
+ return jObject(fields);
718
+ };
719
+ var treeItem = (t) => {
720
+ const fields = [];
721
+ if (t.children.length > 0) fields.push(["children", jArray(t.children.map(treeItem))]);
722
+ if (t.icon !== void 0) fields.push(["icon", str(t.icon)]);
723
+ fields.push(["id", str(t.id)]);
724
+ fields.push(["label", textSource(t.label)]);
725
+ return jObject(fields);
726
+ };
727
+ var embedSpec = (s) => {
728
+ const fields = [];
729
+ if (s.aspectRatio !== "Natural") fields.push(["aspectRatio", str(s.aspectRatio)]);
730
+ if (s.permissions.length > 0)
731
+ fields.push(["permissions", jArray(s.permissions.map((p) => str(p)))]);
732
+ fields.push(["src", binding(s.src)]);
733
+ fields.push(["title", textSource(s.title)]);
734
+ return jObject(fields);
735
+ };
664
736
  var listSpec = (s) => jObject([
665
737
  ["items", jArray(s.items.map(textSource))],
666
738
  ["ordered", bool(s.ordered)]
@@ -869,6 +941,12 @@ var displayKind = (d) => {
869
941
  return hoistSpec("Link", linkSpec(d.spec));
870
942
  case "Image":
871
943
  return hoistSpec("Image", imageSpec(d.spec));
944
+ case "Media":
945
+ return hoistSpec("Media", mediaSpec(d.spec));
946
+ case "Tree":
947
+ return hoistSpec("Tree", treeSpec(d.spec));
948
+ case "Embed":
949
+ return hoistSpec("Embed", embedSpec(d.spec));
872
950
  case "List":
873
951
  return hoistSpec("List", listSpec(d.spec));
874
952
  case "Toast":
@@ -956,6 +1034,40 @@ var formFieldKind = (autoBind, k) => {
956
1034
  ["orientation", str(k.orientation)],
957
1035
  ...valueField(k.value, schema.controlValueDefaults.choice, (v) => binding(v, staticStringOpt))
958
1036
  ]);
1037
+ case "Combobox": {
1038
+ const fields = [];
1039
+ if (k.allowFreeText) fields.push(["allowFreeText", bool(true)]);
1040
+ fields.push(...handlerField("onChange", k.onChange));
1041
+ fields.push(["options", binding(k.options, staticSelectOptions)]);
1042
+ fields.push(
1043
+ ...valueField(k.value, schema.controlValueDefaults.choice, (v) => binding(v, staticStringOpt))
1044
+ );
1045
+ return caseObj("Combobox", fields);
1046
+ }
1047
+ case "Tokens": {
1048
+ const fields = [];
1049
+ if (!k.allowFreeText) fields.push(["allowFreeText", bool(false)]);
1050
+ fields.push(...handlerField("onChange", k.onChange));
1051
+ if (k.suggestions !== void 0)
1052
+ fields.push(["suggestions", binding(k.suggestions, staticSelectOptions)]);
1053
+ fields.push(
1054
+ ...valueField(k.value, schema.controlValueDefaults.tokens, (v) => binding(v, staticStringList))
1055
+ );
1056
+ return caseObj("Tokens", fields);
1057
+ }
1058
+ case "Rating": {
1059
+ const fields = [];
1060
+ if (k.allowHalf) fields.push(["allowHalf", bool(true)]);
1061
+ fields.push(["max", num(k.max)]);
1062
+ fields.push(...handlerField("onChange", k.onChange));
1063
+ fields.push(...valueField(k.value, schema.controlValueDefaults.number, (v) => binding(v)));
1064
+ return caseObj("Rating", fields);
1065
+ }
1066
+ case "Color":
1067
+ return caseObj("Color", [
1068
+ ...handlerField("onChange", k.onChange),
1069
+ ...valueField(k.value, schema.controlValueDefaults.color, (v) => binding(v))
1070
+ ]);
959
1071
  case "TextArea":
960
1072
  return caseObj("TextArea", [
961
1073
  ...handlerField("onChange", k.onChange),
@@ -996,6 +1108,20 @@ var formFieldKind = (autoBind, k) => {
996
1108
  return assertNever(k);
997
1109
  }
998
1110
  };
1111
+ var compareRule = (c) => jObject([
1112
+ ["against", binding(c.against)],
1113
+ ["op", str(c.op)]
1114
+ ]);
1115
+ var fieldRule = (r) => {
1116
+ const fields = [];
1117
+ if (r.compare !== void 0) fields.push(["compare", compareRule(r.compare)]);
1118
+ if (r.format !== void 0) fields.push(["format", str(r.format)]);
1119
+ if (r.maxLength !== void 0) fields.push(["maxLength", intLit(r.maxLength)]);
1120
+ if (r.message !== void 0) fields.push(["message", textSource(r.message)]);
1121
+ if (r.minLength !== void 0) fields.push(["minLength", intLit(r.minLength)]);
1122
+ if (r.pattern !== void 0) fields.push(["pattern", str(r.pattern)]);
1123
+ return jObject(fields);
1124
+ };
999
1125
  var formField = (f) => {
1000
1126
  const fields = [
1001
1127
  ["id", str(f.id)],
@@ -1004,6 +1130,7 @@ var formField = (f) => {
1004
1130
  ["required", bool(f.required)]
1005
1131
  ];
1006
1132
  if (f.help !== void 0) fields.push(["help", textSource(f.help)]);
1133
+ if (f.rule !== void 0) fields.push(["rule", fieldRule(f.rule)]);
1007
1134
  return jObject(fields);
1008
1135
  };
1009
1136
  var formSpec = (s) => {
@@ -1057,6 +1184,10 @@ var fileUploadSpec = (s) => {
1057
1184
  ["onSelect", CLOSURE]
1058
1185
  ];
1059
1186
  if (s.disabled !== void 0) fields.push(["disabled", binding(s.disabled)]);
1187
+ if (s.acceptPaste) fields.push(["acceptPaste", bool(true)]);
1188
+ if (s.dropTarget) fields.push(["dropTarget", bool(true)]);
1189
+ if (s.capture !== void 0) fields.push(["capture", str(s.capture)]);
1190
+ if (s.destination !== void 0) fields.push(["destination", str(s.destination)]);
1060
1191
  return jObject(fields);
1061
1192
  };
1062
1193
  var inputKind = (i) => {
@@ -1194,6 +1325,11 @@ var gridSpec = (s) => {
1194
1325
  if (s.pageStateKey !== void 0) fields.push(["pageStateKey", str(s.pageStateKey)]);
1195
1326
  if (s.defaultSort !== void 0) fields.push(["defaultSort", defaultSortJson(s.defaultSort)]);
1196
1327
  if (s.editStateKey !== void 0) fields.push(["editStateKey", str(s.editStateKey)]);
1328
+ if (s.transferOutKey !== void 0) fields.push(["transferOutKey", str(s.transferOutKey)]);
1329
+ if (s.transferInKey !== void 0) fields.push(["transferInKey", str(s.transferInKey)]);
1330
+ if (s.exportable) fields.push(["exportable", bool(true)]);
1331
+ if (s.keepRowsTogether) fields.push(["keepRowsTogether", bool(true)]);
1332
+ if (s.repeatHeader) fields.push(["repeatHeader", bool(true)]);
1197
1333
  if (s.staticRows !== void 0) {
1198
1334
  const sr = s.staticRows;
1199
1335
  const srFields = [
@@ -1271,6 +1407,11 @@ var boxLayout = (l) => {
1271
1407
  if (l.templateColumns !== void 0) fields.push(["templateColumns", str(l.templateColumns)]);
1272
1408
  return caseObj("Grid", fields);
1273
1409
  }
1410
+ case "Masonry": {
1411
+ const fields = [["cols", intLit(l.cols)]];
1412
+ if (l.gap !== void 0) fields.push(["gap", intLit(l.gap)]);
1413
+ return caseObj("Masonry", fields);
1414
+ }
1274
1415
  case "Auto":
1275
1416
  return caseObj("Auto", []);
1276
1417
  default:
@@ -1282,6 +1423,8 @@ var boxSpec = (s) => {
1282
1423
  if (s.heading !== void 0) fields.push(["heading", textSource(s.heading)]);
1283
1424
  fields.push(["layout", boxLayout(s.layout)]);
1284
1425
  fields.push(["role", str(s.role)]);
1426
+ if (s.keepTogether) fields.push(["keepTogether", bool(true)]);
1427
+ if (s.breakBefore) fields.push(["breakBefore", bool(true)]);
1285
1428
  return jObject(fields);
1286
1429
  };
1287
1430
  var splitPanelSpec = (s) => jObject([
@@ -1336,6 +1479,8 @@ var modalSpec = (s) => {
1336
1479
  ];
1337
1480
  if (s.onDismiss !== void 0) fields.push(["onDismiss", action(s.onDismiss)]);
1338
1481
  if (s.heading !== void 0) fields.push(["heading", textSource(s.heading)]);
1482
+ if (s.modality !== "Modal") fields.push(["modality", str(s.modality)]);
1483
+ if (s.anchor !== void 0) fields.push(["anchor", str(s.anchor)]);
1339
1484
  return jObject(fields);
1340
1485
  };
1341
1486
  var scrollAreaSpec = (s) => {
@@ -1491,6 +1636,9 @@ var nodeKind = (k) => {
1491
1636
  ]);
1492
1637
  case "Switch":
1493
1638
  return caseObj("Switch", [
1639
+ // Phase 1122 — omitted when absent, so every pre-1122 switch stays
1640
+ // byte-identical.
1641
+ ...k.spec.autoAdvanceMs !== void 0 ? [["autoAdvanceMs", num(k.spec.autoAdvanceMs)]] : [],
1494
1642
  [
1495
1643
  "cases",
1496
1644
  jArray(
@@ -1565,6 +1713,8 @@ var semanticStyle = (s) => {
1565
1713
  if (s.weight !== void 0 && s.weight !== "Standard") fields.push(["weight", str(s.weight)]);
1566
1714
  if (s.role !== void 0 && s.role !== "None") fields.push(["role", str(s.role)]);
1567
1715
  if (s.voice !== void 0 && s.voice !== "Default") fields.push(["voice", str(s.voice)]);
1716
+ if (s.direction !== void 0 && s.direction !== "auto")
1717
+ fields.push(["direction", str(s.direction)]);
1568
1718
  return jObject(fields);
1569
1719
  };
1570
1720
  var accessibility = (a) => {
@@ -1578,7 +1728,9 @@ var accessibility = (a) => {
1578
1728
  return jObject(fields);
1579
1729
  };
1580
1730
  var isEmptyState = (s) => s.onLoading === void 0 && s.onEmpty === void 0 && s.onError === void 0;
1581
- var isDefaultStyle = (s) => (s.emphasis === void 0 || s.emphasis === "Normal") && (s.tone === void 0 || s.tone === "Default") && (s.weight === void 0 || s.weight === "Standard") && (s.role === void 0 || s.role === "None") && (s.voice === void 0 || s.voice === "Default");
1731
+ var isDefaultStyle = (s) => (s.emphasis === void 0 || s.emphasis === "Normal") && (s.tone === void 0 || s.tone === "Default") && (s.weight === void 0 || s.weight === "Standard") && (s.role === void 0 || s.role === "None") && (s.voice === void 0 || s.voice === "Default") && // Phase 1472 — `auto` is this member's identity, so a style that declares only
1732
+ // a direction is NOT all-default and the envelope must carry it.
1733
+ (s.direction === void 0 || s.direction === "auto");
1582
1734
  var node = (n) => {
1583
1735
  const fields = [
1584
1736
  ["id", str(n.id)],
@@ -1587,6 +1739,7 @@ var node = (n) => {
1587
1739
  if (!isEmptyState(n.state)) fields.push(["state", stateBehaviour(n.state)]);
1588
1740
  if (!isDefaultStyle(n.style)) fields.push(["style", semanticStyle(n.style)]);
1589
1741
  if (n.accessibility !== void 0) fields.push(["accessibility", accessibility(n.accessibility)]);
1742
+ if (n.tooltip !== void 0) fields.push(["tooltip", textSource(n.tooltip)]);
1590
1743
  return jObject(fields);
1591
1744
  };
1592
1745
  var treeOp = (op) => {
@@ -2683,8 +2836,65 @@ var stepParams = (t) => {
2683
2836
  var pipelineParams = (pipeline) => [
2684
2837
  ...new Set(pipeline.flatMap((t) => stepParams(t)))
2685
2838
  ];
2686
-
2687
- // src/parse.ts
2839
+ var substituteListParamsExpr = (listEnv, e) => {
2840
+ switch (e.kind) {
2841
+ case "col":
2842
+ case "lit":
2843
+ case "param":
2844
+ return e;
2845
+ case "binary":
2846
+ return {
2847
+ kind: "binary",
2848
+ op: e.op,
2849
+ left: substituteListParamsExpr(listEnv, e.left),
2850
+ right: substituteListParamsExpr(listEnv, e.right)
2851
+ };
2852
+ case "not":
2853
+ return { kind: "not", expr: substituteListParamsExpr(listEnv, e.expr) };
2854
+ case "coalesce":
2855
+ return { kind: "coalesce", exprs: e.exprs.map((x) => substituteListParamsExpr(listEnv, x)) };
2856
+ case "case":
2857
+ return {
2858
+ kind: "case",
2859
+ cases: e.cases.map((br) => ({
2860
+ when: substituteListParamsExpr(listEnv, br.when),
2861
+ then: substituteListParamsExpr(listEnv, br.then)
2862
+ })),
2863
+ else: substituteListParamsExpr(listEnv, e.else)
2864
+ };
2865
+ case "cast":
2866
+ return { kind: "cast", type: e.type, expr: substituteListParamsExpr(listEnv, e.expr) };
2867
+ case "apply":
2868
+ return {
2869
+ kind: "apply",
2870
+ fn: e.fn,
2871
+ args: e.args.map((x) => substituteListParamsExpr(listEnv, x))
2872
+ };
2873
+ case "in":
2874
+ return {
2875
+ kind: "in",
2876
+ expr: substituteListParamsExpr(listEnv, e.expr),
2877
+ items: e.items.map((x) => substituteListParamsExpr(listEnv, x))
2878
+ };
2879
+ case "isNull":
2880
+ return { kind: "isNull", expr: substituteListParamsExpr(listEnv, e.expr) };
2881
+ case "inParam": {
2882
+ const expr = substituteListParamsExpr(listEnv, e.expr);
2883
+ const items = Object.prototype.hasOwnProperty.call(listEnv, e.param) ? listEnv[e.param] : void 0;
2884
+ return items === void 0 ? { kind: "inParam", expr, param: e.param } : { kind: "in", expr, items: items.map((c) => ({ kind: "lit", cell: c })) };
2885
+ }
2886
+ }
2887
+ };
2888
+ var substituteListParams = (listEnv, pipeline) => pipeline.map((t) => {
2889
+ switch (t.kind) {
2890
+ case "filter":
2891
+ return { kind: "filter", pred: substituteListParamsExpr(listEnv, t.pred) };
2892
+ case "derive":
2893
+ return { kind: "derive", name: t.name, expr: substituteListParamsExpr(listEnv, t.expr) };
2894
+ default:
2895
+ return t;
2896
+ }
2897
+ });
2688
2898
  var peek = (s) => s.pos < s.text.length ? s.text[s.pos] : " ";
2689
2899
  var advance = (s) => {
2690
2900
  s.pos += 1;
@@ -2699,6 +2909,10 @@ var skipWs = (s) => {
2699
2909
  }
2700
2910
  }
2701
2911
  };
2912
+ var failLimit = (s, message) => ({
2913
+ ok: false,
2914
+ error: { message, offset: s.pos, limit: true }
2915
+ });
2702
2916
  var fail = (s, message) => ({
2703
2917
  ok: false,
2704
2918
  error: { message, offset: s.pos }
@@ -2721,7 +2935,14 @@ var parseStringRaw = (s) => {
2721
2935
  advance(s);
2722
2936
  if (c === '"') {
2723
2937
  return { ok: true, value: out };
2724
- } else if (c === "\\") {
2938
+ }
2939
+ if (out.length > schema.MAX_STRING_LENGTH) {
2940
+ return failLimit(
2941
+ s,
2942
+ `string is longer than the wire limit MAX_STRING_LENGTH = ${schema.MAX_STRING_LENGTH}`
2943
+ );
2944
+ }
2945
+ if (c === "\\") {
2725
2946
  if (s.pos >= s.text.length) return fail(s, "unterminated escape");
2726
2947
  const esc = s.text[s.pos];
2727
2948
  advance(s);
@@ -2821,6 +3042,12 @@ var parseValue = (s) => {
2821
3042
  }
2822
3043
  };
2823
3044
  var parseObjectValue = (s) => {
3045
+ if (s.depth >= schema.MAX_JSON_DEPTH) {
3046
+ return failLimit(
3047
+ s,
3048
+ `JSON nesting deeper than the wire limit MAX_JSON_DEPTH = ${schema.MAX_JSON_DEPTH}`
3049
+ );
3050
+ }
2824
3051
  const open = expectChar(s, "{");
2825
3052
  if (!open.ok) return open;
2826
3053
  skipWs(s);
@@ -2829,15 +3056,34 @@ var parseObjectValue = (s) => {
2829
3056
  advance(s);
2830
3057
  return { ok: true, value: { kind: "JObject", fields } };
2831
3058
  }
3059
+ s.depth += 1;
3060
+ let count = 0;
2832
3061
  for (; ; ) {
2833
3062
  skipWs(s);
2834
3063
  const keyR = parseStringRaw(s);
2835
- if (!keyR.ok) return keyR;
3064
+ if (!keyR.ok) {
3065
+ s.depth -= 1;
3066
+ return keyR;
3067
+ }
2836
3068
  skipWs(s);
2837
3069
  const colon = expectChar(s, ":");
2838
- if (!colon.ok) return colon;
3070
+ if (!colon.ok) {
3071
+ s.depth -= 1;
3072
+ return colon;
3073
+ }
2839
3074
  const valR = parseValue(s);
2840
- if (!valR.ok) return valR;
3075
+ if (!valR.ok) {
3076
+ s.depth -= 1;
3077
+ return valR;
3078
+ }
3079
+ count += 1;
3080
+ if (count > schema.MAX_ARRAY_LENGTH) {
3081
+ s.depth -= 1;
3082
+ return failLimit(
3083
+ s,
3084
+ `object has more members than the wire limit MAX_ARRAY_LENGTH = ${schema.MAX_ARRAY_LENGTH}`
3085
+ );
3086
+ }
2841
3087
  fields.set(keyR.value, valR.value);
2842
3088
  skipWs(s);
2843
3089
  const c = peek(s);
@@ -2845,13 +3091,21 @@ var parseObjectValue = (s) => {
2845
3091
  advance(s);
2846
3092
  } else if (c === "}") {
2847
3093
  advance(s);
3094
+ s.depth -= 1;
2848
3095
  return { ok: true, value: { kind: "JObject", fields } };
2849
3096
  } else {
3097
+ s.depth -= 1;
2850
3098
  return fail(s, `expected ',' or '}' but found '${c}'`);
2851
3099
  }
2852
3100
  }
2853
3101
  };
2854
3102
  var parseArrayValue = (s) => {
3103
+ if (s.depth >= schema.MAX_JSON_DEPTH) {
3104
+ return failLimit(
3105
+ s,
3106
+ `JSON nesting deeper than the wire limit MAX_JSON_DEPTH = ${schema.MAX_JSON_DEPTH}`
3107
+ );
3108
+ }
2855
3109
  const open = expectChar(s, "[");
2856
3110
  if (!open.ok) return open;
2857
3111
  skipWs(s);
@@ -2860,24 +3114,37 @@ var parseArrayValue = (s) => {
2860
3114
  advance(s);
2861
3115
  return { ok: true, value: { kind: "JArray", items } };
2862
3116
  }
3117
+ s.depth += 1;
2863
3118
  for (; ; ) {
2864
3119
  const valR = parseValue(s);
2865
- if (!valR.ok) return valR;
3120
+ if (!valR.ok) {
3121
+ s.depth -= 1;
3122
+ return valR;
3123
+ }
2866
3124
  items.push(valR.value);
3125
+ if (items.length > schema.MAX_ARRAY_LENGTH) {
3126
+ s.depth -= 1;
3127
+ return failLimit(
3128
+ s,
3129
+ `array is longer than the wire limit MAX_ARRAY_LENGTH = ${schema.MAX_ARRAY_LENGTH}`
3130
+ );
3131
+ }
2867
3132
  skipWs(s);
2868
3133
  const c = peek(s);
2869
3134
  if (c === ",") {
2870
3135
  advance(s);
2871
3136
  } else if (c === "]") {
2872
3137
  advance(s);
3138
+ s.depth -= 1;
2873
3139
  return { ok: true, value: { kind: "JArray", items } };
2874
3140
  } else {
3141
+ s.depth -= 1;
2875
3142
  return fail(s, `expected ',' or ']' but found '${c}'`);
2876
3143
  }
2877
3144
  }
2878
3145
  };
2879
3146
  var parse = (input) => {
2880
- const s = { text: input, pos: 0 };
3147
+ const s = { text: input, pos: 0, depth: 0 };
2881
3148
  skipWs(s);
2882
3149
  if (s.pos >= s.text.length) {
2883
3150
  return { ok: false, error: { message: "input is empty", offset: 0 } };
@@ -2895,6 +3162,7 @@ var makeError = (code, path, message, expectedShape) => ({
2895
3162
  var missingField = (path, key, expected) => makeError("MISSING_FIELD", `${path}.${key}`, `missing required field '${key}'`, expected);
2896
3163
  var wrongType = (path, expected) => makeError("WRONG_TYPE", path, `expected ${expected}`, expected);
2897
3164
  var unknownDuCase = (path, got, expected) => makeError("UNKNOWN_DU_CASE", `${path}.$type`, `unknown discriminator '${got}'`, expected);
3165
+ var unknownEnumCase = (path, got, expected) => makeError("UNKNOWN_DU_CASE", path, `unknown discriminator '${got}'`, expected);
2898
3166
  var CLOSURE2 = "<closure>";
2899
3167
  var OPAQUE2 = "<opaque>";
2900
3168
  var requireObject = (path, j) => j.kind === "JObject" ? ok(j.fields) : wrongType(path, "JSON object");
@@ -3047,7 +3315,7 @@ var decodeJValMap = (path, j) => {
3047
3315
  var bareEnum = (path, j, valid, label) => {
3048
3316
  if (j.kind !== "JString") return wrongType(path, `JSON string (${label})`);
3049
3317
  if (valid.includes(j.value)) return ok(j.value);
3050
- return unknownDuCase(path, j.value, valid.join(" | "));
3318
+ return unknownEnumCase(path, j.value, valid.join(" | "));
3051
3319
  };
3052
3320
  var ORIENTATION_ALIASES = {
3053
3321
  // CSS flex-direction prior: a row lays out horizontally, a column vertically.
@@ -3085,7 +3353,25 @@ var decodeHeadingVariant = (p, j) => {
3085
3353
  return bareEnum(p, j, ["Standard", "Eyebrow", "Caption", "Lead"], "HeadingVariant");
3086
3354
  };
3087
3355
  var decodeImageVariant = (p, j) => bareEnum(p, j, ["Default", "Avatar", "Rounded"], "ImageVariant");
3356
+ var decodeImageFit = (p, j) => bareEnum(p, j, ["Natural", "Cover", "Contain"], "ImageFit");
3357
+ var decodeModalityKind = (p, j) => bareEnum(p, j, ["Modal", "Popover"], "ModalityKind");
3358
+ var decodeImageAspect = (p, j) => bareEnum(
3359
+ p,
3360
+ j,
3361
+ ["Natural", "Square", "FourThree", "ThreeTwo", "SixteenNine"],
3362
+ "ImageAspect"
3363
+ );
3364
+ var decodeImageLoading = (p, j) => bareEnum(p, j, ["Eager", "Lazy"], "ImageLoading");
3365
+ var decodeEmbedPermission = (p, j) => bareEnum(
3366
+ p,
3367
+ j,
3368
+ ["AllowScripts", "AllowSameOrigin", "AllowForms", "AllowFullscreen"],
3369
+ "EmbedPermission"
3370
+ );
3088
3371
  var decodeScrollOrientation = (p, j) => bareEnum(p, j, ["Vertical", "Horizontal", "Both"], "ScrollOrientation");
3372
+ var decodeTrackKind = (p, j) => bareEnum(p, j, ["Subtitles", "Captions", "Descriptions", "Chapters"], "TrackKind");
3373
+ var decodeCaptureSource = (p, j) => bareEnum(p, j, ["Camera", "Microphone"], "CaptureSource");
3374
+ var decodeTextDirection = (p, j) => bareEnum(p, j, ["auto", "ltr", "rtl"], "TextDirection");
3089
3375
  var decodeDateVariant = (p, j) => bareEnum(p, j, ["Date", "Time", "DateTime"], "DateVariant");
3090
3376
  var decodeMathDisplay = (p, j) => bareEnum(p, j, ["Inline", "Block"], "MathDisplay");
3091
3377
  var TONE_ALIASES = {
@@ -3118,6 +3404,7 @@ var decodeWeight = (p, j) => (
3118
3404
  // Compact|Standard|Spacious means density (WIRE_FORMAT.md §3.6).
3119
3405
  bareEnum(p, j, ["Compact", "Standard", "Spacious"], "StyleWeight")
3120
3406
  );
3407
+ var decodeTrendPolarity = (p, j) => bareEnum(p, j, ["HigherIsBetter", "LowerIsBetter"], "TrendPolarity");
3121
3408
  var decodeEmphasis = (p, j) => {
3122
3409
  if (j.kind === "JString" && j.value in EMPHASIS_ALIASES) return ok(EMPHASIS_ALIASES[j.value]);
3123
3410
  if (j.kind === "JBool") return ok(j.value ? "Loud" : "Normal");
@@ -4240,12 +4527,11 @@ var decodeBinding = (path, j, parseStatic = (_p, v) => ok(decodeAstValue(v)), pl
4240
4527
  case "State": {
4241
4528
  const key = reqField(path, f, "key", "state key string", requireString);
4242
4529
  if (!key.ok) return key;
4243
- const dv = fieldAliased(f, "defaultValue", ["initialValue", "default"]) ?? { kind: "JNull" };
4244
- let defaultValue = placeholder;
4245
- if (dv !== void 0) {
4246
- const parsed = parseStatic(`${path}.defaultValue`, dv);
4247
- if (parsed.ok) defaultValue = parsed.value;
4248
- }
4530
+ const dvRaw = fieldAliased(f, "defaultValue", ["initialValue", "default"]);
4531
+ const dv = dvRaw ?? { kind: "JNull" };
4532
+ let defaultValue = dvRaw === void 0 ? void 0 : placeholder;
4533
+ const parsed = parseStatic(`${path}.defaultValue`, dv);
4534
+ if (parsed.ok) defaultValue = parsed.value;
4249
4535
  return ok({ kind: "State", key: key.value, defaultValue });
4250
4536
  }
4251
4537
  case "Computed":
@@ -4319,29 +4605,43 @@ var decodeBinding = (path, j, parseStatic = (_p, v) => ok(decodeAstValue(v)), pl
4319
4605
  if (!pipeJ.ok) return pipeJ;
4320
4606
  const liveTagAst = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("$type") : void 0;
4321
4607
  const liveTag = liveTagAst !== void 0 && liveTagAst.kind === "JString" && (liveTagAst.value === "State" || liveTagAst.value === "Selection" || liveTagAst.value === "Query") ? liveTagAst.value : void 0;
4322
- const hasCarried = srcJ.value.kind === "JObject" && srcJ.value.fields.has("defaultValue");
4323
4608
  let source;
4324
- if (liveTag === void 0 || liveTag === "State" && !hasCarried) {
4609
+ if (liveTag === void 0) {
4325
4610
  const src = decodeDataSource(normaliseTransformSource(srcJ.value));
4326
4611
  if (!src.ok) return makeError("WRONG_TYPE", `${path}.source`, src.error);
4327
4612
  source = { kind: "Data", source: src.value };
4328
4613
  } else {
4329
4614
  const b2 = decodeBinding(`${path}.source`, srcJ.value, decodeJVal, void 0);
4330
4615
  if (!b2.ok) return b2;
4616
+ const liveBinding = (() => {
4617
+ const raw = b2.value;
4618
+ const declared = srcJ.value.kind === "JObject" && srcJ.value.fields.has("defaultValue");
4619
+ return raw.kind === "State" && !declared ? { ...raw, defaultValue: void 0 } : raw;
4620
+ })();
4331
4621
  if (liveTag === "State") {
4332
- const snap = decodeDataSource(normaliseTransformSource(srcJ.value));
4333
- if (!snap.ok) return makeError("WRONG_TYPE", `${path}.source`, snap.error);
4334
- source = {
4335
- kind: "Live",
4336
- binding: b2.value,
4337
- initial: snap.value
4338
- };
4622
+ const carriedJ = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("defaultValue") : void 0;
4623
+ const carriesNoData = carriedJ === void 0 || carriedJ.kind === "JArray" && carriedJ.items.length === 0;
4624
+ if (carriesNoData) {
4625
+ source = {
4626
+ kind: "Live",
4627
+ binding: liveBinding,
4628
+ initial: { kind: "Embedded", table: { schema: [], columns: [] } }
4629
+ };
4630
+ } else {
4631
+ const snap = decodeDataSource(normaliseTransformSource(srcJ.value));
4632
+ if (!snap.ok) return makeError("WRONG_TYPE", `${path}.source`, snap.error);
4633
+ source = {
4634
+ kind: "Live",
4635
+ binding: liveBinding,
4636
+ initial: snap.value
4637
+ };
4638
+ }
4339
4639
  } else {
4340
4640
  const dv = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("defaultValue") : void 0;
4341
4641
  const snap = dv !== void 0 ? decodeDataSource(normaliseTransformSource(dv)) : void 0;
4342
4642
  source = {
4343
4643
  kind: "Live",
4344
- binding: b2.value,
4644
+ binding: liveBinding,
4345
4645
  initial: snap !== void 0 && snap.ok ? snap.value : { kind: "Embedded", table: { schema: [], columns: [] } }
4346
4646
  };
4347
4647
  }
@@ -4498,8 +4798,10 @@ var decodeBindingArgs = (path, j) => {
4498
4798
  }
4499
4799
  return ok(out);
4500
4800
  };
4501
- var decodeBindingString = (p, j) => decodeBinding(p, j);
4502
- var decodeBindingBool = (p, j) => decodeBinding(p, j);
4801
+ var decodeBindingString = (p, j) => decodeBinding(p, j, requireString, "");
4802
+ var decodeBindingBool = (p, j) => decodeBinding(p, j, requireBool, false);
4803
+ var decodeBindingFloat = (p, j) => decodeBinding(p, j, requireFloat, 0);
4804
+ var decodeBindingInt = (p, j) => decodeBinding(p, j, requireInt, 0);
4503
4805
  var OPTIONS_PLACEHOLDER = [
4504
4806
  { value: OPAQUE2, label: { kind: "Literal", value: OPAQUE2 } }
4505
4807
  ];
@@ -4683,7 +4985,7 @@ var decodeAction = (path, j) => {
4683
4985
  const s = j.value.length > 24 ? j.value.slice(0, 24) + "\u2026" : j.value;
4684
4986
  return wrongType(
4685
4987
  path,
4686
- `JSON object, got the string '${s}' \u2014 an action is a $type-discriminated object (SetState | Navigate | Call | Notify | Chain | AiTool | WriteToClipboard | Invoke); "<closure>" is not authorable. Pick a real action, e.g. {"$type":"SetState","key":\u2026,"value":\u2026}`
4988
+ `JSON object, got the string '${s}' \u2014 an action is a $type-discriminated object (SetState | Navigate | Call | Notify | Chain | AiTool | WriteToClipboard | Print | Invoke); "<closure>" is not authorable. Pick a real action, e.g. {"$type":"SetState","key":\u2026,"value":\u2026}`
4687
4989
  );
4688
4990
  }
4689
4991
  const fo = requireObject(path, j);
@@ -4803,9 +5105,19 @@ var decodeAction = (path, j) => {
4803
5105
  return r.ok ? ok({ kind: "CommitLocal", nodeId: r.value }) : r;
4804
5106
  }
4805
5107
  case "WriteToClipboard": {
4806
- const r = reqField(path, f, "text", "clipboard payload string", requireString);
5108
+ const r = reqField(path, f, "text", "clipboard payload TextSource", decodeTextSource);
4807
5109
  return r.ok ? ok({ kind: "WriteToClipboard", text: r.value }) : r;
4808
5110
  }
5111
+ case "Print": {
5112
+ for (const key of f.keys()) {
5113
+ if (key !== "$type")
5114
+ return wrongType(
5115
+ `${path}.${key}`,
5116
+ "no member beside $type \u2014 Print takes no payload (WIRE_FORMAT.md \xA73.6.14)"
5117
+ );
5118
+ }
5119
+ return ok({ kind: "Print" });
5120
+ }
4809
5121
  case "ReadFileBody": {
4810
5122
  const fileId = reqField(path, f, "fileRef", "FileRef id string", requireString);
4811
5123
  if (!fileId.ok) return fileId;
@@ -4830,7 +5142,7 @@ var decodeAction = (path, j) => {
4830
5142
  return unknownDuCase(
4831
5143
  path,
4832
5144
  d.value,
4833
- "Dispatch | Call | Notify | Navigate | SetState | AiTool | Chain | CommitLocal | WriteToClipboard | ReadFileBody | Invoke"
5145
+ "Dispatch | Call | Notify | Navigate | SetState | AiTool | Chain | CommitLocal | WriteToClipboard | Print | ReadFileBody | Invoke"
4834
5146
  );
4835
5147
  }
4836
5148
  };
@@ -4842,7 +5154,14 @@ var decodeMetricSpec = (path, j) => {
4842
5154
  const f = fo.value;
4843
5155
  const label = reqField(path, f, "label", "Metric label TextSource", decodeTextSource);
4844
5156
  if (!label.ok) return label;
4845
- const source = reqFieldAliased(path, f, "value", ["data"], "Metric value binding", decodeBinding);
5157
+ const source = reqFieldAliased(
5158
+ path,
5159
+ f,
5160
+ "value",
5161
+ ["data"],
5162
+ "Metric value binding",
5163
+ decodeBindingFloat
5164
+ );
4846
5165
  if (!source.ok) {
4847
5166
  if (source.error.message.includes("expected JSON number")) {
4848
5167
  return {
@@ -4863,10 +5182,12 @@ var decodeMetricSpec = (path, j) => {
4863
5182
  if (!weight.ok) return weight;
4864
5183
  const emphasis = optField(path, f, "emphasis", decodeEmphasis);
4865
5184
  if (!emphasis.ok) return emphasis;
4866
- const trend = optField(path, f, "trend", decodeBinding);
5185
+ const trend = optField(path, f, "trend", decodeBindingFloat);
4867
5186
  if (!trend.ok) return trend;
4868
5187
  const trendFormat = optField(path, f, "trendFormat", decodeCellFormat);
4869
5188
  if (!trendFormat.ok) return trendFormat;
5189
+ const trendPolarity = optField(path, f, "trendPolarity", decodeTrendPolarity);
5190
+ if (!trendPolarity.ok) return trendPolarity;
4870
5191
  const icon = optField(path, f, "icon", decodeIconSource);
4871
5192
  if (!icon.ok) return icon;
4872
5193
  const subtext = optField(path, f, "subtext", decodeTextSource);
@@ -4880,6 +5201,7 @@ var decodeMetricSpec = (path, j) => {
4880
5201
  emphasis: emphasis.value ?? "Normal",
4881
5202
  ...trend.value !== void 0 ? { trend: trend.value } : {},
4882
5203
  ...trendFormat.value !== void 0 ? { trendFormat: trendFormat.value } : {},
5204
+ trendPolarity: trendPolarity.value ?? "HigherIsBetter",
4883
5205
  ...icon.value !== void 0 ? { icon: icon.value } : {},
4884
5206
  ...subtext.value !== void 0 ? { subtext: subtext.value } : {}
4885
5207
  });
@@ -4908,7 +5230,7 @@ var decodeLabelValueRowSpec = (path, j) => {
4908
5230
  "value",
4909
5231
  ["data"],
4910
5232
  "row Binding<float> value",
4911
- decodeBinding
5233
+ decodeBindingFloat
4912
5234
  );
4913
5235
  if (!source.ok) return source;
4914
5236
  const format = optField(path, f, "format", decodeCellFormat);
@@ -4997,6 +5319,23 @@ var decodeLinkSpec = (path, j) => {
4997
5319
  });
4998
5320
  };
4999
5321
  var decodeLinkProtection = (p, j) => bareEnum(p, j, ["email"], "LinkProtection");
5322
+ var decodeSrcSetEntry = (path, j) => {
5323
+ const fo = requireObject(path, j);
5324
+ if (!fo.ok) return fo;
5325
+ const src = reqField(
5326
+ path,
5327
+ fo.value,
5328
+ "src",
5329
+ "srcSet entry Binding<string> src",
5330
+ decodeBindingString
5331
+ );
5332
+ if (!src.ok) return src;
5333
+ const widthJ = tryField(fo.value, "width");
5334
+ if (widthJ === void 0) return missingField(path, "width", "positive intrinsic pixel width");
5335
+ if (widthJ.kind !== "JNumber" || widthJ.value <= 0 || !Number.isInteger(widthJ.value))
5336
+ return wrongType(`${path}.width`, "JSON number (positive integer pixel width)");
5337
+ return ok({ src: src.value, width: widthJ.value });
5338
+ };
5000
5339
  var decodeImageSpec = (path, j) => {
5001
5340
  const fo = requireObject(path, j);
5002
5341
  if (!fo.ok) return fo;
@@ -5007,7 +5346,217 @@ var decodeImageSpec = (path, j) => {
5007
5346
  if (!src.ok) return src;
5008
5347
  const variant = reqField(path, f, "variant", "ImageVariant", decodeImageVariant);
5009
5348
  if (!variant.ok) return variant;
5010
- return ok({ alt: alt.value, src: src.value, variant: variant.value });
5349
+ const fitJ = tryField(f, "fit");
5350
+ const fit = fitJ === void 0 ? ok("Natural") : decodeImageFit(`${path}.fit`, fitJ);
5351
+ if (!fit.ok) return fit;
5352
+ const aspectJ = tryField(f, "aspectRatio");
5353
+ const aspectRatio = aspectJ === void 0 ? ok("Natural") : decodeImageAspect(`${path}.aspectRatio`, aspectJ);
5354
+ if (!aspectRatio.ok) return aspectRatio;
5355
+ const loadingJ = tryField(f, "loading");
5356
+ const loading = loadingJ === void 0 ? ok("Eager") : decodeImageLoading(`${path}.loading`, loadingJ);
5357
+ if (!loading.ok) return loading;
5358
+ const caption = optField(path, f, "caption", decodeTextSource);
5359
+ if (!caption.ok) return caption;
5360
+ const srcSetJ = tryField(f, "srcSet");
5361
+ const srcSet = srcSetJ === void 0 ? ok([]) : (() => {
5362
+ const arr = requireArray(`${path}.srcSet`, srcSetJ);
5363
+ if (!arr.ok) return arr;
5364
+ return traverseIndexed(
5365
+ arr.value,
5366
+ (i, el) => decodeSrcSetEntry(`${path}.srcSet[${i}]`, el)
5367
+ );
5368
+ })();
5369
+ if (!srcSet.ok) return srcSet;
5370
+ const expandableJ = tryField(f, "expandable");
5371
+ const expandable = expandableJ === void 0 ? ok(false) : requireBool(`${path}.expandable`, expandableJ);
5372
+ if (!expandable.ok) return expandable;
5373
+ return ok({
5374
+ alt: alt.value,
5375
+ src: src.value,
5376
+ variant: variant.value,
5377
+ fit: fit.value,
5378
+ aspectRatio: aspectRatio.value,
5379
+ loading: loading.value,
5380
+ srcSet: srcSet.value,
5381
+ expandable: expandable.value,
5382
+ ...caption.value !== void 0 ? { caption: caption.value } : {}
5383
+ });
5384
+ };
5385
+ var decodeMediaKind = (path, j) => {
5386
+ const fo = requireObject(path, j);
5387
+ if (!fo.ok) return fo;
5388
+ const f = fo.value;
5389
+ const d = requireDiscriminator(path, f);
5390
+ if (!d.ok) return d;
5391
+ switch (d.value) {
5392
+ case "Video": {
5393
+ const autoplayJ = tryField(f, "autoplay");
5394
+ const autoplay = autoplayJ === void 0 ? ok(false) : requireBool(`${path}.autoplay`, autoplayJ);
5395
+ if (!autoplay.ok) return autoplay;
5396
+ const poster = optField(path, f, "poster", decodeBindingString);
5397
+ if (!poster.ok) return poster;
5398
+ return ok({
5399
+ $type: "Video",
5400
+ autoplay: autoplay.value,
5401
+ ...poster.value !== void 0 ? { poster: poster.value } : {}
5402
+ });
5403
+ }
5404
+ case "Audio":
5405
+ return ok({ $type: "Audio" });
5406
+ default:
5407
+ return unknownDuCase(path, d.value, "Video | Audio");
5408
+ }
5409
+ };
5410
+ var decodeMediaSpec = (path, j) => {
5411
+ const fo = requireObject(path, j);
5412
+ if (!fo.ok) return fo;
5413
+ const f = fo.value;
5414
+ const src = reqField(path, f, "src", "Media Binding<string> Src", decodeBindingString);
5415
+ if (!src.ok) return src;
5416
+ const label = reqField(path, f, "label", "Media accessible label TextSource", decodeTextSource);
5417
+ if (!label.ok) return label;
5418
+ const kind = reqField(path, f, "kind", "MediaKind (Video | Audio)", decodeMediaKind);
5419
+ if (!kind.ok) return kind;
5420
+ const controlsJ = tryField(f, "controls");
5421
+ const controls = controlsJ === void 0 ? ok(true) : requireBool(`${path}.controls`, controlsJ);
5422
+ if (!controls.ok) return controls;
5423
+ const loopJ = tryField(f, "loop");
5424
+ const loop = loopJ === void 0 ? ok(false) : requireBool(`${path}.loop`, loopJ);
5425
+ if (!loop.ok) return loop;
5426
+ const tracksJ = tryField(f, "tracks");
5427
+ const tracks = tracksJ === void 0 ? ok([]) : (() => {
5428
+ const arr = requireArray(`${path}.tracks`, tracksJ);
5429
+ if (!arr.ok) return arr;
5430
+ return traverseIndexed(
5431
+ arr.value,
5432
+ (i, el) => decodeTrackEntry(`${path}.tracks[${i}]`, el)
5433
+ );
5434
+ })();
5435
+ if (!tracks.ok) return tracks;
5436
+ const transcript = optField(path, f, "transcript", decodeTextSource);
5437
+ if (!transcript.ok) return transcript;
5438
+ return ok({
5439
+ src: src.value,
5440
+ label: label.value,
5441
+ controls: controls.value,
5442
+ loop: loop.value,
5443
+ kind: kind.value,
5444
+ tracks: tracks.value,
5445
+ ...transcript.value !== void 0 ? { transcript: transcript.value } : {}
5446
+ });
5447
+ };
5448
+ var decodeTrackEntry = (path, j) => {
5449
+ const fo = requireObject(path, j);
5450
+ if (!fo.ok) return fo;
5451
+ const f = fo.value;
5452
+ const kind = reqField(path, f, "kind", "TrackKind", decodeTrackKind);
5453
+ if (!kind.ok) return kind;
5454
+ const src = reqField(path, f, "src", "track Binding<string> Src", decodeBindingString);
5455
+ if (!src.ok) return src;
5456
+ const srcLang = reqField(path, f, "srcLang", "track srcLang string", requireString);
5457
+ if (!srcLang.ok) return srcLang;
5458
+ const label = reqField(path, f, "label", "track label TextSource", decodeTextSource);
5459
+ if (!label.ok) return label;
5460
+ const defaultJ = tryField(f, "default");
5461
+ const dflt = defaultJ === void 0 ? ok(false) : requireBool(`${path}.default`, defaultJ);
5462
+ if (!dflt.ok) return dflt;
5463
+ return ok({
5464
+ kind: kind.value,
5465
+ src: src.value,
5466
+ srcLang: srcLang.value,
5467
+ label: label.value,
5468
+ default: dflt.value
5469
+ });
5470
+ };
5471
+ var decodeTreeSpec = (path, j) => {
5472
+ const fo = requireObject(path, j);
5473
+ if (!fo.ok) return fo;
5474
+ const f = fo.value;
5475
+ const itemsJ = requireField(path, f, "items", "Tree items list");
5476
+ if (!itemsJ.ok) return itemsJ;
5477
+ const arr = requireArray(`${path}.items`, itemsJ.value);
5478
+ if (!arr.ok) return arr;
5479
+ const items = traverseIndexed(arr.value, (i, el) => decodeTreeItem(`${path}.items[${i}]`, el));
5480
+ if (!items.ok) return items;
5481
+ const expandedStateKey = optField(path, f, "expandedStateKey", requireString);
5482
+ if (!expandedStateKey.ok) return expandedStateKey;
5483
+ const selectionStateKey = optField(path, f, "selectionStateKey", requireString);
5484
+ if (!selectionStateKey.ok) return selectionStateKey;
5485
+ return ok({
5486
+ items: items.value,
5487
+ ...expandedStateKey.value !== void 0 ? { expandedStateKey: expandedStateKey.value } : {},
5488
+ ...selectionStateKey.value !== void 0 ? { selectionStateKey: selectionStateKey.value } : {},
5489
+ // Emitted only when present (rule 4); the value is the closure sentinel.
5490
+ ...tryField(f, "onSelect") !== void 0 ? { onSelect: () => placeholderAction } : {}
5491
+ });
5492
+ };
5493
+ var decodeTreeItem = (path, j) => {
5494
+ if (itemDepth >= schema.MAX_NODE_DEPTH) {
5495
+ return limitError(
5496
+ path,
5497
+ `tree-item nesting deeper than the wire limit MAX_NODE_DEPTH = ${schema.MAX_NODE_DEPTH}`,
5498
+ `a tree nesting items no more than ${schema.MAX_NODE_DEPTH} levels deep`
5499
+ );
5500
+ }
5501
+ itemDepth += 1;
5502
+ const r = decodeTreeItemInner(path, j);
5503
+ itemDepth -= 1;
5504
+ return r;
5505
+ };
5506
+ var decodeTreeItemInner = (path, j) => {
5507
+ const fo = requireObject(path, j);
5508
+ if (!fo.ok) return fo;
5509
+ const f = fo.value;
5510
+ const id = reqField(path, f, "id", "TreeItem id string", requireString);
5511
+ if (!id.ok) return id;
5512
+ const label = reqField(path, f, "label", "TreeItem label TextSource", decodeTextSource);
5513
+ if (!label.ok) return label;
5514
+ const childrenJ = tryField(f, "children");
5515
+ const children = childrenJ === void 0 ? ok([]) : (() => {
5516
+ const carr = requireArray(`${path}.children`, childrenJ);
5517
+ if (!carr.ok) return carr;
5518
+ return traverseIndexed(
5519
+ carr.value,
5520
+ (i, el) => decodeTreeItem(`${path}.children[${i}]`, el)
5521
+ );
5522
+ })();
5523
+ if (!children.ok) return children;
5524
+ const icon = optField(path, f, "icon", requireString);
5525
+ if (!icon.ok) return icon;
5526
+ return ok({
5527
+ id: id.value,
5528
+ label: label.value,
5529
+ children: children.value,
5530
+ ...icon.value !== void 0 ? { icon: icon.value } : {}
5531
+ });
5532
+ };
5533
+ var decodeEmbedSpec = (path, j) => {
5534
+ const fo = requireObject(path, j);
5535
+ if (!fo.ok) return fo;
5536
+ const f = fo.value;
5537
+ const src = reqField(path, f, "src", "Embed Binding<string> Src", decodeBindingString);
5538
+ if (!src.ok) return src;
5539
+ const title = reqField(path, f, "title", "Embed accessible title TextSource", decodeTextSource);
5540
+ if (!title.ok) return title;
5541
+ const aspectJ = tryField(f, "aspectRatio");
5542
+ const aspectRatio = aspectJ === void 0 ? ok("Natural") : decodeImageAspect(`${path}.aspectRatio`, aspectJ);
5543
+ if (!aspectRatio.ok) return aspectRatio;
5544
+ const permissionsJ = tryField(f, "permissions");
5545
+ const permissions = permissionsJ === void 0 ? ok([]) : (() => {
5546
+ const arr = requireArray(`${path}.permissions`, permissionsJ);
5547
+ if (!arr.ok) return arr;
5548
+ return traverseIndexed(
5549
+ arr.value,
5550
+ (i, el) => decodeEmbedPermission(`${path}.permissions[${i}]`, el)
5551
+ );
5552
+ })();
5553
+ if (!permissions.ok) return permissions;
5554
+ return ok({
5555
+ src: src.value,
5556
+ title: title.value,
5557
+ aspectRatio: aspectRatio.value,
5558
+ permissions: permissions.value
5559
+ });
5011
5560
  };
5012
5561
  var decodeListSpec = (path, j) => {
5013
5562
  const fo = requireObject(path, j);
@@ -5151,7 +5700,7 @@ var decodeProgressSpec = (path, j) => {
5151
5700
  const fo = requireObject(path, j);
5152
5701
  if (!fo.ok) return fo;
5153
5702
  const f = fo.value;
5154
- const fraction = reqField(path, f, "fraction", "Progress fraction binding", decodeBinding);
5703
+ const fraction = reqField(path, f, "fraction", "Progress fraction binding", decodeBindingFloat);
5155
5704
  if (!fraction.ok) return fraction;
5156
5705
  const indeterminate = optField(path, f, "indeterminate", requireBool);
5157
5706
  if (!indeterminate.ok) return indeterminate;
@@ -5201,9 +5750,9 @@ var decodeDrawStyle = (path, j) => {
5201
5750
  if (!fill.ok) return fill;
5202
5751
  const stroke = optField(path, f, "stroke", decodeBindingString);
5203
5752
  if (!stroke.ok) return stroke;
5204
- const strokeWidth = optField(path, f, "strokeWidth", decodeBinding);
5753
+ const strokeWidth = optField(path, f, "strokeWidth", decodeBindingFloat);
5205
5754
  if (!strokeWidth.ok) return strokeWidth;
5206
- const opacity = optField(path, f, "opacity", decodeBinding);
5755
+ const opacity = optField(path, f, "opacity", decodeBindingFloat);
5207
5756
  if (!opacity.ok) return opacity;
5208
5757
  const textAnchor = optField(path, f, "textAnchor", decodeTextAnchor);
5209
5758
  if (!textAnchor.ok) return textAnchor;
@@ -5482,6 +6031,18 @@ var decodeDisplayKind = (path, j) => {
5482
6031
  const r = decodeImageSpec(path, j);
5483
6032
  return r.ok ? ok({ kind: "Image", spec: r.value }) : r;
5484
6033
  }
6034
+ case "Embed": {
6035
+ const r = decodeEmbedSpec(path, j);
6036
+ return r.ok ? ok({ kind: "Embed", spec: r.value }) : r;
6037
+ }
6038
+ case "Media": {
6039
+ const r = decodeMediaSpec(path, j);
6040
+ return r.ok ? ok({ kind: "Media", spec: r.value }) : r;
6041
+ }
6042
+ case "Tree": {
6043
+ const r = decodeTreeSpec(path, j);
6044
+ return r.ok ? ok({ kind: "Tree", spec: r.value }) : r;
6045
+ }
5485
6046
  case "List": {
5486
6047
  const r = decodeListSpec(path, j);
5487
6048
  return r.ok ? ok({ kind: "List", spec: r.value }) : r;
@@ -5506,7 +6067,7 @@ var decodeDisplayKind = (path, j) => {
5506
6067
  return unknownDuCase(
5507
6068
  path,
5508
6069
  d.value,
5509
- "Heading | Markdown | Metric | Badge | Link | Image | List | Toast | CodeBlock | Math | Drawing | Sparkline | Callout | Progress | Skeleton | LabelValueRow"
6070
+ "Heading | Markdown | Metric | Badge | Link | Image | Media | Embed | Tree | List | Toast | CodeBlock | Math | Drawing | Sparkline | Callout | Progress | Skeleton | LabelValueRow | Fact"
5510
6071
  );
5511
6072
  }
5512
6073
  };
@@ -5533,7 +6094,11 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5533
6094
  return v.ok ? ok({ kind: "Text", value: v.value, ...onChangeField }) : v;
5534
6095
  }
5535
6096
  case "Number": {
5536
- const v = valueOr(decodeBinding, schema.controlValueDefaults.number, "Number value binding");
6097
+ const v = valueOr(
6098
+ decodeBindingFloat,
6099
+ schema.controlValueDefaults.number,
6100
+ "Number value binding"
6101
+ );
5537
6102
  return v.ok ? ok({ kind: "Number", value: v.value, ...onChangeField }) : v;
5538
6103
  }
5539
6104
  case "Checkbox": {
@@ -5585,7 +6150,7 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5585
6150
  }
5586
6151
  case "RangedNumber": {
5587
6152
  const value = valueOr(
5588
- decodeBinding,
6153
+ decodeBindingFloat,
5589
6154
  schema.controlValueDefaults.number,
5590
6155
  "RangedNumber value binding"
5591
6156
  );
@@ -5633,6 +6198,95 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5633
6198
  orientation: orientation.value
5634
6199
  });
5635
6200
  }
6201
+ case "Combobox": {
6202
+ const options = reqField(
6203
+ path,
6204
+ f,
6205
+ "options",
6206
+ "Combobox options binding",
6207
+ decodeBindingSelectOptions
6208
+ );
6209
+ if (!options.ok) return options;
6210
+ const allowFreeTextJ = tryField(f, "allowFreeText");
6211
+ const allowFreeText = allowFreeTextJ === void 0 ? ok(false) : requireBool(`${path}.allowFreeText`, allowFreeTextJ);
6212
+ if (!allowFreeText.ok) return allowFreeText;
6213
+ const value = valueOr(
6214
+ decodeBindingStringOpt,
6215
+ schema.controlValueDefaults.choice,
6216
+ "Combobox value binding"
6217
+ );
6218
+ if (!value.ok) return value;
6219
+ return ok({
6220
+ kind: "Combobox",
6221
+ allowFreeText: allowFreeText.value,
6222
+ options: options.value,
6223
+ value: value.value,
6224
+ ...onChangeField
6225
+ });
6226
+ }
6227
+ case "Tokens": {
6228
+ const allowFreeTextJ = tryField(f, "allowFreeText");
6229
+ const allowFreeText = allowFreeTextJ === void 0 ? ok(true) : requireBool(`${path}.allowFreeText`, allowFreeTextJ);
6230
+ if (!allowFreeText.ok) return allowFreeText;
6231
+ const suggestions = optField(path, f, "suggestions", decodeBindingSelectOptions);
6232
+ if (!suggestions.ok) return suggestions;
6233
+ if (!allowFreeText.value && suggestions.value === void 0)
6234
+ return wrongType(
6235
+ `${path}.allowFreeText`,
6236
+ "a suggestion source alongside allowFreeText:false \u2014 a closed token field with nothing to pick from admits no token at all (WIRE_FORMAT.md \xA73.6.19)"
6237
+ );
6238
+ const value = valueOr(
6239
+ decodeBindingStringList,
6240
+ schema.controlValueDefaults.tokens,
6241
+ "Tokens Binding<string list> value"
6242
+ );
6243
+ if (!value.ok) return value;
6244
+ return ok({
6245
+ kind: "Tokens",
6246
+ allowFreeText: allowFreeText.value,
6247
+ value: value.value,
6248
+ ...suggestions.value !== void 0 ? { suggestions: suggestions.value } : {},
6249
+ ...onChangeField
6250
+ });
6251
+ }
6252
+ case "Rating": {
6253
+ const maxJ = requireField(path, f, "max", "Rating max integer of 1 or more");
6254
+ if (!maxJ.ok) return maxJ;
6255
+ if (maxJ.value.kind !== "JNumber" || maxJ.value.value < 1 || !Number.isInteger(maxJ.value.value))
6256
+ return wrongType(`${path}.max`, "JSON number (an integer scale of 1 or more)");
6257
+ const max = maxJ.value.value;
6258
+ const allowHalfJ = tryField(f, "allowHalf");
6259
+ const allowHalf = allowHalfJ === void 0 ? ok(false) : requireBool(`${path}.allowHalf`, allowHalfJ);
6260
+ if (!allowHalf.ok) return allowHalf;
6261
+ const value = valueOr(
6262
+ decodeBindingFloat,
6263
+ schema.controlValueDefaults.number,
6264
+ "Rating value binding"
6265
+ );
6266
+ if (!value.ok) return value;
6267
+ return ok({
6268
+ kind: "Rating",
6269
+ max,
6270
+ allowHalf: allowHalf.value,
6271
+ value: value.value,
6272
+ ...onChangeField
6273
+ });
6274
+ }
6275
+ case "Color": {
6276
+ const value = valueOr(
6277
+ decodeBinding,
6278
+ schema.controlValueDefaults.color,
6279
+ "Color value binding"
6280
+ );
6281
+ if (!value.ok) return value;
6282
+ const bound = value.value;
6283
+ if (bound.kind === "Static" && !(typeof bound.value === "string" && /^#[0-9a-fA-F]{6}$/.test(bound.value)))
6284
+ return wrongType(
6285
+ `${path}.value`,
6286
+ "a #rrggbb colour literal \u2014 six hexadecimal digits after a #, the one form a native colour input can hold (WIRE_FORMAT.md \xA73.6.17)"
6287
+ );
6288
+ return ok({ kind: "Color", value: value.value, ...onChangeField });
6289
+ }
5636
6290
  case "TextArea": {
5637
6291
  const rows = reqField(path, f, "rows", "textarea row count integer", requireInt);
5638
6292
  if (!rows.ok) return rows;
@@ -5699,6 +6353,77 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5699
6353
  return unknownDuCase(path, d.value, WRONG_FORM_FIELD_KIND_HINT);
5700
6354
  }
5701
6355
  };
6356
+ var TEXT_FORMATS = ["email", "url", "tel"];
6357
+ var COMPARE_OPS = ["eq", "neq", "lt", "lte", "gt", "gte"];
6358
+ var decodeTextFormat = (path, j) => bareEnum(path, j, TEXT_FORMATS, "TextFormat");
6359
+ var decodeCompareOp = (path, j) => bareEnum(path, j, COMPARE_OPS, "CompareOp");
6360
+ var decodeCompareRule = (path, j) => {
6361
+ const fo = requireObject(path, j);
6362
+ if (!fo.ok) return fo;
6363
+ const f = fo.value;
6364
+ const op = reqField(path, f, "op", "CompareOp", decodeCompareOp);
6365
+ if (!op.ok) return op;
6366
+ const against = reqField(path, f, "against", "Binding", (p, v) => decodeBinding(p, v));
6367
+ if (!against.ok) return against;
6368
+ return ok({ op: op.value, against: against.value });
6369
+ };
6370
+ var decodeFieldRule = (path, j) => {
6371
+ const fo = requireObject(path, j);
6372
+ if (!fo.ok) return fo;
6373
+ const f = fo.value;
6374
+ const format = optField(path, f, "format", decodeTextFormat);
6375
+ if (!format.ok) return format;
6376
+ const pattern = optField(path, f, "pattern", requireString);
6377
+ if (!pattern.ok) return pattern;
6378
+ const minLength = optField(path, f, "minLength", requireInt);
6379
+ if (!minLength.ok) return minLength;
6380
+ const maxLength = optField(path, f, "maxLength", requireInt);
6381
+ if (!maxLength.ok) return maxLength;
6382
+ const compare = optField(path, f, "compare", decodeCompareRule);
6383
+ if (!compare.ok) return compare;
6384
+ const message = optField(path, f, "message", decodeTextSource);
6385
+ if (!message.ok) return message;
6386
+ const constrains = format.value !== void 0 || pattern.value !== void 0 || minLength.value !== void 0 || maxLength.value !== void 0 || compare.value !== void 0;
6387
+ if (!constrains)
6388
+ return makeError(
6389
+ "WRONG_TYPE",
6390
+ path,
6391
+ "a rule that constrains nothing is a defect, not a no-op \u2014 declare at least one of format / pattern / minLength / maxLength / compare, or omit 'rule' entirely",
6392
+ "FieldRule with at least one constraint slot"
6393
+ );
6394
+ if (minLength.value !== void 0 && maxLength.value !== void 0 && minLength.value > maxLength.value)
6395
+ return makeError(
6396
+ "WRONG_TYPE",
6397
+ path,
6398
+ `minLength ${minLength.value} is above maxLength ${maxLength.value} \u2014 an inverted length bound admits no value at all, so the field could never be submitted`,
6399
+ "minLength <= maxLength"
6400
+ );
6401
+ return ok({
6402
+ ...format.value !== void 0 ? { format: format.value } : {},
6403
+ ...pattern.value !== void 0 ? { pattern: pattern.value } : {},
6404
+ ...minLength.value !== void 0 ? { minLength: minLength.value } : {},
6405
+ ...maxLength.value !== void 0 ? { maxLength: maxLength.value } : {},
6406
+ ...compare.value !== void 0 ? { compare: compare.value } : {},
6407
+ ...message.value !== void 0 ? { message: message.value } : {}
6408
+ });
6409
+ };
6410
+ var FORM_FIELD_NEAR_MISSES = [
6411
+ ["validation", "rule"],
6412
+ ["constraints", "rule"],
6413
+ ["validate", "rule"]
6414
+ ];
6415
+ var checkFormFieldNearMisses = (path, f) => {
6416
+ for (const [name, canonical] of FORM_FIELD_NEAR_MISSES) {
6417
+ if (tryField(f, name) !== void 0)
6418
+ return makeError(
6419
+ "WRONG_TYPE",
6420
+ `${path}.${name}`,
6421
+ `'${name}' is not part of the form vocabulary \u2014 it would be ignored, not honoured, and the field would accept anything`,
6422
+ canonical
6423
+ );
6424
+ }
6425
+ return ok(void 0);
6426
+ };
5702
6427
  var decodeFormField = (path, j) => {
5703
6428
  const fo = requireObject(path, j);
5704
6429
  if (!fo.ok) return fo;
@@ -5720,12 +6445,17 @@ var decodeFormField = (path, j) => {
5720
6445
  if (!required.ok) return required;
5721
6446
  const help = optField(path, f, "help", decodeTextSource);
5722
6447
  if (!help.ok) return help;
6448
+ const nm = checkFormFieldNearMisses(path, f);
6449
+ if (!nm.ok) return nm;
6450
+ const rule = optField(path, f, "rule", decodeFieldRule);
6451
+ if (!rule.ok) return rule;
5723
6452
  return ok({
5724
6453
  id: id.value,
5725
6454
  kind: kind.value,
5726
6455
  label: label.value,
5727
6456
  required: required.value,
5728
- ...help.value !== void 0 ? { help: help.value } : {}
6457
+ ...help.value !== void 0 ? { help: help.value } : {},
6458
+ ...rule.value !== void 0 ? { rule: rule.value } : {}
5729
6459
  });
5730
6460
  };
5731
6461
  var decodeFormSpec = (path, j) => {
@@ -5853,12 +6583,31 @@ var decodeFileUploadSpec = (path, j) => {
5853
6583
  if (!multiple.ok) return multiple;
5854
6584
  const disabled = optField(path, f, "disabled", decodeBindingBool);
5855
6585
  if (!disabled.ok) return disabled;
6586
+ const dropTargetJ = tryField(f, "dropTarget");
6587
+ const dropTarget = dropTargetJ === void 0 ? ok(false) : requireBool(`${path}.dropTarget`, dropTargetJ);
6588
+ if (!dropTarget.ok) return dropTarget;
6589
+ const acceptPasteJ = tryField(f, "acceptPaste");
6590
+ const acceptPaste = acceptPasteJ === void 0 ? ok(false) : requireBool(`${path}.acceptPaste`, acceptPasteJ);
6591
+ if (!acceptPaste.ok) return acceptPaste;
6592
+ const capture = optField(path, f, "capture", decodeCaptureSource);
6593
+ if (!capture.ok) return capture;
6594
+ const destinationJ = tryField(f, "destination");
6595
+ const destination = destinationJ === void 0 ? ok(void 0) : (() => {
6596
+ const str3 = requireString(`${path}.destination`, destinationJ);
6597
+ if (!str3.ok) return str3;
6598
+ return str3.value === "" ? wrongType(`${path}.destination`, "a non-empty host-registered destination id") : ok(str3.value);
6599
+ })();
6600
+ if (!destination.ok) return destination;
5856
6601
  return ok({
5857
6602
  accept: accept.value,
5858
6603
  label: label.value,
5859
6604
  multiple: multiple.value,
5860
6605
  onSelect: () => placeholderAction,
5861
- ...disabled.value !== void 0 ? { disabled: disabled.value } : {}
6606
+ ...disabled.value !== void 0 ? { disabled: disabled.value } : {},
6607
+ dropTarget: dropTarget.value,
6608
+ acceptPaste: acceptPaste.value,
6609
+ ...capture.value !== void 0 ? { capture: capture.value } : {},
6610
+ ...destination.value !== void 0 ? { destination: destination.value } : {}
5862
6611
  });
5863
6612
  };
5864
6613
  var decodeInputKind = (path, j) => {
@@ -6276,6 +7025,16 @@ var decodeGridSpec = (path, j) => {
6276
7025
  if (!pk.ok) return pk;
6277
7026
  pageStateKey = pk.value;
6278
7027
  }
7028
+ const transferOutKey = optField(path, f, "transferOutKey", requireString);
7029
+ if (!transferOutKey.ok) return transferOutKey;
7030
+ const transferInKey = optField(path, f, "transferInKey", requireString);
7031
+ if (!transferInKey.ok) return transferInKey;
7032
+ const exportable = optField(path, f, "exportable", requireBool);
7033
+ if (!exportable.ok) return exportable;
7034
+ const keepRowsTogether = optField(path, f, "keepRowsTogether", requireBool);
7035
+ if (!keepRowsTogether.ok) return keepRowsTogether;
7036
+ const repeatHeader = optField(path, f, "repeatHeader", requireBool);
7037
+ if (!repeatHeader.ok) return repeatHeader;
6279
7038
  const staticRowsJ = tryField(f, "staticRows");
6280
7039
  let staticRows;
6281
7040
  if (staticRowsJ !== void 0) {
@@ -6296,6 +7055,11 @@ var decodeGridSpec = (path, j) => {
6296
7055
  ...pageStateKey !== void 0 ? { pageStateKey } : {},
6297
7056
  ...defaultSort !== void 0 ? { defaultSort } : {},
6298
7057
  ...editStateKey !== void 0 ? { editStateKey } : {},
7058
+ ...transferOutKey.value !== void 0 ? { transferOutKey: transferOutKey.value } : {},
7059
+ ...transferInKey.value !== void 0 ? { transferInKey: transferInKey.value } : {},
7060
+ exportable: exportable.value ?? false,
7061
+ keepRowsTogether: keepRowsTogether.value ?? false,
7062
+ repeatHeader: repeatHeader.value ?? false,
6299
7063
  ...staticRows !== void 0 ? { staticRows } : {}
6300
7064
  });
6301
7065
  };
@@ -6464,10 +7228,23 @@ var decodeBoxLayout = (path, j) => {
6464
7228
  ...templateColumns.value !== void 0 ? { templateColumns: templateColumns.value } : {}
6465
7229
  });
6466
7230
  }
7231
+ case "Masonry": {
7232
+ const colsJ = tryField(f, "cols") ?? tryField(f, "columns");
7233
+ if (colsJ === void 0) return missingField(path, "cols", "positive integer column count");
7234
+ if (colsJ.kind !== "JNumber" || colsJ.value <= 0 || !Number.isInteger(colsJ.value))
7235
+ return wrongType(`${path}.cols`, "JSON number (positive integer column count)");
7236
+ const masonryGap = optField(path, f, "gap", requireInt);
7237
+ if (!masonryGap.ok) return masonryGap;
7238
+ return ok({
7239
+ kind: "Masonry",
7240
+ cols: colsJ.value,
7241
+ ...masonryGap.value !== void 0 ? { gap: masonryGap.value } : {}
7242
+ });
7243
+ }
6467
7244
  case "Auto":
6468
7245
  return ok({ kind: "Auto" });
6469
7246
  default:
6470
- return unknownDuCase(path, d.value, "Flex | Grid | Auto");
7247
+ return unknownDuCase(path, d.value, "Flex | Grid | Masonry | Auto");
6471
7248
  }
6472
7249
  };
6473
7250
  var decodeBoxRole = (path, j) => {
@@ -6480,7 +7257,7 @@ var decodeBoxRole = (path, j) => {
6480
7257
  case "Separator":
6481
7258
  return ok(s.value);
6482
7259
  default:
6483
- return unknownDuCase(path, s.value, "Group | Card | Dashboard | Separator");
7260
+ return unknownEnumCase(path, s.value, "Group | Card | Dashboard | Separator");
6484
7261
  }
6485
7262
  };
6486
7263
  var decodeBox = (path, j) => {
@@ -6495,11 +7272,17 @@ var decodeBox = (path, j) => {
6495
7272
  if (!layout.ok) return layout;
6496
7273
  const role = reqField(path, f, "role", "role string", decodeBoxRole);
6497
7274
  if (!role.ok) return role;
7275
+ const keepTogether = optField(path, f, "keepTogether", requireBool);
7276
+ if (!keepTogether.ok) return keepTogether;
7277
+ const breakBefore = optField(path, f, "breakBefore", requireBool);
7278
+ if (!breakBefore.ok) return breakBefore;
6498
7279
  return ok({
6499
7280
  children: children.value,
6500
7281
  ...heading.value !== void 0 ? { heading: heading.value } : {},
6501
7282
  layout: layout.value,
6502
- role: role.value
7283
+ role: role.value,
7284
+ keepTogether: keepTogether.value ?? false,
7285
+ breakBefore: breakBefore.value ?? false
6503
7286
  });
6504
7287
  };
6505
7288
  var decodeSplitPanelSpec = (path, j) => {
@@ -6563,7 +7346,7 @@ var decodeTabsSpec = (path, j) => {
6563
7346
  }
6564
7347
  const activeTag = optField(path, f, "activeTag", decodeBindingString);
6565
7348
  if (!activeTag.ok) return activeTag;
6566
- const activeIndex = optField(path, f, "activeIndex", decodeBinding);
7349
+ const activeIndex = optField(path, f, "activeIndex", decodeBindingInt);
6567
7350
  if (!activeIndex.ok) return activeIndex;
6568
7351
  return ok({
6569
7352
  children: children.value,
@@ -6580,7 +7363,7 @@ var decodeStepperSpec = (path, j) => {
6580
7363
  const fo = requireObject(path, j);
6581
7364
  if (!fo.ok) return fo;
6582
7365
  const f = fo.value;
6583
- const activeStep = reqField(path, f, "activeStep", "activeStep binding", decodeBinding);
7366
+ const activeStep = reqField(path, f, "activeStep", "activeStep binding", decodeBindingInt);
6584
7367
  if (!activeStep.ok) return activeStep;
6585
7368
  const children = decodeChildren(path, f);
6586
7369
  if (!children.ok) return children;
@@ -6646,12 +7429,19 @@ var decodeModalSpec = (path, j) => {
6646
7429
  if (!open.ok) return open;
6647
7430
  const heading = optFieldAliased(path, f, "heading", ["title"], decodeTextSource);
6648
7431
  if (!heading.ok) return heading;
7432
+ const modalityJ = tryField(f, "modality");
7433
+ const modality = modalityJ === void 0 ? ok("Modal") : decodeModalityKind(`${path}.modality`, modalityJ);
7434
+ if (!modality.ok) return modality;
7435
+ const anchor = optField(path, f, "anchor", requireString);
7436
+ if (!anchor.ok) return anchor;
6649
7437
  return ok({
6650
7438
  children: children.value,
6651
7439
  dismissable: dismissable.value,
6652
7440
  ...onDismiss.value !== void 0 ? { onDismiss: onDismiss.value } : {},
6653
7441
  open: open.value,
6654
- ...heading.value !== void 0 ? { heading: heading.value } : {}
7442
+ ...heading.value !== void 0 ? { heading: heading.value } : {},
7443
+ modality: modality.value,
7444
+ ...anchor.value !== void 0 ? { anchor: anchor.value } : {}
6655
7445
  });
6656
7446
  };
6657
7447
  var decodeScrollAreaSpec = (path, j) => {
@@ -6745,7 +7535,7 @@ var decodeContentHash = (path, j) => {
6745
7535
  if (!strictnessR.ok) return strictnessR;
6746
7536
  const s = strictnessR.value;
6747
7537
  if (s !== "StrictReplay" && s !== "AdvisoryWarning" && s !== "Enforced") {
6748
- return unknownDuCase(`${path}.strictness`, s, "StrictReplay | AdvisoryWarning | Enforced");
7538
+ return unknownEnumCase(`${path}.strictness`, s, "StrictReplay | AdvisoryWarning | Enforced");
6749
7539
  }
6750
7540
  return ok({ algorithm: algorithm.value, hash: hash.value, strictness: s });
6751
7541
  };
@@ -6876,11 +7666,11 @@ var decodeEffectClass = (path, j) => {
6876
7666
  const host = reqField(path, fo.value, "hostEffect", "EffectClass hostEffect", requireString);
6877
7667
  if (!host.ok) return host;
6878
7668
  if (host.value !== "Pure" && host.value !== "ReadsHost" && host.value !== "WritesHost")
6879
- return unknownDuCase(`${path}.hostEffect`, host.value, "Pure | ReadsHost | WritesHost");
7669
+ return unknownEnumCase(`${path}.hostEffect`, host.value, "Pure | ReadsHost | WritesHost");
6880
7670
  const det = reqField(path, fo.value, "determinism", "EffectClass determinism", requireString);
6881
7671
  if (!det.ok) return det;
6882
7672
  if (det.value !== "Deterministic" && det.value !== "Clock" && det.value !== "Random" && det.value !== "Network")
6883
- return unknownDuCase(
7673
+ return unknownEnumCase(
6884
7674
  `${path}.determinism`,
6885
7675
  det.value,
6886
7676
  "Deterministic | Clock | Random | Network"
@@ -6900,6 +7690,14 @@ var decodeNodeKind = (path, j) => {
6900
7690
  const f = fo.value;
6901
7691
  const d = requireDiscriminator(path, f);
6902
7692
  if (!d.ok) return d;
7693
+ if (schema.narrows(walkPolicy) && schema.NODE_KIND_NAMES.includes(d.value) && !schema.admits(walkPolicy, d.value)) {
7694
+ return makeError(
7695
+ "KIND_NOT_ADMITTED",
7696
+ `${path}.$type`,
7697
+ `node kind '${d.value}' is not admitted by decode policy '${walkPolicy.identity}'`,
7698
+ schema.policyHint(walkPolicy)
7699
+ );
7700
+ }
6903
7701
  switch (d.value) {
6904
7702
  // The four behavioural categories are flat on the wire (WIRE_FORMAT §3.2):
6905
7703
  // the `kind` object carries the primitive discriminator directly, so route
@@ -6929,6 +7727,9 @@ var decodeNodeKind = (path, j) => {
6929
7727
  case "Fact":
6930
7728
  case "Link":
6931
7729
  case "Image":
7730
+ case "Media":
7731
+ case "Embed":
7732
+ case "Tree":
6932
7733
  case "List":
6933
7734
  case "Toast":
6934
7735
  case "CodeBlock":
@@ -7028,9 +7829,24 @@ var decodeNodeKind = (path, j) => {
7028
7829
  if (!cases.ok) return cases;
7029
7830
  const def = reqField(path, f, "default", "Switch default Node", decodeNodeAst);
7030
7831
  if (!def.ok) return def;
7832
+ const autoAdvanceMsJ = tryField(f, "autoAdvanceMs");
7833
+ let autoAdvanceMs;
7834
+ if (autoAdvanceMsJ !== void 0) {
7835
+ if (autoAdvanceMsJ.kind !== "JNumber" || autoAdvanceMsJ.value < 1 || !Number.isInteger(autoAdvanceMsJ.value))
7836
+ return wrongType(
7837
+ `${path}.autoAdvanceMs`,
7838
+ "JSON number (a positive whole number of milliseconds)"
7839
+ );
7840
+ autoAdvanceMs = autoAdvanceMsJ.value;
7841
+ }
7031
7842
  return ok({
7032
7843
  kind: "Switch",
7033
- spec: { on: on.value, cases: cases.value, default: def.value }
7844
+ spec: {
7845
+ on: on.value,
7846
+ cases: cases.value,
7847
+ default: def.value,
7848
+ ...autoAdvanceMs !== void 0 ? { autoAdvanceMs } : {}
7849
+ }
7034
7850
  });
7035
7851
  }
7036
7852
  case "FragmentDecl": {
@@ -7196,18 +8012,65 @@ var decodeSemanticStyle = (path, j) => {
7196
8012
  if (!role.ok) return role;
7197
8013
  const voice = optField(path, f, "voice", decodeFontVoice);
7198
8014
  if (!voice.ok) return voice;
8015
+ const direction = optField(path, f, "direction", decodeTextDirection);
8016
+ if (!direction.ok) return direction;
7199
8017
  return ok({
7200
8018
  tone: tone.value ?? "Default",
7201
8019
  weight: weight.value ?? "Standard",
7202
8020
  emphasis: emphasis.value ?? "Normal",
7203
8021
  role: role.value ?? "None",
7204
- voice: voice.value ?? "Default"
8022
+ voice: voice.value ?? "Default",
8023
+ direction: direction.value ?? "auto"
7205
8024
  });
7206
8025
  };
8026
+ var A11Y_NEAR_MISSES = [
8027
+ [
8028
+ "aria-label",
8029
+ "label \u2014 the accessible name, a Binding<string> (a bare string is the \xA73.6 shorthand)"
8030
+ ],
8031
+ [
8032
+ "ariaLabel",
8033
+ "label \u2014 the accessible name, a Binding<string> (a bare string is the \xA73.6 shorthand)"
8034
+ ],
8035
+ ["aria-labelledby", "labelledBy \u2014 the id of a sibling node whose text carries the name"],
8036
+ ["ariaLabelledBy", "labelledBy \u2014 the id of a sibling node whose text carries the name"],
8037
+ [
8038
+ "labelledby",
8039
+ "labelledBy \u2014 the slot name is camelCase on the wire, not the ARIA attribute spelling"
8040
+ ],
8041
+ ["aria-describedby", "describedBy \u2014 the id of a sibling node whose text carries the description"],
8042
+ ["ariaDescribedBy", "describedBy \u2014 the id of a sibling node whose text carries the description"],
8043
+ [
8044
+ "describedby",
8045
+ "describedBy \u2014 the slot name is camelCase on the wire, not the ARIA attribute spelling"
8046
+ ],
8047
+ ["aria-role", "role \u2014 the ARIA role NAME as a bare string"],
8048
+ ["ariaRole", "role \u2014 the ARIA role NAME as a bare string"],
8049
+ ["aria-live", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
8050
+ ["ariaLive", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
8051
+ ["live", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
8052
+ ["liveregion", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
8053
+ ["aria-hidden", "hidden \u2014 a Binding<bool> (a bare bool is the \xA73.6 shorthand)"],
8054
+ ["ariaHidden", "hidden \u2014 a Binding<bool> (a bare bool is the \xA73.6 shorthand)"]
8055
+ ];
8056
+ var checkA11yNearMisses = (path, f) => {
8057
+ for (const [name, canonical] of A11Y_NEAR_MISSES) {
8058
+ if (tryField(f, name) !== void 0)
8059
+ return makeError(
8060
+ "WRONG_TYPE",
8061
+ `${path}.${name}`,
8062
+ `'${name}' is not part of the accessibility vocabulary \u2014 it would be ignored, not honoured, and the intent would reach assistive technology as nothing at all`,
8063
+ canonical
8064
+ );
8065
+ }
8066
+ return ok(void 0);
8067
+ };
7207
8068
  var decodeAccessibility = (path, j) => {
7208
8069
  const fo = requireObject(path, j);
7209
8070
  if (!fo.ok) return fo;
7210
8071
  const f = fo.value;
8072
+ const nearMiss2 = checkA11yNearMisses(path, f);
8073
+ if (!nearMiss2.ok) return nearMiss2;
7211
8074
  const label = optField(path, f, "label", decodeBindingString);
7212
8075
  if (!label.ok) return label;
7213
8076
  const labelledBy = optField(path, f, "labelledBy", requireString);
@@ -7252,7 +8115,41 @@ var placeholderClosureNode = {
7252
8115
  voice: "Default"
7253
8116
  }
7254
8117
  };
8118
+ var walkDepth = 0;
8119
+ var walkNodes = 0;
8120
+ var opDepth = 0;
8121
+ var itemDepth = 0;
8122
+ var walkPolicy = schema.admitAll;
8123
+ var resetWalk = (policy = schema.admitAll) => {
8124
+ walkDepth = 0;
8125
+ walkNodes = 0;
8126
+ opDepth = 0;
8127
+ itemDepth = 0;
8128
+ walkPolicy = policy;
8129
+ };
8130
+ var limitError = (path, message, expected) => makeError("LIMIT_EXCEEDED", path, message, expected);
7255
8131
  var decodeNodeAst = (path, j) => {
8132
+ if (walkDepth >= schema.MAX_NODE_DEPTH) {
8133
+ return limitError(
8134
+ path,
8135
+ `node nesting deeper than the wire limit MAX_NODE_DEPTH = ${schema.MAX_NODE_DEPTH}`,
8136
+ `a tree nesting nodes no more than ${schema.MAX_NODE_DEPTH} levels deep`
8137
+ );
8138
+ }
8139
+ walkNodes += 1;
8140
+ if (walkNodes > schema.MAX_NODES) {
8141
+ return limitError(
8142
+ path,
8143
+ `the document holds more than the wire limit MAX_NODES = ${schema.MAX_NODES} nodes`,
8144
+ `a tree of no more than ${schema.MAX_NODES} nodes in total`
8145
+ );
8146
+ }
8147
+ walkDepth += 1;
8148
+ const r = decodeNodeAstInner(path, j);
8149
+ walkDepth -= 1;
8150
+ return r;
8151
+ };
8152
+ var decodeNodeAstInner = (path, j) => {
7256
8153
  const fo = requireObject(path, j);
7257
8154
  if (!fo.ok) return fo;
7258
8155
  const f = fo.value;
@@ -7271,15 +8168,37 @@ var decodeNodeAst = (path, j) => {
7271
8168
  if (!style.ok) return style;
7272
8169
  const accessibility2 = optField(path, f, "accessibility", decodeAccessibility);
7273
8170
  if (!accessibility2.ok) return accessibility2;
8171
+ const tooltip = optField(path, f, "tooltip", decodeTextSource);
8172
+ if (!tooltip.ok) return tooltip;
7274
8173
  return ok({
7275
8174
  id: idStr.value,
7276
8175
  kind: kind.value,
7277
8176
  state: state.value,
7278
8177
  style: style.value,
7279
- ...accessibility2.value !== void 0 ? { accessibility: accessibility2.value } : {}
8178
+ ...accessibility2.value !== void 0 ? { accessibility: accessibility2.value } : {},
8179
+ ...tooltip.value !== void 0 ? { tooltip: tooltip.value } : {}
7280
8180
  });
7281
8181
  };
7282
8182
  var decodeTreeOpAst = (path, j) => {
8183
+ if (opDepth >= schema.MAX_NODE_DEPTH) {
8184
+ return limitError(
8185
+ path,
8186
+ `op nesting deeper than the wire limit MAX_NODE_DEPTH = ${schema.MAX_NODE_DEPTH}`,
8187
+ `a Batch nesting ops no more than ${schema.MAX_NODE_DEPTH} levels deep`
8188
+ );
8189
+ }
8190
+ opDepth += 1;
8191
+ const r = decodeTreeOpAstInner(path, j);
8192
+ opDepth -= 1;
8193
+ return r;
8194
+ };
8195
+ var retiredPositionalField = (path, f, name, opKind) => tryField(f, name) !== void 0 ? makeError(
8196
+ "WRONG_TYPE",
8197
+ `${path}.${name}`,
8198
+ `'${name}' was removed from the wire format \u2014 ${opKind} appends, and order is stated by naming ids with ReorderChildren`,
8199
+ "a Batch of the structural op followed by ReorderChildren"
8200
+ ) : ok(void 0);
8201
+ var decodeTreeOpAstInner = (path, j) => {
7283
8202
  const fo = requireObject(path, j);
7284
8203
  if (!fo.ok) return fo;
7285
8204
  const f = fo.value;
@@ -7332,6 +8251,8 @@ var decodeTreeOpAst = (path, j) => {
7332
8251
  return state.ok ? ok({ kind: "UpdateState", target: t.value, state: state.value }) : state;
7333
8252
  }
7334
8253
  case "InsertChild": {
8254
+ const retired = retiredPositionalField(path, f, "position", "InsertChild");
8255
+ if (!retired.ok) return retired;
7335
8256
  const parentJ = reqField(path, f, "parentId", "parent NodeId", requireString);
7336
8257
  if (!parentJ.ok) return parentJ;
7337
8258
  const child = reqField(path, f, "child", "child Node object", decodeNodeAst);
@@ -7346,6 +8267,8 @@ var decodeTreeOpAst = (path, j) => {
7346
8267
  return t.ok ? ok({ kind: "RemoveNode", target: t.value }) : t;
7347
8268
  }
7348
8269
  case "MoveNode": {
8270
+ const retired = retiredPositionalField(path, f, "newPosition", "MoveNode");
8271
+ if (!retired.ok) return retired;
7349
8272
  const t = target();
7350
8273
  if (!t.ok) return t;
7351
8274
  const newParent = reqField(path, f, "newParentId", "new parent NodeId", requireString);
@@ -7427,6 +8350,8 @@ var coerce = {
7427
8350
  tone: (v) => viaAst(v, decodeTone),
7428
8351
  weight: (v) => viaAst(v, decodeWeight),
7429
8352
  emphasis: (v) => viaAst(v, decodeEmphasis),
8353
+ /** `Metric.TrendPolarity` (Phase 867) - the UpdateProp twin of `decodeTrendPolarity`. */
8354
+ trendPolarity: (v) => viaAst(v, decodeTrendPolarity),
7430
8355
  /**
7431
8356
  * The behavioural `emphasis` BOOL on Fact / LabelValueRow — the UpdateProp
7432
8357
  * twin of `decodeEmphasisFlag`, so a TreeOp edit gets the same
@@ -7447,13 +8372,18 @@ var invalidJson = (parseMessage) => makeError(
7447
8372
  `input is not valid JSON: ${parseMessage}`,
7448
8373
  "well-formed JSON object per the canonical-JSON shape"
7449
8374
  );
7450
- var decodeNode = (json) => {
8375
+ var parseFailure = (e) => e.limit === true ? makeError("LIMIT_EXCEEDED", "$", e.message, "a document within the WIRE_FORMAT \xA721 limits") : invalidJson(e.message);
8376
+ var decodeNode = (json, policy) => {
7451
8377
  const parsed = parse(json);
7452
- return parsed.ok ? decodeNodeAst("$", parsed.value) : invalidJson(parsed.error.message);
8378
+ if (!parsed.ok) return parseFailure(parsed.error);
8379
+ resetWalk(policy);
8380
+ return decodeNodeAst("$", parsed.value);
7453
8381
  };
7454
- var decodeOp = (json) => {
8382
+ var decodeOp = (json, policy) => {
7455
8383
  const parsed = parse(json);
7456
- return parsed.ok ? decodeTreeOpAst("$", parsed.value) : invalidJson(parsed.error.message);
8384
+ if (!parsed.ok) return parseFailure(parsed.error);
8385
+ resetWalk(policy);
8386
+ return decodeTreeOpAst("$", parsed.value);
7457
8387
  };
7458
8388
 
7459
8389
  // src/apply.ts
@@ -7620,6 +8550,11 @@ var updateField = (field2, value, kind) => {
7620
8550
  coerce.cellFormat(value),
7621
8551
  (x) => disp({ kind: "Metric", spec: { ...s, trendFormat: x } })
7622
8552
  );
8553
+ case "TrendPolarity":
8554
+ return patch(
8555
+ coerce.trendPolarity(value),
8556
+ (x) => disp({ kind: "Metric", spec: { ...s, trendPolarity: x } })
8557
+ );
7623
8558
  case "Icon":
7624
8559
  return patch(
7625
8560
  coerce.iconSource(value),
@@ -7903,6 +8838,12 @@ var updateField = (field2, value, kind) => {
7903
8838
  (x) => lay({ kind: "Box", spec: { ...s, layout: { ...mode, cols: x } } })
7904
8839
  );
7905
8840
  }
8841
+ if (field2 === "Cols" && mode.kind === "Masonry") {
8842
+ return patch(
8843
+ coerce.int(value),
8844
+ (x) => lay({ kind: "Box", spec: { ...s, layout: { ...mode, cols: x } } })
8845
+ );
8846
+ }
7906
8847
  if (field2 === "TemplateColumns" && mode.kind === "Grid") {
7907
8848
  return patch(
7908
8849
  coerce.string(value),
@@ -8690,10 +9631,12 @@ var str2 = (s) => {
8690
9631
  }
8691
9632
  return out + '"';
8692
9633
  };
9634
+ var encodeActorValue = (a) => a.kind === "human" ? `{"kind":"human","id":${str2(a.id)}}` : `{"kind":"agent","model":${str2(a.model)},"version":${str2(a.version)},"id":${str2(a.id)}}`;
8693
9635
  var encodeEnvelope = (e) => e.$type === "Success" ? '{"$type":"Success"}' : `{"$type":"Failure","code":${str2(e.code)},"message":${str2(e.message)}}`;
8694
9636
  var encodeDagRecord = (record) => {
8695
9637
  let out = "{";
8696
- out += `"hash":${str2(record.hash)}`;
9638
+ out += `"actor":${encodeActorValue(record.actor)}`;
9639
+ out += `,"hash":${str2(record.hash)}`;
8697
9640
  out += `,"op":${encodeOp(record.op)}`;
8698
9641
  if (record.outcomeHash !== void 0) out += `,"outcomeHash":${str2(record.outcomeHash)}`;
8699
9642
  out += `,"parents":[${record.parents.map(str2).join(",")}]`;
@@ -8702,7 +9645,6 @@ var encodeDagRecord = (record) => {
8702
9645
  out += `,"streamId":${str2(record.streamId)}`;
8703
9646
  out += `,"timestamp":${record.timestamp}`;
8704
9647
  out += `,"tombstoned":${record.tombstoned ? "true" : "false"}`;
8705
- out += `,"userId":${str2(record.userId)}`;
8706
9648
  return out + "}";
8707
9649
  };
8708
9650
  var astToJson = (ast) => {
@@ -8725,6 +9667,20 @@ var astToJson = (ast) => {
8725
9667
  }
8726
9668
  };
8727
9669
  var asString = (ast) => ast !== void 0 && ast.kind === "JString" ? ast.value : void 0;
9670
+ var decodeActor = (ast) => {
9671
+ if (ast === void 0 || ast.kind !== "JObject") return void 0;
9672
+ const kind = asString(field(ast.fields, "kind"));
9673
+ const id = asString(field(ast.fields, "id"));
9674
+ if (id === void 0) return void 0;
9675
+ if (kind === "human") return { kind: "human", id };
9676
+ if (kind === "agent") {
9677
+ const model = asString(field(ast.fields, "model"));
9678
+ const version = asString(field(ast.fields, "version"));
9679
+ if (model === void 0 || version === void 0) return void 0;
9680
+ return { kind: "agent", model, version, id };
9681
+ }
9682
+ return void 0;
9683
+ };
8728
9684
  var decodeDagRecord = (json) => {
8729
9685
  const parsed = parse(json);
8730
9686
  if (!parsed.ok) return { ok: false, error: `dag envelope parse: ${parsed.error.message}` };
@@ -8733,12 +9689,19 @@ var decodeDagRecord = (json) => {
8733
9689
  const f = root.fields;
8734
9690
  const hash = asString(field(f, "hash"));
8735
9691
  const streamId = asString(field(f, "streamId"));
8736
- const userId = asString(field(f, "userId"));
9692
+ const actorAst = field(f, "actor");
8737
9693
  const opAst = field(f, "op");
8738
9694
  const parentsAst = field(f, "parents");
8739
9695
  const tsAst = field(f, "timestamp");
8740
- if (hash === void 0 || streamId === void 0 || userId === void 0)
8741
- return { ok: false, error: "dag envelope: missing hash/streamId/userId" };
9696
+ if (actorAst === void 0 && field(f, "userId") !== void 0)
9697
+ return {
9698
+ ok: false,
9699
+ error: "dag envelope: pre-1144 record \u2014 'userId' was replaced by the typed 'actor', and DAG content addresses do not carry forward"
9700
+ };
9701
+ if (hash === void 0 || streamId === void 0)
9702
+ return { ok: false, error: "dag envelope: missing hash/streamId" };
9703
+ const actor = decodeActor(actorAst);
9704
+ if (actor === void 0) return { ok: false, error: "dag envelope: missing/malformed 'actor'" };
8742
9705
  if (opAst === void 0) return { ok: false, error: "dag envelope: missing op" };
8743
9706
  if (parentsAst === void 0 || parentsAst.kind !== "JArray")
8744
9707
  return { ok: false, error: "dag envelope: missing/!array parents" };
@@ -8774,7 +9737,7 @@ var decodeDagRecord = (json) => {
8774
9737
  op: opResult.value,
8775
9738
  ...outcomeHash !== void 0 ? { outcomeHash } : {},
8776
9739
  ...promptId !== void 0 ? { promptId } : {},
8777
- userId,
9740
+ actor,
8778
9741
  timestamp: tsAst.value,
8779
9742
  resultEnvelope,
8780
9743
  tombstoned: tombAst !== void 0 && tombAst.kind === "JBool" && tombAst.value
@@ -9767,9 +10730,64 @@ var validateAnswerDocument = (json) => {
9767
10730
  if (!answer.ok) return answer;
9768
10731
  return validateAnswerAt("$.answer", contract.value, answer.value);
9769
10732
  };
10733
+ var HOST_RESERVED_PREFIX = "host.";
10734
+ var isHostReserved = (key) => typeof key === "string" && key.startsWith(HOST_RESERVED_PREFIX);
10735
+ var isPlainObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
10736
+ var isStateDeclaration = (v) => isPlainObject(v) && v["kind"] === "State" && typeof v["key"] === "string" && "defaultValue" in v && v["defaultValue"] !== void 0;
10737
+ var controlDefaults = Object.values(schema.controlValueDefaults);
10738
+ var deepEqual = (a, b) => {
10739
+ try {
10740
+ return JSON.stringify(a) === JSON.stringify(b);
10741
+ } catch {
10742
+ return false;
10743
+ }
10744
+ };
10745
+ var isAutoBoundFieldValue = (binding2, fieldId) => binding2.key === fieldId && controlDefaults.some((d) => deepEqual(d, binding2.defaultValue));
10746
+ var isEmptyDeclaration = (value) => {
10747
+ if (Array.isArray(value)) return value.length === 0;
10748
+ if (isPlainObject(value)) {
10749
+ const columns = value["columns"];
10750
+ if (isPlainObject(columns)) return Object.keys(columns).length === 0;
10751
+ }
10752
+ return false;
10753
+ };
10754
+ var collectStateSeeds = (tree) => {
10755
+ const seeds = {};
10756
+ const seen = /* @__PURE__ */ new Set();
10757
+ const visit = (value, autoBindFieldId) => {
10758
+ if (value === null || typeof value !== "object") return;
10759
+ if (seen.has(value)) return;
10760
+ seen.add(value);
10761
+ if (Array.isArray(value)) {
10762
+ for (const item of value) visit(item, autoBindFieldId);
10763
+ return;
10764
+ }
10765
+ const obj = value;
10766
+ if (isStateDeclaration(obj)) {
10767
+ const key = obj.key;
10768
+ const shouldSkip = isHostReserved(key) || Object.prototype.hasOwnProperty.call(seeds, key) || isEmptyDeclaration(obj.defaultValue) || autoBindFieldId !== void 0 && isAutoBoundFieldValue(obj, autoBindFieldId);
10769
+ if (!shouldSkip) seeds[key] = obj.defaultValue;
10770
+ }
10771
+ const record = obj;
10772
+ const ownId = record["id"];
10773
+ const fieldId = typeof ownId === "string" && typeof record["required"] === "boolean" ? ownId : void 0;
10774
+ for (const [k, v] of Object.entries(obj)) {
10775
+ const established = k === "kind" && fieldId !== void 0 ? fieldId : void 0;
10776
+ visit(v, established ?? autoBindFieldId);
10777
+ }
10778
+ };
10779
+ visit(tree, void 0);
10780
+ return seeds;
10781
+ };
10782
+ var withStateSeeds = (tree, sources) => {
10783
+ const seeds = collectStateSeeds(tree);
10784
+ if (Object.keys(seeds).length === 0) return sources;
10785
+ return { ...sources, state: { ...seeds, ...sources.state ?? {} } };
10786
+ };
9770
10787
 
9771
10788
  exports.ELICITATION_KEY = ELICITATION_KEY;
9772
10789
  exports.ELICITATION_VERSION = ELICITATION_VERSION;
10790
+ exports.HOST_RESERVED_PREFIX = HOST_RESERVED_PREFIX;
9773
10791
  exports.PAYLOAD_KEY = PAYLOAD_KEY;
9774
10792
  exports.PROFILE_KEY = PROFILE_KEY;
9775
10793
  exports.REQUIRED_PROFILE_KEY = REQUIRED_PROFILE_KEY;
@@ -9777,6 +10795,7 @@ exports.apply = apply;
9777
10795
  exports.canPlace = canPlace;
9778
10796
  exports.cellString = cellString;
9779
10797
  exports.coerce = coerce;
10798
+ exports.collectStateSeeds = collectStateSeeds;
9780
10799
  exports.coreV1 = coreV1;
9781
10800
  exports.decodeDagRecord = decodeDagRecord;
9782
10801
  exports.decodeElicitation = decodeElicitation;
@@ -9824,9 +10843,11 @@ exports.renderAstCanonical = renderAstCanonical;
9824
10843
  exports.renderProfile = renderProfile;
9825
10844
  exports.sequentialFreshIds = sequentialFreshIds;
9826
10845
  exports.stepParams = stepParams;
10846
+ exports.substituteListParams = substituteListParams;
9827
10847
  exports.tryParseProfile = tryParseProfile;
9828
10848
  exports.validateAnswer = validateAnswer;
9829
10849
  exports.validateAnswerAt = validateAnswerAt;
9830
10850
  exports.validateAnswerDocument = validateAnswerDocument;
10851
+ exports.withStateSeeds = withStateSeeds;
9831
10852
  //# sourceMappingURL=index.cjs.map
9832
10853
  //# sourceMappingURL=index.cjs.map