@nodegx/preview 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4936,7 +4936,7 @@ var require_lib3 = __commonJS({
4936
4936
  return this.resolve([]);
4937
4937
  }
4938
4938
  var values2 = new Array(len);
4939
- var resolved2 = 0;
4939
+ var resolved3 = 0;
4940
4940
  var i2 = -1;
4941
4941
  var promise = new this(INTERNAL);
4942
4942
  while (++i2 < len) {
@@ -4952,7 +4952,7 @@ var require_lib3 = __commonJS({
4952
4952
  });
4953
4953
  function resolveFromAll(outValue) {
4954
4954
  values2[i3] = outValue;
4955
- if (++resolved2 === len && !called) {
4955
+ if (++resolved3 === len && !called) {
4956
4956
  called = true;
4957
4957
  handlers.resolve(promise, values2);
4958
4958
  }
@@ -6222,15 +6222,15 @@ var require_crc32 = __commonJS({
6222
6222
  "use strict";
6223
6223
  var utils = require_utils3();
6224
6224
  function makeTable() {
6225
- var c, table = [];
6225
+ var c, table2 = [];
6226
6226
  for (var n = 0; n < 256; n++) {
6227
6227
  c = n;
6228
6228
  for (var k = 0; k < 8; k++) {
6229
6229
  c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
6230
6230
  }
6231
- table[n] = c;
6231
+ table2[n] = c;
6232
6232
  }
6233
- return table;
6233
+ return table2;
6234
6234
  }
6235
6235
  var crcTable = makeTable();
6236
6236
  function crc32(crc, buf, len, pos) {
@@ -7228,15 +7228,15 @@ var require_crc322 = __commonJS({
7228
7228
  "../../node_modules/pako/lib/zlib/crc32.js"(exports2, module2) {
7229
7229
  "use strict";
7230
7230
  function makeTable() {
7231
- var c, table = [];
7231
+ var c, table2 = [];
7232
7232
  for (var n = 0; n < 256; n++) {
7233
7233
  c = n;
7234
7234
  for (var k = 0; k < 8; k++) {
7235
7235
  c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
7236
7236
  }
7237
- table[n] = c;
7237
+ table2[n] = c;
7238
7238
  }
7239
- return table;
7239
+ return table2;
7240
7240
  }
7241
7241
  var crcTable = makeTable();
7242
7242
  function crc32(crc, buf, len, pos) {
@@ -9030,7 +9030,7 @@ var require_inftrees = __commonJS({
9030
9030
  64,
9031
9031
  64
9032
9032
  ];
9033
- module2.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
9033
+ module2.exports = function inflate_table(type, lens, lens_index, codes, table2, table_index, work, opts) {
9034
9034
  var bits = opts.bits;
9035
9035
  var len = 0;
9036
9036
  var sym = 0;
@@ -9070,8 +9070,8 @@ var require_inftrees = __commonJS({
9070
9070
  root2 = max2;
9071
9071
  }
9072
9072
  if (max2 === 0) {
9073
- table[table_index++] = 1 << 24 | 64 << 16 | 0;
9074
- table[table_index++] = 1 << 24 | 64 << 16 | 0;
9073
+ table2[table_index++] = 1 << 24 | 64 << 16 | 0;
9074
+ table2[table_index++] = 1 << 24 | 64 << 16 | 0;
9075
9075
  opts.bits = 1;
9076
9076
  return 0;
9077
9077
  }
@@ -9146,7 +9146,7 @@ var require_inftrees = __commonJS({
9146
9146
  min2 = fill;
9147
9147
  do {
9148
9148
  fill -= incr;
9149
- table[next2 + (huff >> drop2) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
9149
+ table2[next2 + (huff >> drop2) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
9150
9150
  } while (fill !== 0);
9151
9151
  incr = 1 << len - 1;
9152
9152
  while (huff & incr) {
@@ -9185,11 +9185,11 @@ var require_inftrees = __commonJS({
9185
9185
  return 1;
9186
9186
  }
9187
9187
  low = huff & mask;
9188
- table[low] = root2 << 24 | curr << 16 | next2 - table_index | 0;
9188
+ table2[low] = root2 << 24 | curr << 16 | next2 - table_index | 0;
9189
9189
  }
9190
9190
  }
9191
9191
  if (huff !== 0) {
9192
- table[next2 + huff] = len - drop2 << 24 | 64 << 16 | 0;
9192
+ table2[next2 + huff] = len - drop2 << 24 | 64 << 16 | 0;
9193
9193
  }
9194
9194
  opts.bits = root2;
9195
9195
  return 0;
@@ -9236,7 +9236,7 @@ var require_inflate = __commonJS({
9236
9236
  var STORED = 14;
9237
9237
  var COPY_ = 15;
9238
9238
  var COPY = 16;
9239
- var TABLE2 = 17;
9239
+ var TABLE3 = 17;
9240
9240
  var LENLENS = 18;
9241
9241
  var CODELENS = 19;
9242
9242
  var LEN_ = 20;
@@ -9824,7 +9824,7 @@ var require_inflate = __commonJS({
9824
9824
  }
9825
9825
  break;
9826
9826
  case 2:
9827
- state2.mode = TABLE2;
9827
+ state2.mode = TABLE3;
9828
9828
  break;
9829
9829
  case 3:
9830
9830
  strm.msg = "invalid block type";
@@ -9882,7 +9882,7 @@ var require_inflate = __commonJS({
9882
9882
  }
9883
9883
  state2.mode = TYPE;
9884
9884
  break;
9885
- case TABLE2:
9885
+ case TABLE3:
9886
9886
  while (bits < 14) {
9887
9887
  if (have === 0) {
9888
9888
  break inf_leave;
@@ -18973,8 +18973,21 @@ var require_node2 = __commonJS({
18973
18973
  const scope = this.nodeScope;
18974
18974
  const runContext = scope && scope.runContext;
18975
18975
  if (!runContext || !runContext.beginStep || !runContext.endStep) return;
18976
- const step = runContext.beginStep({ nodeId: this.id, nodeType: this.name });
18977
- if (step !== void 0 && step !== null) runContext.endStep(step, { status: "failure", code, message, detail });
18976
+ const recordValues = !!runContext.recordValues;
18977
+ const step = runContext.beginStep({
18978
+ nodeId: this.id,
18979
+ nodeType: this.name,
18980
+ ...recordValues ? { inputs: snapshotInputValues(this) } : {}
18981
+ });
18982
+ if (step !== void 0 && step !== null) {
18983
+ runContext.endStep(step, {
18984
+ status: "failure",
18985
+ code,
18986
+ message,
18987
+ detail,
18988
+ ...recordValues ? { outputs: snapshotOutputValues(this) } : {}
18989
+ });
18990
+ }
18978
18991
  };
18979
18992
  Node17.prototype.setDiagnostic = function(key, message) {
18980
18993
  setDiagnostic(this, key, message);
@@ -18984,6 +18997,47 @@ var require_node2 = __commonJS({
18984
18997
  return diagnosticsEnabled(this);
18985
18998
  }
18986
18999
  });
19000
+ function isSignalPortType(type) {
19001
+ if (type === "signal") return true;
19002
+ return !!type && typeof type === "object" && type.name === "signal";
19003
+ }
19004
+ function snapshotInputValues(node) {
19005
+ const out = {};
19006
+ const values2 = node._inputValues || {};
19007
+ const inputs = node._inputs || {};
19008
+ let declared2 = {};
19009
+ try {
19010
+ const register3 = node.context && node.context.nodeRegister;
19011
+ if (register3 && register3.hasNode(node.name)) declared2 = register3.getNodeMetadata(node.name).inputs || {};
19012
+ } catch (e) {
19013
+ }
19014
+ for (const name2 of Object.keys(values2)) {
19015
+ const value2 = values2[name2];
19016
+ if (value2 === void 0 || typeof value2 === "function") continue;
19017
+ const port5 = inputs[name2];
19018
+ if (port5 && isSignalPortType(port5.type)) continue;
19019
+ const meta = declared2[name2];
19020
+ if (meta && isSignalPortType(meta.type)) continue;
19021
+ out[name2] = value2;
19022
+ }
19023
+ return out;
19024
+ }
19025
+ function snapshotOutputValues(node) {
19026
+ const out = {};
19027
+ const list2 = node._outputList || [];
19028
+ for (const port5 of list2) {
19029
+ if (!port5 || isSignalPortType(port5.type)) continue;
19030
+ let value2;
19031
+ try {
19032
+ value2 = port5.value;
19033
+ } catch (e) {
19034
+ continue;
19035
+ }
19036
+ if (value2 === void 0 || typeof value2 === "function") continue;
19037
+ out[port5.name] = value2;
19038
+ }
19039
+ return out;
19040
+ }
18987
19041
  Node17.prototype.beginOutcome = function(inputData) {
18988
19042
  const token = { reported: void 0 };
18989
19043
  const cause = currentTraceCause(this.context);
@@ -18991,7 +19045,13 @@ var require_node2 = __commonJS({
18991
19045
  const scope = this.nodeScope;
18992
19046
  const runContext = scope && scope.runContext;
18993
19047
  if (runContext && runContext.beginStep) {
18994
- token.step = runContext.beginStep({ nodeId: this.id, nodeType: this.name, inputData });
19048
+ token.step = runContext.beginStep({
19049
+ nodeId: this.id,
19050
+ nodeType: this.name,
19051
+ inputData,
19052
+ // P123-STU-FNRUNVALUES — opt-in; absent, the step object is exactly what it always was.
19053
+ ...runContext.recordValues ? { inputs: snapshotInputValues(this) } : {}
19054
+ });
18995
19055
  }
18996
19056
  return token;
18997
19057
  };
@@ -19070,7 +19130,10 @@ var require_node2 = __commonJS({
19070
19130
  message: options && options.message,
19071
19131
  // The subject of the failure, for a record whose steps are all called `http`. See
19072
19132
  // `RuntimeStepEnd.detail` — the node already composes this for the error bus.
19073
- detail: options && options.detail
19133
+ detail: options && options.detail,
19134
+ // P123-STU-FNRUNVALUES — read now, after the signals: "the outcome is the last thing an
19135
+ // action does", so every value it produced is already on its ports.
19136
+ ...runContext.recordValues ? { outputs: snapshotOutputValues(this) } : {}
19074
19137
  });
19075
19138
  }
19076
19139
  }
@@ -24604,9 +24667,704 @@ var require_runtasks = __commonJS({
24604
24667
  }
24605
24668
  });
24606
24669
 
24670
+ // ../noodl-runtime/src/utils.ts
24671
+ var utils_exports = {};
24672
+ __export(utils_exports, {
24673
+ getAbsoluteUrl: () => getAbsoluteUrl,
24674
+ logJavaScriptNodeError: () => logJavaScriptNodeError,
24675
+ thrownMessage: () => thrownMessage
24676
+ });
24677
+ function getAbsoluteUrl(_url) {
24678
+ const url = String(_url);
24679
+ if (!url || url[0] === "/" || url.includes("://") || url.startsWith("data:")) {
24680
+ return url;
24681
+ }
24682
+ return (Noodl.baseUrl || "/") + url;
24683
+ }
24684
+ function thrownMessage(error) {
24685
+ if (error && error.message) return String(error.message);
24686
+ try {
24687
+ return String(error);
24688
+ } catch {
24689
+ return typeof error;
24690
+ }
24691
+ }
24692
+ function logJavaScriptNodeError(error) {
24693
+ const prefix = "Error in JS node run code.";
24694
+ if (error === null || typeof error !== "object" && typeof error !== "function") {
24695
+ console.log(prefix, thrownMessage(error));
24696
+ return;
24697
+ }
24698
+ const proto = Object.getPrototypeOf(error);
24699
+ const kind = proto && proto.constructor && proto.constructor.name ? proto.constructor.name : "Error";
24700
+ console.log(prefix, kind + ": " + thrownMessage(error), error.stack);
24701
+ }
24702
+ var init_utils = __esm({
24703
+ "../noodl-runtime/src/utils.ts"() {
24704
+ }
24705
+ });
24706
+
24707
+ // ../noodl-runtime/src/componentwalk.ts
24708
+ var componentwalk_exports = {};
24709
+ __export(componentwalk_exports, {
24710
+ COMPONENT_OBJECT_TYPES: () => COMPONENT_OBJECT_TYPES,
24711
+ componentAncestorNames: () => componentAncestorNames,
24712
+ componentAncestors: () => componentAncestors,
24713
+ findAncestorWithComponentObject: () => findAncestorWithComponentObject,
24714
+ findAncestorWithName: () => findAncestorWithName,
24715
+ findAncestorWithNodeType: () => findAncestorWithNodeType,
24716
+ findAncestorWithProperty: () => findAncestorWithProperty,
24717
+ findComponentAncestor: () => findComponentAncestor,
24718
+ parentComponentOf: () => parentComponentOf,
24719
+ scopeChain: () => scopeChain,
24720
+ scopeChainNames: () => scopeChainNames
24721
+ });
24722
+ function parentComponentOf(component) {
24723
+ if (!component) return void 0;
24724
+ let parent;
24725
+ if (component.getRoots().length > 0) {
24726
+ const root2 = component.getRoots()[0];
24727
+ if (root2.getVisualParentNode) {
24728
+ const visualParent = root2.getVisualParentNode();
24729
+ if (visualParent) {
24730
+ parent = visualParent.nodeScope.componentOwner;
24731
+ }
24732
+ } else if (root2.parentNodeScope) {
24733
+ parent = component.parentNodeScope.componentOwner;
24734
+ }
24735
+ } else if (component.parentNodeScope) {
24736
+ parent = component.parentNodeScope.componentOwner;
24737
+ }
24738
+ if (parent && parent.nodeScope && parent.nodeScope.componentOwner !== component) {
24739
+ return parent;
24740
+ }
24741
+ return void 0;
24742
+ }
24743
+ function componentAncestors(component) {
24744
+ const ancestors = [];
24745
+ let current = component;
24746
+ for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
24747
+ const parent = parentComponentOf(current);
24748
+ if (!parent) break;
24749
+ ancestors.push(parent);
24750
+ current = parent;
24751
+ }
24752
+ return ancestors;
24753
+ }
24754
+ function findComponentAncestor(component, predicate) {
24755
+ let current = component;
24756
+ for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
24757
+ const parent = parentComponentOf(current);
24758
+ if (!parent) return void 0;
24759
+ if (predicate(parent)) return parent;
24760
+ current = parent;
24761
+ }
24762
+ return void 0;
24763
+ }
24764
+ function findAncestorWithNodeType(component, types) {
24765
+ return findComponentAncestor(
24766
+ component,
24767
+ (candidate) => types.some((type) => candidate.nodeScope.getNodesWithType(type).length > 0)
24768
+ );
24769
+ }
24770
+ function findAncestorWithComponentObject(component) {
24771
+ return findAncestorWithNodeType(component, COMPONENT_OBJECT_TYPES);
24772
+ }
24773
+ function findAncestorWithName(component, name2) {
24774
+ return findComponentAncestor(component, (candidate) => candidate.name === name2);
24775
+ }
24776
+ function scopeChain(component) {
24777
+ const chain2 = [];
24778
+ let current = component;
24779
+ for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
24780
+ if (!current) break;
24781
+ chain2.push(current);
24782
+ if (!current.parentNodeScope) break;
24783
+ current = current.parentNodeScope.componentOwner;
24784
+ }
24785
+ return chain2;
24786
+ }
24787
+ function scopeChainNames(component) {
24788
+ return scopeChain(component).map((entry) => entry.name);
24789
+ }
24790
+ function findAncestorWithProperty(component, property2) {
24791
+ const chain2 = scopeChain(component);
24792
+ for (let i2 = 0; i2 < chain2.length; i2++) {
24793
+ if (chain2[i2][property2] !== void 0) return chain2[i2];
24794
+ }
24795
+ return void 0;
24796
+ }
24797
+ function componentAncestorNames(component) {
24798
+ return componentAncestors(component).map((ancestor) => ancestor.name);
24799
+ }
24800
+ var MAX_WALK_DEPTH, COMPONENT_OBJECT_TYPES;
24801
+ var init_componentwalk = __esm({
24802
+ "../noodl-runtime/src/componentwalk.ts"() {
24803
+ "use strict";
24804
+ MAX_WALK_DEPTH = 1e3;
24805
+ COMPONENT_OBJECT_TYPES = ["net.noodl.ComponentObject", "Component State"];
24806
+ }
24807
+ });
24808
+
24809
+ // ../noodl-runtime/src/resolvedtarget.ts
24810
+ function summariseTargets(labels) {
24811
+ const distinct = [];
24812
+ for (let i2 = 0; i2 < labels.length; i2++) {
24813
+ const label = labels[i2];
24814
+ if (label === void 0) continue;
24815
+ if (distinct.indexOf(label) === -1) distinct.push(label);
24816
+ }
24817
+ if (distinct.length === 0) return void 0;
24818
+ if (distinct.length === 1) return "\u2192 " + distinct[0];
24819
+ const listed = distinct.slice(0, MAX_NAMES_LISTED).join(", ");
24820
+ const rest2 = distinct.length - MAX_NAMES_LISTED;
24821
+ return "\u2192 " + distinct.length + " targets: " + listed + (rest2 > 0 ? ", +" + rest2 : "");
24822
+ }
24823
+ var MAX_NAMES_LISTED, ResolvedTargetReporter;
24824
+ var init_resolvedtarget = __esm({
24825
+ "../noodl-runtime/src/resolvedtarget.ts"() {
24826
+ "use strict";
24827
+ MAX_NAMES_LISTED = 3;
24828
+ ResolvedTargetReporter = class {
24829
+ constructor() {
24830
+ /** Weak, so a torn-down runtime's bookkeeping goes with it and needs no reset call. */
24831
+ this._byContext = /* @__PURE__ */ new WeakMap();
24832
+ }
24833
+ /**
24834
+ * Record what `node` bound to and push the summary to the editor.
24835
+ *
24836
+ * Safe to call every resolution; identical summaries are dropped rather than sent, so a
24837
+ * node that re-resolves each frame costs one string comparison.
24838
+ */
24839
+ report(node, target) {
24840
+ const state2 = this._stateFor(node);
24841
+ if (!state2) return;
24842
+ let instances = state2.byGraphNode.get(node.id);
24843
+ if (!instances) {
24844
+ instances = /* @__PURE__ */ new Map();
24845
+ state2.byGraphNode.set(node.id, instances);
24846
+ }
24847
+ instances.set(node, target);
24848
+ this._flush(node, state2, instances);
24849
+ }
24850
+ /** Drop an instance. Call from `_onNodeDeleted`, or this map is a leak. */
24851
+ forget(node) {
24852
+ const state2 = this._stateFor(node);
24853
+ if (!state2) return;
24854
+ const instances = state2.byGraphNode.get(node.id);
24855
+ if (!instances) return;
24856
+ instances.delete(node);
24857
+ if (instances.size === 0) {
24858
+ state2.byGraphNode.delete(node.id);
24859
+ state2.lastSent.delete(node.id);
24860
+ return;
24861
+ }
24862
+ this._flush(node, state2, instances);
24863
+ }
24864
+ _stateFor(node) {
24865
+ const context = node.context;
24866
+ if (!context) return void 0;
24867
+ let state2 = this._byContext.get(context);
24868
+ if (!state2) {
24869
+ state2 = { byGraphNode: /* @__PURE__ */ new Map(), lastSent: /* @__PURE__ */ new Map() };
24870
+ this._byContext.set(context, state2);
24871
+ }
24872
+ return state2;
24873
+ }
24874
+ _flush(node, state2, instances) {
24875
+ const labels = [];
24876
+ instances.forEach((label) => labels.push(label));
24877
+ const summary = summariseTargets(labels);
24878
+ if (state2.lastSent.has(node.id) && state2.lastSent.get(node.id) === summary) return;
24879
+ state2.lastSent.set(node.id, summary);
24880
+ const editorConnection = node.context && node.context.editorConnection;
24881
+ if (!editorConnection || !editorConnection.isRunningLocally()) return;
24882
+ if (typeof editorConnection.sendNodeSubLabel !== "function") return;
24883
+ editorConnection.sendNodeSubLabel(node.id, summary);
24884
+ }
24885
+ };
24886
+ }
24887
+ });
24888
+
24889
+ // ../noodl-runtime/src/foreachitem.ts
24890
+ var foreachitem_exports = {};
24891
+ __export(foreachitem_exports, {
24892
+ forgetForEachItem: () => forgetForEachItem,
24893
+ resolveForEachItem: () => resolveForEachItem
24894
+ });
24895
+ function resolveForEachItem(node, options = {}) {
24896
+ const chain2 = scopeChain(node.nodeScope.componentOwner);
24897
+ const wanted = options.target;
24898
+ if (wanted) {
24899
+ const named3 = firstNamed(chain2, wanted);
24900
+ if (!named3) {
24901
+ return miss(
24902
+ node,
24903
+ "repeater-item/target-not-found",
24904
+ 'No component named "' + wanted + '" contains this node',
24905
+ wanted,
24906
+ { target: wanted, scope: scopeChainNames(node.nodeScope.componentOwner) }
24907
+ );
24908
+ }
24909
+ if (named3[FOR_EACH_MODEL] === void 0) {
24910
+ return miss(
24911
+ node,
24912
+ "repeater-item/target-has-no-item",
24913
+ 'The component "' + wanted + '" has no current item \u2014 it is not used as a Repeater or Run Tasks template',
24914
+ wanted,
24915
+ { target: wanted }
24916
+ );
24917
+ }
24918
+ return hit(node, named3);
24919
+ }
24920
+ const owner = firstWithItem(chain2);
24921
+ if (!owner) {
24922
+ return miss(
24923
+ node,
24924
+ "repeater-item/no-item-in-scope",
24925
+ 'Id Source is set to "From repeater", but this node is not inside a Repeater or Run Tasks template',
24926
+ void 0,
24927
+ { scope: scopeChainNames(node.nodeScope.componentOwner) }
24928
+ );
24929
+ }
24930
+ return hit(node, owner);
24931
+ }
24932
+ function forgetForEachItem(node) {
24933
+ resolvedTargets.forget(node);
24934
+ lastMissByNode.delete(node);
24935
+ }
24936
+ function firstNamed(chain2, name2) {
24937
+ for (let i2 = 0; i2 < chain2.length; i2++) {
24938
+ if (chain2[i2].name === name2) return chain2[i2];
24939
+ }
24940
+ return void 0;
24941
+ }
24942
+ function firstWithItem(chain2) {
24943
+ for (let i2 = 0; i2 < chain2.length; i2++) {
24944
+ if (chain2[i2][FOR_EACH_MODEL] !== void 0) return chain2[i2];
24945
+ }
24946
+ return void 0;
24947
+ }
24948
+ function hit(node, owner) {
24949
+ lastMissByNode.delete(node);
24950
+ resolvedTargets.report(node, owner.name);
24951
+ return owner[FOR_EACH_MODEL];
24952
+ }
24953
+ function miss(node, code, message, target, detail) {
24954
+ resolvedTargets.report(node, void 0);
24955
+ const seen = code + "|" + (target || "");
24956
+ if (lastMissByNode.get(node) !== seen) {
24957
+ lastMissByNode.set(node, seen);
24958
+ node.raiseRuntimeError(code, message, detail);
24959
+ }
24960
+ return void 0;
24961
+ }
24962
+ var FOR_EACH_MODEL, resolvedTargets, lastMissByNode;
24963
+ var init_foreachitem = __esm({
24964
+ "../noodl-runtime/src/foreachitem.ts"() {
24965
+ "use strict";
24966
+ init_componentwalk();
24967
+ init_resolvedtarget();
24968
+ FOR_EACH_MODEL = "_forEachModel";
24969
+ resolvedTargets = new ResolvedTargetReporter();
24970
+ lastMissByNode = /* @__PURE__ */ new WeakMap();
24971
+ }
24972
+ });
24973
+
24974
+ // ../noodl-runtime/src/javascriptnodeparser.js
24975
+ var require_javascriptnodeparser = __commonJS({
24976
+ "../noodl-runtime/src/javascriptnodeparser.js"(exports2, module2) {
24977
+ "use strict";
24978
+ var Model28 = require_model2();
24979
+ var { getAbsoluteUrl: getAbsoluteUrl2 } = (init_utils(), __toCommonJS(utils_exports));
24980
+ var { findAncestorWithComponentObject: findAncestorWithComponentObject2 } = (init_componentwalk(), __toCommonJS(componentwalk_exports));
24981
+ var { resolveForEachItem: resolveForEachItem2 } = (init_foreachitem(), __toCommonJS(foreachitem_exports));
24982
+ var userFunctionsCache = {};
24983
+ function JavascriptNodeParser4(code, options) {
24984
+ this.inputs = {};
24985
+ this.outputs = {};
24986
+ this.error = void 0;
24987
+ this.code = code;
24988
+ const node = options ? options.node : void 0;
24989
+ this._initializeAPIs();
24990
+ var userCode = userFunctionsCache[code];
24991
+ if (!userCode) {
24992
+ try {
24993
+ userCode = new Function(["define", "script", "Node", "Component"], JavascriptNodeParser4.getCodePrefix() + code);
24994
+ userFunctionsCache[code] = userCode;
24995
+ } catch (e) {
24996
+ this.error = e.message;
24997
+ console.error(e);
24998
+ }
24999
+ }
25000
+ if (userCode) {
25001
+ try {
25002
+ userCode(
25003
+ this.define.bind(this),
25004
+ this.script.bind(this),
25005
+ this.apis.Node,
25006
+ node ? JavascriptNodeParser4.getComponentScopeForNode(node) : {}
25007
+ );
25008
+ this._afterSourced();
25009
+ } catch (e) {
25010
+ this.error = e.message;
25011
+ console.error(e);
25012
+ }
25013
+ }
25014
+ }
25015
+ JavascriptNodeParser4.prototype.define = function(userObject) {
25016
+ this.inputs = userObject.inputs || {};
25017
+ this.outputs = userObject.outputs || {};
25018
+ this.setup = userObject.setup;
25019
+ this.change = userObject.run || userObject.change;
25020
+ this.destroy = userObject.destroy;
25021
+ this.definedObject = userObject;
25022
+ };
25023
+ function _scriptExtend(_this) {
25024
+ var _extended = {
25025
+ inputs: _this.inputs || {},
25026
+ outputs: _this.outputs || {},
25027
+ setup: function(inputs, outputs2) {
25028
+ this.inputs = inputs;
25029
+ this.outputs = outputs2;
25030
+ this.setOutputs = function(states) {
25031
+ for (var key3 in states) {
25032
+ this.outputs[key3] = states[key3];
25033
+ this.flagOutputDirty(key3);
25034
+ }
25035
+ };
25036
+ if (_this.methods) {
25037
+ for (var key2 in _this.methods) {
25038
+ this[key2] = _this.methods[key2];
25039
+ }
25040
+ }
25041
+ _this.setup && _this.setup.apply(this);
25042
+ },
25043
+ destroy: function(inputs, outputs2) {
25044
+ this.inputs = inputs;
25045
+ this.outputs = outputs2;
25046
+ _this.destroy && _this.destroy.apply(this);
25047
+ },
25048
+ change: function(inputs, outputs2) {
25049
+ this.inputs = inputs;
25050
+ this.outputs = outputs2;
25051
+ var old = this._oldInputs || {};
25052
+ if (_this.changed) {
25053
+ for (var key2 in inputs) {
25054
+ if (inputs[key2] !== old[key2]) {
25055
+ var changedFunction = _this.changed[key2];
25056
+ if (typeof changedFunction === "function") changedFunction.apply(this, [inputs[key2], old[key2]]);
25057
+ }
25058
+ }
25059
+ }
25060
+ this._oldInputs = Object.assign({}, inputs);
25061
+ }
25062
+ };
25063
+ if (_this.signals) {
25064
+ for (var key in _this.signals) {
25065
+ _extended[key] = _this.signals[key];
25066
+ _extended.inputs[key] = "signal";
25067
+ }
25068
+ }
25069
+ return _extended;
25070
+ }
25071
+ JavascriptNodeParser4.prototype.script = function(userObject) {
25072
+ var _userObjectExtended = _scriptExtend(userObject);
25073
+ this.inputs = _userObjectExtended.inputs || {};
25074
+ this.outputs = _userObjectExtended.outputs || {};
25075
+ this.setup = _userObjectExtended.setup;
25076
+ this.change = _userObjectExtended.run || _userObjectExtended.change;
25077
+ this.destroy = _userObjectExtended.destroy;
25078
+ this.definedObject = _userObjectExtended;
25079
+ };
25080
+ JavascriptNodeParser4.prototype._initializeAPIs = function() {
25081
+ this.apis = {
25082
+ Node: {
25083
+ Inputs: {},
25084
+ Outputs: {},
25085
+ Signals: {},
25086
+ Setters: {}
25087
+ }
25088
+ };
25089
+ };
25090
+ JavascriptNodeParser4.prototype._afterSourced = function() {
25091
+ if (this.definedObject !== void 0) return;
25092
+ var _Node = this.apis.Node;
25093
+ this.inputs = Object.assign({}, _Node.Inputs || {});
25094
+ this.outputs = Object.assign({}, _Node.Outputs || {});
25095
+ this.setup = function(inputs, outputs2) {
25096
+ const _this = this;
25097
+ _Node.setOutputs = function(_outputs) {
25098
+ for (var key2 in _outputs) {
25099
+ outputs2[key2] = _outputs[key2];
25100
+ _this.flagOutputDirty(key2);
25101
+ }
25102
+ };
25103
+ _Node.OnInit && _Node.OnInit.apply(this);
25104
+ };
25105
+ this.destroy = _Node.OnDestroy || this.destory;
25106
+ this.change = (inputs, outputs2, changedInputs) => {
25107
+ for (var key2 in changedInputs) {
25108
+ if (typeof _Node.Setters[key2] === "function") {
25109
+ _Node.Setters[key2](inputs[key2]);
25110
+ }
25111
+ }
25112
+ if (typeof _Node.OnInputsChanged === "function") {
25113
+ _Node.OnInputsChanged();
25114
+ }
25115
+ };
25116
+ this.definedObject = {
25117
+ inputs: this.inputs,
25118
+ outputs: this.outputs,
25119
+ setup: this.setup,
25120
+ destroy: this.destroy,
25121
+ change: this.change
25122
+ };
25123
+ if (_Node.Signals !== void 0) {
25124
+ for (var key in _Node.Signals) {
25125
+ if (typeof _Node.Signals[key] === "function") {
25126
+ this.inputs[key] = "signal";
25127
+ this.definedObject[key] = _Node.Signals[key];
25128
+ }
25129
+ }
25130
+ }
25131
+ };
25132
+ JavascriptNodeParser4.createFromCode = function(code, options) {
25133
+ return new JavascriptNodeParser4(code, options);
25134
+ };
25135
+ function failedParser(message) {
25136
+ var parser = Object.create(JavascriptNodeParser4.prototype);
25137
+ parser.inputs = {};
25138
+ parser.outputs = {};
25139
+ parser.error = message;
25140
+ parser.code = void 0;
25141
+ parser.apis = { Node: {} };
25142
+ return parser;
25143
+ }
25144
+ JavascriptNodeParser4.createFromURL = function(url, callback, options) {
25145
+ url = getAbsoluteUrl2(url);
25146
+ var settled = false;
25147
+ function settle(parser) {
25148
+ if (settled) return;
25149
+ settled = true;
25150
+ callback(parser);
25151
+ }
25152
+ var xhr = new window.XMLHttpRequest();
25153
+ xhr.open("GET", url, true);
25154
+ xhr.onreadystatechange = function() {
25155
+ if (this.readyState === 4 || this.readyState === XMLHttpRequest.DONE) {
25156
+ if (this.status !== 0 && (this.status < 200 || this.status >= 300)) {
25157
+ settle(failedParser('Could not load "' + url + '": the server answered ' + this.status));
25158
+ return;
25159
+ }
25160
+ if (this.status === 0) {
25161
+ settle(failedParser('Could not load "' + url + '": the request failed'));
25162
+ return;
25163
+ }
25164
+ settle(new JavascriptNodeParser4(this.response, options));
25165
+ }
25166
+ };
25167
+ xhr.onerror = function() {
25168
+ settle(failedParser('Could not load "' + url + '": the request failed'));
25169
+ };
25170
+ xhr.send();
25171
+ };
25172
+ JavascriptNodeParser4.parseAndAddPortsFromScript = function(script2, ports, options) {
25173
+ function _exists(port5) {
25174
+ if (typeof port5 === "string") return ports.find((p) => p.name === port5) !== void 0;
25175
+ else return ports.find((p) => p.name === port5.name && p.plug === port5.plug) !== void 0;
25176
+ }
25177
+ function _addPortsFromMatch(match, options2) {
25178
+ if (match === void 0 || match === null) return;
25179
+ const unique2 = {};
25180
+ for (const _s of match) {
25181
+ let name2 = _s[1];
25182
+ if (name2 === void 0) continue;
25183
+ unique2[name2] = true;
25184
+ }
25185
+ Object.keys(unique2).forEach((p) => {
25186
+ if (_exists({
25187
+ name: options2.prefix + p,
25188
+ plug: options2.plug
25189
+ }))
25190
+ return;
25191
+ ports.push({
25192
+ name: options2.prefix + p,
25193
+ displayName: p,
25194
+ plug: options2.plug,
25195
+ type: options2.type,
25196
+ group: options2.group
25197
+ });
25198
+ });
25199
+ }
25200
+ if (!options.skipInputs) {
25201
+ _addPortsFromMatch(script2.matchAll(/Inputs\.([A-Za-z0-9_]+)/g), {
25202
+ type: options.inputType || "*",
25203
+ plug: "input",
25204
+ group: options.inputGroup || "Inputs",
25205
+ prefix: options.inputPrefix || ""
25206
+ });
25207
+ _addPortsFromMatch(script2.matchAll(/Inputs\s*\[\s*(?:'|")(.*)(?:'|")\s*\]/g), {
25208
+ type: options.inputType || "*",
25209
+ plug: "inputs",
25210
+ group: options.inputGroup || "Inputs",
25211
+ prefix: options.inputPrefix || ""
25212
+ });
25213
+ }
25214
+ if (!options.skipOutputs) {
25215
+ if (!options.skipOutputSignals) {
25216
+ _addPortsFromMatch(script2.matchAll(/Outputs\.([A-Za-z0-9]+)\s*\(\s*\)/g), {
25217
+ type: "signal",
25218
+ plug: "output",
25219
+ group: "Outputs",
25220
+ prefix: options.outputPrefix || ""
25221
+ });
25222
+ _addPortsFromMatch(script2.matchAll(/Outputs\s*\[\s*(?:'|")(.*)(?:'|")\s*\]\(\s*\)/g), {
25223
+ type: "signal",
25224
+ plug: "output",
25225
+ group: "Outputs",
25226
+ prefix: options.outputPrefix || ""
25227
+ });
25228
+ }
25229
+ if (!options.skipRegularOutputs) {
25230
+ _addPortsFromMatch(script2.matchAll(/Outputs\.([A-Za-z0-9_]+)/g), {
25231
+ type: "*",
25232
+ plug: "output",
25233
+ group: "Outputs",
25234
+ prefix: options.outputPrefix || ""
25235
+ });
25236
+ _addPortsFromMatch(script2.matchAll(/Outputs\s*\[\s*\"([^\"]*)\"\s*\]/g), {
25237
+ type: "*",
25238
+ plug: "output",
25239
+ group: "Outputs",
25240
+ prefix: options.outputPrefix || ""
25241
+ });
25242
+ }
25243
+ }
25244
+ };
25245
+ JavascriptNodeParser4.prototype.getPorts = function() {
25246
+ var ports = [];
25247
+ var self2 = this;
25248
+ Object.keys(this.inputs).forEach(function(name2) {
25249
+ var inputPort2 = self2.inputs[name2];
25250
+ var port5 = {
25251
+ name: name2,
25252
+ plug: "input"
25253
+ };
25254
+ if (typeof inputPort2 === "string") {
25255
+ port5.type = {
25256
+ name: inputPort2
25257
+ };
25258
+ port5.group = "Inputs";
25259
+ } else {
25260
+ for (var p in inputPort2) {
25261
+ port5[p] = inputPort2[p];
25262
+ }
25263
+ }
25264
+ ports.push(port5);
25265
+ });
25266
+ Object.keys(this.outputs).forEach(function(name2) {
25267
+ ports.push({
25268
+ name: name2,
25269
+ type: {
25270
+ name: self2.outputs[name2]
25271
+ },
25272
+ plug: "output",
25273
+ group: "Outputs"
25274
+ });
25275
+ });
25276
+ JavascriptNodeParser4.parseAndAddPortsFromScript(this.code, ports, {});
25277
+ return ports;
25278
+ };
25279
+ var _componentScopes = {};
25280
+ function _findParentComponentStateModelId(node) {
25281
+ const parent = findAncestorWithComponentObject2(node.nodeScope.componentOwner);
25282
+ if (!parent) return;
25283
+ return "componentState" + parent.getInstanceId();
25284
+ }
25285
+ JavascriptNodeParser4.getComponentScopeForNode = function(node) {
25286
+ const componentId = node.nodeScope.componentOwner.getInstanceId();
25287
+ if (_componentScopes[componentId] === void 0) {
25288
+ _componentScopes[componentId] = {};
25289
+ const componentObject = (node.nodeScope.modelScope || Model28).get("componentState" + componentId);
25290
+ _componentScopes[componentId].Object = componentObject;
25291
+ }
25292
+ const parentComponentObjectId = _findParentComponentStateModelId(node);
25293
+ const parentComponentObject = parentComponentObjectId !== void 0 ? (node.nodeScope.modelScope || Model28).get(parentComponentObjectId) : void 0;
25294
+ _componentScopes[componentId].ParentObject = parentComponentObject;
25295
+ Object.defineProperty(_componentScopes[componentId], "RepeaterObject", {
25296
+ configurable: true,
25297
+ enumerable: true,
25298
+ get: function() {
25299
+ return resolveForEachItem2(node);
25300
+ }
25301
+ });
25302
+ return _componentScopes[componentId];
25303
+ };
25304
+ JavascriptNodeParser4.getCodePrefix = function() {
25305
+ return "const Script = (typeof Node !== 'undefined')?Node:undefined;\n";
25306
+ };
25307
+ JavascriptNodeParser4.createNoodlAPI = function() {
25308
+ return typeof window !== "undefined" && window.Noodl !== void 0 ? window.Noodl : {};
25309
+ };
25310
+ module2.exports = JavascriptNodeParser4;
25311
+ }
25312
+ });
25313
+
25314
+ // ../noodl-runtime/src/printedcode.ts
25315
+ function table() {
25316
+ return globalThis[TABLE];
25317
+ }
25318
+ function hasPrintedCode() {
25319
+ return table() !== void 0;
25320
+ }
25321
+ function sameParams(a, b) {
25322
+ return a.length === b.length && a.every((p, i2) => p === b[i2]);
25323
+ }
25324
+ function findPrintedCode(params, body, async) {
25325
+ const list2 = table()?.get(body);
25326
+ return list2 && list2.find((e) => e.async === async && sameParams(e.params, params));
25327
+ }
25328
+ function findPrintedBody(body, async) {
25329
+ const list2 = table()?.get(body);
25330
+ return list2 && list2.find((e) => e.async === async);
25331
+ }
25332
+ function compileCode(params, body, options) {
25333
+ const async = !!(options && options.async);
25334
+ const printed = findPrintedCode(params, body, async);
25335
+ if (printed) return printed.fn;
25336
+ if (table()?.refuseOthers) throw new Error(NOT_PRINTED_MESSAGE);
25337
+ const Ctor = async ? AsyncFunction : Function;
25338
+ return new Ctor(...params, body);
25339
+ }
25340
+ function functionNodeBody(script2) {
25341
+ const JavascriptNodeParser4 = require_javascriptnodeparser();
25342
+ return JavascriptNodeParser4.getCodePrefix() + script2;
25343
+ }
25344
+ function expressionNodeBody(expression) {
25345
+ return EXPRESSION_PREAMBLE + "return (" + expression + ");";
25346
+ }
25347
+ var NOT_PRINTED_MESSAGE, TABLE, AsyncFunction, FUNCTION_NODE_PARAMS, EXPRESSION_PREAMBLE, REST_REQUEST_PARAMS, REST_RESPONSE_PARAMS, MAP_COLLECTION_PARAMS;
25348
+ var init_printedcode = __esm({
25349
+ "../noodl-runtime/src/printedcode.ts"() {
25350
+ NOT_PRINTED_MESSAGE = "This code was not printed when the app was deployed, and code cannot be compiled here. Deploy the app again.";
25351
+ TABLE = Symbol.for("nodegx.printedCode");
25352
+ AsyncFunction = Object.getPrototypeOf(async function() {
25353
+ }).constructor;
25354
+ FUNCTION_NODE_PARAMS = ["Inputs", "Outputs", "Noodl", "Component", "Scripts"];
25355
+ EXPRESSION_PREAMBLE = [
25356
+ 'var min = Math.min, max = Math.max, cos = Math.cos, sin = Math.sin, tan = Math.tan, sqrt = Math.sqrt, pi = Math.PI, round = Math.round, floor = Math.floor, ceil = Math.ceil, abs = Math.abs, random = Math.random, pow = Math.pow, log = Math.log, exp = Math.exp;try { var NoodlContext = (typeof Noodl !== "undefined") ? Noodl : (typeof global !== "undefined" && global.Noodl) || {}; var Variables = NoodlContext.Variables || {}; var Objects = NoodlContext.Objects || {}; var Arrays = NoodlContext.Arrays || {};} catch (e) { var Variables = {}, Objects = {}, Arrays = {};}'
25357
+ ].join("");
25358
+ REST_REQUEST_PARAMS = ["Inputs", "Outputs", "Request"];
25359
+ REST_RESPONSE_PARAMS = ["Inputs", "Outputs", "Response"];
25360
+ MAP_COLLECTION_PARAMS = ["map", "object"];
25361
+ }
25362
+ });
25363
+
24607
25364
  // ../noodl-runtime/src/nodes/std-library/data/restnode.ts
24608
25365
  var require_restnode = __commonJS({
24609
25366
  "../noodl-runtime/src/nodes/std-library/data/restnode.ts"(exports2, module2) {
25367
+ init_printedcode();
24610
25368
  var defaultRequestScript = "//Add custom code to setup the request object before the request\n//is made.\n//\n//*Request.resource contains the resource path of the request.\n//*Request.method contains the method, GET, POST, PUT or DELETE.\n//*Request.headers is a map where you can add additional headers.\n//*Request.parameters is a map the parameters that will be appended\n// to the url.\n//*Request.content contains the content of the request as a javascript\n// object.\n//\n";
24611
25369
  var defaultResponseScript = "// Add custom code to convert the response content to outputs\n//\n//*Response.status The status code of the response\n//*Response.content The content of the response as a javascript\n// object.\n//*Response.request The request object that resulted in the response.\n//\n//*Inputs and *Outputs contain the inputs and outputs of the node.\n";
24612
25370
  var RestNode = {
@@ -24695,7 +25453,7 @@ var require_restnode = __commonJS({
24695
25453
  group: "Scripts",
24696
25454
  set: function(script2) {
24697
25455
  try {
24698
- this._internal.requestFunc = new Function("Inputs", "Outputs", "Request", script2);
25456
+ this._internal.requestFunc = compileCode(REST_REQUEST_PARAMS, script2);
24699
25457
  } catch (e) {
24700
25458
  console.log(e);
24701
25459
  }
@@ -24712,7 +25470,7 @@ var require_restnode = __commonJS({
24712
25470
  group: "Scripts",
24713
25471
  set: function(script2) {
24714
25472
  try {
24715
- this._internal.responseFunc = new Function("Inputs", "Outputs", "Response", script2);
25473
+ this._internal.responseFunc = compileCode(REST_RESPONSE_PARAMS, script2);
24716
25474
  } catch (e) {
24717
25475
  console.log(e);
24718
25476
  }
@@ -25702,656 +26460,13 @@ var require_lodash = __commonJS({
25702
26460
  }
25703
26461
  });
25704
26462
 
25705
- // ../noodl-runtime/src/utils.ts
25706
- var utils_exports = {};
25707
- __export(utils_exports, {
25708
- getAbsoluteUrl: () => getAbsoluteUrl,
25709
- logJavaScriptNodeError: () => logJavaScriptNodeError,
25710
- thrownMessage: () => thrownMessage
25711
- });
25712
- function getAbsoluteUrl(_url) {
25713
- const url = String(_url);
25714
- if (!url || url[0] === "/" || url.includes("://") || url.startsWith("data:")) {
25715
- return url;
25716
- }
25717
- return (Noodl.baseUrl || "/") + url;
25718
- }
25719
- function thrownMessage(error) {
25720
- if (error && error.message) return String(error.message);
25721
- try {
25722
- return String(error);
25723
- } catch {
25724
- return typeof error;
25725
- }
25726
- }
25727
- function logJavaScriptNodeError(error) {
25728
- const prefix = "Error in JS node run code.";
25729
- if (error === null || typeof error !== "object" && typeof error !== "function") {
25730
- console.log(prefix, thrownMessage(error));
25731
- return;
25732
- }
25733
- const proto = Object.getPrototypeOf(error);
25734
- const kind = proto && proto.constructor && proto.constructor.name ? proto.constructor.name : "Error";
25735
- console.log(prefix, kind + ": " + thrownMessage(error), error.stack);
25736
- }
25737
- var init_utils = __esm({
25738
- "../noodl-runtime/src/utils.ts"() {
25739
- }
25740
- });
25741
-
25742
- // ../noodl-runtime/src/componentwalk.ts
25743
- var componentwalk_exports = {};
25744
- __export(componentwalk_exports, {
25745
- COMPONENT_OBJECT_TYPES: () => COMPONENT_OBJECT_TYPES,
25746
- componentAncestorNames: () => componentAncestorNames,
25747
- componentAncestors: () => componentAncestors,
25748
- findAncestorWithComponentObject: () => findAncestorWithComponentObject,
25749
- findAncestorWithName: () => findAncestorWithName,
25750
- findAncestorWithNodeType: () => findAncestorWithNodeType,
25751
- findAncestorWithProperty: () => findAncestorWithProperty,
25752
- findComponentAncestor: () => findComponentAncestor,
25753
- parentComponentOf: () => parentComponentOf,
25754
- scopeChain: () => scopeChain,
25755
- scopeChainNames: () => scopeChainNames
25756
- });
25757
- function parentComponentOf(component) {
25758
- if (!component) return void 0;
25759
- let parent;
25760
- if (component.getRoots().length > 0) {
25761
- const root2 = component.getRoots()[0];
25762
- if (root2.getVisualParentNode) {
25763
- const visualParent = root2.getVisualParentNode();
25764
- if (visualParent) {
25765
- parent = visualParent.nodeScope.componentOwner;
25766
- }
25767
- } else if (root2.parentNodeScope) {
25768
- parent = component.parentNodeScope.componentOwner;
25769
- }
25770
- } else if (component.parentNodeScope) {
25771
- parent = component.parentNodeScope.componentOwner;
25772
- }
25773
- if (parent && parent.nodeScope && parent.nodeScope.componentOwner !== component) {
25774
- return parent;
25775
- }
25776
- return void 0;
25777
- }
25778
- function componentAncestors(component) {
25779
- const ancestors = [];
25780
- let current = component;
25781
- for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
25782
- const parent = parentComponentOf(current);
25783
- if (!parent) break;
25784
- ancestors.push(parent);
25785
- current = parent;
25786
- }
25787
- return ancestors;
25788
- }
25789
- function findComponentAncestor(component, predicate) {
25790
- let current = component;
25791
- for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
25792
- const parent = parentComponentOf(current);
25793
- if (!parent) return void 0;
25794
- if (predicate(parent)) return parent;
25795
- current = parent;
25796
- }
25797
- return void 0;
25798
- }
25799
- function findAncestorWithNodeType(component, types) {
25800
- return findComponentAncestor(
25801
- component,
25802
- (candidate) => types.some((type) => candidate.nodeScope.getNodesWithType(type).length > 0)
25803
- );
25804
- }
25805
- function findAncestorWithComponentObject(component) {
25806
- return findAncestorWithNodeType(component, COMPONENT_OBJECT_TYPES);
25807
- }
25808
- function findAncestorWithName(component, name2) {
25809
- return findComponentAncestor(component, (candidate) => candidate.name === name2);
25810
- }
25811
- function scopeChain(component) {
25812
- const chain2 = [];
25813
- let current = component;
25814
- for (let depth = 0; depth < MAX_WALK_DEPTH; depth++) {
25815
- if (!current) break;
25816
- chain2.push(current);
25817
- if (!current.parentNodeScope) break;
25818
- current = current.parentNodeScope.componentOwner;
25819
- }
25820
- return chain2;
25821
- }
25822
- function scopeChainNames(component) {
25823
- return scopeChain(component).map((entry) => entry.name);
25824
- }
25825
- function findAncestorWithProperty(component, property2) {
25826
- const chain2 = scopeChain(component);
25827
- for (let i2 = 0; i2 < chain2.length; i2++) {
25828
- if (chain2[i2][property2] !== void 0) return chain2[i2];
25829
- }
25830
- return void 0;
25831
- }
25832
- function componentAncestorNames(component) {
25833
- return componentAncestors(component).map((ancestor) => ancestor.name);
25834
- }
25835
- var MAX_WALK_DEPTH, COMPONENT_OBJECT_TYPES;
25836
- var init_componentwalk = __esm({
25837
- "../noodl-runtime/src/componentwalk.ts"() {
25838
- "use strict";
25839
- MAX_WALK_DEPTH = 1e3;
25840
- COMPONENT_OBJECT_TYPES = ["net.noodl.ComponentObject", "Component State"];
25841
- }
25842
- });
25843
-
25844
- // ../noodl-runtime/src/resolvedtarget.ts
25845
- function summariseTargets(labels) {
25846
- const distinct = [];
25847
- for (let i2 = 0; i2 < labels.length; i2++) {
25848
- const label = labels[i2];
25849
- if (label === void 0) continue;
25850
- if (distinct.indexOf(label) === -1) distinct.push(label);
25851
- }
25852
- if (distinct.length === 0) return void 0;
25853
- if (distinct.length === 1) return "\u2192 " + distinct[0];
25854
- const listed = distinct.slice(0, MAX_NAMES_LISTED).join(", ");
25855
- const rest2 = distinct.length - MAX_NAMES_LISTED;
25856
- return "\u2192 " + distinct.length + " targets: " + listed + (rest2 > 0 ? ", +" + rest2 : "");
25857
- }
25858
- var MAX_NAMES_LISTED, ResolvedTargetReporter;
25859
- var init_resolvedtarget = __esm({
25860
- "../noodl-runtime/src/resolvedtarget.ts"() {
25861
- "use strict";
25862
- MAX_NAMES_LISTED = 3;
25863
- ResolvedTargetReporter = class {
25864
- constructor() {
25865
- /** Weak, so a torn-down runtime's bookkeeping goes with it and needs no reset call. */
25866
- this._byContext = /* @__PURE__ */ new WeakMap();
25867
- }
25868
- /**
25869
- * Record what `node` bound to and push the summary to the editor.
25870
- *
25871
- * Safe to call every resolution; identical summaries are dropped rather than sent, so a
25872
- * node that re-resolves each frame costs one string comparison.
25873
- */
25874
- report(node, target) {
25875
- const state2 = this._stateFor(node);
25876
- if (!state2) return;
25877
- let instances = state2.byGraphNode.get(node.id);
25878
- if (!instances) {
25879
- instances = /* @__PURE__ */ new Map();
25880
- state2.byGraphNode.set(node.id, instances);
25881
- }
25882
- instances.set(node, target);
25883
- this._flush(node, state2, instances);
25884
- }
25885
- /** Drop an instance. Call from `_onNodeDeleted`, or this map is a leak. */
25886
- forget(node) {
25887
- const state2 = this._stateFor(node);
25888
- if (!state2) return;
25889
- const instances = state2.byGraphNode.get(node.id);
25890
- if (!instances) return;
25891
- instances.delete(node);
25892
- if (instances.size === 0) {
25893
- state2.byGraphNode.delete(node.id);
25894
- state2.lastSent.delete(node.id);
25895
- return;
25896
- }
25897
- this._flush(node, state2, instances);
25898
- }
25899
- _stateFor(node) {
25900
- const context = node.context;
25901
- if (!context) return void 0;
25902
- let state2 = this._byContext.get(context);
25903
- if (!state2) {
25904
- state2 = { byGraphNode: /* @__PURE__ */ new Map(), lastSent: /* @__PURE__ */ new Map() };
25905
- this._byContext.set(context, state2);
25906
- }
25907
- return state2;
25908
- }
25909
- _flush(node, state2, instances) {
25910
- const labels = [];
25911
- instances.forEach((label) => labels.push(label));
25912
- const summary = summariseTargets(labels);
25913
- if (state2.lastSent.has(node.id) && state2.lastSent.get(node.id) === summary) return;
25914
- state2.lastSent.set(node.id, summary);
25915
- const editorConnection = node.context && node.context.editorConnection;
25916
- if (!editorConnection || !editorConnection.isRunningLocally()) return;
25917
- if (typeof editorConnection.sendNodeSubLabel !== "function") return;
25918
- editorConnection.sendNodeSubLabel(node.id, summary);
25919
- }
25920
- };
25921
- }
25922
- });
25923
-
25924
- // ../noodl-runtime/src/foreachitem.ts
25925
- var foreachitem_exports = {};
25926
- __export(foreachitem_exports, {
25927
- forgetForEachItem: () => forgetForEachItem,
25928
- resolveForEachItem: () => resolveForEachItem
25929
- });
25930
- function resolveForEachItem(node, options = {}) {
25931
- const chain2 = scopeChain(node.nodeScope.componentOwner);
25932
- const wanted = options.target;
25933
- if (wanted) {
25934
- const named2 = firstNamed(chain2, wanted);
25935
- if (!named2) {
25936
- return miss(
25937
- node,
25938
- "repeater-item/target-not-found",
25939
- 'No component named "' + wanted + '" contains this node',
25940
- wanted,
25941
- { target: wanted, scope: scopeChainNames(node.nodeScope.componentOwner) }
25942
- );
25943
- }
25944
- if (named2[FOR_EACH_MODEL] === void 0) {
25945
- return miss(
25946
- node,
25947
- "repeater-item/target-has-no-item",
25948
- 'The component "' + wanted + '" has no current item \u2014 it is not used as a Repeater or Run Tasks template',
25949
- wanted,
25950
- { target: wanted }
25951
- );
25952
- }
25953
- return hit(node, named2);
25954
- }
25955
- const owner = firstWithItem(chain2);
25956
- if (!owner) {
25957
- return miss(
25958
- node,
25959
- "repeater-item/no-item-in-scope",
25960
- 'Id Source is set to "From repeater", but this node is not inside a Repeater or Run Tasks template',
25961
- void 0,
25962
- { scope: scopeChainNames(node.nodeScope.componentOwner) }
25963
- );
25964
- }
25965
- return hit(node, owner);
25966
- }
25967
- function forgetForEachItem(node) {
25968
- resolvedTargets.forget(node);
25969
- lastMissByNode.delete(node);
25970
- }
25971
- function firstNamed(chain2, name2) {
25972
- for (let i2 = 0; i2 < chain2.length; i2++) {
25973
- if (chain2[i2].name === name2) return chain2[i2];
25974
- }
25975
- return void 0;
25976
- }
25977
- function firstWithItem(chain2) {
25978
- for (let i2 = 0; i2 < chain2.length; i2++) {
25979
- if (chain2[i2][FOR_EACH_MODEL] !== void 0) return chain2[i2];
25980
- }
25981
- return void 0;
25982
- }
25983
- function hit(node, owner) {
25984
- lastMissByNode.delete(node);
25985
- resolvedTargets.report(node, owner.name);
25986
- return owner[FOR_EACH_MODEL];
25987
- }
25988
- function miss(node, code, message, target, detail) {
25989
- resolvedTargets.report(node, void 0);
25990
- const seen = code + "|" + (target || "");
25991
- if (lastMissByNode.get(node) !== seen) {
25992
- lastMissByNode.set(node, seen);
25993
- node.raiseRuntimeError(code, message, detail);
25994
- }
25995
- return void 0;
25996
- }
25997
- var FOR_EACH_MODEL, resolvedTargets, lastMissByNode;
25998
- var init_foreachitem = __esm({
25999
- "../noodl-runtime/src/foreachitem.ts"() {
26000
- "use strict";
26001
- init_componentwalk();
26002
- init_resolvedtarget();
26003
- FOR_EACH_MODEL = "_forEachModel";
26004
- resolvedTargets = new ResolvedTargetReporter();
26005
- lastMissByNode = /* @__PURE__ */ new WeakMap();
26006
- }
26007
- });
26008
-
26009
- // ../noodl-runtime/src/javascriptnodeparser.js
26010
- var require_javascriptnodeparser = __commonJS({
26011
- "../noodl-runtime/src/javascriptnodeparser.js"(exports2, module2) {
26012
- "use strict";
26013
- var Model28 = require_model2();
26014
- var { getAbsoluteUrl: getAbsoluteUrl2 } = (init_utils(), __toCommonJS(utils_exports));
26015
- var { findAncestorWithComponentObject: findAncestorWithComponentObject2 } = (init_componentwalk(), __toCommonJS(componentwalk_exports));
26016
- var { resolveForEachItem: resolveForEachItem2 } = (init_foreachitem(), __toCommonJS(foreachitem_exports));
26017
- var userFunctionsCache = {};
26018
- function JavascriptNodeParser4(code, options) {
26019
- this.inputs = {};
26020
- this.outputs = {};
26021
- this.error = void 0;
26022
- this.code = code;
26023
- const node = options ? options.node : void 0;
26024
- this._initializeAPIs();
26025
- var userCode = userFunctionsCache[code];
26026
- if (!userCode) {
26027
- try {
26028
- userCode = new Function(["define", "script", "Node", "Component"], JavascriptNodeParser4.getCodePrefix() + code);
26029
- userFunctionsCache[code] = userCode;
26030
- } catch (e) {
26031
- this.error = e.message;
26032
- console.error(e);
26033
- }
26034
- }
26035
- if (userCode) {
26036
- try {
26037
- userCode(
26038
- this.define.bind(this),
26039
- this.script.bind(this),
26040
- this.apis.Node,
26041
- node ? JavascriptNodeParser4.getComponentScopeForNode(node) : {}
26042
- );
26043
- this._afterSourced();
26044
- } catch (e) {
26045
- this.error = e.message;
26046
- console.error(e);
26047
- }
26048
- }
26049
- }
26050
- JavascriptNodeParser4.prototype.define = function(userObject) {
26051
- this.inputs = userObject.inputs || {};
26052
- this.outputs = userObject.outputs || {};
26053
- this.setup = userObject.setup;
26054
- this.change = userObject.run || userObject.change;
26055
- this.destroy = userObject.destroy;
26056
- this.definedObject = userObject;
26057
- };
26058
- function _scriptExtend(_this) {
26059
- var _extended = {
26060
- inputs: _this.inputs || {},
26061
- outputs: _this.outputs || {},
26062
- setup: function(inputs, outputs2) {
26063
- this.inputs = inputs;
26064
- this.outputs = outputs2;
26065
- this.setOutputs = function(states) {
26066
- for (var key3 in states) {
26067
- this.outputs[key3] = states[key3];
26068
- this.flagOutputDirty(key3);
26069
- }
26070
- };
26071
- if (_this.methods) {
26072
- for (var key2 in _this.methods) {
26073
- this[key2] = _this.methods[key2];
26074
- }
26075
- }
26076
- _this.setup && _this.setup.apply(this);
26077
- },
26078
- destroy: function(inputs, outputs2) {
26079
- this.inputs = inputs;
26080
- this.outputs = outputs2;
26081
- _this.destroy && _this.destroy.apply(this);
26082
- },
26083
- change: function(inputs, outputs2) {
26084
- this.inputs = inputs;
26085
- this.outputs = outputs2;
26086
- var old = this._oldInputs || {};
26087
- if (_this.changed) {
26088
- for (var key2 in inputs) {
26089
- if (inputs[key2] !== old[key2]) {
26090
- var changedFunction = _this.changed[key2];
26091
- if (typeof changedFunction === "function") changedFunction.apply(this, [inputs[key2], old[key2]]);
26092
- }
26093
- }
26094
- }
26095
- this._oldInputs = Object.assign({}, inputs);
26096
- }
26097
- };
26098
- if (_this.signals) {
26099
- for (var key in _this.signals) {
26100
- _extended[key] = _this.signals[key];
26101
- _extended.inputs[key] = "signal";
26102
- }
26103
- }
26104
- return _extended;
26105
- }
26106
- JavascriptNodeParser4.prototype.script = function(userObject) {
26107
- var _userObjectExtended = _scriptExtend(userObject);
26108
- this.inputs = _userObjectExtended.inputs || {};
26109
- this.outputs = _userObjectExtended.outputs || {};
26110
- this.setup = _userObjectExtended.setup;
26111
- this.change = _userObjectExtended.run || _userObjectExtended.change;
26112
- this.destroy = _userObjectExtended.destroy;
26113
- this.definedObject = _userObjectExtended;
26114
- };
26115
- JavascriptNodeParser4.prototype._initializeAPIs = function() {
26116
- this.apis = {
26117
- Node: {
26118
- Inputs: {},
26119
- Outputs: {},
26120
- Signals: {},
26121
- Setters: {}
26122
- }
26123
- };
26124
- };
26125
- JavascriptNodeParser4.prototype._afterSourced = function() {
26126
- if (this.definedObject !== void 0) return;
26127
- var _Node = this.apis.Node;
26128
- this.inputs = Object.assign({}, _Node.Inputs || {});
26129
- this.outputs = Object.assign({}, _Node.Outputs || {});
26130
- this.setup = function(inputs, outputs2) {
26131
- const _this = this;
26132
- _Node.setOutputs = function(_outputs) {
26133
- for (var key2 in _outputs) {
26134
- outputs2[key2] = _outputs[key2];
26135
- _this.flagOutputDirty(key2);
26136
- }
26137
- };
26138
- _Node.OnInit && _Node.OnInit.apply(this);
26139
- };
26140
- this.destroy = _Node.OnDestroy || this.destory;
26141
- this.change = (inputs, outputs2, changedInputs) => {
26142
- for (var key2 in changedInputs) {
26143
- if (typeof _Node.Setters[key2] === "function") {
26144
- _Node.Setters[key2](inputs[key2]);
26145
- }
26146
- }
26147
- if (typeof _Node.OnInputsChanged === "function") {
26148
- _Node.OnInputsChanged();
26149
- }
26150
- };
26151
- this.definedObject = {
26152
- inputs: this.inputs,
26153
- outputs: this.outputs,
26154
- setup: this.setup,
26155
- destroy: this.destroy,
26156
- change: this.change
26157
- };
26158
- if (_Node.Signals !== void 0) {
26159
- for (var key in _Node.Signals) {
26160
- if (typeof _Node.Signals[key] === "function") {
26161
- this.inputs[key] = "signal";
26162
- this.definedObject[key] = _Node.Signals[key];
26163
- }
26164
- }
26165
- }
26166
- };
26167
- JavascriptNodeParser4.createFromCode = function(code, options) {
26168
- return new JavascriptNodeParser4(code, options);
26169
- };
26170
- function failedParser(message) {
26171
- var parser = Object.create(JavascriptNodeParser4.prototype);
26172
- parser.inputs = {};
26173
- parser.outputs = {};
26174
- parser.error = message;
26175
- parser.code = void 0;
26176
- parser.apis = { Node: {} };
26177
- return parser;
26178
- }
26179
- JavascriptNodeParser4.createFromURL = function(url, callback, options) {
26180
- url = getAbsoluteUrl2(url);
26181
- var settled = false;
26182
- function settle(parser) {
26183
- if (settled) return;
26184
- settled = true;
26185
- callback(parser);
26186
- }
26187
- var xhr = new window.XMLHttpRequest();
26188
- xhr.open("GET", url, true);
26189
- xhr.onreadystatechange = function() {
26190
- if (this.readyState === 4 || this.readyState === XMLHttpRequest.DONE) {
26191
- if (this.status !== 0 && (this.status < 200 || this.status >= 300)) {
26192
- settle(failedParser('Could not load "' + url + '": the server answered ' + this.status));
26193
- return;
26194
- }
26195
- if (this.status === 0) {
26196
- settle(failedParser('Could not load "' + url + '": the request failed'));
26197
- return;
26198
- }
26199
- settle(new JavascriptNodeParser4(this.response, options));
26200
- }
26201
- };
26202
- xhr.onerror = function() {
26203
- settle(failedParser('Could not load "' + url + '": the request failed'));
26204
- };
26205
- xhr.send();
26206
- };
26207
- JavascriptNodeParser4.parseAndAddPortsFromScript = function(script2, ports, options) {
26208
- function _exists(port5) {
26209
- if (typeof port5 === "string") return ports.find((p) => p.name === port5) !== void 0;
26210
- else return ports.find((p) => p.name === port5.name && p.plug === port5.plug) !== void 0;
26211
- }
26212
- function _addPortsFromMatch(match, options2) {
26213
- if (match === void 0 || match === null) return;
26214
- const unique2 = {};
26215
- for (const _s of match) {
26216
- let name2 = _s[1];
26217
- if (name2 === void 0) continue;
26218
- unique2[name2] = true;
26219
- }
26220
- Object.keys(unique2).forEach((p) => {
26221
- if (_exists({
26222
- name: options2.prefix + p,
26223
- plug: options2.plug
26224
- }))
26225
- return;
26226
- ports.push({
26227
- name: options2.prefix + p,
26228
- displayName: p,
26229
- plug: options2.plug,
26230
- type: options2.type,
26231
- group: options2.group
26232
- });
26233
- });
26234
- }
26235
- if (!options.skipInputs) {
26236
- _addPortsFromMatch(script2.matchAll(/Inputs\.([A-Za-z0-9_]+)/g), {
26237
- type: options.inputType || "*",
26238
- plug: "input",
26239
- group: options.inputGroup || "Inputs",
26240
- prefix: options.inputPrefix || ""
26241
- });
26242
- _addPortsFromMatch(script2.matchAll(/Inputs\s*\[\s*(?:'|")(.*)(?:'|")\s*\]/g), {
26243
- type: options.inputType || "*",
26244
- plug: "inputs",
26245
- group: options.inputGroup || "Inputs",
26246
- prefix: options.inputPrefix || ""
26247
- });
26248
- }
26249
- if (!options.skipOutputs) {
26250
- if (!options.skipOutputSignals) {
26251
- _addPortsFromMatch(script2.matchAll(/Outputs\.([A-Za-z0-9]+)\s*\(\s*\)/g), {
26252
- type: "signal",
26253
- plug: "output",
26254
- group: "Outputs",
26255
- prefix: options.outputPrefix || ""
26256
- });
26257
- _addPortsFromMatch(script2.matchAll(/Outputs\s*\[\s*(?:'|")(.*)(?:'|")\s*\]\(\s*\)/g), {
26258
- type: "signal",
26259
- plug: "output",
26260
- group: "Outputs",
26261
- prefix: options.outputPrefix || ""
26262
- });
26263
- }
26264
- if (!options.skipRegularOutputs) {
26265
- _addPortsFromMatch(script2.matchAll(/Outputs\.([A-Za-z0-9_]+)/g), {
26266
- type: "*",
26267
- plug: "output",
26268
- group: "Outputs",
26269
- prefix: options.outputPrefix || ""
26270
- });
26271
- _addPortsFromMatch(script2.matchAll(/Outputs\s*\[\s*\"([^\"]*)\"\s*\]/g), {
26272
- type: "*",
26273
- plug: "output",
26274
- group: "Outputs",
26275
- prefix: options.outputPrefix || ""
26276
- });
26277
- }
26278
- }
26279
- };
26280
- JavascriptNodeParser4.prototype.getPorts = function() {
26281
- var ports = [];
26282
- var self2 = this;
26283
- Object.keys(this.inputs).forEach(function(name2) {
26284
- var inputPort2 = self2.inputs[name2];
26285
- var port5 = {
26286
- name: name2,
26287
- plug: "input"
26288
- };
26289
- if (typeof inputPort2 === "string") {
26290
- port5.type = {
26291
- name: inputPort2
26292
- };
26293
- port5.group = "Inputs";
26294
- } else {
26295
- for (var p in inputPort2) {
26296
- port5[p] = inputPort2[p];
26297
- }
26298
- }
26299
- ports.push(port5);
26300
- });
26301
- Object.keys(this.outputs).forEach(function(name2) {
26302
- ports.push({
26303
- name: name2,
26304
- type: {
26305
- name: self2.outputs[name2]
26306
- },
26307
- plug: "output",
26308
- group: "Outputs"
26309
- });
26310
- });
26311
- JavascriptNodeParser4.parseAndAddPortsFromScript(this.code, ports, {});
26312
- return ports;
26313
- };
26314
- var _componentScopes = {};
26315
- function _findParentComponentStateModelId(node) {
26316
- const parent = findAncestorWithComponentObject2(node.nodeScope.componentOwner);
26317
- if (!parent) return;
26318
- return "componentState" + parent.getInstanceId();
26319
- }
26320
- JavascriptNodeParser4.getComponentScopeForNode = function(node) {
26321
- const componentId = node.nodeScope.componentOwner.getInstanceId();
26322
- if (_componentScopes[componentId] === void 0) {
26323
- _componentScopes[componentId] = {};
26324
- const componentObject = (node.nodeScope.modelScope || Model28).get("componentState" + componentId);
26325
- _componentScopes[componentId].Object = componentObject;
26326
- }
26327
- const parentComponentObjectId = _findParentComponentStateModelId(node);
26328
- const parentComponentObject = parentComponentObjectId !== void 0 ? (node.nodeScope.modelScope || Model28).get(parentComponentObjectId) : void 0;
26329
- _componentScopes[componentId].ParentObject = parentComponentObject;
26330
- Object.defineProperty(_componentScopes[componentId], "RepeaterObject", {
26331
- configurable: true,
26332
- enumerable: true,
26333
- get: function() {
26334
- return resolveForEachItem2(node);
26335
- }
26336
- });
26337
- return _componentScopes[componentId];
26338
- };
26339
- JavascriptNodeParser4.getCodePrefix = function() {
26340
- return "const Script = (typeof Node !== 'undefined')?Node:undefined;\n";
26341
- };
26342
- JavascriptNodeParser4.createNoodlAPI = function() {
26343
- return typeof window !== "undefined" && window.Noodl !== void 0 ? window.Noodl : {};
26344
- };
26345
- module2.exports = JavascriptNodeParser4;
26346
- }
26347
- });
26348
-
26349
26463
  // ../noodl-runtime/src/nodes/std-library/expression.ts
26350
26464
  var require_expression = __commonJS({
26351
26465
  "../noodl-runtime/src/nodes/std-library/expression.ts"(exports2, module2) {
26352
26466
  "use strict";
26353
26467
  init_expression_ports();
26354
26468
  init_logic_search_tags();
26469
+ init_printedcode();
26355
26470
  init_outcome();
26356
26471
  init_run_on_value_change();
26357
26472
  var Node17 = require_node2();
@@ -26580,11 +26695,27 @@ var require_expression = __commonJS({
26580
26695
  const args = Object.keys(this._internal.scope);
26581
26696
  this._internal.compiledWith = args.slice();
26582
26697
  args.push("Noodl");
26698
+ const printed = findPrintedBody(expression, false);
26699
+ if (printed) {
26700
+ this._internal.compiledWith = printed.params.slice(0, -1);
26701
+ this._internal.compileError = void 0;
26702
+ return printed.fn;
26703
+ }
26704
+ if (hasPrintedCode()) {
26705
+ try {
26706
+ const fn = compileCode(args, expression);
26707
+ this._internal.compileError = void 0;
26708
+ return fn;
26709
+ } catch (e) {
26710
+ this._internal.compileError = e.message;
26711
+ return void 0;
26712
+ }
26713
+ }
26583
26714
  const key = expression + args.join(" ");
26584
26715
  if (compiledFunctionsCache2.hasOwnProperty(key) === false) {
26585
- args.push(expression);
26716
+ const params = args.slice();
26586
26717
  try {
26587
- compiledFunctionsCache2[key] = construct(Function, args);
26718
+ compiledFunctionsCache2[key] = compileCode(params, expression);
26588
26719
  this._internal.compileError = void 0;
26589
26720
  } catch (e) {
26590
26721
  this._internal.compileError = e.message;
@@ -26616,7 +26747,7 @@ var require_expression = __commonJS({
26616
26747
  description: "JavaScript expression whose value becomes Result. Every name it reads becomes an input port, except JavaScript's own (String, Number, JSON, Date, parseInt, Math and the rest), the Math shortcuts (round, min, pi\u2026) and keywords such as typeof; a port can never be called one of those, nor run, expression or evaluateAtLoad, which are this node's own inputs",
26617
26748
  set: function(value2) {
26618
26749
  const internal2 = this._internal;
26619
- internal2.currentExpression = functionPreamble + "return (" + value2 + ");";
26750
+ internal2.currentExpression = expressionNodeBody(value2);
26620
26751
  internal2.compiledFunction = void 0;
26621
26752
  const newInputs = expressionPorts(value2);
26622
26753
  internal2.referencedPorts = newInputs;
@@ -26815,17 +26946,7 @@ var require_expression = __commonJS({
26815
26946
  }
26816
26947
  }
26817
26948
  };
26818
- var functionPreamble = [
26819
- 'var min = Math.min, max = Math.max, cos = Math.cos, sin = Math.sin, tan = Math.tan, sqrt = Math.sqrt, pi = Math.PI, round = Math.round, floor = Math.floor, ceil = Math.ceil, abs = Math.abs, random = Math.random, pow = Math.pow, log = Math.log, exp = Math.exp;try { var NoodlContext = (typeof Noodl !== "undefined") ? Noodl : (typeof global !== "undefined" && global.Noodl) || {}; var Variables = NoodlContext.Variables || {}; var Objects = NoodlContext.Objects || {}; var Arrays = NoodlContext.Arrays || {};} catch (e) { var Variables = {}, Objects = {}, Arrays = {};}'
26820
- ].join("");
26821
26949
  var NOT_EVALUATED2 = {};
26822
- function construct(constructor, args) {
26823
- function F() {
26824
- return constructor.apply(this, args);
26825
- }
26826
- F.prototype = constructor.prototype;
26827
- return new F();
26828
- }
26829
26950
  var compiledFunctionsCache2 = {};
26830
26951
  function reservedNameMessage2(names2) {
26831
26952
  const list2 = names2.length > 1 ? names2.slice(0, -1).join(", ") + " and " + names2[names2.length - 1] : names2.join("");
@@ -26929,10 +27050,10 @@ function rawPositionFromStack(stack) {
26929
27050
  function stackLineOffset() {
26930
27051
  if (cachedOffset !== void 0) return cachedOffset;
26931
27052
  try {
26932
- const AsyncFunction = Object.getPrototypeOf(async function() {
27053
+ const AsyncFunction2 = Object.getPrototypeOf(async function() {
26933
27054
  }).constructor;
26934
27055
  let captured;
26935
- const probe = new AsyncFunction(
27056
+ const probe = new AsyncFunction2(
26936
27057
  "Inputs",
26937
27058
  "Outputs",
26938
27059
  "Noodl",
@@ -26987,12 +27108,12 @@ function undeclaredPortNameMessage(name2, side, isSignal = false) {
26987
27108
  function noOutputWrittenMessage(ports) {
26988
27109
  if (ports.length === 0) return "";
26989
27110
  const first2 = ports[0];
26990
- const named2 = ports.map((p) => '"' + p.label + '"').join(", ");
27111
+ const named3 = ports.map((p) => '"' + p.label + '"').join(", ");
26991
27112
  const which = ports.length === 1 ? "it" : '"' + first2.label + '"';
26992
27113
  if (first2.isSignal) {
26993
- return "The script ran but produced no output: " + named2 + " never fired. Fire " + which + " in the script with " + portUsage("Outputs", first2.label, true) + ".";
27114
+ return "The script ran but produced no output: " + named3 + " never fired. Fire " + which + " in the script with " + portUsage("Outputs", first2.label, true) + ".";
26994
27115
  }
26995
- return "The script ran but produced no output: " + named2 + " stayed empty. Write " + which + " in the script with " + portUsage("Outputs", first2.label, false) + " \u2014 assigning to a plain variable of the same name does not reach the port.";
27116
+ return "The script ran but produced no output: " + named3 + " stayed empty. Write " + which + " in the script with " + portUsage("Outputs", first2.label, false) + " \u2014 assigning to a plain variable of the same name does not reach the port.";
26996
27117
  }
26997
27118
  function proplistLabels(model2, parameter) {
26998
27119
  const rows = model2 && model2.parameters && model2.parameters[parameter];
@@ -27196,6 +27317,7 @@ var require_simplejavascript = __commonJS({
27196
27317
  init_scriptfiles();
27197
27318
  init_function_ports();
27198
27319
  init_tracecause();
27320
+ init_printedcode();
27199
27321
  var Node17 = require_node2();
27200
27322
  var JavascriptNodeParser4 = require_javascriptnodeparser();
27201
27323
  var { logJavaScriptNodeError: logJavaScriptNodeError2, thrownMessage: thrownMessage3 } = (init_utils(), __toCommonJS(utils_exports));
@@ -27722,16 +27844,7 @@ var require_simplejavascript = __commonJS({
27722
27844
  parseScript: function(script2) {
27723
27845
  let func;
27724
27846
  try {
27725
- const AsyncFunction = Object.getPrototypeOf(async function() {
27726
- }).constructor;
27727
- func = new AsyncFunction(
27728
- "Inputs",
27729
- "Outputs",
27730
- "Noodl",
27731
- "Component",
27732
- "Scripts",
27733
- JavascriptNodeParser4.getCodePrefix() + script2
27734
- );
27847
+ func = compileCode(FUNCTION_NODE_PARAMS, functionNodeBody(script2), { async: true });
27735
27848
  this._internal.parseError = void 0;
27736
27849
  this._internal.lastReportedError = void 0;
27737
27850
  } catch (e) {
@@ -27799,9 +27912,9 @@ var require_simplejavascript = __commonJS({
27799
27912
  return;
27800
27913
  }
27801
27914
  try {
27802
- const AsyncFunction = Object.getPrototypeOf(async function() {
27915
+ const AsyncFunction2 = Object.getPrototypeOf(async function() {
27803
27916
  }).constructor;
27804
- new AsyncFunction("Inputs", "Outputs", "Noodl", "Component", script2);
27917
+ new AsyncFunction2("Inputs", "Outputs", "Noodl", "Component", script2);
27805
27918
  context.editorConnection.clearWarning(node.component.name, node.id, "js-function-parse-waring");
27806
27919
  } catch (e) {
27807
27920
  context.editorConnection.sendWarning(node.component.name, node.id, "js-function-parse-waring", {
@@ -28304,6 +28417,7 @@ var require_logic_builder = __commonJS({
28304
28417
  init_logic_builder_io2();
28305
28418
  init_logic_builder_probe();
28306
28419
  init_logic_search_tags();
28420
+ init_printedcode();
28307
28421
  init_outcome();
28308
28422
  var EdgeTriggeredInput7 = require_edgetriggeredinput();
28309
28423
  var LogicBuilderNode = {
@@ -28658,47 +28772,49 @@ var require_logic_builder = __commonJS({
28658
28772
  return null;
28659
28773
  }
28660
28774
  try {
28661
- const fn = new Function(
28662
- "Inputs",
28663
- "Outputs",
28664
- "Noodl",
28665
- "Variables",
28666
- "Objects",
28667
- "Arrays",
28668
- "sendSignalOnOutput",
28669
- "__triggerSignal__",
28670
- /**
28671
- * LGC-003 §1 — the ninth and tenth parameters, and the reason there is only ever one
28672
- * generated string.
28673
- *
28674
- * The editor emits `__p("<blockId>", …)` around every value block and `__s("<blockId>")`
28675
- * before every statement, always — there is no debug build and no release build, so
28676
- * there is no class of defect that appears only when nobody is watching. What changes
28677
- * is which functions land here: the shared identity pair, or a recorder.
28678
- *
28679
- * ⚠️ **Declared unconditionally, including for code generated before this existed.**
28680
- * A `generatedCode` string saved by an older editor mentions neither name, and an
28681
- * unused parameter costs nothing — whereas making the list conditional on the code
28682
- * would put a `code.indexOf('__p')` on the compile path and give the runtime two
28683
- * shapes of compiled function to reason about.
28684
- */
28685
- "__p",
28686
- "__s",
28687
- /**
28688
- * The eleventh parameter, and the only one that shadows a global rather than adding a
28689
- * name (FIX-004 redaction ruling b).
28690
- *
28691
- * ⚠️ **Order is the contract.** This list and the argument list in `_executeLogic` are
28692
- * positional, so a parameter added here and not there — or added in a different place —
28693
- * silently shifts every argument after it. `__triggerSignal__` was already once built
28694
- * and then not passed, which read as `undefined` inside every block program ever run.
28695
- * A spec asserts this node's parameter names in order for that reason.
28696
- *
28697
- * Declared unconditionally, exactly as `__p`/`__s` are: code generated before this
28698
- * existed says `console.log`, which is the whole point, and code that never mentions
28699
- * `console` pays one unused parameter.
28700
- */
28701
- "console",
28775
+ const fn = compileCode(
28776
+ [
28777
+ "Inputs",
28778
+ "Outputs",
28779
+ "Noodl",
28780
+ "Variables",
28781
+ "Objects",
28782
+ "Arrays",
28783
+ "sendSignalOnOutput",
28784
+ "__triggerSignal__",
28785
+ /**
28786
+ * LGC-003 §1 — the ninth and tenth parameters, and the reason there is only ever one
28787
+ * generated string.
28788
+ *
28789
+ * The editor emits `__p("<blockId>", …)` around every value block and `__s("<blockId>")`
28790
+ * before every statement, always — there is no debug build and no release build, so
28791
+ * there is no class of defect that appears only when nobody is watching. What changes
28792
+ * is which functions land here: the shared identity pair, or a recorder.
28793
+ *
28794
+ * ⚠️ **Declared unconditionally, including for code generated before this existed.**
28795
+ * A `generatedCode` string saved by an older editor mentions neither name, and an
28796
+ * unused parameter costs nothing — whereas making the list conditional on the code
28797
+ * would put a `code.indexOf('__p')` on the compile path and give the runtime two
28798
+ * shapes of compiled function to reason about.
28799
+ */
28800
+ "__p",
28801
+ "__s",
28802
+ /**
28803
+ * The eleventh parameter, and the only one that shadows a global rather than adding a
28804
+ * name (FIX-004 redaction ruling b).
28805
+ *
28806
+ * ⚠️ **Order is the contract.** This list and the argument list in `_executeLogic` are
28807
+ * positional, so a parameter added here and not there — or added in a different place —
28808
+ * silently shifts every argument after it. `__triggerSignal__` was already once built
28809
+ * and then not passed, which read as `undefined` inside every block program ever run.
28810
+ * A spec asserts this node's parameter names in order for that reason.
28811
+ *
28812
+ * Declared unconditionally, exactly as `__p`/`__s` are: code generated before this
28813
+ * existed says `console.log`, which is the whole point, and code that never mentions
28814
+ * `console` pays one unused parameter.
28815
+ */
28816
+ "console"
28817
+ ],
28702
28818
  code
28703
28819
  );
28704
28820
  return fn;
@@ -30148,9 +30264,9 @@ var init_SseConnectionPool = __esm({
30148
30264
  // ../noodl-runtime/src/api/backends/realtime/SseTransport.ts
30149
30265
  function entryIsAbout(entry, collection) {
30150
30266
  if (!entry || typeof entry !== "object") return true;
30151
- const named2 = entry.collection;
30152
- if (typeof named2 !== "string") return true;
30153
- return named2 === collection;
30267
+ const named3 = entry.collection;
30268
+ if (typeof named3 !== "string") return true;
30269
+ return named3 === collection;
30154
30270
  }
30155
30271
  var NODEGX_SSE, POCKETBASE_SSE, SseTransport;
30156
30272
  var init_SseTransport = __esm({
@@ -30809,6 +30925,19 @@ function recordFieldPorts(ctx, options) {
30809
30925
  }
30810
30926
  return ports;
30811
30927
  }
30928
+ function recordBuiltInDatePorts(ctx, existingPorts, options = {}) {
30929
+ if (!ctx.selectedCollection || !isParseWireContext(ctx)) return [];
30930
+ const have = new Set(existingPorts.map((port5) => port5.name));
30931
+ const ports = [];
30932
+ for (const field2 of RECORD_BUILT_IN_DATES) {
30933
+ if (have.has(`prop-${field2}`)) continue;
30934
+ ports.push({ name: `prop-${field2}`, displayName: field2, type: { name: "date" }, plug: "output", group: "Properties" });
30935
+ if (options.includeChangedSignals && !have.has(`changed-${field2}`)) {
30936
+ ports.push({ name: `changed-${field2}`, displayName: `${field2} Changed`, type: "signal", plug: "output", group: "Events" });
30937
+ }
30938
+ }
30939
+ return ports;
30940
+ }
30812
30941
  function recordPortType(field2) {
30813
30942
  if (field2.nativeType && Object.prototype.hasOwnProperty.call(PARSE_PORT_TYPES, field2.nativeType)) {
30814
30943
  return { name: PARSE_PORT_TYPES[field2.nativeType] };
@@ -30919,7 +31048,7 @@ function parseTypeNameFor(field2) {
30919
31048
  function recordFilterBackendType(ctx, fallback) {
30920
31049
  return ctx.backendType || fallback;
30921
31050
  }
30922
- var PARSE_PORT_TYPES, PARSE_SYSTEM_CLASSES;
31051
+ var PARSE_PORT_TYPES, PARSE_SYSTEM_CLASSES, RECORD_BUILT_IN_DATES;
30923
31052
  var init_record_ports = __esm({
30924
31053
  "../noodl-runtime/src/nodes/std-library/data/record-ports.ts"() {
30925
31054
  init_resolveBackend_pure();
@@ -30934,6 +31063,7 @@ var init_record_ports = __esm({
30934
31063
  { label: "User", value: "_User" },
30935
31064
  { label: "Role", value: "_Role" }
30936
31065
  ]);
31066
+ RECORD_BUILT_IN_DATES = Object.freeze(["createdAt", "updatedAt"]);
30937
31067
  }
30938
31068
  });
30939
31069
 
@@ -31233,8 +31363,8 @@ function relationsFromDirectus(rows) {
31233
31363
  function relationsFromPostgrestSpec(spec) {
31234
31364
  const definitions = spec?.definitions ?? {};
31235
31365
  const result2 = [];
31236
- const analyse = (table) => {
31237
- const properties2 = definitions[table]?.properties ?? {};
31366
+ const analyse = (table2) => {
31367
+ const properties2 = definitions[table2]?.properties ?? {};
31238
31368
  const foreignKeys = [];
31239
31369
  let primaryKeyCount = 0;
31240
31370
  for (const [column, definition4] of Object.entries(properties2)) {
@@ -31246,8 +31376,8 @@ function relationsFromPostgrestSpec(spec) {
31246
31376
  }
31247
31377
  return { foreignKeys, primaryKeyCount };
31248
31378
  };
31249
- for (const table of Object.keys(definitions)) {
31250
- const { foreignKeys, primaryKeyCount } = analyse(table);
31379
+ for (const table2 of Object.keys(definitions)) {
31380
+ const { foreignKeys, primaryKeyCount } = analyse(table2);
31251
31381
  const isJunction = foreignKeys.length === 2 && primaryKeyCount === 2 && foreignKeys.every((fk) => fk.primaryKey);
31252
31382
  if (isJunction) {
31253
31383
  const [left, right] = foreignKeys;
@@ -31264,7 +31394,7 @@ function relationsFromPostgrestSpec(spec) {
31264
31394
  cardinality: "many",
31265
31395
  write: {
31266
31396
  kind: "junction",
31267
- collection: table,
31397
+ collection: table2,
31268
31398
  sourceField: near.column,
31269
31399
  targetField: far.column,
31270
31400
  // The pair *is* the primary key, so a duplicate is a `23505` and
@@ -31278,7 +31408,7 @@ function relationsFromPostgrestSpec(spec) {
31278
31408
  }
31279
31409
  for (const fk of foreignKeys) {
31280
31410
  result2.push({
31281
- collection: table,
31411
+ collection: table2,
31282
31412
  field: fk.column,
31283
31413
  target: fk.target,
31284
31414
  cardinality: "one",
@@ -31286,8 +31416,8 @@ function relationsFromPostgrestSpec(spec) {
31286
31416
  });
31287
31417
  result2.push({
31288
31418
  collection: fk.target,
31289
- field: table,
31290
- target: table,
31419
+ field: table2,
31420
+ target: table2,
31291
31421
  cardinality: "many",
31292
31422
  write: { kind: "foreignKey", field: fk.column, on: "target" }
31293
31423
  });
@@ -31560,11 +31690,11 @@ var init_filter = __esm({
31560
31690
 
31561
31691
  // ../nodegx-backend-contract/src/descriptors/helpers.ts
31562
31692
  function filterTable(fallback, overrides) {
31563
- const table = {};
31693
+ const table2 = {};
31564
31694
  for (const operator of FILTER_OPERATORS) {
31565
- table[operator] = overrides[operator] ?? fallback;
31695
+ table2[operator] = overrides[operator] ?? fallback;
31566
31696
  }
31567
- return Object.freeze(table);
31697
+ return Object.freeze(table2);
31568
31698
  }
31569
31699
  var supported, unsupported, degraded, conditional;
31570
31700
  var init_helpers = __esm({
@@ -33060,12 +33190,12 @@ var init_operational = __esm({
33060
33190
  });
33061
33191
 
33062
33192
  // ../nodegx-backend-contract/src/targetGoes.ts
33063
- function whenTargetGoesProblems(table, columns) {
33193
+ function whenTargetGoesProblems(table2, columns) {
33064
33194
  const out = [];
33065
33195
  for (const col of columns) {
33066
33196
  const rule = col.whenTargetGoes;
33067
33197
  if (rule === void 0) continue;
33068
- const at = `"${table}.${col.name}"`;
33198
+ const at = `"${table2}.${col.name}"`;
33069
33199
  if (typeof rule !== "string" || !WHEN_TARGET_GOES.includes(rule)) {
33070
33200
  out.push(`${at} says "${String(rule)}" for when what it points at goes; it must be one of ${WHEN_TARGET_GOES.join(", ")}.`);
33071
33201
  } else if (col.type !== "Pointer") {
@@ -33080,12 +33210,12 @@ function whenTargetGoesProblems(table, columns) {
33080
33210
  }
33081
33211
  function rulesByTarget(schema) {
33082
33212
  const out = /* @__PURE__ */ new Map();
33083
- for (const table of schema.listTables()) {
33084
- for (const col of schema.getTableSchema(table)?.columns || []) {
33213
+ for (const table2 of schema.listTables()) {
33214
+ for (const col of schema.getTableSchema(table2)?.columns || []) {
33085
33215
  const rule = col.whenTargetGoes;
33086
33216
  if (col.type !== "Pointer" || !col.targetClass || !rule || !WHEN_TARGET_GOES.includes(rule)) continue;
33087
33217
  const list2 = out.get(col.targetClass) || [];
33088
- list2.push({ collection: table, field: col.name, rule });
33218
+ list2.push({ collection: table2, field: col.name, rule });
33089
33219
  out.set(col.targetClass, list2);
33090
33220
  }
33091
33221
  }
@@ -33093,18 +33223,18 @@ function rulesByTarget(schema) {
33093
33223
  }
33094
33224
  function relations(schema) {
33095
33225
  const out = [];
33096
- for (const table of schema.listTables())
33097
- for (const col of schema.getTableSchema(table)?.columns || []) if (col.type === "Relation") out.push([table, col.name, col.targetClass || ""]);
33226
+ for (const table2 of schema.listTables())
33227
+ for (const col of schema.getTableSchema(table2)?.columns || []) if (col.type === "Relation") out.push([table2, col.name, col.targetClass || ""]);
33098
33228
  return out;
33099
33229
  }
33100
33230
  function pairsOf(rels, schema, collection, objectId) {
33101
33231
  const out = [];
33102
- for (const [table, field2, target] of rels) {
33103
- if (table === collection) {
33104
- const ids = schema.getRelatedIds(table, objectId, field2);
33105
- for (const relatedId of Array.isArray(ids) ? ids : []) out.push({ collection: table, objectId, field: field2, relatedId: String(relatedId) });
33232
+ for (const [table2, field2, target] of rels) {
33233
+ if (table2 === collection) {
33234
+ const ids = schema.getRelatedIds(table2, objectId, field2);
33235
+ for (const relatedId of Array.isArray(ids) ? ids : []) out.push({ collection: table2, objectId, field: field2, relatedId: String(relatedId) });
33106
33236
  }
33107
- if (target === collection) for (const owner of schema.getRelationOwners(table, field2, objectId)) out.push({ collection: table, objectId: owner, field: field2, relatedId: objectId });
33237
+ if (target === collection) for (const owner of schema.getRelationOwners(table2, field2, objectId)) out.push({ collection: table2, objectId: owner, field: field2, relatedId: objectId });
33108
33238
  }
33109
33239
  return out;
33110
33240
  }
@@ -33119,7 +33249,7 @@ async function linkedIds(ctx, collection, field2, id) {
33119
33249
  async function planDelete(ctx, collection, objectId) {
33120
33250
  const rules2 = rulesByTarget(ctx.schema);
33121
33251
  const rels = relations(ctx.schema);
33122
- if (!rules2.has(collection) && !rels.some(([table, , target]) => table === collection || target === collection)) return null;
33252
+ if (!rules2.has(collection) && !rels.some(([table2, , target]) => table2 === collection || target === collection)) return null;
33123
33253
  if (await ctx.count(collection, { objectId }) === 0) return null;
33124
33254
  const key = (c, id) => `${c}\0${id}`;
33125
33255
  const gone = [{ collection, objectId }];
@@ -33240,9 +33370,9 @@ function idOf(v) {
33240
33370
  if (typeof v === "string" && v) return v;
33241
33371
  return void 0;
33242
33372
  }
33243
- function targetOf(ctx, table, field2) {
33244
- const col = ctx.schema.getTableSchema(table)?.columns?.find((c) => c.name === field2);
33245
- if (!col?.targetClass) throw new Error(`${table}.${field2} is not a link the schema knows the target of`);
33373
+ function targetOf(ctx, table2, field2) {
33374
+ const col = ctx.schema.getTableSchema(table2)?.columns?.find((c) => c.name === field2);
33375
+ if (!col?.targetClass) throw new Error(`${table2}.${field2} is not a link the schema knows the target of`);
33246
33376
  return col.targetClass;
33247
33377
  }
33248
33378
  async function dryRunMigration(ctx, plan) {
@@ -33937,7 +34067,8 @@ var init_ParseWireAdapter = __esm({
33937
34067
  runId !== void 0 ? { "X-NodeGX-Run": runId } : {},
33938
34068
  options.headers || {}
33939
34069
  );
33940
- fetch(endpoint + path10, {
34070
+ const send = typeof _noodl_cloudservices !== "undefined" && _noodl_cloudservices.fetch ? _noodl_cloudservices.fetch : fetch;
34071
+ send(endpoint + path10, {
33941
34072
  method: options.method || "GET",
33942
34073
  headers,
33943
34074
  body: JSON.stringify(options.content)
@@ -33992,8 +34123,9 @@ var init_ParseWireAdapter = __esm({
33992
34123
  // P99 HLT-023: pass the server's words on, as `fetch` and the rest do. Dropped here, a
33993
34124
  // refusal that names its cause (the per-run ceiling, a 429 with its class) reached the
33994
34125
  // function as "Failed to query."
33995
- error: function(res) {
33996
- options.error(res && res.error);
34126
+ // P115-HST006-STALEROWS: and the status, so a reader can tell a refusal (403) from a blip.
34127
+ error: function(res, status) {
34128
+ options.error(res && res.error, status);
33997
34129
  }
33998
34130
  });
33999
34131
  }
@@ -35272,8 +35404,8 @@ function savedItemToNeutral(item, resolve5, options) {
35272
35404
  if (isSavedGroup(item)) return savedFilterToNeutral(item, resolve5, options);
35273
35405
  const condition = item;
35274
35406
  const isConnected = condition.valueSource === "connected" && !!condition.valuePortName;
35275
- const resolved2 = isConnected && resolve5 ? resolve5(condition.valuePortName) : void 0;
35276
- const value2 = isConnected ? resolved2 !== void 0 || options.dropUnresolvedConnected ? resolved2 : condition.value : condition.value;
35407
+ const resolved3 = isConnected && resolve5 ? resolve5(condition.valuePortName) : void 0;
35408
+ const value2 = isConnected ? resolved3 !== void 0 || options.dropUnresolvedConnected ? resolved3 : condition.value : condition.value;
35277
35409
  if (condition.kind === "relation") {
35278
35410
  if (value2 === void 0 || value2 === null || value2 === "") return null;
35279
35411
  return {
@@ -37609,7 +37741,8 @@ var init_RestDataAdapter = __esm({
37609
37741
  const total = options.count ? readTotalCount(profile, body, headers, rows.length) : void 0;
37610
37742
  options.success(records, total);
37611
37743
  },
37612
- fail: (message) => options.error(message)
37744
+ fail: (message, status) => options.error(message, status)
37745
+ // P115-HST006-STALEROWS: a refusal is told apart
37613
37746
  }
37614
37747
  );
37615
37748
  }
@@ -39158,8 +39291,19 @@ var require_cloudstore = __commonJS({
39158
39291
  }
39159
39292
  return obj;
39160
39293
  }
39294
+ function _schemaOf(collectionName2) {
39295
+ const collection = collectionName2 !== void 0 ? CloudStore7._collections[collectionName2] : void 0;
39296
+ if (!collection) return void 0;
39297
+ if (collection.schema) return collection.schema;
39298
+ if (!Array.isArray(collection.columns)) return void 0;
39299
+ const properties2 = {};
39300
+ for (const column of collection.columns) {
39301
+ if (column && column.name) properties2[column.name] = { type: column.type, targetClass: column.targetClass };
39302
+ }
39303
+ return { properties: properties2 };
39304
+ }
39161
39305
  function _serializeObject(data, collectionName2, modelScope) {
39162
- if (CloudStore7._collections[collectionName2]) var schema = CloudStore7._collections[collectionName2].schema;
39306
+ var schema = _schemaOf(collectionName2);
39163
39307
  for (var key in data) {
39164
39308
  var _type = schema && schema.properties && schema.properties[key] ? schema.properties[key].type : void 0;
39165
39309
  if (data[key] === void 0 || data[key] === null) {
@@ -39244,14 +39388,14 @@ var require_cloudstore = __commonJS({
39244
39388
  function _fromJSON(item, collectionName2, modelScope) {
39245
39389
  const m = (modelScope || Model28).get(item.objectId);
39246
39390
  m._class = collectionName2;
39247
- if (collectionName2 !== void 0 && CloudStore7._collections[collectionName2] !== void 0)
39248
- var schema = CloudStore7._collections[collectionName2].schema;
39391
+ var schema = _schemaOf(collectionName2);
39249
39392
  for (var key in item) {
39250
39393
  if (key === "objectId" || key === "ACL") continue;
39251
39394
  var _type = schema && schema.properties && schema.properties[key] ? schema.properties[key].type : void 0;
39252
39395
  if (_type === void 0 && item[key] && item[key].__type === "Pointer" && item[key].objectId !== void 0) {
39253
39396
  _type = "Pointer";
39254
39397
  }
39398
+ if (_type === void 0 && (key === "createdAt" || key === "updatedAt")) _type = "Date";
39255
39399
  const value2 = _deserializeJSON(item[key], _type, modelScope);
39256
39400
  if (Array.isArray(value2) && sameList2(m.get(key), value2)) continue;
39257
39401
  m.set(key, value2);
@@ -39468,8 +39612,19 @@ function convertVisualFilter(query2, options) {
39468
39612
  });
39469
39613
  return Object.keys(where2).length === 0 ? void 0 : where2;
39470
39614
  }
39615
+ function instantOf(operand) {
39616
+ let at;
39617
+ if (operand instanceof Date) at = operand.getTime();
39618
+ else if (operand && operand.__type === "Date" && typeof operand.iso === "string") at = Date.parse(operand.iso);
39619
+ else if (typeof operand === "string") at = Date.parse(operand);
39620
+ return at === void 0 || Number.isNaN(at) ? void 0 : at;
39621
+ }
39471
39622
  function matchesOperator(value2, op, condition) {
39472
39623
  const operand = condition[op];
39624
+ if (value2 instanceof Date && Object.prototype.hasOwnProperty.call(DATE_COMPARISONS, op)) {
39625
+ const at = instantOf(operand);
39626
+ if (at !== void 0) return DATE_COMPARISONS[op](value2.getTime(), at);
39627
+ }
39473
39628
  switch (op) {
39474
39629
  case "$eq":
39475
39630
  return operand && operand.__type === "Pointer" ? value2 === operand.objectId : value2 == operand;
@@ -39548,8 +39703,8 @@ function convertVisualSorting(sorting) {
39548
39703
  }
39549
39704
  function convertFilterOp(filter2, options) {
39550
39705
  try {
39551
- const resolved2 = resolveRelatedClasses(filter2, options.modelScope);
39552
- return toParseWhere(resolved2, {
39706
+ const resolved3 = resolveRelatedClasses(filter2, options.modelScope);
39707
+ return toParseWhere(resolved3, {
39553
39708
  backend: backendType(),
39554
39709
  schema: schemaFor(options.collectionName)
39555
39710
  });
@@ -39561,13 +39716,21 @@ function convertFilterOp(filter2, options) {
39561
39716
  throw e;
39562
39717
  }
39563
39718
  }
39564
- var CloudStore, ModelImport2, Model5;
39719
+ var CloudStore, ModelImport2, Model5, DATE_COMPARISONS;
39565
39720
  var init_queryutils = __esm({
39566
39721
  "../noodl-runtime/src/api/queryutils.ts"() {
39567
39722
  init_translators2();
39568
39723
  CloudStore = require_cloudstore();
39569
39724
  ModelImport2 = require_model2();
39570
39725
  Model5 = ModelImport2;
39726
+ DATE_COMPARISONS = {
39727
+ $eq: (a, b) => a === b,
39728
+ $ne: (a, b) => a !== b,
39729
+ $lt: (a, b) => a < b,
39730
+ $lte: (a, b) => a <= b,
39731
+ $gt: (a, b) => a > b,
39732
+ $gte: (a, b) => a >= b
39733
+ };
39571
39734
  }
39572
39735
  });
39573
39736
 
@@ -40148,8 +40311,9 @@ var require_dbcollectionnode2 = __commonJS({
40148
40311
  this.setCollection(_c);
40149
40312
  this.sendSignalOnOutput("fetched");
40150
40313
  },
40151
- error: (err) => {
40152
- if (this._internal.collection === void 0) this.setCollection(_c);
40314
+ error: (err, status) => {
40315
+ const refused = status === 401 || status === 403;
40316
+ if (refused || this._internal.collection === void 0) this.setCollection(_c);
40153
40317
  this.setError(err || "Failed to fetch.");
40154
40318
  }
40155
40319
  });
@@ -40973,7 +41137,9 @@ var require_dbmodelnode2 = __commonJS({
40973
41137
  includeChangedSignals: true
40974
41138
  }) : [];
40975
41139
  ports.push(...fieldPorts);
40976
- ports.push(...recordWiredFieldPorts(node, fieldPorts, { plug: "output" }));
41140
+ const datePorts = recordBuiltInDatePorts(ctx, fieldPorts, { includeChangedSignals: true });
41141
+ ports.push(...datePorts);
41142
+ ports.push(...recordWiredFieldPorts(node, [...fieldPorts, ...datePorts], { plug: "output" }));
40977
41143
  sendSchemaPorts(editorConnection, node.id, ports, { staticPorts: staticPortNames(ModelNodeDefinition3) });
40978
41144
  }
40979
41145
  var DbModelNodeModule = {
@@ -45169,6 +45335,7 @@ var require_mapcollectionnode = __commonJS({
45169
45335
  "../noodl-runtime/src/nodes/std-library/data/mapcollectionnode.ts"(exports2, module2) {
45170
45336
  "use strict";
45171
45337
  init_outcome();
45338
+ init_printedcode();
45172
45339
  init_itemsinput();
45173
45340
  var Node17 = require_node2();
45174
45341
  var Collection5 = require_collection();
@@ -45287,7 +45454,7 @@ var require_mapcollectionnode = __commonJS({
45287
45454
  compileMapScript: function(code) {
45288
45455
  this._internal.mapCode = code;
45289
45456
  try {
45290
- this._internal.mapFunc = new Function("map", "object", code);
45457
+ this._internal.mapFunc = compileCode(MAP_COLLECTION_PARAMS, code);
45291
45458
  } catch (e) {
45292
45459
  this._internal.mapFunc = void 0;
45293
45460
  this._internal.mapCompileError = e.message || String(e);
@@ -47774,12 +47941,12 @@ var require_datetostring = __commonJS({
47774
47941
  if (rendered2.indexOf(needle) === -1) return;
47775
47942
  rendered2 = rendered2.split(needle).join(render2());
47776
47943
  };
47777
- const named2 = (options) => new Intl.DateTimeFormat(locale, zone ? { ...options, timeZone: zone } : options).format(t);
47944
+ const named3 = (options) => new Intl.DateTimeFormat(locale, zone ? { ...options, timeZone: zone } : options).format(t);
47778
47945
  const hours12 = (fields.hours + 11) % 12 + 1;
47779
47946
  const meridiem = fields.hours < 12 ? "am" : "pm";
47780
- substitute("dayName", () => named2({ weekday: "long" }));
47781
- substitute("dayShort", () => named2({ weekday: "short" }));
47782
- substitute("monthName", () => named2({ month: "long" }));
47947
+ substitute("dayName", () => named3({ weekday: "long" }));
47948
+ substitute("dayShort", () => named3({ weekday: "short" }));
47949
+ substitute("monthName", () => named3({ month: "long" }));
47783
47950
  substitute("hours12", () => ("0" + hours12).slice(-2));
47784
47951
  substitute("h12", () => String(hours12));
47785
47952
  substitute("ampm", () => meridiem);
@@ -50467,9 +50634,9 @@ var init_EntityDecoder = __esm({
50467
50634
  replacement = ncrResult;
50468
50635
  tier = LIMIT_TIER_BASE;
50469
50636
  } else {
50470
- const resolved2 = this._resolveName(token);
50471
- replacement = resolved2?.value;
50472
- tier = resolved2?.tier;
50637
+ const resolved3 = this._resolveName(token);
50638
+ replacement = resolved3?.value;
50639
+ tier = resolved3?.tier;
50473
50640
  }
50474
50641
  if (replacement === void 0) {
50475
50642
  i2++;
@@ -51147,7 +51314,7 @@ var init_DocTypeReader = __esm({
51147
51314
  });
51148
51315
 
51149
51316
  // ../../node_modules/anynum/digitTable.js
51150
- var SCRIPT_ZEROS, NOT_DIGIT, HIGH_MAP, LOW_MAX, LOW_MIN, TABLE_OFFSET, TABLE_SIZE, TABLE;
51317
+ var SCRIPT_ZEROS, NOT_DIGIT, HIGH_MAP, LOW_MAX, LOW_MIN, TABLE_OFFSET, TABLE_SIZE, TABLE2;
51151
51318
  var init_digitTable = __esm({
51152
51319
  "../../node_modules/anynum/digitTable.js"() {
51153
51320
  SCRIPT_ZEROS = [
@@ -51287,12 +51454,12 @@ var init_digitTable = __esm({
51287
51454
  LOW_MIN = 1632;
51288
51455
  TABLE_OFFSET = LOW_MIN;
51289
51456
  TABLE_SIZE = LOW_MAX - LOW_MIN + 1;
51290
- TABLE = new Uint8Array(TABLE_SIZE).fill(NOT_DIGIT);
51457
+ TABLE2 = new Uint8Array(TABLE_SIZE).fill(NOT_DIGIT);
51291
51458
  for (const zero of SCRIPT_ZEROS) {
51292
51459
  for (let d = 0; d < 10; d++) {
51293
51460
  const cp = zero + d;
51294
51461
  if (cp <= LOW_MAX) {
51295
- TABLE[cp - TABLE_OFFSET] = d;
51462
+ TABLE2[cp - TABLE_OFFSET] = d;
51296
51463
  } else {
51297
51464
  HIGH_MAP.set(cp, d);
51298
51465
  }
@@ -51330,7 +51497,7 @@ function anynum(str4) {
51330
51497
  }
51331
51498
  continue;
51332
51499
  }
51333
- if (TABLE[cc - TABLE_OFFSET] !== NOT_DIGIT || MINUS_SET.has(cc)) {
51500
+ if (TABLE2[cc - TABLE_OFFSET] !== NOT_DIGIT || MINUS_SET.has(cc)) {
51334
51501
  firstHit = i2;
51335
51502
  break;
51336
51503
  }
@@ -51368,7 +51535,7 @@ function anynum(str4) {
51368
51535
  chars.push("-");
51369
51536
  continue;
51370
51537
  }
51371
- const d = TABLE[cc - TABLE_OFFSET];
51538
+ const d = TABLE2[cc - TABLE_OFFSET];
51372
51539
  chars.push(d !== NOT_DIGIT ? String.fromCharCode(d + 48) : str4[i2]);
51373
51540
  }
51374
51541
  return chars.join("");
@@ -54316,9 +54483,9 @@ function firstOf(...values2) {
54316
54483
  function toISODate(value2) {
54317
54484
  const raw = text(value2).trim().replace(/\s*\([^)]*\)$/, "");
54318
54485
  if (!raw) return null;
54319
- const named2 = /\s([A-Z]{1,5})$/.exec(raw);
54320
- if (named2 && ZONE_NAMES_READ.indexOf(named2[1]) === -1) return null;
54321
- const zoned = !!named2 || /(?:Z|[+-]\d{2}:?\d{2})$/.test(raw);
54486
+ const named3 = /\s([A-Z]{1,5})$/.exec(raw);
54487
+ if (named3 && ZONE_NAMES_READ.indexOf(named3[1]) === -1) return null;
54488
+ const zoned = !!named3 || /(?:Z|[+-]\d{2}:?\d{2})$/.test(raw);
54322
54489
  const asUTC = zoned || /^\d{4}-\d{2}-\d{2}$/.test(raw) ? raw : /^\d{4}-\d{2}-\d{2}T/.test(raw) ? raw + "Z" : raw + " GMT";
54323
54490
  const ms = Date.parse(asUTC);
54324
54491
  return isNaN(ms) ? null : new Date(ms).toISOString();
@@ -57377,9 +57544,9 @@ function captureGroups(m) {
57377
57544
  }
57378
57545
  function namedCaptureGroups(m) {
57379
57546
  const out = {};
57380
- const named2 = m.groups;
57381
- if (named2) {
57382
- for (const key in named2) out[key] = named2[key] === void 0 ? "" : named2[key];
57547
+ const named3 = m.groups;
57548
+ if (named3) {
57549
+ for (const key in named3) out[key] = named3[key] === void 0 ? "" : named3[key];
57383
57550
  }
57384
57551
  return out;
57385
57552
  }
@@ -60977,6 +61144,7 @@ var require_globalstoresubscribenode = __commonJS({
60977
61144
  description: "The watched value: one key gives that key, several give an object of just those keys, none gives the whole store",
60978
61145
  group: "Data",
60979
61146
  getter: function() {
61147
+ if (!this._internal.unsubscribe) return void 0;
60980
61148
  return this.projectValue(globalStoreManager.getState(this._internal.storeName));
60981
61149
  }
60982
61150
  },
@@ -68312,8 +68480,8 @@ function sourceName(el) {
68312
68480
  return label.length > 60 ? label.slice(0, 57) + "\u2026" : label || "item";
68313
68481
  }
68314
68482
  function zoneName(zone, el) {
68315
- const named2 = String(zone._internal.dropZoneName || "").trim();
68316
- if (named2) return named2;
68483
+ const named3 = String(zone._internal.dropZoneName || "").trim();
68484
+ if (named3) return named3;
68317
68485
  const label = el && el.getAttribute("aria-label");
68318
68486
  if (label) return label;
68319
68487
  const all = orderedZones(zone);
@@ -72721,8 +72889,8 @@ function readColor(value2, depth = 0) {
72721
72889
  const asVar = VAR_FN.exec(text3);
72722
72890
  if (asVar) {
72723
72891
  if (depth >= 8) return null;
72724
- const resolved2 = cssVariableValue(asVar[1]);
72725
- if (resolved2) return readColor(resolved2, depth + 1);
72892
+ const resolved3 = cssVariableValue(asVar[1]);
72893
+ if (resolved3) return readColor(resolved3, depth + 1);
72726
72894
  if (asVar[2] !== void 0) return readColor(asVar[2], depth + 1);
72727
72895
  return null;
72728
72896
  }
@@ -76852,7 +77020,14 @@ var init_TextInput = __esm({
76852
77020
  ref: props.useLabel ? void 0 : noodlRootRef(this.props.noodlNode),
76853
77021
  ...props.useLabel ? void 0 : dataAttributeProps(props.dom),
76854
77022
  style: props.useLabel ? { ...clearedRootStyles(style2), ...inputWrapperStyle } : inputWrapperStyle,
76855
- "noodl-style-tag": "inputWrapper"
77023
+ "noodl-style-tag": "inputWrapper",
77024
+ onMouseDown: (e) => {
77025
+ const field2 = this.ref.current;
77026
+ if (!field2 || !props.enabled || e.button !== 0 || field2.contains(e.target)) return;
77027
+ e.preventDefault();
77028
+ window.addEventListener("click", preventGlobalFocusChange, true);
77029
+ this.focus();
77030
+ }
76856
77031
  },
76857
77032
  props.useIcon && props.iconPlacement === "left" ? _renderIcon() : null,
76858
77033
  inputContent,
@@ -82051,18 +82226,18 @@ function Columns(props) {
82051
82226
  return () => observer.disconnect();
82052
82227
  }, [masonry, children.length, containerWidth]);
82053
82228
  const columnLayout = readColumnLayoutString(props.layoutString);
82054
- const resolved2 = columnLayout === null ? null : resolveColumnLayout(columnLayout, props, containerWidth, children.length);
82055
- const breakpoint = resolved2?.breakpoint ?? "Default";
82229
+ const resolved3 = columnLayout === null ? null : resolveColumnLayout(columnLayout, props, containerWidth, children.length);
82230
+ const breakpoint = resolved3?.breakpoint ?? "Default";
82056
82231
  (0, import_react17.useEffect)(() => {
82057
82232
  props.onBreakpointChanged?.(breakpoint);
82058
82233
  if (breakpoint === "Medium") props.onAtMedium?.();
82059
82234
  else if (breakpoint === "Small") props.onAtSmall?.();
82060
82235
  }, [breakpoint]);
82061
82236
  if (!props.children) return null;
82062
- if (resolved2 === null) {
82237
+ if (resolved3 === null) {
82063
82238
  return /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, props.children);
82064
82239
  }
82065
- const { layout, columnAmount, fractionSize } = resolved2;
82240
+ const { layout, columnAmount, fractionSize } = resolved3;
82066
82241
  columnAmountRef.current = columnAmount;
82067
82242
  const columnLefts = masonry ? computeColumnOffsets(layout, fractionSize) : null;
82068
82243
  const packed = masonry && masonryOffsets !== null && masonryOffsets.tops.length === children.length;
@@ -98015,8 +98190,8 @@ var init_parentcomponentobject = __esm({
98015
98190
  const self2 = this.nodeScope.componentOwner;
98016
98191
  const wanted = this._internal.targetComponent;
98017
98192
  if (wanted) {
98018
- const named2 = findAncestorWithName(self2, wanted);
98019
- if (!named2) {
98193
+ const named3 = findAncestorWithName(self2, wanted);
98194
+ if (!named3) {
98020
98195
  this._internal.parentComponentName = void 0;
98021
98196
  resolvedTargets2.report(this, void 0);
98022
98197
  this.reportMiss("parent-component-object/target-not-found", 'No ancestor component named "' + wanted + '"', {
@@ -98025,7 +98200,7 @@ var init_parentcomponentobject = __esm({
98025
98200
  });
98026
98201
  return;
98027
98202
  }
98028
- if (!COMPONENT_OBJECT_TYPES.some((type) => named2.nodeScope.getNodesWithType(type).length > 0)) {
98203
+ if (!COMPONENT_OBJECT_TYPES.some((type) => named3.nodeScope.getNodesWithType(type).length > 0)) {
98029
98204
  this._internal.parentComponentName = void 0;
98030
98205
  resolvedTargets2.report(this, void 0);
98031
98206
  this.reportMiss(
@@ -98035,11 +98210,11 @@ var init_parentcomponentobject = __esm({
98035
98210
  );
98036
98211
  return;
98037
98212
  }
98038
- this._internal.parentComponentName = named2.name;
98213
+ this._internal.parentComponentName = named3.name;
98039
98214
  this._internal.lastMissCode = void 0;
98040
98215
  this._internal.lastError = void 0;
98041
- resolvedTargets2.report(this, named2.name);
98042
- return "componentState" + named2.getInstanceId();
98216
+ resolvedTargets2.report(this, named3.name);
98217
+ return "componentState" + named3.getInstanceId();
98043
98218
  }
98044
98219
  const parent = findAncestorWithComponentObject(self2);
98045
98220
  if (!parent) {
@@ -98218,22 +98393,22 @@ var init_setparentcomponentobjectproperties = __esm({
98218
98393
  const self2 = this.nodeScope.componentOwner;
98219
98394
  const wanted = this._internal.targetComponent;
98220
98395
  if (wanted) {
98221
- const named2 = findAncestorWithName(self2, wanted);
98222
- if (!named2) {
98396
+ const named3 = findAncestorWithName(self2, wanted);
98397
+ if (!named3) {
98223
98398
  return {
98224
98399
  missCode: "set-parent-component-object-properties/target-not-found",
98225
98400
  missMessage: 'No ancestor component named "' + wanted + '"',
98226
98401
  missDetail: { target: wanted, ancestors: componentAncestorNames(self2) }
98227
98402
  };
98228
98403
  }
98229
- if (!COMPONENT_OBJECT_TYPES.some((type) => named2.nodeScope.getNodesWithType(type).length > 0)) {
98404
+ if (!COMPONENT_OBJECT_TYPES.some((type) => named3.nodeScope.getNodesWithType(type).length > 0)) {
98230
98405
  return {
98231
98406
  missCode: "set-parent-component-object-properties/target-has-no-object",
98232
98407
  missMessage: 'The component "' + wanted + '" has no Component Object node',
98233
98408
  missDetail: { target: wanted }
98234
98409
  };
98235
98410
  }
98236
- return { id: "componentState" + named2.getInstanceId(), name: named2.name };
98411
+ return { id: "componentState" + named3.getInstanceId(), name: named3.name };
98237
98412
  }
98238
98413
  const parent = findAncestorWithComponentObject(self2);
98239
98414
  if (!parent) {
@@ -100538,15 +100713,15 @@ var init_closepopup = __esm({
100538
100713
  const candidates = popups.map((component) => component.name);
100539
100714
  const wanted = this._internal.targetComponent;
100540
100715
  if (wanted) {
100541
- const named2 = popups.find((component) => component.name === wanted);
100542
- if (!named2) {
100716
+ const named3 = popups.find((component) => component.name === wanted);
100717
+ if (!named3) {
100543
100718
  return {
100544
100719
  candidates,
100545
100720
  missCode: "close-popup/target-not-found",
100546
100721
  missMessage: 'This node is not inside a popup named "' + wanted + '"' + (candidates.length ? " \u2014 it is inside: " + candidates.join(", ") : "")
100547
100722
  };
100548
100723
  }
100549
- return { popup: named2, close: named2._popupCloseHandler, candidates };
100724
+ return { popup: named3, close: named3._popupCloseHandler, candidates };
100550
100725
  }
100551
100726
  if (this._internal.closeCallback) {
100552
100727
  return { popup: popups[0], close: this._internal.closeCallback, candidates };
@@ -100958,7 +101133,9 @@ var init_userservice = __esm({
100958
101133
  this.adapter = new ParseAuthAdapter({
100959
101134
  // The module-scope serialiser, exactly as before — `_User` properties have
100960
101135
  // always been serialised against the process-wide Model store.
100961
- serializeObject: (data, collectionName2) => import_cloudstore2.default._serializeObject(data, collectionName2)
101136
+ // P115-HST006-VIEWERTS2554: the third argument (the model scope) is named, undefined, as JavaScript already
101137
+ // passed it: the runtime's generated types declare all three, and the production viewer build type-checks.
101138
+ serializeObject: (data, collectionName2) => import_cloudstore2.default._serializeObject(data, collectionName2, void 0)
100962
101139
  });
100963
101140
  this._bridge(this.adapter);
100964
101141
  if (this._consumeAuthReturn()) return;
@@ -101011,12 +101188,12 @@ var init_userservice = __esm({
101011
101188
  */
101012
101189
  _handle(backendId) {
101013
101190
  if (backendId && backendId !== ACTIVE_BACKEND) {
101014
- const named2 = resolveBackendFromRuntime(backendId);
101015
- return named2 ? named2.handle : void 0;
101191
+ const named3 = resolveBackendFromRuntime(backendId);
101192
+ return named3 ? named3.handle : void 0;
101016
101193
  }
101017
101194
  if (!this.endpoint) {
101018
- const resolved2 = resolveBackendFromRuntime(ACTIVE_BACKEND);
101019
- if (resolved2) return resolved2.handle;
101195
+ const resolved3 = resolveBackendFromRuntime(ACTIVE_BACKEND);
101196
+ if (resolved3) return resolved3.handle;
101020
101197
  }
101021
101198
  return {
101022
101199
  id: "_active_",
@@ -111599,9 +111776,9 @@ var require_fast_uri = __commonJS({
111599
111776
  }
111600
111777
  function resolve5(baseURI, relativeURI, options) {
111601
111778
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
111602
- const resolved2 = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
111779
+ const resolved3 = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
111603
111780
  schemelessOptions.skipEscape = true;
111604
- return serialize(resolved2, schemelessOptions);
111781
+ return serialize(resolved3, schemelessOptions);
111605
111782
  }
111606
111783
  function resolveComponent(base, relative2, options, skipNormalization) {
111607
111784
  const target = {};
@@ -185127,11 +185304,11 @@ var TokenResolver = class _TokenResolver {
185127
185304
  }
185128
185305
  const token = this.tokens.get(tokenName);
185129
185306
  if (!token) return void 0;
185130
- const resolved2 = this._resolveValue(token.value, depth);
185131
- if (resolved2 !== void 0) {
185132
- this.cache.set(tokenName, resolved2);
185307
+ const resolved3 = this._resolveValue(token.value, depth);
185308
+ if (resolved3 !== void 0) {
185309
+ this.cache.set(tokenName, resolved3);
185133
185310
  }
185134
- return resolved2;
185311
+ return resolved3;
185135
185312
  }
185136
185313
  /**
185137
185314
  * P102 CMP-001 §3 — resolve every `var()` **inside** a value, so a preview can paint it.
@@ -185806,6 +185983,13 @@ var CommentsModel = class extends import_model15.default {
185806
185983
 
185807
185984
  // ../noodl-editor/src/editor/src/models/warningsmodel.ts
185808
185985
  var import_model16 = __toESM(require_model());
185986
+ function sameWarning(a, b) {
185987
+ try {
185988
+ return JSON.stringify(a) === JSON.stringify(b);
185989
+ } catch {
185990
+ return false;
185991
+ }
185992
+ }
185809
185993
  var WarningsModel = class _WarningsModel extends import_model16.default {
185810
185994
  constructor() {
185811
185995
  super();
@@ -185818,13 +186002,23 @@ var WarningsModel = class _WarningsModel extends import_model16.default {
185818
186002
  static {
185819
186003
  this.instance = new _WarningsModel();
185820
186004
  }
186005
+ /**
186006
+ * P132-HIDDENPANELCHURN: a set that changes nothing says nothing. `readNameList` clears its warning on every read,
186007
+ * and the Components panel reads page info (so names) on every `warningsChanged`: when a clear of a warning that was
186008
+ * not there still announced a change, the two fed each other once per `setTimeout(1)`, ~480 times a second, for as
186009
+ * long as a project was open (the panel, the top bar and every mounted dialog re-rendering each time).
186010
+ * The same object set again still announces: its owner may have changed it in place.
186011
+ */
185821
186012
  setWarning(ref, warning) {
185822
186013
  var w = this.getWarningsForRef(ref, warning !== void 0);
185823
186014
  if (!warning) {
185824
- if (w) delete w[ref.key];
186015
+ if (!w || w[ref.key] === void 0) return;
186016
+ delete w[ref.key];
185825
186017
  } else {
185826
186018
  warning.level = warning.level || "warning";
186019
+ const had = w[ref.key];
185827
186020
  w[ref.key] = { ref, warning };
186021
+ if (had && had.warning !== warning && sameWarning(had.warning, warning)) return;
185828
186022
  }
185829
186023
  this.scheduleNotifyChanged();
185830
186024
  }
@@ -191886,11 +192080,11 @@ var ParameterValueResolver = class {
191886
192080
  * ```
191887
192081
  */
191888
192082
  static toString(paramValue) {
191889
- const resolved2 = this.resolve(paramValue, "display" /* Display */);
191890
- if (typeof resolved2 === "object" && resolved2 !== null) {
192083
+ const resolved3 = this.resolve(paramValue, "display" /* Display */);
192084
+ if (typeof resolved3 === "object" && resolved3 !== null) {
191891
192085
  return "";
191892
192086
  }
191893
- return String(resolved2 ?? "");
192087
+ return String(resolved3 ?? "");
191894
192088
  }
191895
192089
  /**
191896
192090
  * Safely converts any parameter value to a number for display.
@@ -191909,15 +192103,15 @@ var ParameterValueResolver = class {
191909
192103
  * ```
191910
192104
  */
191911
192105
  static toNumber(paramValue) {
191912
- const resolved2 = this.resolve(paramValue, "display" /* Display */);
191913
- if (typeof resolved2 === "object" && resolved2 !== null) {
192106
+ const resolved3 = this.resolve(paramValue, "display" /* Display */);
192107
+ if (typeof resolved3 === "object" && resolved3 !== null) {
191914
192108
  return void 0;
191915
192109
  }
191916
192110
  const rawValue = isExpressionParameter(paramValue) ? paramValue.fallback : paramValue;
191917
192111
  if (rawValue === null || rawValue === void 0) {
191918
192112
  return void 0;
191919
192113
  }
191920
- const num = Number(resolved2);
192114
+ const num = Number(resolved3);
191921
192115
  return isNaN(num) ? void 0 : num;
191922
192116
  }
191923
192117
  /**
@@ -191937,11 +192131,11 @@ var ParameterValueResolver = class {
191937
192131
  * ```
191938
192132
  */
191939
192133
  static toBoolean(paramValue) {
191940
- const resolved2 = this.resolve(paramValue, "display" /* Display */);
191941
- if (typeof resolved2 === "object" && resolved2 !== null) {
192134
+ const resolved3 = this.resolve(paramValue, "display" /* Display */);
192135
+ if (typeof resolved3 === "object" && resolved3 !== null) {
191942
192136
  return false;
191943
192137
  }
191944
- return Boolean(resolved2);
192138
+ return Boolean(resolved3);
191945
192139
  }
191946
192140
  /**
191947
192141
  * Checks if a parameter value is an expression parameter.
@@ -191987,7 +192181,7 @@ var NodeGraphNode = class _NodeGraphNode extends import_model22.default {
191987
192181
  }
191988
192182
  /** Get the label of the node */
191989
192183
  get label() {
191990
- if (!this._label) return this.type.labelForNode(this);
192184
+ if (!this._label) return this.derivedTitle ?? this.type.labelForNode(this);
191991
192185
  return this._label;
191992
192186
  }
191993
192187
  /** Set the label of the node */
@@ -191995,6 +192189,12 @@ var NodeGraphNode = class _NodeGraphNode extends import_model22.default {
191995
192189
  this._label = value2;
191996
192190
  this.notifyListeners("labelChanged");
191997
192191
  }
192192
+ /** Set the derived title. `undefined` clears it. */
192193
+ setDerivedTitle(title) {
192194
+ if (this.derivedTitle === title) return;
192195
+ this.derivedTitle = title;
192196
+ this.notifyListeners("derivedTitleChanged");
192197
+ }
191998
192198
  /** Set the runtime sub-label. `undefined` clears it. */
191999
192199
  setRuntimeSubLabel(subLabel) {
192000
192200
  if (this.runtimeSubLabel === subLabel) return;
@@ -195499,8 +195699,8 @@ function readDeployedRoots(outDir) {
195499
195699
  };
195500
195700
  add(data.components);
195501
195701
  const bundleDir = path4.join(outDir, "noodl_bundles");
195502
- const named2 = Object.keys(data.componentIndex ?? {}).filter((id) => id !== "root");
195503
- for (const id of named2) {
195702
+ const named3 = Object.keys(data.componentIndex ?? {}).filter((id) => id !== "root");
195703
+ for (const id of named3) {
195504
195704
  const file = path4.join(bundleDir, `${id}.json`);
195505
195705
  if (fs3.existsSync(file)) {
195506
195706
  add(JSON.parse(fs3.readFileSync(file, "utf8")));
@@ -195512,7 +195712,7 @@ function readDeployedRoots(outDir) {
195512
195712
  }
195513
195713
  }
195514
195714
  if (fs3.existsSync(bundleDir)) {
195515
- const live = new Set(named2.map((id) => `${id}.json`));
195715
+ const live = new Set(named3.map((id) => `${id}.json`));
195516
195716
  reading.staleBundles = fs3.readdirSync(bundleDir).filter((file) => file.endsWith(".json") && !live.has(file)).sort();
195517
195717
  }
195518
195718
  return reading;
@@ -195609,9 +195809,9 @@ function walk2(value2, path10, seen) {
195609
195809
  const c = walk2(item, `${path10}[${i2}]`, seen);
195610
195810
  return c === void 0 ? null : c;
195611
195811
  });
195612
- const named2 = obj;
195613
- if (typeof named2.getId === "function") {
195614
- const id = named2.getId();
195812
+ const named3 = obj;
195813
+ if (typeof named3.getId === "function") {
195814
+ const id = named3.getId();
195615
195815
  if (typeof id === "string") return { $array: id, items };
195616
195816
  }
195617
195817
  return items;
@@ -198422,12 +198622,12 @@ function formatDate(t, formatString, timeZone, localeTag) {
198422
198622
  if (rendered2.indexOf(needle) === -1) return;
198423
198623
  rendered2 = rendered2.split(needle).join(render2());
198424
198624
  };
198425
- const named2 = (options) => new Intl.DateTimeFormat(locale, zone ? { ...options, timeZone: zone } : options).format(date);
198625
+ const named3 = (options) => new Intl.DateTimeFormat(locale, zone ? { ...options, timeZone: zone } : options).format(date);
198426
198626
  const hours12 = (fields.hours + 11) % 12 + 1;
198427
198627
  const meridiem = fields.hours < 12 ? "am" : "pm";
198428
- substitute("dayName", () => named2({ weekday: "long" }));
198429
- substitute("dayShort", () => named2({ weekday: "short" }));
198430
- substitute("monthName", () => named2({ month: "long" }));
198628
+ substitute("dayName", () => named3({ weekday: "long" }));
198629
+ substitute("dayShort", () => named3({ weekday: "short" }));
198630
+ substitute("monthName", () => named3({ month: "long" }));
198431
198631
  substitute("hours12", () => ("0" + hours12).slice(-2));
198432
198632
  substitute("h12", () => String(hours12));
198433
198633
  substitute("ampm", () => meridiem);
@@ -199982,6 +200182,7 @@ function selectedClass(params, context) {
199982
200182
  function shownFields(klass, skipRelations) {
199983
200183
  return Object.entries(klass?.fields ?? {}).filter(([field2, decl]) => field2 !== "ACL" && !(skipRelations && decl.relation !== void 0));
199984
200184
  }
200185
+ var RECORD_BUILT_IN_DATES2 = Object.freeze(["createdAt", "updatedAt"]);
199985
200186
  function onParseWire(context) {
199986
200187
  const type = context.schema?.backendType;
199987
200188
  return type === void 0 || type === "parse" || type === "nodegx";
@@ -202522,9 +202723,9 @@ var ZONE_NAMES_READ2 = ["UT", "UTC", "GMT", "Z", "EST", "EDT", "CST", "CDT", "MS
202522
202723
  function toISODate2(value2) {
202523
202724
  const raw = text2(value2).trim().replace(/\s*\([^)]*\)$/, "");
202524
202725
  if (!raw) return null;
202525
- const named2 = /\s([A-Z]{1,5})$/.exec(raw);
202526
- if (named2 && ZONE_NAMES_READ2.indexOf(named2[1]) === -1) return null;
202527
- const zoned = !!named2 || /(?:Z|[+-]\d{2}:?\d{2})$/.test(raw);
202726
+ const named3 = /\s([A-Z]{1,5})$/.exec(raw);
202727
+ if (named3 && ZONE_NAMES_READ2.indexOf(named3[1]) === -1) return null;
202728
+ const zoned = !!named3 || /(?:Z|[+-]\d{2}:?\d{2})$/.test(raw);
202528
202729
  const asUTC = zoned || /^\d{4}-\d{2}-\d{2}$/.test(raw) ? raw : /^\d{4}-\d{2}-\d{2}T/.test(raw) ? raw + "Z" : raw + " GMT";
202529
202730
  const ms = Date.parse(asUTC);
202530
202731
  return isNaN(ms) ? null : new Date(ms).toISOString();
@@ -205956,8 +206157,8 @@ function busy(s) {
205956
206157
  return s.phase !== "idle" || s.carry >= 0;
205957
206158
  }
205958
206159
  function cardIndex(value2) {
205959
- const named2 = JSON.stringify(value2);
205960
- return CARDS.findIndex((c) => JSON.stringify(c) === named2);
206160
+ const named3 = JSON.stringify(value2);
206161
+ return CARDS.findIndex((c) => JSON.stringify(c) === named3);
205961
206162
  }
205962
206163
  function track2(s, over) {
205963
206164
  const here = over && zoneFor(s);
@@ -206686,12 +206887,12 @@ function busy2(s) {
206686
206887
  return s.phase !== "idle" || s.carry >= 0;
206687
206888
  }
206688
206889
  function cardIndex2(value2) {
206689
- const named2 = JSON.stringify(value2);
206690
- return CARDS2.findIndex((c) => JSON.stringify(c) === named2);
206890
+ const named3 = JSON.stringify(value2);
206891
+ return CARDS2.findIndex((c) => JSON.stringify(c) === named3);
206691
206892
  }
206692
206893
  function childIndexOf(value2) {
206693
- const named2 = JSON.stringify(value2);
206694
- return CHILDREN.findIndex((c) => JSON.stringify(c) === named2);
206894
+ const named3 = JSON.stringify(value2);
206895
+ return CHILDREN.findIndex((c) => JSON.stringify(c) === named3);
206695
206896
  }
206696
206897
  function track3(s, over) {
206697
206898
  const here = over && zoneFor2(s);
@@ -207213,8 +207414,8 @@ function busy3(s) {
207213
207414
  return s.phase !== "idle" || s.carry >= 0;
207214
207415
  }
207215
207416
  function cardIndex3(value2) {
207216
- const named2 = JSON.stringify(value2);
207217
- return CARDS3.findIndex((c) => JSON.stringify(c) === named2);
207417
+ const named3 = JSON.stringify(value2);
207418
+ return CARDS3.findIndex((c) => JSON.stringify(c) === named3);
207218
207419
  }
207219
207420
  function track4(s, over) {
207220
207421
  const here = over && zoneFor3(s);
@@ -207795,8 +207996,8 @@ function busy4(s) {
207795
207996
  return s.phase !== "idle" || s.carry >= 0;
207796
207997
  }
207797
207998
  function cardIndex4(value2) {
207798
- const named2 = JSON.stringify(value2);
207799
- return CARDS4.findIndex((c) => JSON.stringify(c) === named2);
207999
+ const named3 = JSON.stringify(value2);
208000
+ return CARDS4.findIndex((c) => JSON.stringify(c) === named3);
207800
208001
  }
207801
208002
  function track5(s, over) {
207802
208003
  const here = over && zoneFor4(s);
@@ -208657,8 +208858,8 @@ function busy5(s) {
208657
208858
  return s.phase !== "idle" || s.carry >= 0;
208658
208859
  }
208659
208860
  function cardIndex5(value2) {
208660
- const named2 = JSON.stringify(value2);
208661
- return CARDS5.findIndex((c) => JSON.stringify(c) === named2);
208861
+ const named3 = JSON.stringify(value2);
208862
+ return CARDS5.findIndex((c) => JSON.stringify(c) === named3);
208662
208863
  }
208663
208864
  function track6(s, over) {
208664
208865
  const here = over && zoneFor5(s);
@@ -214096,10 +214297,18 @@ var RecordNode = defineNode({
214096
214297
  // then `prop-` alone for every name a wire or a parameter declares and the schema does not (recordWiredFieldPorts :260-345)
214097
214298
  outputs: (params, context) => {
214098
214299
  const out = {};
214099
- for (const [field2, decl] of shownFields(selectedClass(params, context), true)) {
214300
+ const klass = selectedClass(params, context);
214301
+ for (const [field2, decl] of shownFields(klass, true)) {
214100
214302
  out["prop-" + field2] = { ...propertyOutput(field2), ...recordFieldPort(decl) };
214101
214303
  out["changed-" + field2] = changedSignal(field2);
214102
214304
  }
214305
+ if (klass && onParseWire(context)) {
214306
+ for (const field2 of RECORD_BUILT_IN_DATES2)
214307
+ if (!("prop-" + field2 in out)) {
214308
+ out["prop-" + field2] = propertyOutput(field2, "date");
214309
+ if (!("changed-" + field2 in out)) out["changed-" + field2] = changedSignal(field2);
214310
+ }
214311
+ }
214103
214312
  for (const field2 of recordWiredFieldNames2(params, context)) if (!("prop-" + field2 in out)) out["prop-" + field2] = propertyOutput(field2);
214104
214313
  return out;
214105
214314
  },
@@ -217300,9 +217509,9 @@ function captureGroups2(m) {
217300
217509
  }
217301
217510
  function namedCaptureGroups2(m) {
217302
217511
  const out = {};
217303
- const named2 = m.groups;
217304
- if (named2) {
217305
- for (const key in named2) out[key] = named2[key] === void 0 ? "" : named2[key];
217512
+ const named3 = m.groups;
217513
+ if (named3) {
217514
+ for (const key in named3) out[key] = named3[key] === void 0 ? "" : named3[key];
217306
217515
  }
217307
217516
  return out;
217308
217517
  }
@@ -221573,9 +221782,9 @@ var OUTPUT_TYPES = ["*", ...INPUT_TYPES, "signal"];
221573
221782
  var labelsOf = (list2) => Array.isArray(list2) ? list2.map((r) => r && r.label).filter((l) => typeof l === "string" && l.length > 0) : [];
221574
221783
  function parse(text3) {
221575
221784
  try {
221576
- const AsyncFunction = Object.getPrototypeOf(async function() {
221785
+ const AsyncFunction2 = Object.getPrototypeOf(async function() {
221577
221786
  }).constructor;
221578
- new AsyncFunction(...PARAMETERS, CODE_PREFIX + text3);
221787
+ new AsyncFunction2(...PARAMETERS, CODE_PREFIX + text3);
221579
221788
  return void 0;
221580
221789
  } catch (e) {
221581
221790
  return e && e.message ? String(e.message) : String(e);
@@ -221599,9 +221808,9 @@ function outputNames(params, script2) {
221599
221808
  if (params["outtype-" + label] === "signal") signals.push(label);
221600
221809
  else values2.push(label);
221601
221810
  }
221602
- const named2 = functionScriptPortNames2(script2);
221603
- for (const n of named2.signals) if (!signals.includes(n) && !values2.includes(n)) signals.push(n);
221604
- for (const n of named2.outputs) if (!signals.includes(n) && !values2.includes(n)) values2.push(n);
221811
+ const named3 = functionScriptPortNames2(script2);
221812
+ for (const n of named3.signals) if (!signals.includes(n) && !values2.includes(n)) signals.push(n);
221813
+ for (const n of named3.outputs) if (!signals.includes(n) && !values2.includes(n)) values2.push(n);
221605
221814
  return { signals, values: values2 };
221606
221815
  }
221607
221816
  function runCode(s, signals) {
@@ -234831,9 +235040,9 @@ function conditionIsUnsatisfied(condition, params) {
234831
235040
  return result2 === false;
234832
235041
  }
234833
235042
  function resolveAgainstDefaults(params, defaults) {
234834
- const resolved2 = { ...defaults };
234835
- for (const [name2, value2] of Object.entries(params)) if (value2 !== void 0) resolved2[name2] = value2;
234836
- return resolved2;
235043
+ const resolved3 = { ...defaults };
235044
+ for (const [name2, value2] of Object.entries(params)) if (value2 !== void 0) resolved3[name2] = value2;
235045
+ return resolved3;
234837
235046
  }
234838
235047
  function conditionForInput(groups, portName) {
234839
235048
  if (!groups) return void 0;
@@ -234872,6 +235081,7 @@ var NUMBER_WITH_UNIT = /^\s*(-?\d+(?:\.\d+)?)\s*(px|%|vw|vh|em|rem|deg|s|ms)\s*$
234872
235081
  function isPlainObject3(value2) {
234873
235082
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
234874
235083
  }
235084
+ var TOKEN_IN_VALUE = /var\(--[A-Za-z0-9_-]+\)/;
234875
235085
  function isTokenReference2(value2) {
234876
235086
  return typeof value2 === "string" && value2.startsWith("var(");
234877
235087
  }
@@ -234943,10 +235153,11 @@ function unitsFormat(type) {
234943
235153
  suggestion: JSON.stringify({ value: Number(parsed2[1]), unit: parsed2[2] })
234944
235154
  };
234945
235155
  }
235156
+ const token = typeof value2 === "string" ? TOKEN_IN_VALUE.exec(value2)?.[0] : void 0;
234946
235157
  return {
234947
235158
  severity: "error",
234948
- message: `expects a number or { "value", "unit" } object. Got ${describeValue3(value2)}.`,
234949
- suggestion: JSON.stringify({ value: 16, unit: unit2 })
235159
+ message: `expects a number, a { "value", "unit" } object or a var(--token) reference. Got ${describeValue3(value2)}.` + (token ? ` This port takes a token alone, not inside an expression: use ${token}, or add a token that holds the size you want.` : ""),
235160
+ suggestion: JSON.stringify(token ?? { value: 16, unit: unit2 })
234950
235161
  };
234951
235162
  }
234952
235163
  };
@@ -235416,13 +235627,13 @@ function checkParameterValues(nodes, catalog, options) {
235416
235627
  });
235417
235628
  }
235418
235629
  if (dynamicSkips.length > 0) {
235419
- const named2 = dynamicSkips.map((n) => `"${n}"`).join(", ");
235630
+ const named3 = dynamicSkips.map((n) => `"${n}"`).join(", ");
235420
235631
  const rawNote = catalog.dynamicPortNote(node.type) ?? "this node determines ports at runtime";
235421
235632
  const note = /[.!?]$/.test(rawNote.trim()) ? rawNote.trim() : `${rawNote.trim()}.`;
235422
235633
  diagnostics.push({
235423
235634
  code: "dynamic-port-skipped" /* DynamicPortSkipped */,
235424
235635
  severity: "info",
235425
- message: `${dynamicSkips.length === 1 ? "Parameter" : "Parameters"} ${named2} on ${node.type} ${dynamicSkips.length === 1 ? "names" : "name"} no port the catalog can see, and ${dynamicSkips.length === 1 ? "it was" : "they were"} not checked: ` + note + " So this node is unverified by that check rather than verified as correct.",
235636
+ message: `${dynamicSkips.length === 1 ? "Parameter" : "Parameters"} ${named3} on ${node.type} ${dynamicSkips.length === 1 ? "names" : "name"} no port the catalog can see, and ${dynamicSkips.length === 1 ? "it was" : "they were"} not checked: ` + note + " So this node is unverified by that check rather than verified as correct.",
235426
235637
  location: {
235427
235638
  component,
235428
235639
  nodeId: node.id,
@@ -235584,8 +235795,8 @@ function parentAxis(parent, catalog) {
235584
235795
  const declared2 = PARENT_MAIN_AXIS[parent.type];
235585
235796
  if (declared2 === void 0) return void 0;
235586
235797
  if (declared2 !== "fromFlexDirection") return declared2;
235587
- const resolved2 = resolveAgainstDefaults(parent.parameters ?? {}, catalog.inputDefaults(parent.type));
235588
- const flexDirection = resolved2["flexDirection"];
235798
+ const resolved3 = resolveAgainstDefaults(parent.parameters ?? {}, catalog.inputDefaults(parent.type));
235799
+ const flexDirection = resolved3["flexDirection"];
235589
235800
  if (flexDirection === "row") return "row";
235590
235801
  if (flexDirection === "column" || flexDirection === void 0) return "column";
235591
235802
  return void 0;
@@ -237228,9 +237439,9 @@ var dialogWithoutName = {
237228
237439
  if (typeof accessibleName === "string" && accessibleName.trim() !== "") continue;
237229
237440
  const target = node.parameters?.target;
237230
237441
  if (typeof target !== "string" || target.trim() === "") continue;
237231
- const resolved2 = byName.has(target) ? target : void 0;
237232
- if (resolved2 === void 0) continue;
237233
- if (subtreeHasHeading(resolved2, byName, /* @__PURE__ */ new Set())) continue;
237442
+ const resolved3 = byName.has(target) ? target : void 0;
237443
+ if (resolved3 === void 0) continue;
237444
+ if (subtreeHasHeading(resolved3, byName, /* @__PURE__ */ new Set())) continue;
237234
237445
  diagnostics.push({
237235
237446
  code: "dialog-without-name" /* DialogWithoutName */,
237236
237447
  severity: "warning",
@@ -237412,9 +237623,9 @@ var CODE_PREFIX3 = "const Script = (typeof Node !== 'undefined')?Node:undefined;
237412
237623
  var PARAMS2 = ["Inputs", "Outputs", "Noodl", "Component", "Scripts"];
237413
237624
  function functionScriptCompileError(script2) {
237414
237625
  try {
237415
- const AsyncFunction = Object.getPrototypeOf(async function() {
237626
+ const AsyncFunction2 = Object.getPrototypeOf(async function() {
237416
237627
  }).constructor;
237417
- new AsyncFunction(...PARAMS2, CODE_PREFIX3 + script2);
237628
+ new AsyncFunction2(...PARAMS2, CODE_PREFIX3 + script2);
237418
237629
  return void 0;
237419
237630
  } catch (e) {
237420
237631
  const message = e instanceof Error ? e.message : String(e);
@@ -237781,6 +237992,90 @@ var rowOfWordsFillsItsColumn = {
237781
237992
  }
237782
237993
  };
237783
237994
 
237995
+ // ../noodl-editor/src/editor/src/validation/rules/bandWithoutShell.ts
237996
+ var GROUP2 = "Group";
237997
+ var resolved2 = (node, catalog) => resolveAgainstDefaults(node.parameters ?? {}, catalog.inputDefaults(node.type));
237998
+ var named2 = (nodes) => nodes.slice(0, 4).map((n) => n.label ? `"${n.label}"` : n.type).join(", ") + (nodes.length > 4 ? ", \u2026" : "");
237999
+ var isSet2 = (value2) => value2 !== void 0 && value2 !== null && value2 !== "" && value2 !== 0;
238000
+ function isFullWidth(value2) {
238001
+ if (widthIsPercentage(value2) !== true) return false;
238002
+ const n = typeof value2 === "object" && value2 !== null ? value2.value : parseFloat(String(value2));
238003
+ return Number(n) >= 100;
238004
+ }
238005
+ function spans(params) {
238006
+ return isFullWidth(params["width"]) && !isSet2(params["maxWidth"]) && !isSet2(params["paddingLeft"]) && !isSet2(params["paddingRight"]);
238007
+ }
238008
+ var isCard = (params) => isSet2(params["borderRadius"]) || painted15(params["borderStyle"]);
238009
+ var SECTION_ELEMENTS = /* @__PURE__ */ new Set(["section", "header", "footer"]);
238010
+ var painted15 = (value2) => isSet2(value2) && value2 !== "transparent" && value2 !== "none";
238011
+ function isBand(node, catalog) {
238012
+ if (node.type !== GROUP2) return false;
238013
+ const params = resolved2(node, catalog);
238014
+ if (!spans(params)) return false;
238015
+ if ((params["flexDirection"] ?? "column") !== "column") return false;
238016
+ if (params["alignItems"] !== "center") return false;
238017
+ if (params["position"] === "absolute" || params["position"] === "fixed") return false;
238018
+ if (isCard(params)) return false;
238019
+ return isSet2(params["paddingTop"]) || isSet2(params["paddingBottom"]) || painted15(params["backgroundColor"]) || painted15(params["backgroundGradient"]) || painted15(params["backgroundImage"]) || SECTION_ELEMENTS.has(String(params["as"] ?? ""));
238020
+ }
238021
+ var bandWithoutShell = {
238022
+ code: "band-without-shell" /* BandWithoutShell */,
238023
+ description: "A full-width band holds its content directly instead of inside one shell, so the content runs to the window edge.",
238024
+ defaultEnabled: true,
238025
+ run(ctx) {
238026
+ const out = [];
238027
+ for (const { component, nodeById } of ctx.components) {
238028
+ const inFlowChildren2 = (parent) => (parent.children ?? []).map((id) => nodeById.get(id)).filter((n) => {
238029
+ if (!n) return false;
238030
+ if (isComponentRef(n.type)) return true;
238031
+ if (!ctx.catalog.getNode(n.type)?.isVisual) return false;
238032
+ const p = resolved2(n, ctx.catalog);
238033
+ return p["position"] !== "absolute" && p["position"] !== "fixed";
238034
+ });
238035
+ const guarded = (n, depth = 0) => {
238036
+ if (isComponentRef(n.type)) return true;
238037
+ if (n.type !== GROUP2) return false;
238038
+ const p = resolved2(n, ctx.catalog);
238039
+ if (isSet2(p["maxWidth"]) || isSet2(p["paddingLeft"]) || isSet2(p["paddingRight"])) return true;
238040
+ const kids = inFlowChildren2(n);
238041
+ return depth < 4 && kids.length > 0 && kids.every((k) => guarded(k, depth + 1));
238042
+ };
238043
+ for (const band of component.nodes) {
238044
+ if (!isBand(band, ctx.catalog)) continue;
238045
+ let placed = true;
238046
+ for (let up = band.parent ? nodeById.get(band.parent) : void 0; up; up = up.parent ? nodeById.get(up.parent) : void 0) {
238047
+ if (up.type === "Page") break;
238048
+ const p = up.type === GROUP2 ? resolved2(up, ctx.catalog) : void 0;
238049
+ if (!p || !spans(p) || isCard(p)) {
238050
+ placed = false;
238051
+ break;
238052
+ }
238053
+ }
238054
+ if (!placed) continue;
238055
+ const inside = inFlowChildren2(band);
238056
+ if (inside.length === 0) continue;
238057
+ if (inside.some((n) => isBand(n, ctx.catalog))) continue;
238058
+ const bare2 = inside.filter((n) => !guarded(n));
238059
+ if (bare2.length === 0) continue;
238060
+ const what = bare2.length === inside.length && inside.length > 1 ? `it holds ${inside.length} things directly (${named2(inside)}) instead of one shell` : `${named2(bare2)} ${bare2.length === 1 ? "sits" : "sit"} in it outside a shell`;
238061
+ out.push({
238062
+ code: "band-without-shell" /* BandWithoutShell */,
238063
+ severity: "warning",
238064
+ message: `This is a full-width band (a section of the page), but ${what}, so its words and pictures run to the edge of the window on a desktop. Put everything it holds inside ONE Group with the style vocabulary's "shell" look (maxWidth 1200px, paddingLeft and paddingRight var(--space-6), sizeMode contentHeight), and make that Group the band's only child.`,
238065
+ location: {
238066
+ component: component.name,
238067
+ nodeId: band.id,
238068
+ nodeType: band.type,
238069
+ ...band.label ? { nodeLabel: band.label } : {}
238070
+ },
238071
+ suggestion: 'one child Group with the "shell" look'
238072
+ });
238073
+ }
238074
+ }
238075
+ return out;
238076
+ }
238077
+ };
238078
+
237784
238079
  // ../noodl-editor/src/editor/src/validation/rules/clickAreaHoldsAControl.ts
237785
238080
  var CONTROL_TYPES = /* @__PURE__ */ new Map([
237786
238081
  ["net.noodl.controls.button", "Button"],
@@ -237952,6 +238247,8 @@ var ALL_RULES = [
237952
238247
  // read from the arrangement like the two above, and live so a person sees it while editing.
237953
238248
  contentRowSplitsItsChildren,
237954
238249
  rowOfWordsFillsItsColumn,
238250
+ // P112 OWN-028 AC3 — beside the two above: a band's content outside a shell, read from the arrangement, live.
238251
+ bandWithoutShell,
237955
238252
  oversizedPage,
237956
238253
  // LEG-002 — last, and deliberately: it is the only rule in the set that
237957
238254
  // reports a matter of legibility rather than of correctness, and a reader
@@ -238051,11 +238348,11 @@ function readProjectForDeploy(dir, format) {
238051
238348
  const { legacy, warnings } = readLegacyProject(dir, format);
238052
238349
  const report3 = validateLegacyProject(legacy);
238053
238350
  if (report3.summary.errors > 0) {
238054
- const named2 = report3.diagnostics.filter((diagnostic) => diagnostic.severity === "error").slice(0, 5).map((d) => ` ${d.component}${d.nodeId ? ` \u203A ${d.nodeId}` : ""}: ${d.message}`);
238351
+ const named3 = report3.diagnostics.filter((diagnostic) => diagnostic.severity === "error").slice(0, 5).map((d) => ` ${d.component}${d.nodeId ? ` \u203A ${d.nodeId}` : ""}: ${d.message}`);
238055
238352
  throw new Error(
238056
238353
  `${dir} has ${report3.summary.errors} validation error(s) and was not deployed:
238057
- ` + named2.join("\n") + (report3.summary.errors > named2.length ? `
238058
- \u2026 and ${report3.summary.errors - named2.length} more` : "")
238354
+ ` + named3.join("\n") + (report3.summary.errors > named3.length ? `
238355
+ \u2026 and ${report3.summary.errors - named3.length} more` : "")
238059
238356
  );
238060
238357
  }
238061
238358
  const built = buildProjectModel(legacy, dir);