@abco20/btxml-checker 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.cjs CHANGED
@@ -927,9 +927,9 @@ var require_codegen = __commonJS({
927
927
  }
928
928
  };
929
929
  var Throw = class extends Node {
930
- constructor(error51) {
930
+ constructor(error52) {
931
931
  super();
932
- this.error = error51;
932
+ this.error = error52;
933
933
  }
934
934
  render({ _n }) {
935
935
  return `throw ${this.error};` + _n;
@@ -1166,9 +1166,9 @@ var require_codegen = __commonJS({
1166
1166
  }
1167
1167
  };
1168
1168
  var Catch = class extends BlockNode {
1169
- constructor(error51) {
1169
+ constructor(error52) {
1170
1170
  super();
1171
- this.error = error51;
1171
+ this.error = error52;
1172
1172
  }
1173
1173
  render(opts) {
1174
1174
  return `catch(${this.error})` + super.render(opts);
@@ -1359,9 +1359,9 @@ var require_codegen = __commonJS({
1359
1359
  this._blockNode(node);
1360
1360
  this.code(tryBody);
1361
1361
  if (catchCode) {
1362
- const error51 = this.name("e");
1363
- this._currNode = node.catch = new Catch(error51);
1364
- catchCode(error51);
1362
+ const error52 = this.name("e");
1363
+ this._currNode = node.catch = new Catch(error52);
1364
+ catchCode(error52);
1365
1365
  }
1366
1366
  if (finallyCode) {
1367
1367
  this._currNode = node.finally = new Finally();
@@ -1370,8 +1370,8 @@ var require_codegen = __commonJS({
1370
1370
  return this._endBlockNode(Catch, Finally);
1371
1371
  }
1372
1372
  // `throw` statement
1373
- throw(error51) {
1374
- return this._leafNode(new Throw(error51));
1373
+ throw(error52) {
1374
+ return this._leafNode(new Throw(error52));
1375
1375
  }
1376
1376
  // start self-balancing block
1377
1377
  block(body, nodeCount) {
@@ -1727,10 +1727,10 @@ var require_errors = __commonJS({
1727
1727
  exports2.keyword$DataError = {
1728
1728
  message: ({ keyword, schemaType }) => schemaType ? (0, codegen_1.str)`"${keyword}" keyword must be ${schemaType} ($data)` : (0, codegen_1.str)`"${keyword}" keyword is invalid ($data)`
1729
1729
  };
1730
- function reportError(cxt, error51 = exports2.keywordError, errorPaths, overrideAllErrors) {
1730
+ function reportError(cxt, error52 = exports2.keywordError, errorPaths, overrideAllErrors) {
1731
1731
  const { it } = cxt;
1732
1732
  const { gen, compositeRule, allErrors } = it;
1733
- const errObj = errorObjectCode(cxt, error51, errorPaths);
1733
+ const errObj = errorObjectCode(cxt, error52, errorPaths);
1734
1734
  if (overrideAllErrors !== null && overrideAllErrors !== void 0 ? overrideAllErrors : compositeRule || allErrors) {
1735
1735
  addError(gen, errObj);
1736
1736
  } else {
@@ -1738,10 +1738,10 @@ var require_errors = __commonJS({
1738
1738
  }
1739
1739
  }
1740
1740
  exports2.reportError = reportError;
1741
- function reportExtraError(cxt, error51 = exports2.keywordError, errorPaths) {
1741
+ function reportExtraError(cxt, error52 = exports2.keywordError, errorPaths) {
1742
1742
  const { it } = cxt;
1743
1743
  const { gen, compositeRule, allErrors } = it;
1744
- const errObj = errorObjectCode(cxt, error51, errorPaths);
1744
+ const errObj = errorObjectCode(cxt, error52, errorPaths);
1745
1745
  addError(gen, errObj);
1746
1746
  if (!(compositeRule || allErrors)) {
1747
1747
  returnErrors(it, names_1.default.vErrors);
@@ -1792,19 +1792,19 @@ var require_errors = __commonJS({
1792
1792
  schema: new codegen_1.Name("schema"),
1793
1793
  parentSchema: new codegen_1.Name("parentSchema")
1794
1794
  };
1795
- function errorObjectCode(cxt, error51, errorPaths) {
1795
+ function errorObjectCode(cxt, error52, errorPaths) {
1796
1796
  const { createErrors } = cxt.it;
1797
1797
  if (createErrors === false)
1798
1798
  return (0, codegen_1._)`{}`;
1799
- return errorObject(cxt, error51, errorPaths);
1799
+ return errorObject(cxt, error52, errorPaths);
1800
1800
  }
1801
- function errorObject(cxt, error51, errorPaths = {}) {
1801
+ function errorObject(cxt, error52, errorPaths = {}) {
1802
1802
  const { gen, it } = cxt;
1803
1803
  const keyValues = [
1804
1804
  errorInstancePath(it, errorPaths),
1805
1805
  errorSchemaPath(cxt, errorPaths)
1806
1806
  ];
1807
- extraErrorProps(cxt, error51, keyValues);
1807
+ extraErrorProps(cxt, error52, keyValues);
1808
1808
  return gen.object(...keyValues);
1809
1809
  }
1810
1810
  function errorInstancePath({ errorPath }, { instancePath }) {
@@ -5159,7 +5159,7 @@ var require_limitNumber = __commonJS({
5159
5159
  exclusiveMaximum: { okStr: "<", ok: ops.LT, fail: ops.GTE },
5160
5160
  exclusiveMinimum: { okStr: ">", ok: ops.GT, fail: ops.LTE }
5161
5161
  };
5162
- var error51 = {
5162
+ var error52 = {
5163
5163
  message: ({ keyword, schemaCode }) => (0, codegen_1.str)`must be ${KWDs[keyword].okStr} ${schemaCode}`,
5164
5164
  params: ({ keyword, schemaCode }) => (0, codegen_1._)`{comparison: ${KWDs[keyword].okStr}, limit: ${schemaCode}}`
5165
5165
  };
@@ -5168,7 +5168,7 @@ var require_limitNumber = __commonJS({
5168
5168
  type: "number",
5169
5169
  schemaType: "number",
5170
5170
  $data: true,
5171
- error: error51,
5171
+ error: error52,
5172
5172
  code(cxt) {
5173
5173
  const { keyword, data, schemaCode } = cxt;
5174
5174
  cxt.fail$data((0, codegen_1._)`${data} ${KWDs[keyword].fail} ${schemaCode} || isNaN(${data})`);
@@ -5184,7 +5184,7 @@ var require_multipleOf = __commonJS({
5184
5184
  "use strict";
5185
5185
  Object.defineProperty(exports2, "__esModule", { value: true });
5186
5186
  var codegen_1 = require_codegen();
5187
- var error51 = {
5187
+ var error52 = {
5188
5188
  message: ({ schemaCode }) => (0, codegen_1.str)`must be multiple of ${schemaCode}`,
5189
5189
  params: ({ schemaCode }) => (0, codegen_1._)`{multipleOf: ${schemaCode}}`
5190
5190
  };
@@ -5193,7 +5193,7 @@ var require_multipleOf = __commonJS({
5193
5193
  type: "number",
5194
5194
  schemaType: "number",
5195
5195
  $data: true,
5196
- error: error51,
5196
+ error: error52,
5197
5197
  code(cxt) {
5198
5198
  const { gen, data, schemaCode, it } = cxt;
5199
5199
  const prec = it.opts.multipleOfPrecision;
@@ -5240,7 +5240,7 @@ var require_limitLength = __commonJS({
5240
5240
  var codegen_1 = require_codegen();
5241
5241
  var util_1 = require_util();
5242
5242
  var ucs2length_1 = require_ucs2length();
5243
- var error51 = {
5243
+ var error52 = {
5244
5244
  message({ keyword, schemaCode }) {
5245
5245
  const comp = keyword === "maxLength" ? "more" : "fewer";
5246
5246
  return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} characters`;
@@ -5252,7 +5252,7 @@ var require_limitLength = __commonJS({
5252
5252
  type: "string",
5253
5253
  schemaType: "number",
5254
5254
  $data: true,
5255
- error: error51,
5255
+ error: error52,
5256
5256
  code(cxt) {
5257
5257
  const { keyword, data, schemaCode, it } = cxt;
5258
5258
  const op = keyword === "maxLength" ? codegen_1.operators.GT : codegen_1.operators.LT;
@@ -5272,7 +5272,7 @@ var require_pattern = __commonJS({
5272
5272
  var code_1 = require_code2();
5273
5273
  var util_1 = require_util();
5274
5274
  var codegen_1 = require_codegen();
5275
- var error51 = {
5275
+ var error52 = {
5276
5276
  message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
5277
5277
  params: ({ schemaCode }) => (0, codegen_1._)`{pattern: ${schemaCode}}`
5278
5278
  };
@@ -5281,7 +5281,7 @@ var require_pattern = __commonJS({
5281
5281
  type: "string",
5282
5282
  schemaType: "string",
5283
5283
  $data: true,
5284
- error: error51,
5284
+ error: error52,
5285
5285
  code(cxt) {
5286
5286
  const { gen, data, $data, schema, schemaCode, it } = cxt;
5287
5287
  const u = it.opts.unicodeRegExp ? "u" : "";
@@ -5307,7 +5307,7 @@ var require_limitProperties = __commonJS({
5307
5307
  "use strict";
5308
5308
  Object.defineProperty(exports2, "__esModule", { value: true });
5309
5309
  var codegen_1 = require_codegen();
5310
- var error51 = {
5310
+ var error52 = {
5311
5311
  message({ keyword, schemaCode }) {
5312
5312
  const comp = keyword === "maxProperties" ? "more" : "fewer";
5313
5313
  return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} properties`;
@@ -5319,7 +5319,7 @@ var require_limitProperties = __commonJS({
5319
5319
  type: "object",
5320
5320
  schemaType: "number",
5321
5321
  $data: true,
5322
- error: error51,
5322
+ error: error52,
5323
5323
  code(cxt) {
5324
5324
  const { keyword, data, schemaCode } = cxt;
5325
5325
  const op = keyword === "maxProperties" ? codegen_1.operators.GT : codegen_1.operators.LT;
@@ -5338,7 +5338,7 @@ var require_required = __commonJS({
5338
5338
  var code_1 = require_code2();
5339
5339
  var codegen_1 = require_codegen();
5340
5340
  var util_1 = require_util();
5341
- var error51 = {
5341
+ var error52 = {
5342
5342
  message: ({ params: { missingProperty } }) => (0, codegen_1.str)`must have required property '${missingProperty}'`,
5343
5343
  params: ({ params: { missingProperty } }) => (0, codegen_1._)`{missingProperty: ${missingProperty}}`
5344
5344
  };
@@ -5347,7 +5347,7 @@ var require_required = __commonJS({
5347
5347
  type: "object",
5348
5348
  schemaType: "array",
5349
5349
  $data: true,
5350
- error: error51,
5350
+ error: error52,
5351
5351
  code(cxt) {
5352
5352
  const { gen, schema, schemaCode, data, $data, it } = cxt;
5353
5353
  const { opts } = it;
@@ -5418,7 +5418,7 @@ var require_limitItems = __commonJS({
5418
5418
  "use strict";
5419
5419
  Object.defineProperty(exports2, "__esModule", { value: true });
5420
5420
  var codegen_1 = require_codegen();
5421
- var error51 = {
5421
+ var error52 = {
5422
5422
  message({ keyword, schemaCode }) {
5423
5423
  const comp = keyword === "maxItems" ? "more" : "fewer";
5424
5424
  return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} items`;
@@ -5430,7 +5430,7 @@ var require_limitItems = __commonJS({
5430
5430
  type: "array",
5431
5431
  schemaType: "number",
5432
5432
  $data: true,
5433
- error: error51,
5433
+ error: error52,
5434
5434
  code(cxt) {
5435
5435
  const { keyword, data, schemaCode } = cxt;
5436
5436
  const op = keyword === "maxItems" ? codegen_1.operators.GT : codegen_1.operators.LT;
@@ -5461,7 +5461,7 @@ var require_uniqueItems = __commonJS({
5461
5461
  var codegen_1 = require_codegen();
5462
5462
  var util_1 = require_util();
5463
5463
  var equal_1 = require_equal();
5464
- var error51 = {
5464
+ var error52 = {
5465
5465
  message: ({ params: { i, j } }) => (0, codegen_1.str)`must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
5466
5466
  params: ({ params: { i, j } }) => (0, codegen_1._)`{i: ${i}, j: ${j}}`
5467
5467
  };
@@ -5470,7 +5470,7 @@ var require_uniqueItems = __commonJS({
5470
5470
  type: "array",
5471
5471
  schemaType: "boolean",
5472
5472
  $data: true,
5473
- error: error51,
5473
+ error: error52,
5474
5474
  code(cxt) {
5475
5475
  const { gen, data, $data, schema, parentSchema, schemaCode, it } = cxt;
5476
5476
  if (!$data && !schema)
@@ -5527,14 +5527,14 @@ var require_const = __commonJS({
5527
5527
  var codegen_1 = require_codegen();
5528
5528
  var util_1 = require_util();
5529
5529
  var equal_1 = require_equal();
5530
- var error51 = {
5530
+ var error52 = {
5531
5531
  message: "must be equal to constant",
5532
5532
  params: ({ schemaCode }) => (0, codegen_1._)`{allowedValue: ${schemaCode}}`
5533
5533
  };
5534
5534
  var def = {
5535
5535
  keyword: "const",
5536
5536
  $data: true,
5537
- error: error51,
5537
+ error: error52,
5538
5538
  code(cxt) {
5539
5539
  const { gen, data, $data, schemaCode, schema } = cxt;
5540
5540
  if ($data || schema && typeof schema == "object") {
@@ -5556,7 +5556,7 @@ var require_enum = __commonJS({
5556
5556
  var codegen_1 = require_codegen();
5557
5557
  var util_1 = require_util();
5558
5558
  var equal_1 = require_equal();
5559
- var error51 = {
5559
+ var error52 = {
5560
5560
  message: "must be equal to one of the allowed values",
5561
5561
  params: ({ schemaCode }) => (0, codegen_1._)`{allowedValues: ${schemaCode}}`
5562
5562
  };
@@ -5564,7 +5564,7 @@ var require_enum = __commonJS({
5564
5564
  keyword: "enum",
5565
5565
  schemaType: "array",
5566
5566
  $data: true,
5567
- error: error51,
5567
+ error: error52,
5568
5568
  code(cxt) {
5569
5569
  const { gen, data, $data, schema, schemaCode, it } = cxt;
5570
5570
  if (!$data && schema.length === 0)
@@ -5643,7 +5643,7 @@ var require_additionalItems = __commonJS({
5643
5643
  exports2.validateAdditionalItems = void 0;
5644
5644
  var codegen_1 = require_codegen();
5645
5645
  var util_1 = require_util();
5646
- var error51 = {
5646
+ var error52 = {
5647
5647
  message: ({ params: { len } }) => (0, codegen_1.str)`must NOT have more than ${len} items`,
5648
5648
  params: ({ params: { len } }) => (0, codegen_1._)`{limit: ${len}}`
5649
5649
  };
@@ -5652,7 +5652,7 @@ var require_additionalItems = __commonJS({
5652
5652
  type: "array",
5653
5653
  schemaType: ["boolean", "object"],
5654
5654
  before: "uniqueItems",
5655
- error: error51,
5655
+ error: error52,
5656
5656
  code(cxt) {
5657
5657
  const { parentSchema, it } = cxt;
5658
5658
  const { items } = parentSchema;
@@ -5771,7 +5771,7 @@ var require_items2020 = __commonJS({
5771
5771
  var util_1 = require_util();
5772
5772
  var code_1 = require_code2();
5773
5773
  var additionalItems_1 = require_additionalItems();
5774
- var error51 = {
5774
+ var error52 = {
5775
5775
  message: ({ params: { len } }) => (0, codegen_1.str)`must NOT have more than ${len} items`,
5776
5776
  params: ({ params: { len } }) => (0, codegen_1._)`{limit: ${len}}`
5777
5777
  };
@@ -5780,7 +5780,7 @@ var require_items2020 = __commonJS({
5780
5780
  type: "array",
5781
5781
  schemaType: ["object", "boolean"],
5782
5782
  before: "uniqueItems",
5783
- error: error51,
5783
+ error: error52,
5784
5784
  code(cxt) {
5785
5785
  const { schema, parentSchema, it } = cxt;
5786
5786
  const { prefixItems } = parentSchema;
@@ -5804,7 +5804,7 @@ var require_contains = __commonJS({
5804
5804
  Object.defineProperty(exports2, "__esModule", { value: true });
5805
5805
  var codegen_1 = require_codegen();
5806
5806
  var util_1 = require_util();
5807
- var error51 = {
5807
+ var error52 = {
5808
5808
  message: ({ params: { min, max } }) => max === void 0 ? (0, codegen_1.str)`must contain at least ${min} valid item(s)` : (0, codegen_1.str)`must contain at least ${min} and no more than ${max} valid item(s)`,
5809
5809
  params: ({ params: { min, max } }) => max === void 0 ? (0, codegen_1._)`{minContains: ${min}}` : (0, codegen_1._)`{minContains: ${min}, maxContains: ${max}}`
5810
5810
  };
@@ -5814,7 +5814,7 @@ var require_contains = __commonJS({
5814
5814
  schemaType: ["object", "boolean"],
5815
5815
  before: "uniqueItems",
5816
5816
  trackErrors: true,
5817
- error: error51,
5817
+ error: error52,
5818
5818
  code(cxt) {
5819
5819
  const { gen, schema, parentSchema, data, it } = cxt;
5820
5820
  let min;
@@ -5992,7 +5992,7 @@ var require_propertyNames = __commonJS({
5992
5992
  Object.defineProperty(exports2, "__esModule", { value: true });
5993
5993
  var codegen_1 = require_codegen();
5994
5994
  var util_1 = require_util();
5995
- var error51 = {
5995
+ var error52 = {
5996
5996
  message: "property name must be valid",
5997
5997
  params: ({ params }) => (0, codegen_1._)`{propertyName: ${params.propertyName}}`
5998
5998
  };
@@ -6000,7 +6000,7 @@ var require_propertyNames = __commonJS({
6000
6000
  keyword: "propertyNames",
6001
6001
  type: "object",
6002
6002
  schemaType: ["object", "boolean"],
6003
- error: error51,
6003
+ error: error52,
6004
6004
  code(cxt) {
6005
6005
  const { gen, schema, data, it } = cxt;
6006
6006
  if ((0, util_1.alwaysValidSchema)(it, schema))
@@ -6037,7 +6037,7 @@ var require_additionalProperties = __commonJS({
6037
6037
  var codegen_1 = require_codegen();
6038
6038
  var names_1 = require_names();
6039
6039
  var util_1 = require_util();
6040
- var error51 = {
6040
+ var error52 = {
6041
6041
  message: "must NOT have additional properties",
6042
6042
  params: ({ params }) => (0, codegen_1._)`{additionalProperty: ${params.additionalProperty}}`
6043
6043
  };
@@ -6047,7 +6047,7 @@ var require_additionalProperties = __commonJS({
6047
6047
  schemaType: ["boolean", "object"],
6048
6048
  allowUndefined: true,
6049
6049
  trackErrors: true,
6050
- error: error51,
6050
+ error: error52,
6051
6051
  code(cxt) {
6052
6052
  const { gen, schema, parentSchema, data, errsCount, it } = cxt;
6053
6053
  if (!errsCount)
@@ -6321,7 +6321,7 @@ var require_oneOf = __commonJS({
6321
6321
  Object.defineProperty(exports2, "__esModule", { value: true });
6322
6322
  var codegen_1 = require_codegen();
6323
6323
  var util_1 = require_util();
6324
- var error51 = {
6324
+ var error52 = {
6325
6325
  message: "must match exactly one schema in oneOf",
6326
6326
  params: ({ params }) => (0, codegen_1._)`{passingSchemas: ${params.passing}}`
6327
6327
  };
@@ -6329,7 +6329,7 @@ var require_oneOf = __commonJS({
6329
6329
  keyword: "oneOf",
6330
6330
  schemaType: "array",
6331
6331
  trackErrors: true,
6332
- error: error51,
6332
+ error: error52,
6333
6333
  code(cxt) {
6334
6334
  const { gen, schema, parentSchema, it } = cxt;
6335
6335
  if (!Array.isArray(schema))
@@ -6406,7 +6406,7 @@ var require_if = __commonJS({
6406
6406
  Object.defineProperty(exports2, "__esModule", { value: true });
6407
6407
  var codegen_1 = require_codegen();
6408
6408
  var util_1 = require_util();
6409
- var error51 = {
6409
+ var error52 = {
6410
6410
  message: ({ params }) => (0, codegen_1.str)`must match "${params.ifClause}" schema`,
6411
6411
  params: ({ params }) => (0, codegen_1._)`{failingKeyword: ${params.ifClause}}`
6412
6412
  };
@@ -6414,7 +6414,7 @@ var require_if = __commonJS({
6414
6414
  keyword: "if",
6415
6415
  schemaType: ["object", "boolean"],
6416
6416
  trackErrors: true,
6417
- error: error51,
6417
+ error: error52,
6418
6418
  code(cxt) {
6419
6419
  const { gen, parentSchema, it } = cxt;
6420
6420
  if (parentSchema.then === void 0 && parentSchema.else === void 0) {
@@ -6540,7 +6540,7 @@ var require_format = __commonJS({
6540
6540
  "use strict";
6541
6541
  Object.defineProperty(exports2, "__esModule", { value: true });
6542
6542
  var codegen_1 = require_codegen();
6543
- var error51 = {
6543
+ var error52 = {
6544
6544
  message: ({ schemaCode }) => (0, codegen_1.str)`must match format "${schemaCode}"`,
6545
6545
  params: ({ schemaCode }) => (0, codegen_1._)`{format: ${schemaCode}}`
6546
6546
  };
@@ -6549,7 +6549,7 @@ var require_format = __commonJS({
6549
6549
  type: ["number", "string"],
6550
6550
  schemaType: "string",
6551
6551
  $data: true,
6552
- error: error51,
6552
+ error: error52,
6553
6553
  code(cxt, ruleType) {
6554
6554
  const { gen, data, $data, schema, schemaCode, it } = cxt;
6555
6555
  const { opts, errSchemaPath, schemaEnv, self } = it;
@@ -6704,7 +6704,7 @@ var require_discriminator = __commonJS({
6704
6704
  var compile_1 = require_compile();
6705
6705
  var ref_error_1 = require_ref_error();
6706
6706
  var util_1 = require_util();
6707
- var error51 = {
6707
+ var error52 = {
6708
6708
  message: ({ params: { discrError, tagName } }) => discrError === types_1.DiscrError.Tag ? `tag "${tagName}" must be string` : `value of tag "${tagName}" must be in oneOf`,
6709
6709
  params: ({ params: { discrError, tag, tagName } }) => (0, codegen_1._)`{error: ${discrError}, tag: ${tagName}, tagValue: ${tag}}`
6710
6710
  };
@@ -6712,7 +6712,7 @@ var require_discriminator = __commonJS({
6712
6712
  keyword: "discriminator",
6713
6713
  type: "object",
6714
6714
  schemaType: "object",
6715
- error: error51,
6715
+ error: error52,
6716
6716
  code(cxt) {
6717
6717
  const { gen, data, schema, parentSchema, it } = cxt;
6718
6718
  const { oneOf } = parentSchema;
@@ -7044,10 +7044,10 @@ var require_is = __commonJS({
7044
7044
  return typeof value === "number" || value instanceof Number;
7045
7045
  }
7046
7046
  exports2.number = number4;
7047
- function error51(value) {
7047
+ function error52(value) {
7048
7048
  return value instanceof Error;
7049
7049
  }
7050
- exports2.error = error51;
7050
+ exports2.error = error52;
7051
7051
  function func(value) {
7052
7052
  return typeof value === "function";
7053
7053
  }
@@ -7089,10 +7089,10 @@ var require_is2 = __commonJS({
7089
7089
  return typeof value === "number" || value instanceof Number;
7090
7090
  }
7091
7091
  exports2.number = number4;
7092
- function error51(value) {
7092
+ function error52(value) {
7093
7093
  return value instanceof Error;
7094
7094
  }
7095
- exports2.error = error51;
7095
+ exports2.error = error52;
7096
7096
  function func(value) {
7097
7097
  return typeof value === "function";
7098
7098
  }
@@ -8154,8 +8154,8 @@ var require_messageReader = __commonJS({
8154
8154
  get onError() {
8155
8155
  return this.errorEmitter.event;
8156
8156
  }
8157
- fireError(error51) {
8158
- this.errorEmitter.fire(this.asError(error51));
8157
+ fireError(error52) {
8158
+ this.errorEmitter.fire(this.asError(error52));
8159
8159
  }
8160
8160
  get onClose() {
8161
8161
  return this.closeEmitter.event;
@@ -8169,11 +8169,11 @@ var require_messageReader = __commonJS({
8169
8169
  firePartialMessage(info) {
8170
8170
  this.partialMessageEmitter.fire(info);
8171
8171
  }
8172
- asError(error51) {
8173
- if (error51 instanceof Error) {
8174
- return error51;
8172
+ asError(error52) {
8173
+ if (error52 instanceof Error) {
8174
+ return error52;
8175
8175
  } else {
8176
- return new Error(`Reader received error. Reason: ${Is.string(error51.message) ? error51.message : "unknown"}`);
8176
+ return new Error(`Reader received error. Reason: ${Is.string(error52.message) ? error52.message : "unknown"}`);
8177
8177
  }
8178
8178
  }
8179
8179
  };
@@ -8243,7 +8243,7 @@ var require_messageReader = __commonJS({
8243
8243
  const result = this.readable.onData((data) => {
8244
8244
  this.onData(data);
8245
8245
  });
8246
- this.readable.onError((error51) => this.fireError(error51));
8246
+ this.readable.onError((error52) => this.fireError(error52));
8247
8247
  this.readable.onClose(() => this.fireClose());
8248
8248
  return result;
8249
8249
  }
@@ -8280,12 +8280,12 @@ ${JSON.stringify(Object.fromEntries(headers))}`));
8280
8280
  const bytes = this.options.contentDecoder !== void 0 ? await this.options.contentDecoder.decode(body) : body;
8281
8281
  const message = await this.options.contentTypeDecoder.decode(bytes, this.options);
8282
8282
  this.callback(message);
8283
- }).catch((error51) => {
8284
- this.fireError(error51);
8283
+ }).catch((error52) => {
8284
+ this.fireError(error52);
8285
8285
  });
8286
8286
  }
8287
- } catch (error51) {
8288
- this.fireError(error51);
8287
+ } catch (error52) {
8288
+ this.fireError(error52);
8289
8289
  }
8290
8290
  }
8291
8291
  clearPartialMessageTimer() {
@@ -8344,8 +8344,8 @@ var require_messageWriter = __commonJS({
8344
8344
  get onError() {
8345
8345
  return this.errorEmitter.event;
8346
8346
  }
8347
- fireError(error51, message, count) {
8348
- this.errorEmitter.fire([this.asError(error51), message, count]);
8347
+ fireError(error52, message, count) {
8348
+ this.errorEmitter.fire([this.asError(error52), message, count]);
8349
8349
  }
8350
8350
  get onClose() {
8351
8351
  return this.closeEmitter.event;
@@ -8353,11 +8353,11 @@ var require_messageWriter = __commonJS({
8353
8353
  fireClose() {
8354
8354
  this.closeEmitter.fire(void 0);
8355
8355
  }
8356
- asError(error51) {
8357
- if (error51 instanceof Error) {
8358
- return error51;
8356
+ asError(error52) {
8357
+ if (error52 instanceof Error) {
8358
+ return error52;
8359
8359
  } else {
8360
- return new Error(`Writer received error. Reason: ${Is.string(error51.message) ? error51.message : "unknown"}`);
8360
+ return new Error(`Writer received error. Reason: ${Is.string(error52.message) ? error52.message : "unknown"}`);
8361
8361
  }
8362
8362
  }
8363
8363
  };
@@ -8380,7 +8380,7 @@ var require_messageWriter = __commonJS({
8380
8380
  this.options = ResolvedMessageWriterOptions.fromOptions(options);
8381
8381
  this.errorCount = 0;
8382
8382
  this.writeSemaphore = new semaphore_1.Semaphore(1);
8383
- this.writable.onError((error51) => this.fireError(error51));
8383
+ this.writable.onError((error52) => this.fireError(error52));
8384
8384
  this.writable.onClose(() => this.fireClose());
8385
8385
  }
8386
8386
  async write(msg) {
@@ -8397,9 +8397,9 @@ var require_messageWriter = __commonJS({
8397
8397
  headers.push(ContentLength, buffer.byteLength.toString(), CRLF);
8398
8398
  headers.push(CRLF);
8399
8399
  return this.doWrite(msg, headers, buffer);
8400
- }, (error51) => {
8401
- this.fireError(error51);
8402
- throw error51;
8400
+ }, (error52) => {
8401
+ this.fireError(error52);
8402
+ throw error52;
8403
8403
  });
8404
8404
  });
8405
8405
  }
@@ -8407,14 +8407,14 @@ var require_messageWriter = __commonJS({
8407
8407
  try {
8408
8408
  await this.writable.write(headers.join(""), "ascii");
8409
8409
  return this.writable.write(data);
8410
- } catch (error51) {
8411
- this.handleError(error51, msg);
8412
- return Promise.reject(error51);
8410
+ } catch (error52) {
8411
+ this.handleError(error52, msg);
8412
+ return Promise.reject(error52);
8413
8413
  }
8414
8414
  }
8415
- handleError(error51, msg) {
8415
+ handleError(error52, msg) {
8416
8416
  this.errorCount++;
8417
- this.fireError(error51, msg, this.errorCount);
8417
+ this.fireError(error52, msg, this.errorCount);
8418
8418
  }
8419
8419
  end() {
8420
8420
  this.writable.end();
@@ -8867,8 +8867,8 @@ var require_connection = __commonJS({
8867
8867
  closeEmitter.fire(void 0);
8868
8868
  }
8869
8869
  }
8870
- function readErrorHandler(error51) {
8871
- errorEmitter.fire([error51, void 0, void 0]);
8870
+ function readErrorHandler(error52) {
8871
+ errorEmitter.fire([error52, void 0, void 0]);
8872
8872
  }
8873
8873
  function writeErrorHandler(data) {
8874
8874
  errorEmitter.fire(data);
@@ -8962,11 +8962,11 @@ var require_connection = __commonJS({
8962
8962
  traceSendingResponse(message, method, startTime2);
8963
8963
  messageWriter.write(message).catch(() => logger.error(`Sending response failed.`));
8964
8964
  }
8965
- function replyError(error51, method, startTime2) {
8965
+ function replyError(error52, method, startTime2) {
8966
8966
  const message = {
8967
8967
  jsonrpc: version2,
8968
8968
  id: requestMessage.id,
8969
- error: error51.toJson()
8969
+ error: error52.toJson()
8970
8970
  };
8971
8971
  traceSendingResponse(message, method, startTime2);
8972
8972
  messageWriter.write(message).catch(() => logger.error(`Sending response failed.`));
@@ -9034,12 +9034,12 @@ var require_connection = __commonJS({
9034
9034
  promise2.then((resultOrError) => {
9035
9035
  requestTokens.delete(tokenKey);
9036
9036
  reply(resultOrError, requestMessage.method, startTime);
9037
- }, (error51) => {
9037
+ }, (error52) => {
9038
9038
  requestTokens.delete(tokenKey);
9039
- if (error51 instanceof messages_1.ResponseError) {
9040
- replyError(error51, requestMessage.method, startTime);
9041
- } else if (error51 && Is.string(error51.message)) {
9042
- replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error51.message}`), requestMessage.method, startTime);
9039
+ if (error52 instanceof messages_1.ResponseError) {
9040
+ replyError(error52, requestMessage.method, startTime);
9041
+ } else if (error52 && Is.string(error52.message)) {
9042
+ replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error52.message}`), requestMessage.method, startTime);
9043
9043
  } else {
9044
9044
  replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
9045
9045
  }
@@ -9048,12 +9048,12 @@ var require_connection = __commonJS({
9048
9048
  requestTokens.delete(tokenKey);
9049
9049
  reply(handlerResult, requestMessage.method, startTime);
9050
9050
  }
9051
- } catch (error51) {
9051
+ } catch (error52) {
9052
9052
  requestTokens.delete(tokenKey);
9053
- if (error51 instanceof messages_1.ResponseError) {
9054
- reply(error51, requestMessage.method, startTime);
9055
- } else if (error51 && Is.string(error51.message)) {
9056
- replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error51.message}`), requestMessage.method, startTime);
9053
+ if (error52 instanceof messages_1.ResponseError) {
9054
+ reply(error52, requestMessage.method, startTime);
9055
+ } else if (error52 && Is.string(error52.message)) {
9056
+ replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error52.message}`), requestMessage.method, startTime);
9057
9057
  } else {
9058
9058
  replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
9059
9059
  }
@@ -9081,16 +9081,16 @@ ${JSON.stringify(responseMessage.error, void 0, 4)}`);
9081
9081
  responsePromises.delete(key);
9082
9082
  try {
9083
9083
  if (responseMessage.error) {
9084
- const error51 = responseMessage.error;
9085
- responsePromise.reject(new messages_1.ResponseError(error51.code, error51.message, error51.data));
9084
+ const error52 = responseMessage.error;
9085
+ responsePromise.reject(new messages_1.ResponseError(error52.code, error52.message, error52.data));
9086
9086
  } else if (responseMessage.result !== void 0) {
9087
9087
  responsePromise.resolve(responseMessage.result);
9088
9088
  } else {
9089
9089
  throw new Error("Should never happen.");
9090
9090
  }
9091
- } catch (error51) {
9092
- if (error51.message) {
9093
- logger.error(`Response handler '${responsePromise.method}' failed with message: ${error51.message}`);
9091
+ } catch (error52) {
9092
+ if (error52.message) {
9093
+ logger.error(`Response handler '${responsePromise.method}' failed with message: ${error52.message}`);
9094
9094
  } else {
9095
9095
  logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`);
9096
9096
  }
@@ -9151,9 +9151,9 @@ ${JSON.stringify(responseMessage.error, void 0, 4)}`);
9151
9151
  } else if (starNotificationHandler) {
9152
9152
  starNotificationHandler(message.method, message.params);
9153
9153
  }
9154
- } catch (error51) {
9155
- if (error51.message) {
9156
- logger.error(`Notification handler '${message.method}' failed with message: ${error51.message}`);
9154
+ } catch (error52) {
9155
+ if (error52.message) {
9156
+ logger.error(`Notification handler '${message.method}' failed with message: ${error52.message}`);
9157
9157
  } else {
9158
9158
  logger.error(`Notification handler '${message.method}' failed unexpectedly.`);
9159
9159
  }
@@ -9311,8 +9311,8 @@ ${JSON.stringify(message, null, 4)}`);
9311
9311
  }
9312
9312
  }
9313
9313
  if (responsePromise) {
9314
- const error51 = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : "";
9315
- tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error51}`, data);
9314
+ const error52 = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : "";
9315
+ tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error52}`, data);
9316
9316
  } else {
9317
9317
  tracer.log(`Received response ${message.id} without active response promise.`, data);
9318
9318
  }
@@ -9451,9 +9451,9 @@ ${JSON.stringify(message, null, 4)}`);
9451
9451
  params: messageParams
9452
9452
  };
9453
9453
  traceSendingNotification(notificationMessage);
9454
- return messageWriter.write(notificationMessage).catch((error51) => {
9454
+ return messageWriter.write(notificationMessage).catch((error52) => {
9455
9455
  logger.error(`Sending notification failed.`);
9456
- throw error51;
9456
+ throw error52;
9457
9457
  });
9458
9458
  },
9459
9459
  onNotification: (type, handler) => {
@@ -9578,10 +9578,10 @@ ${JSON.stringify(message, null, 4)}`);
9578
9578
  try {
9579
9579
  await messageWriter.write(requestMessage);
9580
9580
  responsePromises.set(id, responsePromise);
9581
- } catch (error51) {
9581
+ } catch (error52) {
9582
9582
  logger.error(`Sending request failed.`);
9583
- responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, error51.message ? error51.message : "Unknown reason"));
9584
- throw error51;
9583
+ responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, error52.message ? error52.message : "Unknown reason"));
9584
+ throw error52;
9585
9585
  }
9586
9586
  });
9587
9587
  },
@@ -9654,9 +9654,9 @@ ${JSON.stringify(message, null, 4)}`);
9654
9654
  }
9655
9655
  state = ConnectionState.Disposed;
9656
9656
  disposeEmitter.fire(void 0);
9657
- const error51 = new messages_1.ResponseError(messages_1.ErrorCodes.PendingResponseRejected, "Pending response rejected since connection got disposed");
9657
+ const error52 = new messages_1.ResponseError(messages_1.ErrorCodes.PendingResponseRejected, "Pending response rejected since connection got disposed");
9658
9658
  for (const promise2 of responsePromises.values()) {
9659
- promise2.reject(error51);
9659
+ promise2.reject(error52);
9660
9660
  }
9661
9661
  responsePromises = /* @__PURE__ */ new Map();
9662
9662
  requestTokens = /* @__PURE__ */ new Map();
@@ -9977,11 +9977,11 @@ var require_ril = __commonJS({
9977
9977
  }
9978
9978
  write(data, encoding) {
9979
9979
  return new Promise((resolve, reject) => {
9980
- const callback = (error51) => {
9981
- if (error51 === void 0 || error51 === null) {
9980
+ const callback = (error52) => {
9981
+ if (error52 === void 0 || error52 === null) {
9982
9982
  resolve();
9983
9983
  } else {
9984
- reject(error51);
9984
+ reject(error52);
9985
9985
  }
9986
9986
  };
9987
9987
  if (typeof data === "string") {
@@ -10093,7 +10093,7 @@ var require_main = __commonJS({
10093
10093
  super();
10094
10094
  this.process = process3;
10095
10095
  let eventEmitter = this.process;
10096
- eventEmitter.on("error", (error51) => this.fireError(error51));
10096
+ eventEmitter.on("error", (error52) => this.fireError(error52));
10097
10097
  eventEmitter.on("close", () => this.fireClose());
10098
10098
  }
10099
10099
  listen(callback) {
@@ -10108,30 +10108,30 @@ var require_main = __commonJS({
10108
10108
  this.process = process3;
10109
10109
  this.errorCount = 0;
10110
10110
  const eventEmitter = this.process;
10111
- eventEmitter.on("error", (error51) => this.fireError(error51));
10111
+ eventEmitter.on("error", (error52) => this.fireError(error52));
10112
10112
  eventEmitter.on("close", () => this.fireClose);
10113
10113
  }
10114
10114
  write(msg) {
10115
10115
  try {
10116
10116
  if (typeof this.process.send === "function") {
10117
- this.process.send(msg, void 0, void 0, (error51) => {
10118
- if (error51) {
10117
+ this.process.send(msg, void 0, void 0, (error52) => {
10118
+ if (error52) {
10119
10119
  this.errorCount++;
10120
- this.handleError(error51, msg);
10120
+ this.handleError(error52, msg);
10121
10121
  } else {
10122
10122
  this.errorCount = 0;
10123
10123
  }
10124
10124
  });
10125
10125
  }
10126
10126
  return Promise.resolve();
10127
- } catch (error51) {
10128
- this.handleError(error51, msg);
10129
- return Promise.reject(error51);
10127
+ } catch (error52) {
10128
+ this.handleError(error52, msg);
10129
+ return Promise.reject(error52);
10130
10130
  }
10131
10131
  }
10132
- handleError(error51, msg) {
10132
+ handleError(error52, msg) {
10133
10133
  this.errorCount++;
10134
- this.fireError(error51, msg, this.errorCount);
10134
+ this.fireError(error52, msg, this.errorCount);
10135
10135
  }
10136
10136
  end() {
10137
10137
  }
@@ -10142,7 +10142,7 @@ var require_main = __commonJS({
10142
10142
  super();
10143
10143
  this.onData = new api_1.Emitter();
10144
10144
  port.on("close", () => this.fireClose);
10145
- port.on("error", (error51) => this.fireError(error51));
10145
+ port.on("error", (error52) => this.fireError(error52));
10146
10146
  port.on("message", (message) => {
10147
10147
  this.onData.fire(message);
10148
10148
  });
@@ -10158,20 +10158,20 @@ var require_main = __commonJS({
10158
10158
  this.port = port;
10159
10159
  this.errorCount = 0;
10160
10160
  port.on("close", () => this.fireClose());
10161
- port.on("error", (error51) => this.fireError(error51));
10161
+ port.on("error", (error52) => this.fireError(error52));
10162
10162
  }
10163
10163
  write(msg) {
10164
10164
  try {
10165
10165
  this.port.postMessage(msg);
10166
10166
  return Promise.resolve();
10167
- } catch (error51) {
10168
- this.handleError(error51, msg);
10169
- return Promise.reject(error51);
10167
+ } catch (error52) {
10168
+ this.handleError(error52, msg);
10169
+ return Promise.reject(error52);
10170
10170
  }
10171
10171
  }
10172
- handleError(error51, msg) {
10172
+ handleError(error52, msg) {
10173
10173
  this.errorCount++;
10174
- this.fireError(error51, msg, this.errorCount);
10174
+ this.fireError(error52, msg, this.errorCount);
10175
10175
  }
10176
10176
  end() {
10177
10177
  }
@@ -11908,10 +11908,10 @@ var require_is3 = __commonJS({
11908
11908
  return typeof value === "number" || value instanceof Number;
11909
11909
  }
11910
11910
  exports2.number = number4;
11911
- function error51(value) {
11911
+ function error52(value) {
11912
11912
  return value instanceof Error;
11913
11913
  }
11914
- exports2.error = error51;
11914
+ exports2.error = error52;
11915
11915
  function func(value) {
11916
11916
  return typeof value === "function";
11917
11917
  }
@@ -15066,7 +15066,7 @@ var require_server = __commonJS({
15066
15066
  return value;
15067
15067
  } else if (Is.thenable(value)) {
15068
15068
  return new Promise((resolve, reject) => {
15069
- value.then((resolved) => resolve(resolved), (error51) => reject(error51));
15069
+ value.then((resolved) => resolve(resolved), (error52) => reject(error52));
15070
15070
  });
15071
15071
  } else {
15072
15072
  return Promise.resolve(value);
@@ -15380,8 +15380,8 @@ var require_files = __commonJS({
15380
15380
  reject(new Error(`Starting process to resolve node module ${moduleName} failed`));
15381
15381
  return;
15382
15382
  }
15383
- cp.on("error", (error51) => {
15384
- reject(error51);
15383
+ cp.on("error", (error52) => {
15384
+ reject(error52);
15385
15385
  });
15386
15386
  cp.on("message", (message2) => {
15387
15387
  if (message2.c === "r") {
@@ -15398,8 +15398,8 @@ var require_files = __commonJS({
15398
15398
  a: moduleName
15399
15399
  };
15400
15400
  cp.send(message);
15401
- } catch (error51) {
15402
- reject(error51);
15401
+ } catch (error52) {
15402
+ reject(error52);
15403
15403
  }
15404
15404
  });
15405
15405
  }
@@ -15850,7 +15850,7 @@ var require_main4 = __commonJS({
15850
15850
  console.log = function log(...args) {
15851
15851
  logger.log(serialize(args));
15852
15852
  };
15853
- console.error = function error51(...args) {
15853
+ console.error = function error52(...args) {
15854
15854
  logger.error(serialize(args));
15855
15855
  };
15856
15856
  console.trace = function trace(...args) {
@@ -15878,6 +15878,7 @@ var require_node3 = __commonJS({
15878
15878
  });
15879
15879
 
15880
15880
  // src/server.ts
15881
+ var import_promises2 = require("fs/promises");
15881
15882
  var import_node_path3 = __toESM(require("path"), 1);
15882
15883
  var import_node_url3 = require("url");
15883
15884
 
@@ -16068,6 +16069,106 @@ function createTextDocument(uri, text, version2 = 0, languageId = "xml") {
16068
16069
  return document;
16069
16070
  }
16070
16071
 
16072
+ // ../model/src/blackboard-reference.ts
16073
+ var BLACKBOARD_KEY_RE = /^[A-Za-z_][A-Za-z0-9_./:-]*$/;
16074
+ function ok(reference) {
16075
+ return { ok: true, reference };
16076
+ }
16077
+ function error(kind, raw, message) {
16078
+ return {
16079
+ ok: false,
16080
+ error: {
16081
+ kind,
16082
+ raw,
16083
+ message
16084
+ }
16085
+ };
16086
+ }
16087
+ function isValidKey(key) {
16088
+ return BLACKBOARD_KEY_RE.test(key);
16089
+ }
16090
+ function parseScopedKey(raw) {
16091
+ if (!raw) {
16092
+ return error("empty-key", raw, "Blackboard reference key must not be empty");
16093
+ }
16094
+ if (raw[0] === "@") {
16095
+ const key = raw.slice(1);
16096
+ if (!key) {
16097
+ return error("empty-key", raw, "Global blackboard reference key must not be empty");
16098
+ }
16099
+ if (!isValidKey(key)) {
16100
+ return error("invalid-global-key", raw, `Invalid global blackboard reference key: ${raw}`);
16101
+ }
16102
+ return { ok: true, scope: "global", key };
16103
+ }
16104
+ if (!isValidKey(raw)) {
16105
+ return error("invalid-key", raw, `Invalid blackboard reference key: ${raw}`);
16106
+ }
16107
+ return { ok: true, scope: "local", key: raw };
16108
+ }
16109
+ function parsePortBlackboardReference(input) {
16110
+ const { portName } = input;
16111
+ const rawValue = input.rawValue.trim();
16112
+ if (rawValue === "=" || rawValue === "{=}") {
16113
+ return ok({
16114
+ scope: "local",
16115
+ key: portName,
16116
+ raw: rawValue,
16117
+ syntax: "shorthand"
16118
+ });
16119
+ }
16120
+ if (!rawValue.startsWith("{") && !rawValue.endsWith("}")) {
16121
+ return error("not-a-reference", rawValue, `Not a blackboard reference: ${rawValue}`);
16122
+ }
16123
+ if (!(rawValue.startsWith("{") && rawValue.endsWith("}"))) {
16124
+ return error(
16125
+ "unbalanced-braces",
16126
+ rawValue,
16127
+ `Unbalanced blackboard reference braces: ${rawValue}`
16128
+ );
16129
+ }
16130
+ const body = rawValue.slice(1, -1).trim();
16131
+ const parsed = parseScopedKey(body);
16132
+ if (!parsed.ok) {
16133
+ return parsed;
16134
+ }
16135
+ return ok({
16136
+ scope: parsed.scope,
16137
+ key: parsed.key,
16138
+ raw: rawValue,
16139
+ syntax: "braced"
16140
+ });
16141
+ }
16142
+ function parseScriptBlackboardIdentifier(input) {
16143
+ const { rawName } = input;
16144
+ if (!rawName.startsWith("@")) {
16145
+ return error("not-a-reference", rawName, `Not a script blackboard identifier: ${rawName}`);
16146
+ }
16147
+ const parsed = parseScopedKey(rawName);
16148
+ if (!parsed.ok) {
16149
+ return parsed;
16150
+ }
16151
+ if (parsed.scope !== "global") {
16152
+ return error(
16153
+ "not-a-reference",
16154
+ rawName,
16155
+ `Script blackboard identifiers must use the global scope marker: ${rawName}`
16156
+ );
16157
+ }
16158
+ return ok({
16159
+ scope: parsed.scope,
16160
+ key: parsed.key,
16161
+ raw: rawName,
16162
+ syntax: "script"
16163
+ });
16164
+ }
16165
+ function formatBlackboardReference(reference) {
16166
+ return reference.scope === "global" ? `{@${reference.key}}` : `{${reference.key}}`;
16167
+ }
16168
+ function makeBlackboardIdentity(reference) {
16169
+ return `${reference.scope}:${reference.key}`;
16170
+ }
16171
+
16071
16172
  // ../model/src/model.ts
16072
16173
  var BTCPP_DIAGNOSTIC_CODES = {
16073
16174
  DuplicateNodeModelId: "BT006_DUPLICATE_NODE_MODEL_ID"
@@ -16095,31 +16196,76 @@ function toPortSource(document, fallback = "inline-tree-nodes-model") {
16095
16196
  if (document.kind === "model-document") return "external-tree-nodes-model";
16096
16197
  return fallback;
16097
16198
  }
16098
- function collectBlackboardReferences(element, refs, uri) {
16199
+ function advancePosition(start, text) {
16200
+ let line = start.line;
16201
+ let character = start.character;
16202
+ let offset = start.offset;
16203
+ for (const char of text) {
16204
+ offset += char.length;
16205
+ if (char === "\n") {
16206
+ line += 1;
16207
+ character = 0;
16208
+ continue;
16209
+ }
16210
+ character += char.length;
16211
+ }
16212
+ return { line, character, offset };
16213
+ }
16214
+ function rangeFromRawText(start, prefix, text) {
16215
+ const rangeStart = advancePosition(start, prefix);
16216
+ const rangeEnd = advancePosition(rangeStart, text);
16217
+ return {
16218
+ start: rangeStart,
16219
+ end: rangeEnd
16220
+ };
16221
+ }
16222
+ function collectBlackboardReferences(element, refs, uri, documentText) {
16099
16223
  for (const attr of element.attributes || []) {
16100
- const matches = [...String(attr.value).matchAll(/\{([^}]+)\}/g)];
16101
- for (const match of matches) {
16102
- const index = match.index ?? 0;
16103
- const start = attr.valueRange.start;
16104
- const end = {
16105
- ...start,
16106
- character: start.character + match[0].length,
16107
- offset: start.offset + index + match[0].length
16108
- };
16224
+ const baseRange = attr.valueContentRange ?? attr.valueRange;
16225
+ const rawValue = documentText.slice(baseRange.start.offset, baseRange.end.offset);
16226
+ const collectParsedReference = (input) => {
16227
+ const parsed = parsePortBlackboardReference({
16228
+ portName: attr.name,
16229
+ rawValue: input.parsedRaw
16230
+ });
16231
+ if (!parsed.ok) return;
16232
+ const referenceLength = parsed.reference.raw.length;
16109
16233
  refs.push({
16110
- name: match[1],
16234
+ raw: parsed.reference.raw,
16235
+ key: parsed.reference.key,
16236
+ scope: parsed.reference.scope,
16237
+ identity: makeBlackboardIdentity(parsed.reference),
16238
+ syntax: parsed.reference.syntax,
16111
16239
  attributeName: attr.name,
16112
16240
  element,
16113
16241
  uri,
16114
- range: {
16115
- start: { ...start, character: start.character + index, offset: start.offset + index },
16116
- end
16117
- }
16242
+ range: rangeFromRawText(
16243
+ baseRange.start,
16244
+ rawValue.slice(0, input.parsedOffset),
16245
+ parsed.reference.raw.slice(0, referenceLength)
16246
+ )
16118
16247
  });
16248
+ };
16249
+ const parsedWhole = parsePortBlackboardReference({
16250
+ portName: attr.name,
16251
+ rawValue
16252
+ });
16253
+ if (parsedWhole.ok) {
16254
+ const parsedOffset = Math.max(0, rawValue.indexOf(parsedWhole.reference.raw));
16255
+ collectParsedReference({
16256
+ parsedRaw: parsedWhole.reference.raw,
16257
+ parsedOffset
16258
+ });
16259
+ continue;
16260
+ }
16261
+ for (const match of rawValue.matchAll(/\{[^}]*\}/g)) {
16262
+ const parsedRaw = match[0];
16263
+ const parsedOffset = match.index ?? 0;
16264
+ collectParsedReference({ parsedRaw, parsedOffset });
16119
16265
  }
16120
16266
  }
16121
16267
  for (const child of element.children || []) {
16122
- if (child.kind === "element") collectBlackboardReferences(child, refs, uri);
16268
+ if (child.kind === "element") collectBlackboardReferences(child, refs, uri, documentText);
16123
16269
  }
16124
16270
  }
16125
16271
  function extractTreeNodesModel(element, uri, source, editable) {
@@ -16197,8 +16343,10 @@ function extractBehaviorTrees(root, uri) {
16197
16343
  }
16198
16344
  function extractSubTreeReferences(root, uri) {
16199
16345
  const refs = [];
16200
- const walk2 = (node, parentBehaviorTreeId) => {
16346
+ const walk2 = (node, parentBehaviorTreeId, inTreeNodesModel = false) => {
16347
+ if (inTreeNodesModel) return;
16201
16348
  const currentBehaviorTreeId = node.name === "BehaviorTree" ? getAttr(node, "ID")?.value ?? parentBehaviorTreeId : parentBehaviorTreeId;
16349
+ const nextInTreeNodesModel = node.name === "TreeNodesModel";
16202
16350
  if (node.name === "SubTree") {
16203
16351
  const idAttr = getAttr(node, "ID");
16204
16352
  if (idAttr) {
@@ -16215,9 +16363,10 @@ function extractSubTreeReferences(root, uri) {
16215
16363
  }
16216
16364
  }
16217
16365
  for (const child of node.children || []) {
16218
- if (child.kind === "element") walk2(child, currentBehaviorTreeId);
16366
+ if (child.kind === "element") walk2(child, currentBehaviorTreeId, nextInTreeNodesModel);
16219
16367
  }
16220
16368
  };
16369
+ if (root.name === "TreeNodesModel") return refs;
16221
16370
  for (const child of root.children || []) {
16222
16371
  if (child.kind === "element") walk2(child);
16223
16372
  }
@@ -16278,7 +16427,11 @@ function stripSubTreeReferenceAst(def) {
16278
16427
  }
16279
16428
  function stripBlackboardReferenceAst(def) {
16280
16429
  return {
16281
- name: def.name,
16430
+ raw: def.raw,
16431
+ key: def.key,
16432
+ scope: def.scope,
16433
+ identity: def.identity,
16434
+ syntax: def.syntax,
16282
16435
  attributeName: def.attributeName,
16283
16436
  uri: def.uri,
16284
16437
  range: def.range
@@ -16337,7 +16490,11 @@ function extractDocumentModel(document, options) {
16337
16490
  const blockModels = extractTreeNodesModel(block, uri, source, editable);
16338
16491
  const seenInBlock = /* @__PURE__ */ new Map();
16339
16492
  for (const model of blockModels) {
16340
- if (addTreeNodeModelToCollections({ node: model, treeNodesModel, genericSubTreePorts })) {
16493
+ if (addTreeNodeModelToCollections({
16494
+ node: model,
16495
+ treeNodesModel,
16496
+ genericSubTreePorts
16497
+ })) {
16341
16498
  continue;
16342
16499
  }
16343
16500
  if (seenInBlock.has(model.id)) diagnostics.push(createDuplicateNodeModelDiagnostic(model));
@@ -16347,7 +16504,7 @@ function extractDocumentModel(document, options) {
16347
16504
  const subtreeReferences = root ? extractSubTreeReferences(root, uri) : [];
16348
16505
  const blackboardReferences = root ? (() => {
16349
16506
  const refs = [];
16350
- collectBlackboardReferences(root, refs, uri);
16507
+ collectBlackboardReferences(root, refs, uri, document.originalText);
16351
16508
  return refs;
16352
16509
  })() : [];
16353
16510
  const rootMainTreeToExecute = root ? getAttr(root, "main_tree_to_execute") : void 0;
@@ -16361,7 +16518,11 @@ function extractDocumentModel(document, options) {
16361
16518
  blackboardReferences,
16362
16519
  treeNodesModel,
16363
16520
  genericSubTreePorts,
16364
- rootMainTreeToExecute: rootMainTreeToExecute ? { uri, range: rootMainTreeToExecute.range, value: rootMainTreeToExecute.value } : void 0
16521
+ rootMainTreeToExecute: rootMainTreeToExecute ? {
16522
+ uri,
16523
+ range: rootMainTreeToExecute.range,
16524
+ value: rootMainTreeToExecute.value
16525
+ } : void 0
16365
16526
  });
16366
16527
  return {
16367
16528
  extracted: {
@@ -16693,35 +16854,6 @@ function areTypesCompatible(registry2, left, right) {
16693
16854
  }
16694
16855
  return leftType.compatibleWith.includes(rightType.canonical) || rightType.compatibleWith.includes(leftType.canonical);
16695
16856
  }
16696
- function isBlackboardPointer(value, strippedPointer) {
16697
- if (value.length < 3) {
16698
- return false;
16699
- }
16700
- let frontIndex = 0;
16701
- let lastIndex = value.length - 1;
16702
- while (frontIndex <= lastIndex && value[frontIndex] === " ") {
16703
- frontIndex += 1;
16704
- }
16705
- while (frontIndex <= lastIndex && value[lastIndex] === " ") {
16706
- lastIndex -= 1;
16707
- }
16708
- const size = lastIndex - frontIndex + 1;
16709
- const valid = size >= 3 && value[frontIndex] === "{" && value[lastIndex] === "}";
16710
- if (valid && strippedPointer) {
16711
- strippedPointer.current = value.slice(frontIndex + 1, lastIndex);
16712
- }
16713
- return valid;
16714
- }
16715
- function stripBlackboardPointer(value) {
16716
- const strippedPointer = {};
16717
- return isBlackboardPointer(value, strippedPointer) ? strippedPointer.current : void 0;
16718
- }
16719
- function getRemappedKey(portName, rawValue) {
16720
- if (rawValue === "{=}" || rawValue === "=") {
16721
- return portName;
16722
- }
16723
- return stripBlackboardPointer(rawValue);
16724
- }
16725
16857
 
16726
16858
  // ../model/src/generated/btcpp-v4.6.2-builtins.ts
16727
16859
  var btcppV4_6_2BuiltinModels = [
@@ -19253,8 +19385,8 @@ function parse(text, errors = [], options = ParseOptions.DEFAULT) {
19253
19385
  currentParent = previousParents.pop();
19254
19386
  },
19255
19387
  onLiteralValue: onValue,
19256
- onError: (error51, offset, length) => {
19257
- errors.push({ error: error51, offset, length });
19388
+ onError: (error52, offset, length) => {
19389
+ errors.push({ error: error52, offset, length });
19258
19390
  }
19259
19391
  };
19260
19392
  visit(text, visitor, options);
@@ -19307,8 +19439,8 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
19307
19439
  }
19308
19440
  }
19309
19441
  },
19310
- onError: (error51, offset, length) => {
19311
- errors.push({ error: error51, offset, length });
19442
+ onError: (error52, offset, length) => {
19443
+ errors.push({ error: error52, offset, length });
19312
19444
  }
19313
19445
  };
19314
19446
  visit(text, visitor, options);
@@ -19456,8 +19588,8 @@ function visit(text, visitor, options = ParseOptions.DEFAULT) {
19456
19588
  }
19457
19589
  }
19458
19590
  }
19459
- function handleError(error51, skipUntilAfter = [], skipUntil = []) {
19460
- onError(error51);
19591
+ function handleError(error52, skipUntilAfter = [], skipUntil = []) {
19592
+ onError(error52);
19461
19593
  if (skipUntilAfter.length + skipUntil.length > 0) {
19462
19594
  let token = _scanner.getToken();
19463
19595
  while (token !== 17) {
@@ -21043,10 +21175,10 @@ var initializer = (inst, def) => {
21043
21175
  };
21044
21176
  var $ZodError = $constructor("$ZodError", initializer);
21045
21177
  var $ZodRealError = $constructor("$ZodError", initializer, { Parent: Error });
21046
- function flattenError(error51, mapper = (issue2) => issue2.message) {
21178
+ function flattenError(error52, mapper = (issue2) => issue2.message) {
21047
21179
  const fieldErrors = {};
21048
21180
  const formErrors = [];
21049
- for (const sub of error51.issues) {
21181
+ for (const sub of error52.issues) {
21050
21182
  if (sub.path.length > 0) {
21051
21183
  fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
21052
21184
  fieldErrors[sub.path[0]].push(mapper(sub));
@@ -21056,10 +21188,10 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
21056
21188
  }
21057
21189
  return { formErrors, fieldErrors };
21058
21190
  }
21059
- function formatError(error51, mapper = (issue2) => issue2.message) {
21191
+ function formatError(error52, mapper = (issue2) => issue2.message) {
21060
21192
  const fieldErrors = { _errors: [] };
21061
- const processError = (error52, path4 = []) => {
21062
- for (const issue2 of error52.issues) {
21193
+ const processError = (error53, path4 = []) => {
21194
+ for (const issue2 of error53.issues) {
21063
21195
  if (issue2.code === "invalid_union" && issue2.errors.length) {
21064
21196
  issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
21065
21197
  } else if (issue2.code === "invalid_key") {
@@ -21089,14 +21221,14 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
21089
21221
  }
21090
21222
  }
21091
21223
  };
21092
- processError(error51);
21224
+ processError(error52);
21093
21225
  return fieldErrors;
21094
21226
  }
21095
- function treeifyError(error51, mapper = (issue2) => issue2.message) {
21227
+ function treeifyError(error52, mapper = (issue2) => issue2.message) {
21096
21228
  const result = { errors: [] };
21097
- const processError = (error52, path4 = []) => {
21229
+ const processError = (error53, path4 = []) => {
21098
21230
  var _a3, _b;
21099
- for (const issue2 of error52.issues) {
21231
+ for (const issue2 of error53.issues) {
21100
21232
  if (issue2.code === "invalid_union" && issue2.errors.length) {
21101
21233
  issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
21102
21234
  } else if (issue2.code === "invalid_key") {
@@ -21131,7 +21263,7 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
21131
21263
  }
21132
21264
  }
21133
21265
  };
21134
- processError(error51);
21266
+ processError(error52);
21135
21267
  return result;
21136
21268
  }
21137
21269
  function toDotPath(_path) {
@@ -21152,9 +21284,9 @@ function toDotPath(_path) {
21152
21284
  }
21153
21285
  return segs.join("");
21154
21286
  }
21155
- function prettifyError(error51) {
21287
+ function prettifyError(error52) {
21156
21288
  const lines = [];
21157
- const issues = [...error51.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);
21289
+ const issues = [...error52.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);
21158
21290
  for (const issue2 of issues) {
21159
21291
  lines.push(`\u2716 ${issue2.message}`);
21160
21292
  if (issue2.path?.length)
@@ -24152,7 +24284,7 @@ __export(locales_exports, {
24152
24284
  });
24153
24285
 
24154
24286
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ar.js
24155
- var error = () => {
24287
+ var error2 = () => {
24156
24288
  const Sizable = {
24157
24289
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
24158
24290
  file: { unit: "\u0628\u0627\u064A\u062A", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -24254,12 +24386,12 @@ var error = () => {
24254
24386
  };
24255
24387
  function ar_default() {
24256
24388
  return {
24257
- localeError: error()
24389
+ localeError: error2()
24258
24390
  };
24259
24391
  }
24260
24392
 
24261
24393
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/az.js
24262
- var error2 = () => {
24394
+ var error3 = () => {
24263
24395
  const Sizable = {
24264
24396
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
24265
24397
  file: { unit: "bayt", verb: "olmal\u0131d\u0131r" },
@@ -24360,7 +24492,7 @@ var error2 = () => {
24360
24492
  };
24361
24493
  function az_default() {
24362
24494
  return {
24363
- localeError: error2()
24495
+ localeError: error3()
24364
24496
  };
24365
24497
  }
24366
24498
 
@@ -24380,7 +24512,7 @@ function getBelarusianPlural(count, one, few, many) {
24380
24512
  }
24381
24513
  return many;
24382
24514
  }
24383
- var error3 = () => {
24515
+ var error4 = () => {
24384
24516
  const Sizable = {
24385
24517
  string: {
24386
24518
  unit: {
@@ -24517,12 +24649,12 @@ var error3 = () => {
24517
24649
  };
24518
24650
  function be_default() {
24519
24651
  return {
24520
- localeError: error3()
24652
+ localeError: error4()
24521
24653
  };
24522
24654
  }
24523
24655
 
24524
24656
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/bg.js
24525
- var error4 = () => {
24657
+ var error5 = () => {
24526
24658
  const Sizable = {
24527
24659
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
24528
24660
  file: { unit: "\u0431\u0430\u0439\u0442\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -24638,12 +24770,12 @@ var error4 = () => {
24638
24770
  };
24639
24771
  function bg_default() {
24640
24772
  return {
24641
- localeError: error4()
24773
+ localeError: error5()
24642
24774
  };
24643
24775
  }
24644
24776
 
24645
24777
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ca.js
24646
- var error5 = () => {
24778
+ var error6 = () => {
24647
24779
  const Sizable = {
24648
24780
  string: { unit: "car\xE0cters", verb: "contenir" },
24649
24781
  file: { unit: "bytes", verb: "contenir" },
@@ -24747,12 +24879,12 @@ var error5 = () => {
24747
24879
  };
24748
24880
  function ca_default() {
24749
24881
  return {
24750
- localeError: error5()
24882
+ localeError: error6()
24751
24883
  };
24752
24884
  }
24753
24885
 
24754
24886
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/cs.js
24755
- var error6 = () => {
24887
+ var error7 = () => {
24756
24888
  const Sizable = {
24757
24889
  string: { unit: "znak\u016F", verb: "m\xEDt" },
24758
24890
  file: { unit: "bajt\u016F", verb: "m\xEDt" },
@@ -24859,12 +24991,12 @@ var error6 = () => {
24859
24991
  };
24860
24992
  function cs_default() {
24861
24993
  return {
24862
- localeError: error6()
24994
+ localeError: error7()
24863
24995
  };
24864
24996
  }
24865
24997
 
24866
24998
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/da.js
24867
- var error7 = () => {
24999
+ var error8 = () => {
24868
25000
  const Sizable = {
24869
25001
  string: { unit: "tegn", verb: "havde" },
24870
25002
  file: { unit: "bytes", verb: "havde" },
@@ -24975,12 +25107,12 @@ var error7 = () => {
24975
25107
  };
24976
25108
  function da_default() {
24977
25109
  return {
24978
- localeError: error7()
25110
+ localeError: error8()
24979
25111
  };
24980
25112
  }
24981
25113
 
24982
25114
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/de.js
24983
- var error8 = () => {
25115
+ var error9 = () => {
24984
25116
  const Sizable = {
24985
25117
  string: { unit: "Zeichen", verb: "zu haben" },
24986
25118
  file: { unit: "Bytes", verb: "zu haben" },
@@ -25084,12 +25216,12 @@ var error8 = () => {
25084
25216
  };
25085
25217
  function de_default() {
25086
25218
  return {
25087
- localeError: error8()
25219
+ localeError: error9()
25088
25220
  };
25089
25221
  }
25090
25222
 
25091
25223
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/el.js
25092
- var error9 = () => {
25224
+ var error10 = () => {
25093
25225
  const Sizable = {
25094
25226
  string: { unit: "\u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03B5\u03C2", verb: "\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9" },
25095
25227
  file: { unit: "bytes", verb: "\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9" },
@@ -25194,12 +25326,12 @@ var error9 = () => {
25194
25326
  };
25195
25327
  function el_default() {
25196
25328
  return {
25197
- localeError: error9()
25329
+ localeError: error10()
25198
25330
  };
25199
25331
  }
25200
25332
 
25201
25333
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/en.js
25202
- var error10 = () => {
25334
+ var error11 = () => {
25203
25335
  const Sizable = {
25204
25336
  string: { unit: "characters", verb: "to have" },
25205
25337
  file: { unit: "bytes", verb: "to have" },
@@ -25307,12 +25439,12 @@ var error10 = () => {
25307
25439
  };
25308
25440
  function en_default() {
25309
25441
  return {
25310
- localeError: error10()
25442
+ localeError: error11()
25311
25443
  };
25312
25444
  }
25313
25445
 
25314
25446
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/eo.js
25315
- var error11 = () => {
25447
+ var error12 = () => {
25316
25448
  const Sizable = {
25317
25449
  string: { unit: "karaktrojn", verb: "havi" },
25318
25450
  file: { unit: "bajtojn", verb: "havi" },
@@ -25417,12 +25549,12 @@ var error11 = () => {
25417
25549
  };
25418
25550
  function eo_default() {
25419
25551
  return {
25420
- localeError: error11()
25552
+ localeError: error12()
25421
25553
  };
25422
25554
  }
25423
25555
 
25424
25556
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/es.js
25425
- var error12 = () => {
25557
+ var error13 = () => {
25426
25558
  const Sizable = {
25427
25559
  string: { unit: "caracteres", verb: "tener" },
25428
25560
  file: { unit: "bytes", verb: "tener" },
@@ -25550,12 +25682,12 @@ var error12 = () => {
25550
25682
  };
25551
25683
  function es_default() {
25552
25684
  return {
25553
- localeError: error12()
25685
+ localeError: error13()
25554
25686
  };
25555
25687
  }
25556
25688
 
25557
25689
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fa.js
25558
- var error13 = () => {
25690
+ var error14 = () => {
25559
25691
  const Sizable = {
25560
25692
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
25561
25693
  file: { unit: "\u0628\u0627\u06CC\u062A", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -25665,12 +25797,12 @@ var error13 = () => {
25665
25797
  };
25666
25798
  function fa_default() {
25667
25799
  return {
25668
- localeError: error13()
25800
+ localeError: error14()
25669
25801
  };
25670
25802
  }
25671
25803
 
25672
25804
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fi.js
25673
- var error14 = () => {
25805
+ var error15 = () => {
25674
25806
  const Sizable = {
25675
25807
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
25676
25808
  file: { unit: "tavua", subject: "tiedoston" },
@@ -25778,12 +25910,12 @@ var error14 = () => {
25778
25910
  };
25779
25911
  function fi_default() {
25780
25912
  return {
25781
- localeError: error14()
25913
+ localeError: error15()
25782
25914
  };
25783
25915
  }
25784
25916
 
25785
25917
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr.js
25786
- var error15 = () => {
25918
+ var error16 = () => {
25787
25919
  const Sizable = {
25788
25920
  string: { unit: "caract\xE8res", verb: "avoir" },
25789
25921
  file: { unit: "octets", verb: "avoir" },
@@ -25904,12 +26036,12 @@ var error15 = () => {
25904
26036
  };
25905
26037
  function fr_default() {
25906
26038
  return {
25907
- localeError: error15()
26039
+ localeError: error16()
25908
26040
  };
25909
26041
  }
25910
26042
 
25911
26043
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr-CA.js
25912
- var error16 = () => {
26044
+ var error17 = () => {
25913
26045
  const Sizable = {
25914
26046
  string: { unit: "caract\xE8res", verb: "avoir" },
25915
26047
  file: { unit: "octets", verb: "avoir" },
@@ -26012,12 +26144,12 @@ var error16 = () => {
26012
26144
  };
26013
26145
  function fr_CA_default() {
26014
26146
  return {
26015
- localeError: error16()
26147
+ localeError: error17()
26016
26148
  };
26017
26149
  }
26018
26150
 
26019
26151
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/he.js
26020
- var error17 = () => {
26152
+ var error18 = () => {
26021
26153
  const TypeNames = {
26022
26154
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
26023
26155
  number: { label: "\u05DE\u05E1\u05E4\u05E8", gender: "m" },
@@ -26207,12 +26339,12 @@ var error17 = () => {
26207
26339
  };
26208
26340
  function he_default() {
26209
26341
  return {
26210
- localeError: error17()
26342
+ localeError: error18()
26211
26343
  };
26212
26344
  }
26213
26345
 
26214
26346
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hr.js
26215
- var error18 = () => {
26347
+ var error19 = () => {
26216
26348
  const Sizable = {
26217
26349
  string: { unit: "znakova", verb: "imati" },
26218
26350
  file: { unit: "bajtova", verb: "imati" },
@@ -26330,12 +26462,12 @@ var error18 = () => {
26330
26462
  };
26331
26463
  function hr_default() {
26332
26464
  return {
26333
- localeError: error18()
26465
+ localeError: error19()
26334
26466
  };
26335
26467
  }
26336
26468
 
26337
26469
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hu.js
26338
- var error19 = () => {
26470
+ var error20 = () => {
26339
26471
  const Sizable = {
26340
26472
  string: { unit: "karakter", verb: "legyen" },
26341
26473
  file: { unit: "byte", verb: "legyen" },
@@ -26439,7 +26571,7 @@ var error19 = () => {
26439
26571
  };
26440
26572
  function hu_default() {
26441
26573
  return {
26442
- localeError: error19()
26574
+ localeError: error20()
26443
26575
  };
26444
26576
  }
26445
26577
 
@@ -26454,7 +26586,7 @@ function withDefiniteArticle(word) {
26454
26586
  const lastChar = word[word.length - 1];
26455
26587
  return word + (vowels.includes(lastChar) ? "\u0576" : "\u0568");
26456
26588
  }
26457
- var error20 = () => {
26589
+ var error21 = () => {
26458
26590
  const Sizable = {
26459
26591
  string: {
26460
26592
  unit: {
@@ -26587,12 +26719,12 @@ var error20 = () => {
26587
26719
  };
26588
26720
  function hy_default() {
26589
26721
  return {
26590
- localeError: error20()
26722
+ localeError: error21()
26591
26723
  };
26592
26724
  }
26593
26725
 
26594
26726
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/id.js
26595
- var error21 = () => {
26727
+ var error22 = () => {
26596
26728
  const Sizable = {
26597
26729
  string: { unit: "karakter", verb: "memiliki" },
26598
26730
  file: { unit: "byte", verb: "memiliki" },
@@ -26694,12 +26826,12 @@ var error21 = () => {
26694
26826
  };
26695
26827
  function id_default() {
26696
26828
  return {
26697
- localeError: error21()
26829
+ localeError: error22()
26698
26830
  };
26699
26831
  }
26700
26832
 
26701
26833
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/is.js
26702
- var error22 = () => {
26834
+ var error23 = () => {
26703
26835
  const Sizable = {
26704
26836
  string: { unit: "stafi", verb: "a\xF0 hafa" },
26705
26837
  file: { unit: "b\xE6ti", verb: "a\xF0 hafa" },
@@ -26804,12 +26936,12 @@ var error22 = () => {
26804
26936
  };
26805
26937
  function is_default() {
26806
26938
  return {
26807
- localeError: error22()
26939
+ localeError: error23()
26808
26940
  };
26809
26941
  }
26810
26942
 
26811
26943
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/it.js
26812
- var error23 = () => {
26944
+ var error24 = () => {
26813
26945
  const Sizable = {
26814
26946
  string: { unit: "caratteri", verb: "avere" },
26815
26947
  file: { unit: "byte", verb: "avere" },
@@ -26913,12 +27045,12 @@ var error23 = () => {
26913
27045
  };
26914
27046
  function it_default() {
26915
27047
  return {
26916
- localeError: error23()
27048
+ localeError: error24()
26917
27049
  };
26918
27050
  }
26919
27051
 
26920
27052
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ja.js
26921
- var error24 = () => {
27053
+ var error25 = () => {
26922
27054
  const Sizable = {
26923
27055
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
26924
27056
  file: { unit: "\u30D0\u30A4\u30C8", verb: "\u3067\u3042\u308B" },
@@ -27021,12 +27153,12 @@ var error24 = () => {
27021
27153
  };
27022
27154
  function ja_default() {
27023
27155
  return {
27024
- localeError: error24()
27156
+ localeError: error25()
27025
27157
  };
27026
27158
  }
27027
27159
 
27028
27160
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ka.js
27029
- var error25 = () => {
27161
+ var error26 = () => {
27030
27162
  const Sizable = {
27031
27163
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
27032
27164
  file: { unit: "\u10D1\u10D0\u10D8\u10E2\u10D8", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -27134,12 +27266,12 @@ var error25 = () => {
27134
27266
  };
27135
27267
  function ka_default() {
27136
27268
  return {
27137
- localeError: error25()
27269
+ localeError: error26()
27138
27270
  };
27139
27271
  }
27140
27272
 
27141
27273
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/km.js
27142
- var error26 = () => {
27274
+ var error27 = () => {
27143
27275
  const Sizable = {
27144
27276
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
27145
27277
  file: { unit: "\u1794\u17C3", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -27245,7 +27377,7 @@ var error26 = () => {
27245
27377
  };
27246
27378
  function km_default() {
27247
27379
  return {
27248
- localeError: error26()
27380
+ localeError: error27()
27249
27381
  };
27250
27382
  }
27251
27383
 
@@ -27255,7 +27387,7 @@ function kh_default() {
27255
27387
  }
27256
27388
 
27257
27389
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ko.js
27258
- var error27 = () => {
27390
+ var error28 = () => {
27259
27391
  const Sizable = {
27260
27392
  string: { unit: "\uBB38\uC790", verb: "to have" },
27261
27393
  file: { unit: "\uBC14\uC774\uD2B8", verb: "to have" },
@@ -27362,7 +27494,7 @@ var error27 = () => {
27362
27494
  };
27363
27495
  function ko_default() {
27364
27496
  return {
27365
- localeError: error27()
27497
+ localeError: error28()
27366
27498
  };
27367
27499
  }
27368
27500
 
@@ -27380,7 +27512,7 @@ function getUnitTypeFromNumber(number4) {
27380
27512
  return "one";
27381
27513
  return "few";
27382
27514
  }
27383
- var error28 = () => {
27515
+ var error29 = () => {
27384
27516
  const Sizable = {
27385
27517
  string: {
27386
27518
  unit: {
@@ -27566,12 +27698,12 @@ var error28 = () => {
27566
27698
  };
27567
27699
  function lt_default() {
27568
27700
  return {
27569
- localeError: error28()
27701
+ localeError: error29()
27570
27702
  };
27571
27703
  }
27572
27704
 
27573
27705
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/mk.js
27574
- var error29 = () => {
27706
+ var error30 = () => {
27575
27707
  const Sizable = {
27576
27708
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
27577
27709
  file: { unit: "\u0431\u0430\u0458\u0442\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -27676,12 +27808,12 @@ var error29 = () => {
27676
27808
  };
27677
27809
  function mk_default() {
27678
27810
  return {
27679
- localeError: error29()
27811
+ localeError: error30()
27680
27812
  };
27681
27813
  }
27682
27814
 
27683
27815
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ms.js
27684
- var error30 = () => {
27816
+ var error31 = () => {
27685
27817
  const Sizable = {
27686
27818
  string: { unit: "aksara", verb: "mempunyai" },
27687
27819
  file: { unit: "bait", verb: "mempunyai" },
@@ -27784,12 +27916,12 @@ var error30 = () => {
27784
27916
  };
27785
27917
  function ms_default() {
27786
27918
  return {
27787
- localeError: error30()
27919
+ localeError: error31()
27788
27920
  };
27789
27921
  }
27790
27922
 
27791
27923
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/nl.js
27792
- var error31 = () => {
27924
+ var error32 = () => {
27793
27925
  const Sizable = {
27794
27926
  string: { unit: "tekens", verb: "heeft" },
27795
27927
  file: { unit: "bytes", verb: "heeft" },
@@ -27895,12 +28027,12 @@ var error31 = () => {
27895
28027
  };
27896
28028
  function nl_default() {
27897
28029
  return {
27898
- localeError: error31()
28030
+ localeError: error32()
27899
28031
  };
27900
28032
  }
27901
28033
 
27902
28034
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/no.js
27903
- var error32 = () => {
28035
+ var error33 = () => {
27904
28036
  const Sizable = {
27905
28037
  string: { unit: "tegn", verb: "\xE5 ha" },
27906
28038
  file: { unit: "bytes", verb: "\xE5 ha" },
@@ -28004,12 +28136,12 @@ var error32 = () => {
28004
28136
  };
28005
28137
  function no_default() {
28006
28138
  return {
28007
- localeError: error32()
28139
+ localeError: error33()
28008
28140
  };
28009
28141
  }
28010
28142
 
28011
28143
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ota.js
28012
- var error33 = () => {
28144
+ var error34 = () => {
28013
28145
  const Sizable = {
28014
28146
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
28015
28147
  file: { unit: "bayt", verb: "olmal\u0131d\u0131r" },
@@ -28114,12 +28246,12 @@ var error33 = () => {
28114
28246
  };
28115
28247
  function ota_default() {
28116
28248
  return {
28117
- localeError: error33()
28249
+ localeError: error34()
28118
28250
  };
28119
28251
  }
28120
28252
 
28121
28253
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ps.js
28122
- var error34 = () => {
28254
+ var error35 = () => {
28123
28255
  const Sizable = {
28124
28256
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
28125
28257
  file: { unit: "\u0628\u0627\u06CC\u067C\u0633", verb: "\u0648\u0644\u0631\u064A" },
@@ -28229,12 +28361,12 @@ var error34 = () => {
28229
28361
  };
28230
28362
  function ps_default() {
28231
28363
  return {
28232
- localeError: error34()
28364
+ localeError: error35()
28233
28365
  };
28234
28366
  }
28235
28367
 
28236
28368
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pl.js
28237
- var error35 = () => {
28369
+ var error36 = () => {
28238
28370
  const Sizable = {
28239
28371
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
28240
28372
  file: { unit: "bajt\xF3w", verb: "mie\u0107" },
@@ -28339,12 +28471,12 @@ var error35 = () => {
28339
28471
  };
28340
28472
  function pl_default() {
28341
28473
  return {
28342
- localeError: error35()
28474
+ localeError: error36()
28343
28475
  };
28344
28476
  }
28345
28477
 
28346
28478
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pt.js
28347
- var error36 = () => {
28479
+ var error37 = () => {
28348
28480
  const Sizable = {
28349
28481
  string: { unit: "caracteres", verb: "ter" },
28350
28482
  file: { unit: "bytes", verb: "ter" },
@@ -28448,12 +28580,12 @@ var error36 = () => {
28448
28580
  };
28449
28581
  function pt_default() {
28450
28582
  return {
28451
- localeError: error36()
28583
+ localeError: error37()
28452
28584
  };
28453
28585
  }
28454
28586
 
28455
28587
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ro.js
28456
- var error37 = () => {
28588
+ var error38 = () => {
28457
28589
  const Sizable = {
28458
28590
  string: { unit: "caractere", verb: "s\u0103 aib\u0103" },
28459
28591
  file: { unit: "octe\u021Bi", verb: "s\u0103 aib\u0103" },
@@ -28568,7 +28700,7 @@ var error37 = () => {
28568
28700
  };
28569
28701
  function ro_default() {
28570
28702
  return {
28571
- localeError: error37()
28703
+ localeError: error38()
28572
28704
  };
28573
28705
  }
28574
28706
 
@@ -28588,7 +28720,7 @@ function getRussianPlural(count, one, few, many) {
28588
28720
  }
28589
28721
  return many;
28590
28722
  }
28591
- var error38 = () => {
28723
+ var error39 = () => {
28592
28724
  const Sizable = {
28593
28725
  string: {
28594
28726
  unit: {
@@ -28725,12 +28857,12 @@ var error38 = () => {
28725
28857
  };
28726
28858
  function ru_default() {
28727
28859
  return {
28728
- localeError: error38()
28860
+ localeError: error39()
28729
28861
  };
28730
28862
  }
28731
28863
 
28732
28864
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sl.js
28733
- var error39 = () => {
28865
+ var error40 = () => {
28734
28866
  const Sizable = {
28735
28867
  string: { unit: "znakov", verb: "imeti" },
28736
28868
  file: { unit: "bajtov", verb: "imeti" },
@@ -28835,12 +28967,12 @@ var error39 = () => {
28835
28967
  };
28836
28968
  function sl_default() {
28837
28969
  return {
28838
- localeError: error39()
28970
+ localeError: error40()
28839
28971
  };
28840
28972
  }
28841
28973
 
28842
28974
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sv.js
28843
- var error40 = () => {
28975
+ var error41 = () => {
28844
28976
  const Sizable = {
28845
28977
  string: { unit: "tecken", verb: "att ha" },
28846
28978
  file: { unit: "bytes", verb: "att ha" },
@@ -28946,12 +29078,12 @@ var error40 = () => {
28946
29078
  };
28947
29079
  function sv_default() {
28948
29080
  return {
28949
- localeError: error40()
29081
+ localeError: error41()
28950
29082
  };
28951
29083
  }
28952
29084
 
28953
29085
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ta.js
28954
- var error41 = () => {
29086
+ var error42 = () => {
28955
29087
  const Sizable = {
28956
29088
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
28957
29089
  file: { unit: "\u0BAA\u0BC8\u0B9F\u0BCD\u0B9F\u0BC1\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -29057,12 +29189,12 @@ var error41 = () => {
29057
29189
  };
29058
29190
  function ta_default() {
29059
29191
  return {
29060
- localeError: error41()
29192
+ localeError: error42()
29061
29193
  };
29062
29194
  }
29063
29195
 
29064
29196
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/th.js
29065
- var error42 = () => {
29197
+ var error43 = () => {
29066
29198
  const Sizable = {
29067
29199
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
29068
29200
  file: { unit: "\u0E44\u0E1A\u0E15\u0E4C", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -29168,12 +29300,12 @@ var error42 = () => {
29168
29300
  };
29169
29301
  function th_default() {
29170
29302
  return {
29171
- localeError: error42()
29303
+ localeError: error43()
29172
29304
  };
29173
29305
  }
29174
29306
 
29175
29307
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/tr.js
29176
- var error43 = () => {
29308
+ var error44 = () => {
29177
29309
  const Sizable = {
29178
29310
  string: { unit: "karakter", verb: "olmal\u0131" },
29179
29311
  file: { unit: "bayt", verb: "olmal\u0131" },
@@ -29274,12 +29406,12 @@ var error43 = () => {
29274
29406
  };
29275
29407
  function tr_default() {
29276
29408
  return {
29277
- localeError: error43()
29409
+ localeError: error44()
29278
29410
  };
29279
29411
  }
29280
29412
 
29281
29413
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uk.js
29282
- var error44 = () => {
29414
+ var error45 = () => {
29283
29415
  const Sizable = {
29284
29416
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
29285
29417
  file: { unit: "\u0431\u0430\u0439\u0442\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -29383,7 +29515,7 @@ var error44 = () => {
29383
29515
  };
29384
29516
  function uk_default() {
29385
29517
  return {
29386
- localeError: error44()
29518
+ localeError: error45()
29387
29519
  };
29388
29520
  }
29389
29521
 
@@ -29393,7 +29525,7 @@ function ua_default() {
29393
29525
  }
29394
29526
 
29395
29527
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ur.js
29396
- var error45 = () => {
29528
+ var error46 = () => {
29397
29529
  const Sizable = {
29398
29530
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
29399
29531
  file: { unit: "\u0628\u0627\u0626\u0679\u0633", verb: "\u06C1\u0648\u0646\u0627" },
@@ -29499,12 +29631,12 @@ var error45 = () => {
29499
29631
  };
29500
29632
  function ur_default() {
29501
29633
  return {
29502
- localeError: error45()
29634
+ localeError: error46()
29503
29635
  };
29504
29636
  }
29505
29637
 
29506
29638
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uz.js
29507
- var error46 = () => {
29639
+ var error47 = () => {
29508
29640
  const Sizable = {
29509
29641
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
29510
29642
  file: { unit: "bayt", verb: "bo\u2018lishi kerak" },
@@ -29610,12 +29742,12 @@ var error46 = () => {
29610
29742
  };
29611
29743
  function uz_default() {
29612
29744
  return {
29613
- localeError: error46()
29745
+ localeError: error47()
29614
29746
  };
29615
29747
  }
29616
29748
 
29617
29749
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/vi.js
29618
- var error47 = () => {
29750
+ var error48 = () => {
29619
29751
  const Sizable = {
29620
29752
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
29621
29753
  file: { unit: "byte", verb: "c\xF3" },
@@ -29719,12 +29851,12 @@ var error47 = () => {
29719
29851
  };
29720
29852
  function vi_default() {
29721
29853
  return {
29722
- localeError: error47()
29854
+ localeError: error48()
29723
29855
  };
29724
29856
  }
29725
29857
 
29726
29858
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-CN.js
29727
- var error48 = () => {
29859
+ var error49 = () => {
29728
29860
  const Sizable = {
29729
29861
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
29730
29862
  file: { unit: "\u5B57\u8282", verb: "\u5305\u542B" },
@@ -29829,12 +29961,12 @@ var error48 = () => {
29829
29961
  };
29830
29962
  function zh_CN_default() {
29831
29963
  return {
29832
- localeError: error48()
29964
+ localeError: error49()
29833
29965
  };
29834
29966
  }
29835
29967
 
29836
29968
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-TW.js
29837
- var error49 = () => {
29969
+ var error50 = () => {
29838
29970
  const Sizable = {
29839
29971
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
29840
29972
  file: { unit: "\u4F4D\u5143\u7D44", verb: "\u64C1\u6709" },
@@ -29937,12 +30069,12 @@ var error49 = () => {
29937
30069
  };
29938
30070
  function zh_TW_default() {
29939
30071
  return {
29940
- localeError: error49()
30072
+ localeError: error50()
29941
30073
  };
29942
30074
  }
29943
30075
 
29944
30076
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/yo.js
29945
- var error50 = () => {
30077
+ var error51 = () => {
29946
30078
  const Sizable = {
29947
30079
  string: { unit: "\xE0mi", verb: "n\xED" },
29948
30080
  file: { unit: "bytes", verb: "n\xED" },
@@ -30045,7 +30177,7 @@ var error50 = () => {
30045
30177
  };
30046
30178
  function yo_default() {
30047
30179
  return {
30048
- localeError: error50()
30180
+ localeError: error51()
30049
30181
  };
30050
30182
  }
30051
30183
 
@@ -34392,7 +34524,7 @@ function parseModelAugmentationFile(text, options) {
34392
34524
  uri,
34393
34525
  path: options?.path
34394
34526
  };
34395
- } catch (error51) {
34527
+ } catch (error52) {
34396
34528
  return {
34397
34529
  ok: false,
34398
34530
  uri,
@@ -34401,7 +34533,7 @@ function parseModelAugmentationFile(text, options) {
34401
34533
  {
34402
34534
  kind: "json",
34403
34535
  message: "the file could not be parsed as JSON",
34404
- notes: [String(error51.message || error51)]
34536
+ notes: [String(error52.message || error52)]
34405
34537
  }
34406
34538
  ]
34407
34539
  };
@@ -34551,7 +34683,7 @@ function isInvalidValueIssue(issue2) {
34551
34683
  return unionErrors.flat().some(isZodIssueLikeInvalidValue);
34552
34684
  }
34553
34685
  const zodUnionErrors = issue2.unionErrors;
34554
- return Array.isArray(zodUnionErrors) ? zodUnionErrors.flatMap((error51) => error51.issues ?? []).some(isZodIssueLikeInvalidValue) : false;
34686
+ return Array.isArray(zodUnionErrors) ? zodUnionErrors.flatMap((error52) => error52.issues ?? []).some(isZodIssueLikeInvalidValue) : false;
34555
34687
  }
34556
34688
  function isZodIssueLikeInvalidValue(issue2) {
34557
34689
  return typeof issue2 === "object" && issue2 !== null && isInvalidValueIssue(issue2);
@@ -34627,8 +34759,8 @@ function normalizeParsedBtxmlConfig(raw) {
34627
34759
  formatter: normalizeRawFormatterOverrideConfig(override.formatter)
34628
34760
  })
34629
34761
  );
34630
- const ok = !diagnostics.some((d) => d.severity === DiagnosticSeverity.Error);
34631
- return { config: config2, diagnostics, ok };
34762
+ const ok2 = !diagnostics.some((d) => d.severity === DiagnosticSeverity.Error);
34763
+ return { config: config2, diagnostics, ok: ok2 };
34632
34764
  }
34633
34765
  function normalizeBtxmlConfig(raw) {
34634
34766
  const parsed = parseBtxmlConfig(raw);
@@ -34759,6 +34891,7 @@ var RuleCodes = {
34759
34891
  InvalidScriptOperandType: "BT407_INVALID_SCRIPT_OPERAND_TYPE",
34760
34892
  ScriptResultNotBoolCompatible: "BT408_SCRIPT_RESULT_NOT_BOOL_COMPATIBLE",
34761
34893
  ScriptVariableTypeMismatch: "BT410_SCRIPT_VARIABLE_TYPE_MISMATCH",
34894
+ InvalidGlobalBlackboardIdentifier: "BT411_INVALID_GLOBAL_BLACKBOARD_IDENTIFIER",
34762
34895
  InvalidRootElement: "BT001_INVALID_ROOT_ELEMENT",
34763
34896
  MissingBTCPPFormat: "BT002_MISSING_BTCPP_FORMAT",
34764
34897
  MissingBehaviorTreeID: "BT003_MISSING_BEHAVIOR_TREE_ID",
@@ -34837,7 +34970,8 @@ var RULES = {
34837
34970
  codes: [
34838
34971
  RuleCodes.AssignmentToUnknownVariable,
34839
34972
  RuleCodes.InvalidCompoundAssignment,
34840
- RuleCodes.ScriptVariableTypeMismatch
34973
+ RuleCodes.ScriptVariableTypeMismatch,
34974
+ RuleCodes.InvalidGlobalBlackboardIdentifier
34841
34975
  ],
34842
34976
  defaultSeverity: "error",
34843
34977
  description: "Script assignments must target known variables and use compatible types."
@@ -36200,7 +36334,7 @@ function getBehaviorTreeElements(document) {
36200
36334
  (child) => child.kind === "element" && child.name === "BehaviorTree"
36201
36335
  );
36202
36336
  }
36203
- function advancePosition(start, text) {
36337
+ function advancePosition2(start, text) {
36204
36338
  let line = start.line;
36205
36339
  let character = start.character;
36206
36340
  let offset = start.offset;
@@ -36216,32 +36350,66 @@ function advancePosition(start, text) {
36216
36350
  return { line, character, offset };
36217
36351
  }
36218
36352
  function rangeFromText(start, prefix, text) {
36219
- const rangeStart = advancePosition(start, prefix);
36220
- const rangeEnd = advancePosition(rangeStart, text);
36353
+ const rangeStart = advancePosition2(start, prefix);
36354
+ const rangeEnd = advancePosition2(rangeStart, text);
36221
36355
  return {
36222
36356
  start: rangeStart,
36223
36357
  end: rangeEnd
36224
36358
  };
36225
36359
  }
36226
- function extractBlackboardReferences(document, attribute) {
36360
+ function extractBlackboardReferences(document, portName, attribute) {
36227
36361
  const baseRange = attribute.valueContentRange || attribute.valueRange;
36228
36362
  const rawValue = document.originalText.slice(baseRange.start.offset, baseRange.end.offset);
36229
36363
  const references = [];
36230
- for (const match of rawValue.matchAll(/\{([^}]+)\}/g)) {
36364
+ for (const match of rawValue.matchAll(/\{[^}]*\}/g)) {
36231
36365
  const raw = match[0];
36232
- const key = match[1];
36233
36366
  const index = match.index ?? 0;
36367
+ const parsed = parsePortBlackboardReference({ portName, rawValue: raw });
36368
+ if (parsed.ok) {
36369
+ references.push({
36370
+ raw,
36371
+ key: parsed.reference.key,
36372
+ scope: parsed.reference.scope,
36373
+ identity: makeBlackboardIdentity(parsed.reference),
36374
+ range: rangeFromText(baseRange.start, rawValue.slice(0, index), raw),
36375
+ syntax: parsed.reference.syntax === "shorthand" ? "shorthand" : "braced"
36376
+ });
36377
+ continue;
36378
+ }
36234
36379
  references.push({
36235
36380
  raw,
36236
- key,
36381
+ key: raw,
36382
+ scope: "local",
36383
+ identity: `invalid:${raw}`,
36237
36384
  range: rangeFromText(baseRange.start, rawValue.slice(0, index), raw),
36238
- syntax: "braced"
36385
+ syntax: "invalid"
36239
36386
  });
36240
36387
  }
36388
+ if (references.length === 0) {
36389
+ const parsed = parsePortBlackboardReference({ portName, rawValue });
36390
+ if (parsed.ok) {
36391
+ const parsedOffset = Math.max(0, rawValue.indexOf(parsed.reference.raw));
36392
+ references.push({
36393
+ raw: parsed.reference.raw,
36394
+ key: parsed.reference.key,
36395
+ scope: parsed.reference.scope,
36396
+ identity: makeBlackboardIdentity(parsed.reference),
36397
+ range: rangeFromText(
36398
+ baseRange.start,
36399
+ rawValue.slice(0, parsedOffset),
36400
+ parsed.reference.raw
36401
+ ),
36402
+ syntax: parsed.reference.syntax === "shorthand" ? "shorthand" : "braced"
36403
+ });
36404
+ return references;
36405
+ }
36406
+ }
36241
36407
  if (references.length === 0 && (rawValue.includes("{") || rawValue.includes("}"))) {
36242
36408
  references.push({
36243
36409
  raw: rawValue,
36244
36410
  key: rawValue,
36411
+ scope: "local",
36412
+ identity: `invalid:${rawValue}`,
36245
36413
  range: baseRange,
36246
36414
  syntax: "invalid"
36247
36415
  });
@@ -36348,10 +36516,13 @@ function getSemanticPortDirection(usage) {
36348
36516
  }
36349
36517
  function getSemanticPortValueKind(value, blackboardReferences) {
36350
36518
  if (value === "") return "empty";
36351
- if (value === "{=}") return "substitution";
36519
+ if (value === "{=}" || value === "=") return "substitution";
36352
36520
  if (blackboardReferences.some((reference) => reference.syntax === "braced")) {
36353
36521
  return "blackboard-reference";
36354
36522
  }
36523
+ if (blackboardReferences.some((reference) => reference.syntax === "shorthand")) {
36524
+ return "substitution";
36525
+ }
36355
36526
  if (blackboardReferences.some((reference) => reference.syntax === "invalid")) {
36356
36527
  return "unknown";
36357
36528
  }
@@ -36453,7 +36624,11 @@ function buildBtDocumentView(document, options) {
36453
36624
  attribute: portUsage.attribute,
36454
36625
  declaredPort: toPortResolution(portUsage),
36455
36626
  usage: portUsage,
36456
- blackboardReferences: extractBlackboardReferences(document, portUsage.attribute)
36627
+ blackboardReferences: extractBlackboardReferences(
36628
+ document,
36629
+ portUsage.name,
36630
+ portUsage.attribute
36631
+ )
36457
36632
  }));
36458
36633
  node.children = element.children.filter((child) => child.kind === "element").map(
36459
36634
  (child, childIndex) => buildTreeNode(child, behaviorTree, node, [...path4, childIndex])
@@ -36530,7 +36705,11 @@ function buildSemanticDocumentView(document, index, options) {
36530
36705
  attribute: portUsage.attribute,
36531
36706
  declaredPort: toPortResolution(portUsage),
36532
36707
  usage: portUsage,
36533
- blackboardReferences: extractBlackboardReferences(document, portUsage.attribute)
36708
+ blackboardReferences: extractBlackboardReferences(
36709
+ document,
36710
+ portUsage.name,
36711
+ portUsage.attribute
36712
+ )
36534
36713
  })
36535
36714
  )
36536
36715
  };
@@ -37502,6 +37681,9 @@ function parseBtXml(text, options = {}) {
37502
37681
  );
37503
37682
  }
37504
37683
  const root = document.root;
37684
+ const looksLikeBtXml = root?.name === "BehaviorTree" || root?.name === "TreeNodesModel" || root?.name === "root" && (root.attributes.some((a) => a.name === "BTCPP_format" && a.value === "4") || root.children.some(
37685
+ (child) => child.kind === "element" && (child.name === "BehaviorTree" || child.name === "TreeNodesModel")
37686
+ ));
37505
37687
  if (root) {
37506
37688
  for (const node of document.nodes) {
37507
37689
  if (node === root) continue;
@@ -37520,7 +37702,7 @@ function parseBtXml(text, options = {}) {
37520
37702
  }
37521
37703
  }
37522
37704
  }
37523
- if (!document.xmlDeclaration) {
37705
+ if (!document.xmlDeclaration && !looksLikeBtXml) {
37524
37706
  addOptionalDiagnostic(
37525
37707
  "XML008_MISSING_DECLARATION",
37526
37708
  DiagnosticSeverity.Warning,
@@ -37534,7 +37716,7 @@ function parseBtXml(text, options = {}) {
37534
37716
  ]
37535
37717
  }
37536
37718
  );
37537
- } else if (document.xmlDeclaration.encoding && document.xmlDeclaration.encoding.toUpperCase() !== "UTF-8") {
37719
+ } else if (document.xmlDeclaration?.encoding && document.xmlDeclaration.encoding.toUpperCase() !== "UTF-8") {
37538
37720
  const encoding = document.xmlDeclaration.encoding;
37539
37721
  addDiagnostic(
37540
37722
  "XML009_INVALID_ENCODING",
@@ -38940,8 +39122,8 @@ async function loadProjectNodeModels(input) {
38940
39122
  if (parseErrors.length > 0 || !jsonTree) {
38941
39123
  throw new Error(`JSON parse error at offset ${parseErrors[0]?.offset ?? 0}`);
38942
39124
  }
38943
- } catch (error51) {
38944
- const errorMessage = String(error51.message || error51);
39125
+ } catch (error52) {
39126
+ const errorMessage = String(error52.message || error52);
38945
39127
  diagnostics.push(
38946
39128
  createDiagnostic(
38947
39129
  RuleCodes.InvalidNodeDefinitionJson,
@@ -39486,11 +39668,11 @@ function reportLiteralValidation(context, input) {
39486
39668
  });
39487
39669
  }
39488
39670
  function validateLiteralValue(input) {
39489
- const remappedKey = getRemappedKey(input.port.name, input.value);
39490
- if (input.allowRemap && remappedKey !== void 0) {
39671
+ const remappedReference = getExactBlackboardReference(input.port.name, input.value);
39672
+ if (input.allowRemap && remappedReference !== void 0) {
39491
39673
  return void 0;
39492
39674
  }
39493
- if (!input.allowRemap && remappedKey !== void 0) {
39675
+ if (!input.allowRemap && remappedReference !== void 0) {
39494
39676
  return invalidLiteral(input.diagnosticCode, input.value, input.portLabel);
39495
39677
  }
39496
39678
  if (input.port.enum && !input.port.enum.includes(input.value)) {
@@ -39523,8 +39705,12 @@ function getResolvedPortType(port) {
39523
39705
  function getResolvedPortTypeDefinition(registry2, port) {
39524
39706
  return resolveTypeDefinition(registry2, getResolvedPortType(port));
39525
39707
  }
39526
- function getExactRemappedKey(portName, rawValue) {
39527
- return getRemappedKey(portName, rawValue);
39708
+ function getExactBlackboardReference(portName, rawValue) {
39709
+ const parsed = parsePortBlackboardReference({
39710
+ portName,
39711
+ rawValue: rawValue.trim()
39712
+ });
39713
+ return parsed.ok ? parsed.reference : void 0;
39528
39714
  }
39529
39715
  function invalidLiteral(code, literal2, portLabel) {
39530
39716
  return {
@@ -39803,7 +39989,7 @@ var modelRules = [
39803
39989
  const port = model?.ports.find((candidate) => candidate.name === portName);
39804
39990
  if (!port) return;
39805
39991
  if (port.direction === "output") {
39806
- if (getRemappedKey(port.name, defaultAttr.value) === void 0) {
39992
+ if (getExactBlackboardReference(port.name, defaultAttr.value) === void 0) {
39807
39993
  context.report({
39808
39994
  code: RuleCodes.InvalidPortDefaultValue,
39809
39995
  message: `output port default for \`${port.name}\` must be a blackboard remap`,
@@ -39840,30 +40026,34 @@ var modelRules = [
39840
40026
  return {
39841
40027
  ProgramExit() {
39842
40028
  const typeRegistry = getTypeRegistry(context.semantic);
39843
- const bindingsByKey = /* @__PURE__ */ new Map();
40029
+ const bindingsByIdentity = /* @__PURE__ */ new Map();
39844
40030
  const allowStringEntryCompatibility = context.options.allowStringEntryCompatibility ?? true;
39845
40031
  for (const node of context.view.nodes) {
39846
40032
  for (const binding of node.portBindings) {
39847
40033
  if (binding.declaredPort.status !== "resolved") continue;
39848
- const key = getExactRemappedKey(binding.name, binding.value);
39849
- if (!key) continue;
40034
+ const reference = getExactBlackboardReference(binding.name, binding.value);
40035
+ if (!reference) continue;
39850
40036
  const typeDefinition = getResolvedPortTypeDefinition(
39851
40037
  typeRegistry,
39852
40038
  binding.declaredPort.port
39853
40039
  );
39854
40040
  if (!typeDefinition || typeDefinition.kind === "any") continue;
39855
- const records = bindingsByKey.get(key) ?? [];
40041
+ const identity = makeBlackboardIdentity(reference);
40042
+ const records = bindingsByIdentity.get(identity) ?? [];
39856
40043
  records.push({
39857
- key,
40044
+ key: reference.key,
40045
+ scope: reference.scope,
40046
+ displayName: formatBlackboardReference(reference),
40047
+ identity,
39858
40048
  nodeId: describeBindingNode(node.element),
39859
40049
  port: binding.declaredPort.port,
39860
40050
  typeDefinition,
39861
40051
  range: binding.attribute.range
39862
40052
  });
39863
- bindingsByKey.set(key, records);
40053
+ bindingsByIdentity.set(identity, records);
39864
40054
  }
39865
40055
  }
39866
- for (const [key, bindings] of bindingsByKey) {
40056
+ for (const bindings of bindingsByIdentity.values()) {
39867
40057
  const incompatibleTypes = collectIncompatibleTypes(
39868
40058
  context.semantic,
39869
40059
  bindings,
@@ -39875,10 +40065,10 @@ var modelRules = [
39875
40065
  );
39876
40066
  context.report({
39877
40067
  code: RuleCodes.BlackboardTypeMismatch,
39878
- message: `blackboard entry \`${key}\` is used with incompatible port types: ${incompatibleTypes.map((type) => `\`${type}\``).join(", ")}`,
40068
+ message: `blackboard entry \`${primary?.displayName ?? bindings[0]?.displayName ?? bindings[0]?.key ?? ""}\` is used with incompatible port types: ${incompatibleTypes.map((type) => `\`${type}\``).join(", ")}`,
39879
40069
  range: primary?.range,
39880
40070
  details: {
39881
- primaryLabel: `blackboard entry \`${key}\` mixes incompatible port types`,
40071
+ primaryLabel: `blackboard entry \`${primary?.displayName ?? bindings[0]?.displayName ?? bindings[0]?.key ?? ""}\` mixes incompatible port types`,
39882
40072
  notes: bindings.filter((binding) => incompatibleTypes.includes(binding.typeDefinition.canonical)).map(
39883
40073
  (binding) => `${binding.nodeId}.${binding.port.name} declares ${formatPortType(binding.port, binding.typeDefinition)}`
39884
40074
  ),
@@ -39905,7 +40095,8 @@ var modelRules = [
39905
40095
  const portUsage = context.getPortUsage(element, attr.name);
39906
40096
  if (portUsage?.status !== "resolved") continue;
39907
40097
  if (portUsage.port.direction !== "output") continue;
39908
- if (getExactRemappedKey(portUsage.port.name, attr.value) !== void 0) continue;
40098
+ if (getExactBlackboardReference(portUsage.port.name, attr.value) !== void 0)
40099
+ continue;
39909
40100
  context.report({
39910
40101
  code: RuleCodes.OutputPortRequiresRemap,
39911
40102
  message: `output port \`${portUsage.port.name}\` must be remapped to a blackboard entry`,
@@ -39997,6 +40188,22 @@ function classifyScriptAttribute(input) {
39997
40188
  return void 0;
39998
40189
  }
39999
40190
 
40191
+ // ../script/src/analysis/blackboard.ts
40192
+ function classifyScriptIdentifier(name) {
40193
+ if (!name.startsWith("@")) {
40194
+ return { kind: "local", name };
40195
+ }
40196
+ const parsed = parseScriptBlackboardIdentifier({ rawName: name });
40197
+ if (!parsed.ok) {
40198
+ return {
40199
+ kind: "invalid-global-blackboard",
40200
+ raw: name,
40201
+ message: `invalid global blackboard identifier \`${name}\``
40202
+ };
40203
+ }
40204
+ return { kind: "global-blackboard", key: parsed.reference.key };
40205
+ }
40206
+
40000
40207
  // ../script/src/tokenizer.ts
40001
40208
  var TWO_CHAR_TOKENS = /* @__PURE__ */ new Map([
40002
40209
  ["..", "DotDot"],
@@ -40570,12 +40777,22 @@ function createScriptEnvironment(input = {}) {
40570
40777
  const registry2 = createTypeRegistry(input.augmentations ?? []);
40571
40778
  const areTypesCompatible3 = input.areTypesCompatible ?? ((left, right) => areTypesCompatible(registry2, left, right));
40572
40779
  const compatibilityKeys = /* @__PURE__ */ new Map();
40780
+ const globalCompatibilityKeys = /* @__PURE__ */ new Map();
40573
40781
  const environment = {
40574
40782
  symbols: /* @__PURE__ */ new Map(),
40783
+ globalBlackboard: /* @__PURE__ */ new Map(),
40575
40784
  enums: normalizeEnums(input.enums, input.augmentations ?? [])
40576
40785
  };
40577
40786
  for (const symbol2 of input.symbols ?? []) {
40578
- mergeScriptSymbol(environment, compatibilityKeys, symbol2, areTypesCompatible3);
40787
+ mergeScriptSymbol(environment.symbols, compatibilityKeys, symbol2, areTypesCompatible3);
40788
+ }
40789
+ for (const symbol2 of input.globalBlackboardSymbols ?? []) {
40790
+ mergeScriptSymbol(
40791
+ environment.globalBlackboard,
40792
+ globalCompatibilityKeys,
40793
+ symbol2,
40794
+ areTypesCompatible3
40795
+ );
40579
40796
  }
40580
40797
  return environment;
40581
40798
  }
@@ -40584,6 +40801,12 @@ function cloneScriptEnvironment(environment) {
40584
40801
  symbols: new Map(
40585
40802
  [...environment?.symbols.entries() ?? []].map(([name, symbol2]) => [name, { ...symbol2 }])
40586
40803
  ),
40804
+ globalBlackboard: new Map(
40805
+ [...environment?.globalBlackboard.entries() ?? []].map(([name, symbol2]) => [
40806
+ name,
40807
+ { ...symbol2 }
40808
+ ])
40809
+ ),
40587
40810
  enums: new Map(environment?.enums ?? [])
40588
40811
  };
40589
40812
  }
@@ -40612,10 +40835,14 @@ function analyzeScriptFlow(input) {
40612
40835
  ...analysis ? { analysis } : {}
40613
40836
  });
40614
40837
  environment.symbols.clear();
40838
+ environment.globalBlackboard.clear();
40615
40839
  environment.enums.clear();
40616
40840
  for (const [name, symbol2] of environmentAfter.symbols) {
40617
40841
  environment.symbols.set(name, { ...symbol2 });
40618
40842
  }
40843
+ for (const [name, symbol2] of environmentAfter.globalBlackboard) {
40844
+ environment.globalBlackboard.set(name, { ...symbol2 });
40845
+ }
40619
40846
  for (const [name, value] of environmentAfter.enums) {
40620
40847
  environment.enums.set(name, value);
40621
40848
  }
@@ -40691,10 +40918,10 @@ function normalizeEnums(enums, augmentations) {
40691
40918
  }
40692
40919
  return collected;
40693
40920
  }
40694
- function mergeScriptSymbol(environment, compatibilityKeys, next, areTypesCompatible3) {
40695
- const existing = environment.symbols.get(next.name);
40921
+ function mergeScriptSymbol(target, compatibilityKeys, next, areTypesCompatible3) {
40922
+ const existing = target.get(next.name);
40696
40923
  if (!existing) {
40697
- environment.symbols.set(next.name, {
40924
+ target.set(next.name, {
40698
40925
  name: next.name,
40699
40926
  type: next.type,
40700
40927
  source: next.source,
@@ -40706,7 +40933,7 @@ function mergeScriptSymbol(environment, compatibilityKeys, next, areTypesCompati
40706
40933
  }
40707
40934
  const existingCompatibilityKey = compatibilityKeys.get(next.name);
40708
40935
  const conflict = existing.conflict === true || existingCompatibilityKey !== void 0 && next.compatibilityKey !== void 0 && !areTypesCompatible3(existingCompatibilityKey, next.compatibilityKey) || !areScriptTypesCompatible(existing.type, next.type);
40709
- environment.symbols.set(next.name, {
40936
+ target.set(next.name, {
40710
40937
  ...existing,
40711
40938
  readable: existing.readable || next.readable,
40712
40939
  writable: existing.writable || next.writable,
@@ -40728,6 +40955,8 @@ function analyzeScript(input) {
40728
40955
  const identifiers = [];
40729
40956
  const resolvedIdentifiers = [];
40730
40957
  const unknownIdentifiers = [];
40958
+ const globalBlackboardAccesses = [];
40959
+ const invalidGlobalBlackboardIdentifiers = [];
40731
40960
  const introducedSymbols = [];
40732
40961
  const diagnostics = [];
40733
40962
  const statementTypes = [];
@@ -40740,6 +40969,8 @@ function analyzeScript(input) {
40740
40969
  identifiers,
40741
40970
  resolvedIdentifiers,
40742
40971
  unknownIdentifiers,
40972
+ globalBlackboardAccesses,
40973
+ invalidGlobalBlackboardIdentifiers,
40743
40974
  introducedSymbols,
40744
40975
  diagnostics,
40745
40976
  attributeName: input.attributeName ?? "code",
@@ -40752,6 +40983,8 @@ function analyzeScript(input) {
40752
40983
  identifiers,
40753
40984
  resolvedIdentifiers,
40754
40985
  unknownIdentifiers,
40986
+ globalBlackboardAccesses,
40987
+ invalidGlobalBlackboardIdentifiers,
40755
40988
  introducedSymbols,
40756
40989
  diagnostics,
40757
40990
  statementTypes,
@@ -40915,14 +41148,74 @@ function analyzeAssignment(context) {
40915
41148
  }
40916
41149
  const left = expression.left;
40917
41150
  const accessKind = expression.operator === ":=" ? "declare" : expression.operator === "=" ? "write" : "readwrite";
40918
- const access = {
41151
+ const access2 = {
40919
41152
  name: left.name,
40920
41153
  kind: accessKind,
40921
41154
  range: left.range,
40922
41155
  identifier: left,
40923
41156
  statementIndex: context.statementIndex
40924
41157
  };
40925
- identifiers.push(access);
41158
+ identifiers.push(access2);
41159
+ const classified = classifyScriptIdentifier(left.name);
41160
+ if (classified.kind === "invalid-global-blackboard") {
41161
+ context.invalidGlobalBlackboardIdentifiers.push(access2);
41162
+ reportInvalidGlobalBlackboardIdentifier(
41163
+ context,
41164
+ left.range,
41165
+ classified.raw,
41166
+ classified.message
41167
+ );
41168
+ return ERROR_TYPE;
41169
+ }
41170
+ if (classified.kind === "global-blackboard") {
41171
+ const existingSymbol2 = environment.globalBlackboard.get(classified.key);
41172
+ const accessType = expression.operator === ":=" ? rightType : expression.operator === "=" ? existingSymbol2 && isScriptTypeAssignable(existingSymbol2.type, rightType) ? rightType : !existingSymbol2 ? rightType : void 0 : compoundAssignmentResult(
41173
+ existingSymbol2?.type ?? UNKNOWN_TYPE,
41174
+ rightType,
41175
+ expression.operator
41176
+ );
41177
+ if (expression.operator !== ":=" && expression.operator !== "=" && !accessType) {
41178
+ reportDiagnostic(
41179
+ context,
41180
+ "invalid-compound-assignment",
41181
+ expression.range,
41182
+ `operator \`${expression.operator}\` is not valid for these operand types`,
41183
+ `compound assignment \`${expression.operator}\` is not allowed here`,
41184
+ expression.operator === "+=" ? "use number += number or string += string" : "use numeric operands for this compound assignment"
41185
+ );
41186
+ return ERROR_TYPE;
41187
+ }
41188
+ if ((expression.operator === ":=" || expression.operator === "=") && existingSymbol2 && !isScriptTypeAssignable(existingSymbol2.type, rightType)) {
41189
+ reportTypeMismatch(context, left, existingSymbol2.type, rightType);
41190
+ return ERROR_TYPE;
41191
+ }
41192
+ const symbol2 = existingSymbol2 ? { ...existingSymbol2 } : {
41193
+ name: classified.key,
41194
+ type: rightType,
41195
+ source: {
41196
+ kind: "global-blackboard",
41197
+ key: classified.key,
41198
+ range: left.range,
41199
+ originId: context.originId
41200
+ },
41201
+ readable: true,
41202
+ writable: true
41203
+ };
41204
+ symbol2.type = accessType ?? rightType;
41205
+ environment.globalBlackboard.set(classified.key, symbol2);
41206
+ context.resolvedIdentifiers.push({
41207
+ access: access2,
41208
+ resolution: { kind: "global-blackboard", key: classified.key, symbol: symbol2 }
41209
+ });
41210
+ context.globalBlackboardAccesses.push({
41211
+ key: classified.key,
41212
+ rawName: left.name,
41213
+ kind: accessKind,
41214
+ range: left.range,
41215
+ inferredType: symbol2.type
41216
+ });
41217
+ return symbol2.type;
41218
+ }
40926
41219
  const existingSymbol = environment.symbols.get(left.name);
40927
41220
  if (expression.operator === ":=" && !existingSymbol) {
40928
41221
  const symbol2 = {
@@ -40939,14 +41232,14 @@ function analyzeAssignment(context) {
40939
41232
  };
40940
41233
  environment.symbols.set(left.name, symbol2);
40941
41234
  context.resolvedIdentifiers.push({
40942
- access,
41235
+ access: access2,
40943
41236
  resolution: { kind: "symbol", symbol: symbol2 }
40944
41237
  });
40945
41238
  introducedSymbols.push(symbol2);
40946
41239
  return rightType;
40947
41240
  }
40948
41241
  if (!existingSymbol) {
40949
- context.resolvedIdentifiers.push({ access, resolution: { kind: "unknown" } });
41242
+ context.resolvedIdentifiers.push({ access: access2, resolution: { kind: "unknown" } });
40950
41243
  reportDiagnostic(
40951
41244
  context,
40952
41245
  "assignment-to-unknown-variable",
@@ -40958,7 +41251,7 @@ function analyzeAssignment(context) {
40958
41251
  return ERROR_TYPE;
40959
41252
  }
40960
41253
  context.resolvedIdentifiers.push({
40961
- access,
41254
+ access: access2,
40962
41255
  resolution: { kind: "symbol", symbol: existingSymbol }
40963
41256
  });
40964
41257
  if (expression.operator === "=") {
@@ -40993,18 +41286,39 @@ function analyzeAssignment(context) {
40993
41286
  return resultType;
40994
41287
  }
40995
41288
  function analyzeReadIdentifier(context, name, range) {
40996
- const access = {
41289
+ const access2 = {
40997
41290
  name,
40998
41291
  kind: "read",
40999
41292
  range,
41000
41293
  identifier: context.expression,
41001
41294
  statementIndex: context.statementIndex
41002
41295
  };
41003
- context.identifiers.push(access);
41296
+ context.identifiers.push(access2);
41297
+ const classified = classifyScriptIdentifier(name);
41298
+ if (classified.kind === "invalid-global-blackboard") {
41299
+ context.invalidGlobalBlackboardIdentifiers.push(access2);
41300
+ reportInvalidGlobalBlackboardIdentifier(context, range, classified.raw, classified.message);
41301
+ return ERROR_TYPE;
41302
+ }
41303
+ if (classified.kind === "global-blackboard") {
41304
+ const symbol3 = context.environment.globalBlackboard.get(classified.key);
41305
+ context.globalBlackboardAccesses.push({
41306
+ key: classified.key,
41307
+ rawName: name,
41308
+ kind: "read",
41309
+ range,
41310
+ inferredType: symbol3?.type ?? UNKNOWN_TYPE
41311
+ });
41312
+ context.resolvedIdentifiers.push({
41313
+ access: access2,
41314
+ resolution: { kind: "global-blackboard", key: classified.key, ...symbol3 ? { symbol: symbol3 } : {} }
41315
+ });
41316
+ return symbol3?.type ?? UNKNOWN_TYPE;
41317
+ }
41004
41318
  const enumValue = context.environment.enums.get(name);
41005
41319
  if (enumValue !== void 0) {
41006
41320
  context.resolvedIdentifiers.push({
41007
- access,
41321
+ access: access2,
41008
41322
  resolution: { kind: "enum", name, value: enumValue }
41009
41323
  });
41010
41324
  return NUMBER_TYPE;
@@ -41012,13 +41326,13 @@ function analyzeReadIdentifier(context, name, range) {
41012
41326
  const symbol2 = context.environment.symbols.get(name);
41013
41327
  if (symbol2) {
41014
41328
  context.resolvedIdentifiers.push({
41015
- access,
41329
+ access: access2,
41016
41330
  resolution: { kind: "symbol", symbol: symbol2 }
41017
41331
  });
41018
41332
  return symbol2.type;
41019
41333
  }
41020
- context.resolvedIdentifiers.push({ access, resolution: { kind: "unknown" } });
41021
- context.unknownIdentifiers.push(access);
41334
+ context.resolvedIdentifiers.push({ access: access2, resolution: { kind: "unknown" } });
41335
+ context.unknownIdentifiers.push(access2);
41022
41336
  return UNKNOWN_TYPE;
41023
41337
  }
41024
41338
  function compoundAssignmentResult(left, right, operator) {
@@ -41072,6 +41386,16 @@ function reportTypeMismatch(context, identifier, targetType, sourceType) {
41072
41386
  "assign a compatible value or change the variable's source type"
41073
41387
  );
41074
41388
  }
41389
+ function reportInvalidGlobalBlackboardIdentifier(context, range, rawName, message) {
41390
+ reportDiagnostic(
41391
+ context,
41392
+ "invalid-global-blackboard-identifier",
41393
+ range,
41394
+ message,
41395
+ `\`${rawName}\` is not a valid global blackboard identifier`,
41396
+ "use `@name` with a valid blackboard key that starts with a letter or underscore"
41397
+ );
41398
+ }
41075
41399
  function refineLocalSymbol(symbol2, nextType) {
41076
41400
  if (symbol2.source.kind !== "script-assignment") return;
41077
41401
  if (symbol2.type.kind !== "unknown" && symbol2.type.kind !== "error") return;
@@ -41205,7 +41529,10 @@ function getScriptCursorContext(input) {
41205
41529
  };
41206
41530
  }
41207
41531
  if (containing && (containing.type === "Integer" || containing.type === "Real" || containing.type === "String" || containing.type === "Boolean")) {
41208
- return { kind: "literal", range: { start: containing.start, end: containing.end } };
41532
+ return {
41533
+ kind: "literal",
41534
+ range: { start: containing.start, end: containing.end }
41535
+ };
41209
41536
  }
41210
41537
  const operatorRange = scanOperatorRange(source, cursorOffset);
41211
41538
  const previousBeforeOperator = previousToken(tokens, operatorRange.start);
@@ -41259,6 +41586,19 @@ function identifierCompletionItems(input, cursor) {
41259
41586
  sortText: symbol2.source.kind === "script-assignment" ? `1-${symbol2.name}` : `2-${symbol2.name}`
41260
41587
  });
41261
41588
  }
41589
+ for (const symbol2 of environment.globalBlackboard.values()) {
41590
+ if (symbol2.conflict) continue;
41591
+ if (!symbol2.readable) continue;
41592
+ const label = `@${symbol2.name}`;
41593
+ if (!matchesPrefix(label, prefix)) continue;
41594
+ items.push({
41595
+ label,
41596
+ kind: "identifier",
41597
+ detail: describeScriptSymbol(symbol2),
41598
+ replaceRange: cursor.range,
41599
+ sortText: `2-${label}`
41600
+ });
41601
+ }
41262
41602
  for (const value of ["true", "false"]) {
41263
41603
  if (!matchesPrefix(value, prefix)) continue;
41264
41604
  items.push({
@@ -41331,6 +41671,31 @@ function environmentBeforeCursor(input) {
41331
41671
  if (symbol2.source.range.end > input.cursorOffset) continue;
41332
41672
  next.symbols.set(symbol2.name, symbol2);
41333
41673
  }
41674
+ for (const access2 of analyzed.globalBlackboardAccesses) {
41675
+ if (access2.kind === "read") continue;
41676
+ if (access2.range.end > input.cursorOffset) continue;
41677
+ const analyzedSymbol = analyzed.environment.globalBlackboard.get(access2.key);
41678
+ const existing = next.globalBlackboard.get(access2.key);
41679
+ let symbol2;
41680
+ if (analyzedSymbol) {
41681
+ symbol2 = { ...analyzedSymbol };
41682
+ } else if (existing) {
41683
+ symbol2 = { ...existing, type: access2.inferredType };
41684
+ } else {
41685
+ symbol2 = {
41686
+ name: access2.key,
41687
+ type: access2.inferredType,
41688
+ source: {
41689
+ kind: "global-blackboard",
41690
+ key: access2.key,
41691
+ range: access2.range
41692
+ },
41693
+ readable: true,
41694
+ writable: true
41695
+ };
41696
+ }
41697
+ next.globalBlackboard.set(access2.key, symbol2);
41698
+ }
41334
41699
  return next;
41335
41700
  }
41336
41701
  for (const token of tokens) {
@@ -41339,9 +41704,26 @@ function environmentBeforeCursor(input) {
41339
41704
  const next = nextToken(tokens, token.end);
41340
41705
  if (next?.type !== "ColonEqual") continue;
41341
41706
  if (next.end > input.cursorOffset) continue;
41342
- if (environment.symbols.has(token.text)) continue;
41343
- environment.symbols.set(token.text, {
41344
- name: token.text,
41707
+ const classified = classifyScriptIdentifier(token.text);
41708
+ if (classified.kind === "invalid-global-blackboard") continue;
41709
+ if (classified.kind === "global-blackboard") {
41710
+ if (environment.globalBlackboard.has(classified.key)) continue;
41711
+ environment.globalBlackboard.set(classified.key, {
41712
+ name: classified.key,
41713
+ type: { kind: "unknown" },
41714
+ source: {
41715
+ kind: "global-blackboard",
41716
+ key: classified.key,
41717
+ range: { start: token.start, end: token.end }
41718
+ },
41719
+ readable: true,
41720
+ writable: true
41721
+ });
41722
+ continue;
41723
+ }
41724
+ if (environment.symbols.has(classified.name)) continue;
41725
+ environment.symbols.set(classified.name, {
41726
+ name: classified.name,
41345
41727
  type: { kind: "unknown" },
41346
41728
  source: {
41347
41729
  kind: "script-assignment",
@@ -41359,10 +41741,14 @@ function describeScriptSymbol(symbol2) {
41359
41741
  switch (symbol2.source.kind) {
41360
41742
  case "port-remap":
41361
41743
  return `${typeLabel} from ${symbol2.source.nodeType ?? "node"}.${symbol2.source.portName}`;
41744
+ case "global-blackboard-remap":
41745
+ return `${typeLabel} from global blackboard ${symbol2.source.nodeType ?? "node"}.${symbol2.source.portName}`;
41362
41746
  case "subtree-port":
41363
41747
  return `${typeLabel} from ${symbol2.source.nodeType ?? "SubTree"}.${symbol2.source.portName}`;
41364
41748
  case "script-assignment":
41365
41749
  return `${typeLabel} from earlier ${symbol2.source.attributeName} declaration`;
41750
+ case "global-blackboard":
41751
+ return `${typeLabel} from global blackboard @${symbol2.source.key}`;
41366
41752
  case "augmentation":
41367
41753
  return `${typeLabel} from augmentation`;
41368
41754
  case "enum":
@@ -41504,6 +41890,7 @@ function getBehaviorTreeScriptFlow(context, behaviorTree) {
41504
41890
  function buildBaseScriptEnvironment(context, nodes) {
41505
41891
  const registry2 = getTypeRegistry(context.semantic);
41506
41892
  const portSymbols = [];
41893
+ const globalBlackboardSymbols = [];
41507
41894
  const behaviorTreeId = nodes[0]?.behaviorTree.id;
41508
41895
  if (behaviorTreeId) {
41509
41896
  const subtreeModel = context.getNodeModel(behaviorTreeId);
@@ -41529,17 +41916,21 @@ function buildBaseScriptEnvironment(context, nodes) {
41529
41916
  }
41530
41917
  }
41531
41918
  for (const node of nodes) {
41532
- const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
41533
41919
  for (const binding of node.portBindings) {
41534
41920
  if (binding.usage.status !== "resolved") continue;
41535
- const remappedKey = getRemappedKey(binding.usage.port.name, binding.usage.value);
41536
- if (!remappedKey) continue;
41921
+ const parsed = parsePortBlackboardReference({
41922
+ portName: binding.usage.port.name,
41923
+ rawValue: binding.usage.value
41924
+ });
41925
+ if (!parsed.ok) continue;
41926
+ if (parsed.reference.scope === "global") continue;
41537
41927
  const resolvedTypeName = getResolvedPortType(binding.usage.port);
41538
41928
  const resolvedDefinition = getTypeDefinition(context.semantic, resolvedTypeName);
41539
41929
  const compatibilityKey = resolvedDefinition?.canonical ?? resolvedTypeName;
41540
41930
  const direction = binding.usage.port.direction;
41931
+ const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
41541
41932
  portSymbols.push({
41542
- name: remappedKey,
41933
+ name: parsed.reference.key,
41543
41934
  type: scriptTypeFromTypeName(registry2, resolvedTypeName),
41544
41935
  source: {
41545
41936
  kind: "port-remap",
@@ -41553,12 +41944,47 @@ function buildBaseScriptEnvironment(context, nodes) {
41553
41944
  });
41554
41945
  }
41555
41946
  }
41947
+ globalBlackboardSymbols.push(...collectGlobalBlackboardSeedSymbols(context, registry2));
41556
41948
  return createScriptEnvironment({
41557
41949
  symbols: portSymbols,
41950
+ globalBlackboardSymbols,
41558
41951
  augmentations: getModelAugmentations(context.semantic),
41559
41952
  areTypesCompatible: (left, right) => left && right ? areTypesCompatible2(context.semantic, left, right) : true
41560
41953
  });
41561
41954
  }
41955
+ function collectGlobalBlackboardSeedSymbols(context, registry2) {
41956
+ const symbols = [];
41957
+ for (const node of context.view.nodes) {
41958
+ const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
41959
+ for (const binding of node.portBindings) {
41960
+ if (binding.usage.status !== "resolved") continue;
41961
+ const parsed = parsePortBlackboardReference({
41962
+ portName: binding.usage.port.name,
41963
+ rawValue: binding.usage.value
41964
+ });
41965
+ if (!parsed.ok || parsed.reference.scope !== "global") continue;
41966
+ const resolvedTypeName = getResolvedPortType(binding.usage.port);
41967
+ const resolvedDefinition = getTypeDefinition(context.semantic, resolvedTypeName);
41968
+ const compatibilityKey = resolvedDefinition?.canonical ?? resolvedTypeName;
41969
+ const direction = binding.usage.port.direction;
41970
+ symbols.push({
41971
+ name: parsed.reference.key,
41972
+ type: scriptTypeFromTypeName(registry2, resolvedTypeName),
41973
+ source: {
41974
+ kind: "global-blackboard-remap",
41975
+ nodeType,
41976
+ portName: binding.usage.port.name,
41977
+ direction,
41978
+ key: parsed.reference.key
41979
+ },
41980
+ readable: direction === "input" || direction === "output" || direction === "inout",
41981
+ writable: direction === "output" || direction === "inout",
41982
+ compatibilityKey
41983
+ });
41984
+ }
41985
+ }
41986
+ return symbols;
41987
+ }
41562
41988
 
41563
41989
  // ../analyzer/src/analysis/rules/script/no-unknown-variable.ts
41564
41990
  var scriptNoUnknownVariableRule = makeRuleModule({
@@ -41594,7 +42020,7 @@ var scriptValidAssignmentRule = makeRuleModule({
41594
42020
  for (const candidate of getAnalyzedScriptAttributeCandidates(context, element)) {
41595
42021
  if (!candidate.analysis) continue;
41596
42022
  for (const diagnostic of candidate.analysis.diagnostics) {
41597
- const code = diagnostic.code === "assignment-to-unknown-variable" ? RuleCodes.AssignmentToUnknownVariable : diagnostic.code === "invalid-compound-assignment" ? RuleCodes.InvalidCompoundAssignment : diagnostic.code === "variable-type-mismatch" ? RuleCodes.ScriptVariableTypeMismatch : void 0;
42023
+ const code = diagnostic.code === "assignment-to-unknown-variable" ? RuleCodes.AssignmentToUnknownVariable : diagnostic.code === "invalid-compound-assignment" ? RuleCodes.InvalidCompoundAssignment : diagnostic.code === "variable-type-mismatch" ? RuleCodes.ScriptVariableTypeMismatch : diagnostic.code === "invalid-global-blackboard-identifier" ? RuleCodes.InvalidGlobalBlackboardIdentifier : void 0;
41598
42024
  if (!code) continue;
41599
42025
  context.report({
41600
42026
  code,
@@ -41667,16 +42093,16 @@ var scriptValidSyntaxRule = makeRuleModule({
41667
42093
  Element(element) {
41668
42094
  for (const candidate of getScriptAttributeCandidates(context, element)) {
41669
42095
  if (candidate.parseResult.ok) continue;
41670
- for (const error51 of candidate.parseResult.errors) {
41671
- const code = error51.kind === "empty-script" ? RuleCodes.EmptyScript : error51.kind === "invalid-token" ? RuleCodes.InvalidScriptToken : RuleCodes.InvalidScriptSyntax;
42096
+ for (const error52 of candidate.parseResult.errors) {
42097
+ const code = error52.kind === "empty-script" ? RuleCodes.EmptyScript : error52.kind === "invalid-token" ? RuleCodes.InvalidScriptToken : RuleCodes.InvalidScriptSyntax;
41672
42098
  context.report({
41673
42099
  code,
41674
- message: error51.message,
41675
- range: error51.kind === "empty-script" ? candidate.attribute.valueContentRange ?? candidate.attribute.valueRange ?? mapScriptRangeToDocument(
42100
+ message: error52.message,
42101
+ range: error52.kind === "empty-script" ? candidate.attribute.valueContentRange ?? candidate.attribute.valueRange ?? mapScriptRangeToDocument(
41676
42102
  context,
41677
42103
  candidate.attribute,
41678
42104
  attributeScriptRange(candidate.attribute)
41679
- ) : mapScriptRangeToDocument(context, candidate.attribute, error51.range),
42105
+ ) : mapScriptRangeToDocument(context, candidate.attribute, error52.range),
41680
42106
  details: {
41681
42107
  primaryLabel: `invalid script in \`${candidate.attribute.name}\``
41682
42108
  }
@@ -41732,6 +42158,18 @@ var suppressionRules = [
41732
42158
  function getAttr3(element, name) {
41733
42159
  return element.attributes.find((attr) => attr.name === name);
41734
42160
  }
42161
+ function isInsideTreeNodesModel(root, target) {
42162
+ if (!root) return false;
42163
+ const walk2 = (element, inTreeNodesModel) => {
42164
+ const nextInTreeNodesModel = inTreeNodesModel || element.name === "TreeNodesModel";
42165
+ if (element === target) return nextInTreeNodesModel;
42166
+ for (const child of element.children) {
42167
+ if (child.kind === "element" && walk2(child, nextInTreeNodesModel)) return true;
42168
+ }
42169
+ return false;
42170
+ };
42171
+ return walk2(root, false);
42172
+ }
41735
42173
  var treeRules = [
41736
42174
  makeRuleModule({
41737
42175
  name: "tree/require-id",
@@ -41808,6 +42246,7 @@ var treeRules = [
41808
42246
  return {
41809
42247
  Element(element) {
41810
42248
  if (element.name !== "SubTree") return;
42249
+ if (isInsideTreeNodesModel(context.document.root, element)) return;
41811
42250
  const call = context.getSubTreeCallView(element);
41812
42251
  const idAttr = call?.node.element.attributes.find((attr) => attr.name === "ID") ?? getAttr3(element, "ID");
41813
42252
  if (!idAttr) return;
@@ -41828,6 +42267,7 @@ var treeRules = [
41828
42267
  return {
41829
42268
  Element(element) {
41830
42269
  if (element.name !== "SubTree") return;
42270
+ if (isInsideTreeNodesModel(context.document.root, element)) return;
41831
42271
  const idAttr = getAttr3(element, "ID");
41832
42272
  if (!idAttr) return;
41833
42273
  const call = context.getSubTreeCallView(element);
@@ -42794,8 +43234,8 @@ async function discoverBtxmlConfig(input) {
42794
43234
  }
42795
43235
  try {
42796
43236
  raw = await readJson(configUri, input.host);
42797
- } catch (error51) {
42798
- const errorMessage = String(error51.message || error51);
43237
+ } catch (error52) {
43238
+ const errorMessage = String(error52.message || error52);
42799
43239
  return {
42800
43240
  ok: false,
42801
43241
  configUri,
@@ -42855,34 +43295,31 @@ async function discoverBtxmlConfig(input) {
42855
43295
 
42856
43296
  // ../project/src/models.ts
42857
43297
  async function discoverModelFiles(rootUri, modelsConfig, filesConfig, host) {
42858
- const ignore2 = [...filesConfig.ignore];
42859
- const gitignoreLines = filesConfig.useGitignore ? await loadGitignore(rootUri, host) : [];
42860
- const ig = createIgnoreInstance(gitignoreLines);
42861
43298
  const modelFilesPatternResult = await expandPatterns(
42862
43299
  modelsConfig.files,
42863
43300
  rootUri,
42864
- ignore2,
43301
+ [],
42865
43302
  filesConfig.followSymlinks,
42866
43303
  void 0,
42867
- ig,
43304
+ void 0,
42868
43305
  host
42869
43306
  );
42870
43307
  const definitionFilesPatternResult = await expandPatterns(
42871
43308
  modelsConfig.definitions,
42872
43309
  rootUri,
42873
- ignore2,
43310
+ [],
42874
43311
  filesConfig.followSymlinks,
42875
43312
  void 0,
42876
- ig,
43313
+ void 0,
42877
43314
  host
42878
43315
  );
42879
43316
  const augmentationFilesPatternResult = await expandPatterns(
42880
43317
  modelsConfig.augmentations,
42881
43318
  rootUri,
42882
- ignore2,
43319
+ [],
42883
43320
  filesConfig.followSymlinks,
42884
43321
  void 0,
42885
- ig,
43322
+ void 0,
42886
43323
  host
42887
43324
  );
42888
43325
  const modelFiles = modelFilesPatternResult.files.map((uri) => ({
@@ -43361,21 +43798,8 @@ function uniqueItems(items) {
43361
43798
  }
43362
43799
 
43363
43800
  // ../language-service/src/providers/blackboard-symbols.ts
43364
- var BLACKBOARD_KEY_RE = /^[A-Za-z_][A-Za-z0-9_./:-]*$/;
43365
- function validateExtractedBlackboardKey(raw) {
43366
- const key = raw?.trim();
43367
- if (!key) return void 0;
43368
- if (key.includes("{") || key.includes("}")) return void 0;
43369
- return BLACKBOARD_KEY_RE.test(key) ? key : void 0;
43370
- }
43371
- function normalizeBlackboardKey(raw) {
43372
- const value = raw?.trim();
43373
- if (!value) return void 0;
43374
- const extracted = value.startsWith("{") && value.endsWith("}") ? value.slice(1, -1).trim() : value;
43375
- return validateExtractedBlackboardKey(extracted);
43376
- }
43377
- function formatBlackboardReference(key) {
43378
- return `{${key}}`;
43801
+ function formatBlackboardReference2(symbol2) {
43802
+ return formatBlackboardReference(symbol2);
43379
43803
  }
43380
43804
  function normalizeType(type) {
43381
43805
  return type?.trim().replace(/^const\s+/, "").replace(/[&*]\s*$/, "").replace(/\s+/g, " ").toLowerCase();
@@ -43391,31 +43815,32 @@ function collectBlackboardSymbols(context) {
43391
43815
  if (binding.declaredPort.status !== "resolved") continue;
43392
43816
  const port = binding.declaredPort.port;
43393
43817
  for (const ref of binding.blackboardReferences) {
43394
- const key = normalizeBlackboardKey(ref.key);
43395
- if (!key) continue;
43818
+ if (ref.syntax === "invalid") continue;
43396
43819
  const next = {
43397
- key,
43820
+ identity: ref.identity,
43821
+ key: ref.key,
43822
+ scope: ref.scope,
43398
43823
  type: port.type,
43399
43824
  direction: port.direction,
43400
43825
  nodeType: node.usage.nodeType || node.tagName,
43401
43826
  portName: port.name
43402
43827
  };
43403
- const current = grouped.get(key);
43828
+ const current = grouped.get(ref.identity);
43404
43829
  if (!current) {
43405
- grouped.set(key, next);
43830
+ grouped.set(ref.identity, next);
43406
43831
  continue;
43407
43832
  }
43408
43833
  const currentType = normalizeType(current.type);
43409
43834
  const nextType = normalizeType(next.type);
43410
43835
  if (currentType && nextType && currentType !== nextType) {
43411
- grouped.set(key, {
43836
+ grouped.set(ref.identity, {
43412
43837
  ...current,
43413
43838
  conflict: true
43414
43839
  });
43415
43840
  continue;
43416
43841
  }
43417
43842
  if (!currentType && nextType) {
43418
- grouped.set(key, {
43843
+ grouped.set(ref.identity, {
43419
43844
  ...current,
43420
43845
  type: next.type
43421
43846
  });
@@ -43440,23 +43865,45 @@ function getBlackboardReplacementRange(document, attribute, cursorOffset) {
43440
43865
  const endsInBraces = value.endsWith("}");
43441
43866
  if (startsInBraces && cursorOffset > valueStart) {
43442
43867
  const innerStart = valueStart + 1;
43868
+ const innerValueStart = value[1] === "@" ? innerStart + 1 : innerStart;
43443
43869
  const innerEnd = endsInBraces ? valueEnd - 1 : valueEnd;
43444
43870
  return {
43445
- replacementRange: rangeFromOffsets2(document, innerStart, Math.max(innerStart, innerEnd)),
43446
- wrapsReference: false
43871
+ replacementRange: rangeFromOffsets2(
43872
+ document,
43873
+ innerValueStart,
43874
+ Math.max(innerValueStart, innerEnd)
43875
+ ),
43876
+ wrapsReference: false,
43877
+ hasScopeMarker: value[1] === "@"
43447
43878
  };
43448
43879
  }
43449
43880
  return {
43450
43881
  insertText: attribute.value,
43451
43882
  replacementRange: valueContentRange,
43452
- wrapsReference: true
43883
+ wrapsReference: true,
43884
+ hasScopeMarker: false
43453
43885
  };
43454
43886
  }
43455
43887
  function createBlackboardCompletionItem(args) {
43456
43888
  const { document, attribute, cursorOffset, symbol: symbol2, detail } = args;
43457
43889
  const replacement = getBlackboardReplacementRange(document, attribute, cursorOffset);
43458
- const label = formatBlackboardReference(symbol2.key);
43459
- const newText = replacement?.wrapsReference ? label : symbol2.key;
43890
+ const wrapsReference = replacement?.wrapsReference ?? false;
43891
+ const hasScopeMarker = replacement?.hasScopeMarker ?? false;
43892
+ if (hasScopeMarker && symbol2.scope !== "global") return void 0;
43893
+ let label = symbol2.key;
43894
+ if (wrapsReference) {
43895
+ label = formatBlackboardReference2(symbol2);
43896
+ } else if (symbol2.scope === "global") {
43897
+ label = `@${symbol2.key}`;
43898
+ }
43899
+ let newText = symbol2.key;
43900
+ if (wrapsReference) {
43901
+ newText = formatBlackboardReference2(symbol2);
43902
+ } else if (symbol2.scope === "global") {
43903
+ newText = hasScopeMarker ? symbol2.key : `@${symbol2.key}`;
43904
+ }
43905
+ const scopeFilterText = symbol2.scope === "global" ? ` @${symbol2.key}` : "";
43906
+ const filterText = `${symbol2.key} ${label}${scopeFilterText}`.trim();
43460
43907
  return completion(
43461
43908
  label,
43462
43909
  "Reference",
@@ -43466,7 +43913,7 @@ function createBlackboardCompletionItem(args) {
43466
43913
  newText
43467
43914
  } : void 0,
43468
43915
  {
43469
- filterText: `${symbol2.key} ${label}`,
43916
+ filterText,
43470
43917
  insertText: newText
43471
43918
  }
43472
43919
  );
@@ -43500,13 +43947,14 @@ function getScriptIdentifierTarget(context, position) {
43500
43947
  (entry) => entry.access.range.start === cursor.range.start && entry.access.range.end === cursor.range.end && entry.resolution.kind !== "unknown"
43501
43948
  );
43502
43949
  if (!resolved || resolved.resolution.kind === "unknown") return void 0;
43503
- const reference = resolved.resolution.kind === "symbol" ? { kind: "symbol", symbol: resolved.resolution.symbol } : resolved.resolution;
43950
+ const reference = resolved.resolution.kind === "symbol" ? { kind: "symbol", symbol: resolved.resolution.symbol } : resolved.resolution.kind === "global-blackboard" ? { ...resolved.resolution, origin: "script" } : resolved.resolution;
43504
43951
  return {
43505
43952
  attributeContext: scriptContext,
43506
43953
  range: toDocumentRange(context, scriptContext, cursor.range),
43507
43954
  reference,
43508
43955
  flowState,
43509
43956
  occurrence: {
43957
+ uri: context.document.uri,
43510
43958
  attributeContext: scriptContext,
43511
43959
  identifier: resolved.access,
43512
43960
  reference,
@@ -43515,11 +43963,35 @@ function getScriptIdentifierTarget(context, position) {
43515
43963
  };
43516
43964
  }
43517
43965
  function getScriptReferencesForSymbol(context, target) {
43518
- const states = getBehaviorTreeScriptFlow2(context, target.attributeContext.behaviorTree);
43519
- return states.flatMap(
43520
- (state) => collectResolvedOccurrences(context, state).filter(
43521
- (occurrence) => target.reference.kind === "enum" ? occurrence.reference.kind === "enum" && occurrence.reference.name === target.reference.name : sameResolvedSymbol(target.reference.symbol, occurrence.reference)
43522
- )
43966
+ const occurrences = (target.reference.kind === "global-blackboard" ? collectAllScriptOccurrences(context) : getBehaviorTreeScriptFlow2(context, target.attributeContext.behaviorTree).flatMap(
43967
+ (state) => collectResolvedOccurrences(context, state)
43968
+ )).filter(
43969
+ (occurrence) => target.reference.kind === "enum" ? occurrence.reference.kind === "enum" && occurrence.reference.name === target.reference.name : target.reference.kind === "global-blackboard" ? occurrence.reference.kind === "global-blackboard" && occurrence.reference.key === target.reference.key : sameResolvedSymbol(target.reference.symbol, occurrence.reference)
43970
+ );
43971
+ if (target.reference.kind === "global-blackboard") {
43972
+ return uniqueScriptOccurrences([
43973
+ ...occurrences,
43974
+ ...collectGlobalBlackboardRemapOccurrences(context, target.reference.key)
43975
+ ]);
43976
+ }
43977
+ return occurrences;
43978
+ }
43979
+ function getGlobalBlackboardReferenceLocations(context, key) {
43980
+ return uniqueBlackboardLocations(
43981
+ collectGlobalBlackboardRemapOccurrences(context, key).map((occurrence) => ({
43982
+ uri: occurrence.uri,
43983
+ range: occurrence.documentRange
43984
+ }))
43985
+ );
43986
+ }
43987
+ function getGlobalBlackboardScriptLocations(context, key) {
43988
+ return uniqueBlackboardLocations(
43989
+ collectAllScriptOccurrences(context).filter(
43990
+ (occurrence) => occurrence.reference.kind === "global-blackboard" && occurrence.reference.key === key
43991
+ ).map((occurrence) => ({
43992
+ uri: occurrence.uri,
43993
+ range: occurrence.documentRange
43994
+ }))
43523
43995
  );
43524
43996
  }
43525
43997
  function getBehaviorTreeScriptFlowStates(context, behaviorTree) {
@@ -43535,10 +44007,14 @@ function describeScriptSymbol2(symbol2) {
43535
44007
  switch (symbol2.source.kind) {
43536
44008
  case "port-remap":
43537
44009
  return `${typeLabel} from ${symbol2.source.nodeType ?? "node"}.${symbol2.source.portName}`;
44010
+ case "global-blackboard-remap":
44011
+ return `${typeLabel} from global blackboard ${symbol2.source.nodeType ?? "node"}.${symbol2.source.portName}`;
43538
44012
  case "subtree-port":
43539
44013
  return `${typeLabel} from ${symbol2.source.nodeType ?? "SubTree"}.${symbol2.source.portName}`;
43540
44014
  case "script-assignment":
43541
44015
  return `${typeLabel} from earlier ${symbol2.source.attributeName} declaration`;
44016
+ case "global-blackboard":
44017
+ return `${typeLabel} from global blackboard @${symbol2.source.key}`;
43542
44018
  case "augmentation":
43543
44019
  return `${typeLabel} from augmentation`;
43544
44020
  case "enum":
@@ -43614,6 +44090,7 @@ function getScriptAttributeContext(context, element, attribute) {
43614
44090
  function buildBaseScriptEnvironment2(context, nodes) {
43615
44091
  const registry2 = getTypeRegistry(context.semantic);
43616
44092
  const portSymbols = [];
44093
+ const globalBlackboardSymbols = [];
43617
44094
  const behaviorTreeId = nodes[0]?.behaviorTree.id;
43618
44095
  if (behaviorTreeId) {
43619
44096
  const subtreeModel = getNodeModel(context.semantic, behaviorTreeId);
@@ -43639,17 +44116,18 @@ function buildBaseScriptEnvironment2(context, nodes) {
43639
44116
  }
43640
44117
  }
43641
44118
  for (const node of nodes) {
43642
- const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
43643
44119
  for (const binding of node.portBindings) {
43644
44120
  if (binding.declaredPort.status !== "resolved") continue;
43645
- const remappedKey = getRemappedKeyFromBinding(binding);
43646
- if (!remappedKey) continue;
44121
+ const reference = getBlackboardReferenceFromBinding(binding);
44122
+ if (!reference) continue;
44123
+ if (reference.scope === "global") continue;
43647
44124
  const resolvedTypeName = binding.declaredPort.port.type;
43648
44125
  const resolvedDefinition = getTypeDefinition(context.semantic, resolvedTypeName);
43649
44126
  const compatibilityKey = resolvedDefinition?.canonical ?? resolvedTypeName;
43650
44127
  const direction = binding.declaredPort.port.direction;
44128
+ const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
43651
44129
  portSymbols.push({
43652
- name: remappedKey,
44130
+ name: reference.key,
43653
44131
  type: scriptTypeFromTypeName(registry2, resolvedTypeName),
43654
44132
  source: {
43655
44133
  kind: "port-remap",
@@ -43663,19 +44141,57 @@ function buildBaseScriptEnvironment2(context, nodes) {
43663
44141
  });
43664
44142
  }
43665
44143
  }
44144
+ const workspaceNodes = getDocumentTrees(context).flatMap(
44145
+ ({ trees }) => trees.flatMap((tree) => tree.nodes)
44146
+ );
44147
+ globalBlackboardSymbols.push(
44148
+ ...collectGlobalBlackboardSeedSymbols2(context, registry2, workspaceNodes)
44149
+ );
43666
44150
  return createScriptEnvironment({
43667
44151
  symbols: portSymbols,
44152
+ globalBlackboardSymbols,
43668
44153
  augmentations: getModelAugmentations(context.semantic),
43669
44154
  areTypesCompatible: (left, right) => left && right ? areTypesCompatible2(context.semantic, left, right) : true
43670
44155
  });
43671
44156
  }
44157
+ function collectGlobalBlackboardSeedSymbols2(context, registry2, nodes) {
44158
+ const symbols = [];
44159
+ for (const node of nodes) {
44160
+ const nodeType = node.usage.model.status === "resolved" ? node.usage.model.model.id : node.usage.nodeType;
44161
+ for (const binding of node.portBindings) {
44162
+ if (binding.declaredPort.status !== "resolved") continue;
44163
+ const reference = getBlackboardReferenceFromBinding(binding);
44164
+ if (!reference || reference.scope !== "global") continue;
44165
+ const resolvedTypeName = binding.declaredPort.port.type;
44166
+ const resolvedDefinition = getTypeDefinition(context.semantic, resolvedTypeName);
44167
+ const compatibilityKey = resolvedDefinition?.canonical ?? resolvedTypeName;
44168
+ const direction = binding.declaredPort.port.direction;
44169
+ symbols.push({
44170
+ name: reference.key,
44171
+ type: scriptTypeFromTypeName(registry2, resolvedTypeName),
44172
+ source: {
44173
+ kind: "global-blackboard-remap",
44174
+ nodeType,
44175
+ portName: binding.declaredPort.port.name,
44176
+ direction,
44177
+ key: reference.key
44178
+ },
44179
+ readable: direction === "input" || direction === "output" || direction === "inout",
44180
+ writable: direction === "output" || direction === "inout",
44181
+ compatibilityKey
44182
+ });
44183
+ }
44184
+ }
44185
+ return symbols;
44186
+ }
43672
44187
  function collectResolvedOccurrences(context, state) {
43673
44188
  if (!state.analysis) return [];
43674
44189
  return state.analysis.resolvedIdentifiers.flatMap((entry) => {
43675
44190
  if (entry.resolution.kind === "unknown") return [];
43676
- const reference = entry.resolution.kind === "symbol" ? { kind: "symbol", symbol: entry.resolution.symbol } : entry.resolution;
44191
+ const reference = entry.resolution.kind === "symbol" ? { kind: "symbol", symbol: entry.resolution.symbol } : entry.resolution.kind === "global-blackboard" ? { ...entry.resolution, origin: "script" } : entry.resolution;
43677
44192
  return [
43678
44193
  {
44194
+ uri: context.document.uri,
43679
44195
  attributeContext: state.context,
43680
44196
  identifier: entry.access,
43681
44197
  reference,
@@ -43695,6 +44211,112 @@ function sameResolvedSymbol(symbol2, reference) {
43695
44211
  }
43696
44212
  return symbol2.name === candidate.name && symbol2.source.kind === candidate.source.kind;
43697
44213
  }
44214
+ function uniqueScriptOccurrences(occurrences) {
44215
+ const seen = /* @__PURE__ */ new Set();
44216
+ const result = [];
44217
+ for (const occurrence of occurrences) {
44218
+ const key = `${occurrence.uri}:${occurrence.documentRange.start.offset}:${occurrence.documentRange.end.offset}:${occurrence.reference.kind}`;
44219
+ if (seen.has(key)) continue;
44220
+ seen.add(key);
44221
+ result.push(occurrence);
44222
+ }
44223
+ return result;
44224
+ }
44225
+ function collectGlobalBlackboardRemapOccurrences(context, key) {
44226
+ return getDocumentTrees(context).flatMap(
44227
+ ({ uri, trees }) => trees.flatMap(
44228
+ (behaviorTree) => behaviorTree.nodes.flatMap(
44229
+ (node) => node.portBindings.flatMap(
44230
+ (binding) => binding.blackboardReferences.filter((reference) => reference.scope === "global" && reference.key === key).map((reference) => ({
44231
+ uri,
44232
+ attributeContext: {
44233
+ id: `${node.path.join(".")}:${binding.attribute.name}:${node.element.attributes.indexOf(binding.attribute)}`,
44234
+ node,
44235
+ element: node.element,
44236
+ attribute: binding.attribute,
44237
+ source: binding.attribute.value,
44238
+ behaviorTree: node.behaviorTree
44239
+ },
44240
+ identifier: {
44241
+ name: `@${reference.key}`,
44242
+ kind: "read",
44243
+ range: { start: 0, end: 0 },
44244
+ identifier: {
44245
+ kind: "Identifier",
44246
+ name: `@${reference.key}`,
44247
+ range: { start: 0, end: 0 }
44248
+ },
44249
+ statementIndex: -1
44250
+ },
44251
+ reference: {
44252
+ kind: "global-blackboard",
44253
+ key: reference.key,
44254
+ origin: "port-remap"
44255
+ },
44256
+ documentRange: reference.range
44257
+ }))
44258
+ )
44259
+ )
44260
+ )
44261
+ );
44262
+ }
44263
+ function collectAllScriptOccurrences(context) {
44264
+ return getDocumentTrees(context).flatMap(
44265
+ ({ uri, trees }) => trees.flatMap((behaviorTree) => {
44266
+ const nextContext = getContextForUri(context, uri);
44267
+ return getBehaviorTreeScriptFlow2(nextContext, behaviorTree).flatMap(
44268
+ (state) => collectResolvedOccurrencesByUri(nextContext, uri, state)
44269
+ );
44270
+ })
44271
+ );
44272
+ }
44273
+ function collectResolvedOccurrencesByUri(context, uri, state) {
44274
+ return collectResolvedOccurrences(context, state).map((occurrence) => ({
44275
+ ...occurrence,
44276
+ uri
44277
+ }));
44278
+ }
44279
+ function getDocumentTrees(context) {
44280
+ const current = context.documentView ? [{ uri: context.document.uri, trees: context.documentView.behaviorTrees }] : [];
44281
+ const workspace = context.workspace?.documents ?? [];
44282
+ const others = workspace.filter((document) => document.uri !== context.document.uri).map((document) => {
44283
+ const view = buildBtDocumentView(document, {
44284
+ semantic: context.semantic,
44285
+ config: context.config,
44286
+ policy: context.nodeUsagePolicy
44287
+ });
44288
+ return { uri: document.uri, trees: view.behaviorTrees };
44289
+ }).filter((entry) => entry.trees.length > 0);
44290
+ return [...current, ...others];
44291
+ }
44292
+ function getContextForUri(context, uri) {
44293
+ if (uri === context.document.uri) return context;
44294
+ const parsed = context.workspace?.documents.find((document2) => document2.uri === uri);
44295
+ if (!parsed) return context;
44296
+ const document = createTextDocument(uri, parsed.originalText, 0, "btcpp-xml");
44297
+ const documentView = buildBtDocumentView(parsed, {
44298
+ semantic: context.semantic,
44299
+ config: context.config,
44300
+ policy: context.nodeUsagePolicy
44301
+ });
44302
+ return {
44303
+ ...context,
44304
+ document,
44305
+ parsed,
44306
+ documentView
44307
+ };
44308
+ }
44309
+ function uniqueBlackboardLocations(locations) {
44310
+ const seen = /* @__PURE__ */ new Set();
44311
+ const result = [];
44312
+ for (const location of locations) {
44313
+ const key = `${location.uri}:${location.range.start.offset}:${location.range.end.offset}`;
44314
+ if (seen.has(key)) continue;
44315
+ seen.add(key);
44316
+ result.push(location);
44317
+ }
44318
+ return result;
44319
+ }
43698
44320
  function toDocumentRange(context, scriptContext, range) {
43699
44321
  return mapDecodedAttributeRangeToDocumentRange(
43700
44322
  context.parsed ?? { originalText: context.document.text },
@@ -43720,9 +44342,13 @@ function mapDecodedRangeToReplacementRange(context, attribute, range) {
43720
44342
  const document = context.parsed ?? { originalText: context.document.text };
43721
44343
  return mapDecodedAttributeRangeToDocumentRange(document, attribute, range);
43722
44344
  }
43723
- function getRemappedKeyFromBinding(binding) {
44345
+ function getBlackboardReferenceFromBinding(binding) {
43724
44346
  if (binding.declaredPort.status !== "resolved") return void 0;
43725
- return getRemappedKey(binding.declaredPort.port.name, binding.value);
44347
+ const parsed = parsePortBlackboardReference({
44348
+ portName: binding.declaredPort.port.name,
44349
+ rawValue: binding.value
44350
+ });
44351
+ return parsed.ok ? parsed.reference : void 0;
43726
44352
  }
43727
44353
 
43728
44354
  // ../language-service/src/providers/script-completions.ts
@@ -44005,28 +44631,37 @@ function attributeValueItems(input, inspect, context) {
44005
44631
  const unknownTypeSymbols = symbols.filter(
44006
44632
  (symbol2) => !symbol2.conflict && !normalizeType(symbol2.type) && normalizedCurrentType
44007
44633
  );
44008
- const matchingKeyItems = matchingSymbols.map((symbol2) => ({
44009
- ...createBlackboardCompletionItem({
44634
+ const matchingKeyItems = matchingSymbols.flatMap((symbol2) => {
44635
+ const item = createBlackboardCompletionItem({
44010
44636
  document: input.document,
44011
44637
  attribute,
44012
44638
  cursorOffset: input.position.offset,
44013
44639
  symbol: symbol2,
44014
- detail: `${symbol2.type || "unknown"} blackboard key from ${symbol2.nodeType}.${symbol2.portName}`
44015
- }),
44016
- sortText: `${BLACKBOARD_SORT_TEXT.matchingKey}-${symbol2.key}`
44017
- }));
44018
- const unknownKeyItems = unknownTypeSymbols.map((symbol2) => ({
44019
- ...createBlackboardCompletionItem({
44640
+ detail: symbol2.scope === "global" ? `${symbol2.type || "unknown"} global blackboard key from ${symbol2.nodeType}.${symbol2.portName}` : `${symbol2.type || "unknown"} blackboard key from ${symbol2.nodeType}.${symbol2.portName}`
44641
+ });
44642
+ return item ? [
44643
+ {
44644
+ ...item,
44645
+ sortText: `${BLACKBOARD_SORT_TEXT.matchingKey}-${symbol2.scope === "global" ? symbol2.identity : symbol2.key}`
44646
+ }
44647
+ ] : [];
44648
+ });
44649
+ const unknownKeyItems = unknownTypeSymbols.flatMap((symbol2) => {
44650
+ const item = createBlackboardCompletionItem({
44020
44651
  document: input.document,
44021
44652
  attribute,
44022
44653
  cursorOffset: input.position.offset,
44023
44654
  symbol: symbol2,
44024
- detail: `unknown-type blackboard key from ${symbol2.nodeType}.${symbol2.portName}`
44025
- }),
44026
- sortText: `${BLACKBOARD_SORT_TEXT.unknownKey}-${symbol2.key}`
44027
- }));
44028
- items.push(...matchingKeyItems);
44029
- items.push(...unknownKeyItems);
44655
+ detail: symbol2.scope === "global" ? `unknown-type global blackboard key from ${symbol2.nodeType}.${symbol2.portName}` : `unknown-type blackboard key from ${symbol2.nodeType}.${symbol2.portName}`
44656
+ });
44657
+ return item ? [
44658
+ {
44659
+ ...item,
44660
+ sortText: `${BLACKBOARD_SORT_TEXT.unknownKey}-${symbol2.scope === "global" ? symbol2.identity : symbol2.key}`
44661
+ }
44662
+ ] : [];
44663
+ });
44664
+ items.push(...matchingKeyItems, ...unknownKeyItems);
44030
44665
  if (items.length > 0) {
44031
44666
  return uniqueItems(items);
44032
44667
  }
@@ -44059,7 +44694,9 @@ function getCompletions(context, input) {
44059
44694
  };
44060
44695
  }
44061
44696
  if (inspect.kind === "tag-name") {
44062
- return { items: uniqueItems(elementNameItems(context.semantic, inspect.element?.nameRange)) };
44697
+ return {
44698
+ items: uniqueItems(elementNameItems(context.semantic, inspect.element?.nameRange))
44699
+ };
44063
44700
  }
44064
44701
  if (inspect.kind === "closing-tag-name") {
44065
44702
  return { items: uniqueItems(closingTagItems(inspect)) };
@@ -44068,6 +44705,63 @@ function getCompletions(context, input) {
44068
44705
  }
44069
44706
 
44070
44707
  // ../language-service/src/providers/definition.ts
44708
+ function uniqueLocations(locations) {
44709
+ const seen = /* @__PURE__ */ new Set();
44710
+ const result = [];
44711
+ for (const location of locations) {
44712
+ const key = `${location.uri}:${location.range.start.offset}:${location.range.end.offset}`;
44713
+ if (seen.has(key)) continue;
44714
+ seen.add(key);
44715
+ result.push(location);
44716
+ }
44717
+ return result;
44718
+ }
44719
+ function getSubTreeModelDefinitionLocations(semantic, id, fallbackUri) {
44720
+ return getNodeModelDefinitions(semantic, id).filter((definition) => definition.kind === "SubTree").map((definition) => {
44721
+ if (definition.idRange) {
44722
+ return {
44723
+ uri: definition.uri || fallbackUri,
44724
+ range: definition.idRange
44725
+ };
44726
+ }
44727
+ if (definition.range) {
44728
+ return {
44729
+ uri: definition.uri || fallbackUri,
44730
+ range: definition.range
44731
+ };
44732
+ }
44733
+ return void 0;
44734
+ }).filter((location) => Boolean(location));
44735
+ }
44736
+ function getBlackboardDefinitionLocations(documentView, identity, fallbackUri) {
44737
+ if (!documentView) return [];
44738
+ return uniqueLocations(
44739
+ documentView.nodes.flatMap(
44740
+ (node) => node.portBindings.flatMap(
44741
+ (binding) => binding.blackboardReferences.filter((reference) => reference.identity === identity).map((reference) => ({
44742
+ uri: fallbackUri,
44743
+ range: reference.range
44744
+ }))
44745
+ )
44746
+ )
44747
+ );
44748
+ }
44749
+ function getWorkspaceBlackboardLocations(documentView, workspaceDocuments, semantic, config2, policy, identity, fallbackUri) {
44750
+ const current = getBlackboardDefinitionLocations(documentView, identity, fallbackUri);
44751
+ const workspace = (workspaceDocuments ?? []).flatMap((document) => {
44752
+ if (document.uri === fallbackUri) return [];
44753
+ const view = buildBtDocumentView(document, {
44754
+ semantic,
44755
+ config: config2,
44756
+ policy
44757
+ });
44758
+ return getBlackboardDefinitionLocations(view, identity, document.uri);
44759
+ });
44760
+ return uniqueLocations([...current, ...workspace]);
44761
+ }
44762
+ function getDocumentBlackboardLocations(documentView, identity, fallbackUri) {
44763
+ return getBlackboardDefinitionLocations(documentView, identity, fallbackUri);
44764
+ }
44071
44765
  function getDefinitionLocations(parsed, documentView, position, semantic, config2, policy, workspaceDocuments) {
44072
44766
  if (!parsed) return [];
44073
44767
  const inspect = inspectXmlCursor({
@@ -44093,27 +44787,45 @@ function getDefinitionLocations(parsed, documentView, position, semantic, config
44093
44787
  policy
44094
44788
  }) : void 0;
44095
44789
  if (element?.name === "SubTree" && attribute?.name === "ID") {
44790
+ if (usage?.tagForm === "model-definition") {
44791
+ return getBehaviorTrees(semantic, attribute.value).map((def) => def.idRange ? { uri: def.uri, range: def.idRange } : void 0).filter((location) => Boolean(location));
44792
+ }
44793
+ const subtreeModelDefinitions = getSubTreeModelDefinitionLocations(
44794
+ semantic,
44795
+ attribute.value,
44796
+ parsed.uri
44797
+ );
44096
44798
  const target = usage?.subtree?.target;
44097
44799
  if (target?.status === "resolved" && target.kind === "behavior-tree") {
44098
44800
  const behaviorTree = target.behaviorTree;
44099
44801
  if (behaviorTree.idRange) {
44100
- return [
44802
+ return uniqueLocations([
44101
44803
  {
44102
44804
  uri: behaviorTree.uri,
44103
44805
  range: behaviorTree.idRange
44104
- }
44105
- ];
44806
+ },
44807
+ ...subtreeModelDefinitions
44808
+ ]);
44106
44809
  }
44810
+ return subtreeModelDefinitions;
44107
44811
  }
44108
44812
  if (target?.status === "ambiguous") {
44109
- return [...target.behaviorTrees, ...target.definitions].map(
44110
- (def) => def.idRange ? { uri: def.uri || parsed.uri, range: def.idRange } : def.range ? { uri: def.uri || parsed.uri, range: def.range } : void 0
44111
- ).filter((location) => Boolean(location));
44813
+ return uniqueLocations(
44814
+ [
44815
+ ...target.behaviorTrees.map(
44816
+ (def) => def.idRange ? { uri: def.uri || parsed.uri, range: def.idRange } : void 0
44817
+ ),
44818
+ ...subtreeModelDefinitions
44819
+ ].filter((location) => Boolean(location))
44820
+ );
44112
44821
  }
44113
- if (target?.status === "resolved" && target.kind === "node-model" && target.model.idRange) {
44114
- return [{ uri: target.model.uri || parsed.uri, range: target.model.idRange }];
44822
+ if (target?.status === "resolved" && target.kind === "node-model") {
44823
+ if (subtreeModelDefinitions.length > 0) return subtreeModelDefinitions;
44824
+ if (target.model.idRange) {
44825
+ return [{ uri: target.model.uri || parsed.uri, range: target.model.idRange }];
44826
+ }
44115
44827
  }
44116
- return [];
44828
+ return subtreeModelDefinitions;
44117
44829
  }
44118
44830
  if (element?.name === "root" && attribute?.name === "main_tree_to_execute") {
44119
44831
  return getBehaviorTrees(semantic, attribute.value).map((def) => def.idRange ? { uri: def.uri, range: def.idRange } : void 0).filter((location) => Boolean(location));
@@ -44126,6 +44838,20 @@ function getDefinitionLocations(parsed, documentView, position, semantic, config
44126
44838
  }
44127
44839
  if (attribute && element) {
44128
44840
  const binding = documentView ? findPortBindingAtPosition(documentView, position) : void 0;
44841
+ const blackboardReference = binding?.blackboardReferences.find(
44842
+ (reference) => position.offset >= reference.range.start.offset && position.offset <= reference.range.end.offset
44843
+ );
44844
+ if (blackboardReference) {
44845
+ return blackboardReference.scope === "global" ? getWorkspaceBlackboardLocations(
44846
+ documentView,
44847
+ workspaceDocuments,
44848
+ semantic,
44849
+ config2,
44850
+ policy,
44851
+ blackboardReference.identity,
44852
+ parsed.uri
44853
+ ) : getDocumentBlackboardLocations(documentView, blackboardReference.identity, parsed.uri);
44854
+ }
44129
44855
  if (binding?.declaredPort.status === "resolved") {
44130
44856
  const port = binding.declaredPort.port;
44131
44857
  if (port.nameRange) return [{ uri: port.uri || parsed.uri, range: port.nameRange }];
@@ -44169,12 +44895,16 @@ function getDefinition(context, input) {
44169
44895
  ]
44170
44896
  };
44171
44897
  }
44172
- if (symbol2.source.kind === "port-remap") {
44898
+ if (symbol2.source.kind === "port-remap" || symbol2.source.kind === "global-blackboard-remap") {
44173
44899
  const source = symbol2.source;
44900
+ const targetIdentity = makeBlackboardIdentity({
44901
+ scope: source.kind === "global-blackboard-remap" ? "global" : "local",
44902
+ key: symbol2.name
44903
+ });
44174
44904
  const binding = context.documentView?.nodes.filter((node) => node.behaviorTree === scriptTarget.attributeContext.behaviorTree).flatMap((node) => node.portBindings).filter(
44175
44905
  (binding2) => binding2.declaredPort.status === "resolved"
44176
44906
  ).find(
44177
- (binding2) => binding2.declaredPort.port.name === source.portName && binding2.declaredPort.port.direction === source.direction && getRemappedKey(binding2.declaredPort.port.name, binding2.value) === symbol2.name
44907
+ (binding2) => binding2.declaredPort.port.name === source.portName && binding2.declaredPort.port.direction === source.direction && binding2.blackboardReferences.some((reference) => reference.identity === targetIdentity)
44178
44908
  );
44179
44909
  const location = binding?.declaredPort.port.nameRange;
44180
44910
  if (location) {
@@ -44206,6 +44936,39 @@ function getDefinition(context, input) {
44206
44936
  }
44207
44937
  }
44208
44938
  }
44939
+ if (scriptTarget?.reference.kind === "global-blackboard") {
44940
+ const targetIdentity = makeBlackboardIdentity({
44941
+ scope: "global",
44942
+ key: scriptTarget.reference.key
44943
+ });
44944
+ const locations = getGlobalBlackboardReferenceLocations(context, scriptTarget.reference.key);
44945
+ if (locations.length > 0) {
44946
+ return {
44947
+ locations
44948
+ };
44949
+ }
44950
+ const symbol2 = scriptTarget.reference.symbol;
44951
+ if (symbol2?.source.kind === "global-blackboard") {
44952
+ const source = symbol2.source;
44953
+ const declarationState = getBehaviorTreeScriptFlowStates(
44954
+ context,
44955
+ scriptTarget.attributeContext.behaviorTree
44956
+ ).find((state) => state.id === source.originId);
44957
+ const declarationContext = declarationState?.context ?? scriptTarget.attributeContext;
44958
+ return {
44959
+ locations: [
44960
+ {
44961
+ uri: context.document.uri,
44962
+ range: mapDecodedAttributeRangeToDocumentRange(
44963
+ context.parsed ?? { originalText: context.document.text },
44964
+ declarationContext.attribute,
44965
+ source.range
44966
+ )
44967
+ }
44968
+ ]
44969
+ };
44970
+ }
44971
+ }
44209
44972
  return {
44210
44973
  locations: getDefinitionLocations(
44211
44974
  context.parsed,
@@ -44292,6 +45055,18 @@ function getHover(context, input) {
44292
45055
  Value: \`${scriptTarget.reference.value}\``
44293
45056
  };
44294
45057
  }
45058
+ if (scriptTarget.reference.kind === "global-blackboard") {
45059
+ const symbol3 = scriptTarget.reference.symbol;
45060
+ return {
45061
+ range: scriptTarget.range,
45062
+ contents: symbol3 ? [
45063
+ `**Global Blackboard** \`@${scriptTarget.reference.key}\``,
45064
+ "",
45065
+ `Type: \`${formatScriptType3(symbol3.type)}\``,
45066
+ `Source: ${describeScriptSymbol2(symbol3)}`
45067
+ ].join("\n") : `**Global Blackboard** \`@${scriptTarget.reference.key}\``
45068
+ };
45069
+ }
44295
45070
  const symbol2 = scriptTarget.reference.symbol;
44296
45071
  return {
44297
45072
  range: scriptTarget.range,
@@ -44388,7 +45163,7 @@ Resolves to SubTree model in \`${target.model.uri || context.parsed?.uri || "wor
44388
45163
  function toReferenceLocations(context, id) {
44389
45164
  return getSubTreeReferences(context.semantic, id).filter((ref) => ref.parentBehaviorTreeId && ref.idRange).map((ref) => ({ uri: ref.uri, range: ref.idRange })).filter((location) => Boolean(location.range));
44390
45165
  }
44391
- function uniqueLocations(locations) {
45166
+ function uniqueLocations2(locations) {
44392
45167
  const seen = /* @__PURE__ */ new Set();
44393
45168
  const result = [];
44394
45169
  for (const location of locations) {
@@ -44424,9 +45199,9 @@ function getReferences(context, input) {
44424
45199
  const scriptTarget = getScriptIdentifierTarget(context, input.position);
44425
45200
  if (scriptTarget) {
44426
45201
  return {
44427
- locations: uniqueLocations(
45202
+ locations: uniqueLocations2(
44428
45203
  getScriptReferencesForSymbol(context, scriptTarget).map((occurrence) => ({
44429
- uri: context.document.uri,
45204
+ uri: occurrence.uri,
44430
45205
  range: occurrence.documentRange
44431
45206
  }))
44432
45207
  )
@@ -44439,6 +45214,32 @@ function getReferences(context, input) {
44439
45214
  }) : void 0;
44440
45215
  const element = inspect && "element" in inspect ? inspect.element : void 0;
44441
45216
  const attribute = inspect && "attribute" in inspect ? inspect.attribute : void 0;
45217
+ const binding = context.documentView && context.parsed ? context.documentView.nodes.flatMap((node) => node.portBindings).find(
45218
+ (candidate) => candidate.attribute === attribute && input.position.offset >= (candidate.attribute.valueContentRange ?? candidate.attribute.valueRange).start.offset && input.position.offset <= (candidate.attribute.valueContentRange ?? candidate.attribute.valueRange).end.offset
45219
+ ) : void 0;
45220
+ const blackboardReference = binding?.blackboardReferences.find(
45221
+ (reference) => input.position.offset >= reference.range.start.offset && input.position.offset <= reference.range.end.offset
45222
+ );
45223
+ if (blackboardReference) {
45224
+ const identity = makeBlackboardIdentity({
45225
+ scope: blackboardReference.scope,
45226
+ key: blackboardReference.key
45227
+ });
45228
+ return {
45229
+ locations: uniqueLocations2([
45230
+ ...blackboardReference.scope === "global" ? getWorkspaceBlackboardLocations(
45231
+ context.documentView,
45232
+ context.workspace?.documents,
45233
+ context.semantic,
45234
+ context.config,
45235
+ context.nodeUsagePolicy,
45236
+ identity,
45237
+ context.document.uri
45238
+ ) : getDocumentBlackboardLocations(context.documentView, identity, context.document.uri),
45239
+ ...blackboardReference.scope === "global" ? getGlobalBlackboardScriptLocations(context, blackboardReference.key) : []
45240
+ ])
45241
+ };
45242
+ }
44442
45243
  if (element?.name === "BehaviorTree" && attribute?.name === "ID") {
44443
45244
  return {
44444
45245
  locations: toReferenceLocations(context, attribute.value)
@@ -44471,7 +45272,7 @@ function getReferences(context, input) {
44471
45272
  const ids = getReferencedSubTreeIds(context, defs);
44472
45273
  if (ids.length > 0) {
44473
45274
  return {
44474
- locations: uniqueLocations(ids.flatMap((id) => toReferenceLocations(context, id)))
45275
+ locations: uniqueLocations2(ids.flatMap((id) => toReferenceLocations(context, id)))
44475
45276
  };
44476
45277
  }
44477
45278
  return { locations: [] };
@@ -44796,40 +45597,40 @@ function createWorkspaceService(options = {}) {
44796
45597
  return documents2.get(uri);
44797
45598
  },
44798
45599
  getDiagnostics(uri) {
44799
- const access = getDocumentAccess(uri);
44800
- if (!access || !access.emitDiagnostics) return { diagnostics: [] };
45600
+ const access2 = getDocumentAccess(uri);
45601
+ if (!access2 || !access2.emitDiagnostics) return { diagnostics: [] };
44801
45602
  const result = {
44802
- diagnostics: access.snapshot.diagnostics.diagnostics
45603
+ diagnostics: access2.snapshot.diagnostics.diagnostics
44803
45604
  };
44804
- if (access.snapshot.diagnostics.partial) result.partial = true;
45605
+ if (access2.snapshot.diagnostics.partial) result.partial = true;
44805
45606
  return result;
44806
45607
  },
44807
45608
  getWorkspaceDiagnostics() {
44808
45609
  return { diagnostics: [...getRuntimeState()?.diagnostics ?? runtimeDiagnostics] };
44809
45610
  },
44810
45611
  getSemanticDocumentView(uri) {
44811
- const access = getDocumentAccess(uri);
44812
- if (!access) return { diagnostics: [] };
44813
- return getSemanticDocumentResult(uri, access.effectiveConfig);
45612
+ const access2 = getDocumentAccess(uri);
45613
+ if (!access2) return { diagnostics: [] };
45614
+ return getSemanticDocumentResult(uri, access2.effectiveConfig);
44814
45615
  },
44815
45616
  getNodeCatalog(uri) {
44816
- const access = getDocumentAccess(uri);
44817
- if (!access) return { models: [] };
44818
- return { models: getNodeCatalogModels(access.snapshot) };
45617
+ const access2 = getDocumentAccess(uri);
45618
+ if (!access2) return { models: [] };
45619
+ return { models: getNodeCatalogModels(access2.snapshot) };
44819
45620
  },
44820
45621
  getSemanticNode(uri, nodeId) {
44821
- const access = getDocumentAccess(uri);
44822
- if (!access) return {};
44823
- const result = getSemanticDocumentResult(uri, access.effectiveConfig);
45622
+ const access2 = getDocumentAccess(uri);
45623
+ if (!access2) return {};
45624
+ const result = getSemanticDocumentResult(uri, access2.effectiveConfig);
44824
45625
  return {
44825
45626
  node: result.view?.nodes.find((candidate) => candidate.nodeId === nodeId)
44826
45627
  };
44827
45628
  },
44828
45629
  getNodeUsageAt(uri, position) {
44829
- const access = getDocumentAccess(uri);
44830
- if (!access) return {};
44831
- const view = getSemanticView(access.snapshot);
44832
- if (!access.snapshot.parsed || !view) return {};
45630
+ const access2 = getDocumentAccess(uri);
45631
+ if (!access2) return {};
45632
+ const view = getSemanticView(access2.snapshot);
45633
+ if (!access2.snapshot.parsed || !view) return {};
44833
45634
  const node = findSemanticNodeAtPosition(view, position);
44834
45635
  if (!node) return {};
44835
45636
  return {
@@ -44859,16 +45660,16 @@ function createWorkspaceService(options = {}) {
44859
45660
  if (genericKind === "Action" || genericKind === "Condition") {
44860
45661
  return { capable: false, reason: "generic-leaf" };
44861
45662
  }
44862
- const access = getDocumentAccess(uri);
44863
- if (!access) {
45663
+ const access2 = getDocumentAccess(uri);
45664
+ if (!access2) {
44864
45665
  return { capable: false, reason: "unknown-model" };
44865
45666
  }
44866
- const usage = resolveNodeUsage(access.snapshot.semantic, {
45667
+ const usage = resolveNodeUsage(access2.snapshot.semantic, {
44867
45668
  element: createSyntheticElement(tagName, attributes),
44868
- documentRoot: access.snapshot.parsed?.root,
45669
+ documentRoot: access2.snapshot.parsed?.root,
44869
45670
  uri,
44870
- config: access.snapshot.config,
44871
- policy: access.snapshot.nodeUsagePolicy
45671
+ config: access2.snapshot.config,
45672
+ policy: access2.snapshot.nodeUsagePolicy
44872
45673
  });
44873
45674
  if (usage.model.status !== "resolved") {
44874
45675
  return {
@@ -44883,20 +45684,20 @@ function createWorkspaceService(options = {}) {
44883
45684
  };
44884
45685
  },
44885
45686
  getPortInfoAt(uri, position) {
44886
- const access = getDocumentAccess(uri);
44887
- if (!access) return {};
44888
- const view = getSemanticView(access.snapshot);
44889
- if (!access.snapshot.parsed || !view) return {};
45687
+ const access2 = getDocumentAccess(uri);
45688
+ if (!access2) return {};
45689
+ const view = getSemanticView(access2.snapshot);
45690
+ if (!access2.snapshot.parsed || !view) return {};
44890
45691
  const binding = findSemanticPortBindingAtPosition(view, position);
44891
45692
  const nodeUsageAt = this.getNodeUsageAt(uri, position);
44892
45693
  const node = nodeUsageAt.node;
44893
- const usage = binding && node ? resolvePortUsage(access.snapshot.semantic, {
45694
+ const usage = binding && node ? resolvePortUsage(access2.snapshot.semantic, {
44894
45695
  element: node.usage.element,
44895
- documentRoot: access.snapshot.parsed.root,
45696
+ documentRoot: access2.snapshot.parsed.root,
44896
45697
  attributeName: binding.portName,
44897
45698
  uri,
44898
- config: access.snapshot.config,
44899
- policy: access.snapshot.nodeUsagePolicy
45699
+ config: access2.snapshot.config,
45700
+ policy: access2.snapshot.nodeUsagePolicy
44900
45701
  }) : void 0;
44901
45702
  return {
44902
45703
  node,
@@ -44907,72 +45708,72 @@ function createWorkspaceService(options = {}) {
44907
45708
  };
44908
45709
  },
44909
45710
  getFormattingEdits(uri) {
44910
- const access = getDocumentAccess(uri);
44911
- if (!access) return { edits: [], diagnostics: [] };
45711
+ const access2 = getDocumentAccess(uri);
45712
+ if (!access2) return { edits: [], diagnostics: [] };
44912
45713
  return languageService.getFormattingEdits({
44913
- document: access.document,
44914
- config: access.effectiveConfig
45714
+ document: access2.document,
45715
+ config: access2.effectiveConfig
44915
45716
  });
44916
45717
  },
44917
45718
  getCompletions(uri, position, triggerCharacter) {
44918
- const access = getDocumentAccess(uri);
44919
- if (!access) return { items: [] };
45719
+ const access2 = getDocumentAccess(uri);
45720
+ if (!access2) return { items: [] };
44920
45721
  return languageService.getCompletions({
44921
- document: access.document,
45722
+ document: access2.document,
44922
45723
  position,
44923
45724
  workspace: getRuntimeWorkspace(),
44924
45725
  triggerCharacter,
44925
- config: access.effectiveConfig
45726
+ config: access2.effectiveConfig
44926
45727
  });
44927
45728
  },
44928
45729
  getHover(uri, position) {
44929
- const access = getDocumentAccess(uri);
44930
- if (!access) return {};
45730
+ const access2 = getDocumentAccess(uri);
45731
+ if (!access2) return {};
44931
45732
  return languageService.getHover({
44932
- document: access.document,
45733
+ document: access2.document,
44933
45734
  position,
44934
45735
  workspace: getRuntimeWorkspace(),
44935
- config: access.effectiveConfig
45736
+ config: access2.effectiveConfig
44936
45737
  });
44937
45738
  },
44938
45739
  getDefinition(uri, position) {
44939
- const access = getDocumentAccess(uri);
44940
- if (!access) return { locations: [] };
45740
+ const access2 = getDocumentAccess(uri);
45741
+ if (!access2) return { locations: [] };
44941
45742
  return languageService.getDefinition({
44942
- document: access.document,
45743
+ document: access2.document,
44943
45744
  position,
44944
45745
  workspace: getRuntimeWorkspace(),
44945
- config: access.effectiveConfig
45746
+ config: access2.effectiveConfig
44946
45747
  });
44947
45748
  },
44948
45749
  getReferences(uri, position) {
44949
- const access = getDocumentAccess(uri);
44950
- if (!access) return { locations: [] };
45750
+ const access2 = getDocumentAccess(uri);
45751
+ if (!access2) return { locations: [] };
44951
45752
  return languageService.getReferences({
44952
- document: access.document,
45753
+ document: access2.document,
44953
45754
  position,
44954
45755
  workspace: getRuntimeWorkspace(),
44955
- config: access.effectiveConfig
45756
+ config: access2.effectiveConfig
44956
45757
  });
44957
45758
  },
44958
45759
  getDocumentSymbols(uri) {
44959
- const access = getDocumentAccess(uri);
44960
- if (!access) return { symbols: [] };
45760
+ const access2 = getDocumentAccess(uri);
45761
+ if (!access2) return { symbols: [] };
44961
45762
  return languageService.getDocumentSymbols({
44962
- document: access.document,
45763
+ document: access2.document,
44963
45764
  workspace: getRuntimeWorkspace(),
44964
- config: access.effectiveConfig
45765
+ config: access2.effectiveConfig
44965
45766
  });
44966
45767
  },
44967
45768
  getCodeActions(uri, range, diagnostics) {
44968
- const access = getDocumentAccess(uri);
44969
- if (!access) return { actions: [] };
45769
+ const access2 = getDocumentAccess(uri);
45770
+ if (!access2) return { actions: [] };
44970
45771
  return languageService.getCodeActions({
44971
- document: access.document,
45772
+ document: access2.document,
44972
45773
  range,
44973
45774
  diagnostics,
44974
45775
  workspace: getRuntimeWorkspace(),
44975
- config: access.effectiveConfig
45776
+ config: access2.effectiveConfig
44976
45777
  });
44977
45778
  },
44978
45779
  getLanguageService() {
@@ -45080,8 +45881,8 @@ function createNodeWorkspaceHost(cwd = process.cwd()) {
45080
45881
  try {
45081
45882
  await import_promises.default.access(fileUriToPath3(uri), import_node_fs.constants.F_OK);
45082
45883
  return true;
45083
- } catch (error51) {
45084
- if (error51.code !== "ENOENT") throw error51;
45884
+ } catch (error52) {
45885
+ if (error52.code !== "ENOENT") throw error52;
45085
45886
  return false;
45086
45887
  }
45087
45888
  },
@@ -45212,8 +46013,8 @@ function createNodeWorkspaceService(options = {}) {
45212
46013
  resolve(result) {
45213
46014
  resolveReload?.(result);
45214
46015
  },
45215
- reject(error51) {
45216
- rejectReload?.(error51);
46016
+ reject(error52) {
46017
+ rejectReload?.(error52);
45217
46018
  }
45218
46019
  };
45219
46020
  }
@@ -45222,8 +46023,8 @@ function createNodeWorkspaceService(options = {}) {
45222
46023
  const scheduled = pendingReload;
45223
46024
  void load(lastLoadOptions).then((result) => {
45224
46025
  scheduled?.resolve(result);
45225
- }).catch((error51) => {
45226
- scheduled?.reject(error51);
46026
+ }).catch((error52) => {
46027
+ scheduled?.reject(error52);
45227
46028
  }).finally(() => {
45228
46029
  if (pendingReload === scheduled) pendingReload = void 0;
45229
46030
  });
@@ -45723,14 +46524,16 @@ function handleGetChildCapability(workspace, params) {
45723
46524
  }
45724
46525
 
45725
46526
  // src/server.ts
46527
+ var SERVER_VERSION = true ? "0.1.2" : "unknown";
45726
46528
  var connection = (0, import_node4.createConnection)(import_node4.ProposedFeatures.all);
45727
46529
  var documents = new import_node4.TextDocuments(TextDocument);
45728
46530
  var openUris = /* @__PURE__ */ new Set();
45729
46531
  var debounceTimers = /* @__PURE__ */ new Map();
45730
- var documentWorkspaceRoots = /* @__PURE__ */ new Map();
45731
- var workspaceServices = /* @__PURE__ */ new Map();
45732
- var loadedWorkspaceRoots = /* @__PURE__ */ new Set();
45733
- var workspaceRoots = [process.cwd()];
46532
+ var documentProjectKeys = /* @__PURE__ */ new Map();
46533
+ var projectBindings = /* @__PURE__ */ new Map();
46534
+ var projectServices = /* @__PURE__ */ new Map();
46535
+ var loadedProjects = /* @__PURE__ */ new Set();
46536
+ var workspaceRoots = [import_node_path3.default.resolve(process.cwd())];
45734
46537
  var settings = {
45735
46538
  configPath: void 0,
45736
46539
  diagnosticsEnabled: true,
@@ -45751,41 +46554,45 @@ function normalizeDocumentUri(uri) {
45751
46554
  return uri;
45752
46555
  }
45753
46556
  }
45754
- function normalizeWorkspaceRoot2(rootPath) {
45755
- const normalized = import_node_path3.default.resolve(rootPath).replace(/\\/g, "/").replace(/\/$/, "");
46557
+ function normalizeFsPath(fsPath) {
46558
+ const normalized = import_node_path3.default.resolve(fsPath).replace(/\\/g, "/").replace(/\/$/, "");
45756
46559
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
45757
46560
  }
46561
+ function normalizeLanguageId(languageId) {
46562
+ return languageId === "btcpp-xml" ? "btcpp-xml" : "xml";
46563
+ }
46564
+ function toDocumentSnapshot(document) {
46565
+ return {
46566
+ text: document.getText(),
46567
+ version: document.version,
46568
+ languageId: normalizeLanguageId(document.languageId)
46569
+ };
46570
+ }
46571
+ function isWithinPath(parentPath, targetPath) {
46572
+ const normalizedParent = normalizeFsPath(parentPath);
46573
+ const normalizedTarget = normalizeFsPath(targetPath);
46574
+ return normalizedTarget === normalizedParent || normalizedTarget.startsWith(`${normalizedParent}/`);
46575
+ }
45758
46576
  function setWorkspaceRoots(nextRoots) {
45759
- const deduped = /* @__PURE__ */ new Set();
46577
+ const deduped = /* @__PURE__ */ new Map();
45760
46578
  for (const root of nextRoots) {
45761
46579
  const resolvedRoot = import_node_path3.default.resolve(root);
45762
- const normalizedRoot = normalizeWorkspaceRoot2(resolvedRoot);
46580
+ const normalizedRoot = normalizeFsPath(resolvedRoot);
45763
46581
  if (deduped.has(normalizedRoot)) continue;
45764
- deduped.add(normalizedRoot);
46582
+ deduped.set(normalizedRoot, resolvedRoot);
45765
46583
  }
45766
- workspaceRoots = [...deduped].map((normalizedRoot) => {
45767
- return nextRoots.find(
45768
- (root) => normalizeWorkspaceRoot2(import_node_path3.default.resolve(root)) === normalizedRoot
45769
- );
45770
- }).filter((root) => Boolean(root)) || [process.cwd()];
46584
+ workspaceRoots = deduped.size > 0 ? [...deduped.values()] : [import_node_path3.default.resolve(process.cwd())];
45771
46585
  }
45772
46586
  function collectWorkspaceRoots(params) {
45773
46587
  const roots = params.workspaceFolders?.map((folder) => fileUriToPath4(folder.uri)) || (params.rootUri ? [fileUriToPath4(params.rootUri)] : params.rootPath ? [params.rootPath] : []);
45774
46588
  return roots.length > 0 ? roots : [process.cwd()];
45775
46589
  }
45776
- function getWorkspaceService(rootPath) {
45777
- let workspace = workspaceServices.get(rootPath);
45778
- if (workspace) return workspace;
45779
- workspace = createNodeWorkspaceService({ cwd: rootPath });
45780
- workspaceServices.set(rootPath, workspace);
45781
- return workspace;
45782
- }
45783
46590
  function resolveWorkspaceRootForPath(fsPath) {
45784
- const normalizedPath = normalizeWorkspaceRoot2(fsPath);
45785
- let matchedRoot = workspaceRoots[0] || process.cwd();
46591
+ const normalizedPath = normalizeFsPath(fsPath);
46592
+ let matchedRoot = workspaceRoots[0] || import_node_path3.default.resolve(process.cwd());
45786
46593
  let matchedLength = -1;
45787
46594
  for (const root of workspaceRoots) {
45788
- const normalizedRoot = normalizeWorkspaceRoot2(root);
46595
+ const normalizedRoot = normalizeFsPath(root);
45789
46596
  if (normalizedPath !== normalizedRoot && !normalizedPath.startsWith(`${normalizedRoot}/`)) {
45790
46597
  continue;
45791
46598
  }
@@ -45796,18 +46603,21 @@ function resolveWorkspaceRootForPath(fsPath) {
45796
46603
  return matchedRoot;
45797
46604
  }
45798
46605
  function resolveWorkspaceRootForUri(uri) {
45799
- if (!uri.startsWith("file://")) return workspaceRoots[0] || process.cwd();
46606
+ if (!uri.startsWith("file://")) return workspaceRoots[0] || import_node_path3.default.resolve(process.cwd());
45800
46607
  try {
45801
46608
  return resolveWorkspaceRootForPath(fileUriToPath4(uri));
45802
46609
  } catch {
45803
- return workspaceRoots[0] || process.cwd();
46610
+ return workspaceRoots[0] || import_node_path3.default.resolve(process.cwd());
45804
46611
  }
45805
46612
  }
45806
- function getDocumentWorkspaceRoot(uri) {
45807
- return documentWorkspaceRoots.get(uri) || resolveWorkspaceRootForUri(uri);
45808
- }
45809
- function getWorkspaceForDocumentUri(uri) {
45810
- return getWorkspaceService(getDocumentWorkspaceRoot(uri));
46613
+ function withNormalizedTextDocumentUri(params) {
46614
+ return {
46615
+ ...params,
46616
+ textDocument: {
46617
+ ...params.textDocument,
46618
+ uri: normalizeDocumentUri(params.textDocument.uri)
46619
+ }
46620
+ };
45811
46621
  }
45812
46622
  function applySettings(next) {
45813
46623
  const scoped = next && typeof next === "object" && "btxml" in next ? next.btxml : next;
@@ -45821,103 +46631,187 @@ function applySettings(next) {
45821
46631
  diagnosticsDebounceMs: Number(value.diagnosticsDebounceMs ?? value.lsp?.diagnosticsDebounceMs ?? 200) || 200
45822
46632
  };
45823
46633
  }
45824
- function getDocument(uri) {
45825
- const normalizedUri = normalizeDocumentUri(uri);
45826
- const workspace = getWorkspaceForDocumentUri(normalizedUri);
45827
- return workspace.getDocument(normalizedUri) || workspace.getDocument(fileUriToPath4(normalizedUri));
46634
+ async function pathExists(fsPath) {
46635
+ try {
46636
+ await (0, import_promises2.access)(fsPath);
46637
+ return true;
46638
+ } catch {
46639
+ return false;
46640
+ }
45828
46641
  }
45829
- function withNormalizedTextDocumentUri(params) {
46642
+ function getConfiguredConfigPath(workspaceRoot) {
46643
+ if (!settings.configPath) return void 0;
46644
+ return import_node_path3.default.isAbsolute(settings.configPath) ? import_node_path3.default.resolve(settings.configPath) : import_node_path3.default.resolve(workspaceRoot, settings.configPath);
46645
+ }
46646
+ async function findNearestConfigPath(documentPath, workspaceRoot) {
46647
+ const boundedRoot = isWithinPath(workspaceRoot, documentPath) ? import_node_path3.default.resolve(workspaceRoot) : void 0;
46648
+ let currentDir = import_node_path3.default.dirname(documentPath);
46649
+ while (true) {
46650
+ const candidate = import_node_path3.default.join(currentDir, "btxml.config.json");
46651
+ if (await pathExists(candidate)) return candidate;
46652
+ if (boundedRoot && normalizeFsPath(currentDir) === normalizeFsPath(boundedRoot))
46653
+ return void 0;
46654
+ const parentDir = import_node_path3.default.dirname(currentDir);
46655
+ if (parentDir === currentDir) return void 0;
46656
+ if (boundedRoot && !isWithinPath(boundedRoot, parentDir)) return void 0;
46657
+ currentDir = parentDir;
46658
+ }
46659
+ }
46660
+ function toWorkspaceProjectBinding(workspaceRoot) {
46661
+ const resolvedWorkspaceRoot = import_node_path3.default.resolve(workspaceRoot);
45830
46662
  return {
45831
- ...params,
45832
- textDocument: {
45833
- ...params.textDocument,
45834
- uri: normalizeDocumentUri(params.textDocument.uri)
45835
- }
46663
+ key: `workspace:${normalizeFsPath(resolvedWorkspaceRoot)}`,
46664
+ cwd: resolvedWorkspaceRoot,
46665
+ workspaceRoot: resolvedWorkspaceRoot
45836
46666
  };
45837
46667
  }
45838
- async function reloadWorkspace(rootPath) {
45839
- const workspace = getWorkspaceService(rootPath);
45840
- const result = await workspace.loadProject({
45841
- cwd: rootPath,
45842
- configPath: settings.configPath
45843
- });
45844
- if (workspace.getResolvedConfig()) {
45845
- loadedWorkspaceRoots.add(rootPath);
45846
- } else {
45847
- loadedWorkspaceRoots.delete(rootPath);
46668
+ function toConfigProjectBinding(configPath2, workspaceRoot) {
46669
+ const resolvedConfigPath = import_node_path3.default.resolve(configPath2);
46670
+ return {
46671
+ key: `config:${normalizeFsPath(resolvedConfigPath)}`,
46672
+ cwd: import_node_path3.default.dirname(resolvedConfigPath),
46673
+ workspaceRoot: import_node_path3.default.resolve(workspaceRoot),
46674
+ configPath: resolvedConfigPath
46675
+ };
46676
+ }
46677
+ async function resolveProjectForDocumentUri(uri) {
46678
+ const workspaceRoot = import_node_path3.default.resolve(resolveWorkspaceRootForUri(uri));
46679
+ const configuredConfigPath = getConfiguredConfigPath(workspaceRoot);
46680
+ if (configuredConfigPath) {
46681
+ return toConfigProjectBinding(configuredConfigPath, workspaceRoot);
45848
46682
  }
46683
+ if (uri.startsWith("file://")) {
46684
+ try {
46685
+ const nearestConfigPath = await findNearestConfigPath(fileUriToPath4(uri), workspaceRoot);
46686
+ if (nearestConfigPath) return toConfigProjectBinding(nearestConfigPath, workspaceRoot);
46687
+ } catch {
46688
+ }
46689
+ }
46690
+ return toWorkspaceProjectBinding(workspaceRoot);
46691
+ }
46692
+ function getProjectService(binding) {
46693
+ projectBindings.set(binding.key, binding);
46694
+ let projectService = projectServices.get(binding.key);
46695
+ if (projectService) return projectService;
46696
+ projectService = createNodeWorkspaceService({ cwd: binding.cwd });
46697
+ projectServices.set(binding.key, projectService);
46698
+ return projectService;
46699
+ }
46700
+ function getProjectBindingForDocumentUri(uri) {
46701
+ const key = documentProjectKeys.get(uri);
46702
+ return key ? projectBindings.get(key) : void 0;
46703
+ }
46704
+ function getProjectServiceForBoundDocumentUri(uri) {
46705
+ const binding = getProjectBindingForDocumentUri(uri);
46706
+ return binding ? getProjectService(binding) : void 0;
46707
+ }
46708
+ function getWorkspaceDocument(uri) {
46709
+ const normalizedUri = normalizeDocumentUri(uri);
46710
+ const projectService = getProjectServiceForBoundDocumentUri(normalizedUri);
46711
+ return projectService?.getDocument(normalizedUri) || (normalizedUri.startsWith("file://") ? projectService?.getDocument(fileUriToPath4(normalizedUri)) : void 0);
46712
+ }
46713
+ function getOpenDocumentSnapshot(uri) {
46714
+ const document = documents.get(uri);
46715
+ if (document) return toDocumentSnapshot(document);
46716
+ const projectService = getProjectServiceForBoundDocumentUri(uri);
46717
+ const workspaceDocument = projectService?.getDocument(uri);
46718
+ return workspaceDocument ? toDocumentSnapshot(workspaceDocument) : void 0;
46719
+ }
46720
+ function isProjectInUse(key) {
46721
+ for (const projectKey of documentProjectKeys.values()) {
46722
+ if (projectKey === key) return true;
46723
+ }
46724
+ return false;
46725
+ }
46726
+ function disposeProject(key) {
46727
+ const projectService = projectServices.get(key);
46728
+ if (projectService) projectService.dispose();
46729
+ projectServices.delete(key);
46730
+ projectBindings.delete(key);
46731
+ loadedProjects.delete(key);
46732
+ }
46733
+ function disposeProjectIfUnused(key) {
46734
+ if (isProjectInUse(key)) return;
46735
+ disposeProject(key);
46736
+ }
46737
+ function disposeUnusedProjects() {
46738
+ for (const key of [...projectServices.keys()]) {
46739
+ disposeProjectIfUnused(key);
46740
+ }
46741
+ }
46742
+ async function reloadProject(binding, options) {
46743
+ const projectService = getProjectService(binding);
46744
+ const result = await projectService.loadProject(
46745
+ binding.configPath ? {
46746
+ cwd: binding.cwd,
46747
+ configPath: binding.configPath
46748
+ } : {
46749
+ cwd: binding.workspaceRoot
46750
+ }
46751
+ );
46752
+ loadedProjects.add(binding.key);
45849
46753
  if (!result.ok && result.diagnostics.length > 0) {
45850
46754
  const lines = result.diagnostics.map((diag) => `${diag.severity} ${diag.code} ${diag.message}`);
45851
46755
  process.stderr.write(`${lines.join("\n")}
45852
46756
  `);
45853
46757
  }
45854
- for (const uri of openUris) {
45855
- if (getDocumentWorkspaceRoot(uri) !== rootPath) continue;
45856
- publishDiagnostics(uri);
46758
+ if (options?.publishDiagnostics !== false) {
46759
+ for (const uri of openUris) {
46760
+ if (documentProjectKeys.get(uri) !== binding.key) continue;
46761
+ publishDiagnostics(uri);
46762
+ }
45857
46763
  }
45858
46764
  return result;
45859
46765
  }
45860
- async function reloadAllWorkspaces() {
45861
- return Promise.all(workspaceRoots.map((rootPath) => reloadWorkspace(rootPath)));
46766
+ async function ensureProjectLoaded(binding) {
46767
+ if (loadedProjects.has(binding.key)) return false;
46768
+ await reloadProject(binding);
46769
+ return true;
45862
46770
  }
45863
- async function handleWorkspaceFoldersChanged(params) {
45864
- const removedRoots = new Set(
45865
- params.event.removed.map((folder) => normalizeWorkspaceRoot2(fileUriToPath4(folder.uri)))
45866
- );
45867
- const addedRoots = params.event.added.map((folder) => fileUriToPath4(folder.uri));
45868
- const movedOpenDocuments = /* @__PURE__ */ new Map();
45869
- for (const uri of openUris) {
45870
- const previousRoot = documentWorkspaceRoots.get(uri);
45871
- if (!previousRoot || !removedRoots.has(normalizeWorkspaceRoot2(previousRoot))) continue;
45872
- const document = workspaceServices.get(previousRoot)?.getDocument(uri);
45873
- movedOpenDocuments.set(
45874
- uri,
45875
- document ? {
45876
- text: document.text,
45877
- version: document.version,
45878
- languageId: document.languageId
45879
- } : void 0
45880
- );
45881
- }
45882
- setWorkspaceRoots(
45883
- workspaceRoots.filter((rootPath) => !removedRoots.has(normalizeWorkspaceRoot2(rootPath))).concat(addedRoots)
45884
- );
45885
- for (const [rootPath, workspace] of [...workspaceServices.entries()]) {
45886
- if (workspaceRoots.some(
45887
- (candidate) => normalizeWorkspaceRoot2(candidate) === normalizeWorkspaceRoot2(rootPath)
45888
- )) {
45889
- continue;
45890
- }
45891
- workspace.dispose();
45892
- workspaceServices.delete(rootPath);
45893
- loadedWorkspaceRoots.delete(rootPath);
46771
+ async function bindOpenDocument(uri, snapshot) {
46772
+ const normalizedUri = normalizeDocumentUri(uri);
46773
+ const nextBinding = await resolveProjectForDocumentUri(normalizedUri);
46774
+ const previousKey = documentProjectKeys.get(normalizedUri);
46775
+ const previousService = previousKey ? projectServices.get(previousKey) : void 0;
46776
+ const nextService = getProjectService(nextBinding);
46777
+ const changedProject = previousKey !== nextBinding.key;
46778
+ const wasLoaded = loadedProjects.has(nextBinding.key);
46779
+ if (changedProject) previousService?.closeDocument(normalizedUri);
46780
+ documentProjectKeys.set(normalizedUri, nextBinding.key);
46781
+ projectBindings.set(nextBinding.key, nextBinding);
46782
+ if (!wasLoaded) {
46783
+ await reloadProject(nextBinding, { publishDiagnostics: false });
46784
+ }
46785
+ if (!wasLoaded || changedProject || !nextService.getDocument(normalizedUri)) {
46786
+ nextService.openDocument(normalizedUri, snapshot.text, snapshot.version, snapshot.languageId);
46787
+ } else {
46788
+ nextService.updateDocument(normalizedUri, snapshot.text, snapshot.version, snapshot.languageId);
45894
46789
  }
45895
- await reloadAllWorkspaces();
46790
+ if (changedProject && previousKey) disposeProjectIfUnused(previousKey);
46791
+ return { binding: nextBinding, reloaded: !wasLoaded };
46792
+ }
46793
+ async function rebindAllOpenDocuments() {
45896
46794
  for (const uri of openUris) {
45897
- const nextRoot = resolveWorkspaceRootForUri(uri);
45898
- const previousRoot = documentWorkspaceRoots.get(uri);
45899
- if (previousRoot === nextRoot) {
45900
- publishDiagnostics(uri);
45901
- continue;
45902
- }
45903
- const previousWorkspace = previousRoot ? workspaceServices.get(previousRoot) : void 0;
45904
- const document = previousWorkspace?.getDocument(uri) ?? movedOpenDocuments.get(uri);
45905
- previousWorkspace?.closeDocument(uri);
45906
- documentWorkspaceRoots.set(uri, nextRoot);
45907
- if (document) {
45908
- getWorkspaceService(nextRoot).openDocument(
45909
- uri,
45910
- document.text,
45911
- document.version,
45912
- document.languageId
45913
- );
45914
- }
46795
+ const snapshot = getOpenDocumentSnapshot(uri);
46796
+ if (!snapshot) continue;
46797
+ await bindOpenDocument(uri, snapshot);
45915
46798
  publishDiagnostics(uri);
45916
46799
  }
46800
+ disposeUnusedProjects();
46801
+ }
46802
+ async function getProjectServiceForDocumentUri(uri) {
46803
+ const normalizedUri = normalizeDocumentUri(uri);
46804
+ const boundBinding = getProjectBindingForDocumentUri(normalizedUri);
46805
+ if (boundBinding) {
46806
+ await ensureProjectLoaded(boundBinding);
46807
+ return getProjectService(boundBinding);
46808
+ }
46809
+ const binding = await resolveProjectForDocumentUri(normalizedUri);
46810
+ await ensureProjectLoaded(binding);
46811
+ return getProjectService(binding);
45917
46812
  }
45918
46813
  function publishDiagnostics(uri) {
45919
46814
  const normalizedUri = normalizeDocumentUri(uri);
45920
- const workspace = getWorkspaceForDocumentUri(normalizedUri);
45921
46815
  if (!settings.diagnosticsEnabled) {
45922
46816
  connection.sendNotification("textDocument/publishDiagnostics", {
45923
46817
  uri: normalizedUri,
@@ -45925,15 +46819,16 @@ function publishDiagnostics(uri) {
45925
46819
  });
45926
46820
  return;
45927
46821
  }
45928
- const document = getDocument(normalizedUri);
45929
- if (!document) {
46822
+ const document = getWorkspaceDocument(normalizedUri);
46823
+ const projectService = getProjectServiceForBoundDocumentUri(normalizedUri);
46824
+ if (!document || !projectService) {
45930
46825
  connection.sendNotification("textDocument/publishDiagnostics", {
45931
46826
  uri: normalizedUri,
45932
46827
  diagnostics: []
45933
46828
  });
45934
46829
  return;
45935
46830
  }
45936
- const result = workspace.getDiagnostics(normalizedUri);
46831
+ const result = projectService.getDiagnostics(normalizedUri);
45937
46832
  connection.sendNotification("textDocument/publishDiagnostics", {
45938
46833
  uri: normalizedUri,
45939
46834
  diagnostics: result.diagnostics.map(toDiagnostic)
@@ -45948,58 +46843,56 @@ function scheduleDiagnostics(uri) {
45948
46843
  }, settings.diagnosticsDebounceMs);
45949
46844
  debounceTimers.set(uri, timeout);
45950
46845
  }
46846
+ function bindingMatchesFilePath(binding, fsPath) {
46847
+ if (binding.configPath && normalizeFsPath(binding.configPath) === normalizeFsPath(fsPath))
46848
+ return true;
46849
+ return isWithinPath(binding.cwd, fsPath);
46850
+ }
45951
46851
  documents.onDidOpen(async (event) => {
45952
46852
  const normalizedUri = normalizeDocumentUri(event.document.uri);
45953
- const rootPath = resolveWorkspaceRootForUri(normalizedUri);
45954
- documentWorkspaceRoots.set(normalizedUri, rootPath);
45955
- if (!loadedWorkspaceRoots.has(rootPath)) {
45956
- await reloadWorkspace(rootPath);
45957
- }
45958
46853
  openUris.add(normalizedUri);
45959
- const workspace = getWorkspaceService(rootPath);
45960
- workspace.openDocument(
45961
- normalizedUri,
45962
- event.document.getText(),
45963
- event.document.version,
45964
- event.document.languageId === "btcpp-xml" ? "btcpp-xml" : "xml"
45965
- );
46854
+ await bindOpenDocument(normalizedUri, toDocumentSnapshot(event.document));
45966
46855
  publishDiagnostics(normalizedUri);
45967
46856
  });
45968
46857
  documents.onDidChangeContent((event) => {
45969
46858
  const normalizedUri = normalizeDocumentUri(event.document.uri);
45970
- const workspace = getWorkspaceForDocumentUri(normalizedUri);
45971
- workspace.updateDocument(
46859
+ const projectService = getProjectServiceForBoundDocumentUri(normalizedUri);
46860
+ if (!projectService) return;
46861
+ projectService.updateDocument(
45972
46862
  normalizedUri,
45973
46863
  event.document.getText(),
45974
46864
  event.document.version,
45975
- event.document.languageId === "btcpp-xml" ? "btcpp-xml" : "xml"
46865
+ normalizeLanguageId(event.document.languageId)
45976
46866
  );
45977
46867
  scheduleDiagnostics(normalizedUri);
45978
46868
  });
45979
46869
  documents.onDidClose((event) => {
45980
46870
  const normalizedUri = normalizeDocumentUri(event.document.uri);
45981
- const workspace = getWorkspaceForDocumentUri(normalizedUri);
46871
+ const projectKey = documentProjectKeys.get(normalizedUri);
46872
+ const projectService = projectKey ? projectServices.get(projectKey) : void 0;
45982
46873
  openUris.delete(normalizedUri);
45983
46874
  const existing = debounceTimers.get(normalizedUri);
45984
46875
  if (existing) clearTimeout(existing);
45985
46876
  debounceTimers.delete(normalizedUri);
45986
- workspace.closeDocument(normalizedUri);
45987
- documentWorkspaceRoots.delete(normalizedUri);
46877
+ projectService?.closeDocument(normalizedUri);
46878
+ if (projectKey) {
46879
+ documentProjectKeys.delete(normalizedUri);
46880
+ disposeProjectIfUnused(projectKey);
46881
+ }
45988
46882
  connection.sendNotification("textDocument/publishDiagnostics", {
45989
46883
  uri: normalizedUri,
45990
46884
  diagnostics: []
45991
46885
  });
45992
46886
  });
45993
- connection.onInitialize(async (params) => {
46887
+ connection.onInitialize((params) => {
45994
46888
  applySettings(params.initializationOptions);
45995
46889
  setWorkspaceRoots(
45996
46890
  collectWorkspaceRoots(params)
45997
46891
  );
45998
- await reloadAllWorkspaces();
45999
46892
  return {
46000
46893
  serverInfo: {
46001
46894
  name: "btxml",
46002
- version: "0.1.0"
46895
+ version: SERVER_VERSION
46003
46896
  },
46004
46897
  capabilities: {
46005
46898
  textDocumentSync: import_node4.TextDocumentSyncKind.Incremental,
@@ -46031,114 +46924,125 @@ connection.onNotification(
46031
46924
  "workspace/didChangeConfiguration",
46032
46925
  async (params) => {
46033
46926
  applySettings(params.settings);
46034
- await reloadAllWorkspaces();
46927
+ loadedProjects.clear();
46928
+ await rebindAllOpenDocuments();
46035
46929
  }
46036
46930
  );
46037
46931
  connection.onNotification(
46038
46932
  "workspace/didChangeWorkspaceFolders",
46039
46933
  async (params) => {
46040
- await handleWorkspaceFoldersChanged(params);
46934
+ const removedRoots = new Set(
46935
+ params.event.removed.map((folder) => normalizeFsPath(fileUriToPath4(folder.uri)))
46936
+ );
46937
+ const addedRoots = params.event.added.map((folder) => fileUriToPath4(folder.uri));
46938
+ setWorkspaceRoots(
46939
+ workspaceRoots.filter((rootPath) => !removedRoots.has(normalizeFsPath(rootPath))).concat(addedRoots)
46940
+ );
46941
+ loadedProjects.clear();
46942
+ await rebindAllOpenDocuments();
46041
46943
  }
46042
46944
  );
46043
46945
  connection.onNotification("workspace/didChangeWatchedFiles", async (params) => {
46044
46946
  const changes = params?.changes || [];
46045
- const reloadedRoots = /* @__PURE__ */ new Set();
46046
- await Promise.all(
46047
- changes.map(async (change) => {
46048
- const normalizedUri = normalizeDocumentUri(change.uri);
46049
- const affectedRoots = normalizedUri.startsWith("file://") ? (() => {
46050
- const rootPath = resolveWorkspaceRootForUri(normalizedUri);
46051
- const fsPath = fileUriToPath4(normalizedUri);
46052
- const normalizedRoot = normalizeWorkspaceRoot2(rootPath);
46053
- const normalizedPath = normalizeWorkspaceRoot2(fsPath);
46054
- return normalizedPath === normalizedRoot || normalizedPath.startsWith(`${normalizedRoot}/`) ? [rootPath] : workspaceRoots;
46055
- })() : workspaceRoots;
46056
- const reloads = await Promise.all(
46057
- affectedRoots.map(
46058
- (rootPath) => getWorkspaceService(rootPath).notifyWatchedFileChanged(normalizedUri)
46059
- )
46060
- );
46061
- if (reloads.some((result) => result)) {
46062
- for (const rootPath of affectedRoots) reloadedRoots.add(rootPath);
46063
- }
46064
- })
46065
- );
46066
- if (reloadedRoots.size > 0) {
46067
- for (const uri of openUris) {
46068
- if (!reloadedRoots.has(getDocumentWorkspaceRoot(uri))) continue;
46069
- publishDiagnostics(uri);
46947
+ if (changes.length === 0) return;
46948
+ if (changes.some(
46949
+ (change) => normalizeDocumentUri(change.uri).toLowerCase().endsWith("btxml.config.json")
46950
+ )) {
46951
+ loadedProjects.clear();
46952
+ await rebindAllOpenDocuments();
46953
+ return;
46954
+ }
46955
+ const reloadedProjects = /* @__PURE__ */ new Set();
46956
+ for (const change of changes) {
46957
+ const normalizedUri = normalizeDocumentUri(change.uri);
46958
+ if (!normalizedUri.startsWith("file://")) continue;
46959
+ const fsPath = fileUriToPath4(normalizedUri);
46960
+ for (const binding of projectBindings.values()) {
46961
+ if (!bindingMatchesFilePath(binding, fsPath)) continue;
46962
+ const result = await getProjectService(binding).notifyWatchedFileChanged(normalizedUri);
46963
+ if (!result) continue;
46964
+ loadedProjects.add(binding.key);
46965
+ reloadedProjects.add(binding.key);
46070
46966
  }
46071
46967
  }
46968
+ if (reloadedProjects.size === 0) return;
46969
+ for (const uri of openUris) {
46970
+ const projectKey = documentProjectKeys.get(uri);
46971
+ if (!projectKey || !reloadedProjects.has(projectKey)) continue;
46972
+ publishDiagnostics(uri);
46973
+ }
46072
46974
  });
46073
- connection.onRequest("textDocument/completion", (params) => {
46975
+ connection.onRequest("textDocument/completion", async (params) => {
46074
46976
  if (!settings.completionEnabled) return [];
46075
46977
  const normalizedParams = withNormalizedTextDocumentUri(params);
46076
46978
  return handleCompletion(
46077
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46078
- getDocument(normalizedParams.textDocument.uri),
46979
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
46980
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46079
46981
  normalizedParams
46080
46982
  );
46081
46983
  });
46082
- connection.onRequest("textDocument/hover", (params) => {
46984
+ connection.onRequest("textDocument/hover", async (params) => {
46083
46985
  const normalizedParams = withNormalizedTextDocumentUri(params);
46084
46986
  return handleHover(
46085
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46086
- getDocument(normalizedParams.textDocument.uri),
46987
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
46988
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46087
46989
  normalizedParams
46088
46990
  );
46089
46991
  });
46090
- connection.onRequest("textDocument/definition", (params) => {
46992
+ connection.onRequest("textDocument/definition", async (params) => {
46091
46993
  const normalizedParams = withNormalizedTextDocumentUri(params);
46092
46994
  return handleDefinition(
46093
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46094
- getDocument(normalizedParams.textDocument.uri),
46995
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
46996
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46095
46997
  normalizedParams
46096
46998
  );
46097
46999
  });
46098
- connection.onRequest("textDocument/references", (params) => {
47000
+ connection.onRequest("textDocument/references", async (params) => {
46099
47001
  const normalizedParams = withNormalizedTextDocumentUri(params);
46100
47002
  return handleReferences(
46101
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46102
- getDocument(normalizedParams.textDocument.uri),
47003
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
47004
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46103
47005
  normalizedParams
46104
47006
  );
46105
47007
  });
46106
- connection.onRequest("textDocument/documentSymbol", (params) => {
47008
+ connection.onRequest("textDocument/documentSymbol", async (params) => {
46107
47009
  const normalizedParams = withNormalizedTextDocumentUri(params);
46108
47010
  return handleDocumentSymbols(
46109
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46110
- getDocument(normalizedParams.textDocument.uri),
47011
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
47012
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46111
47013
  normalizedParams,
46112
47014
  import_node4.SymbolKind
46113
47015
  );
46114
47016
  });
46115
- connection.onRequest("textDocument/formatting", (params) => {
47017
+ connection.onRequest("textDocument/formatting", async (params) => {
46116
47018
  if (!settings.formatEnabled) return [];
46117
47019
  const normalizedParams = withNormalizedTextDocumentUri(params);
46118
47020
  return handleFormatting(
46119
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46120
- getDocument(normalizedParams.textDocument.uri),
47021
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
47022
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46121
47023
  normalizedParams
46122
47024
  );
46123
47025
  });
46124
- connection.onRequest("textDocument/codeAction", (params) => {
47026
+ connection.onRequest("textDocument/codeAction", async (params) => {
46125
47027
  const normalizedParams = withNormalizedTextDocumentUri(params);
46126
47028
  return handleCodeActions(
46127
- getWorkspaceForDocumentUri(normalizedParams.textDocument.uri),
46128
- getDocument(normalizedParams.textDocument.uri),
47029
+ await getProjectServiceForDocumentUri(normalizedParams.textDocument.uri),
47030
+ getWorkspaceDocument(normalizedParams.textDocument.uri),
46129
47031
  normalizedParams
46130
47032
  );
46131
47033
  });
46132
- connection.onRequest("btxml/getNodeModelById", (params) => {
46133
- return handleGetNodeModelById(getWorkspaceForDocumentUri(normalizeDocumentUri(params.uri)), {
47034
+ connection.onRequest("btxml/getNodeModelById", async (params) => {
47035
+ const normalizedUri = normalizeDocumentUri(params.uri);
47036
+ return handleGetNodeModelById(await getProjectServiceForDocumentUri(normalizedUri), {
46134
47037
  ...params,
46135
- uri: normalizeDocumentUri(params.uri)
47038
+ uri: normalizedUri
46136
47039
  });
46137
47040
  });
46138
- connection.onRequest("btxml/getChildCapability", (params) => {
46139
- return handleGetChildCapability(getWorkspaceForDocumentUri(normalizeDocumentUri(params.uri)), {
47041
+ connection.onRequest("btxml/getChildCapability", async (params) => {
47042
+ const normalizedUri = normalizeDocumentUri(params.uri);
47043
+ return handleGetChildCapability(await getProjectServiceForDocumentUri(normalizedUri), {
46140
47044
  ...params,
46141
- uri: normalizeDocumentUri(params.uri)
47045
+ uri: normalizedUri
46142
47046
  });
46143
47047
  });
46144
47048
  async function startLanguageServer() {
@@ -46147,8 +47051,8 @@ async function startLanguageServer() {
46147
47051
  }
46148
47052
 
46149
47053
  // src/main.ts
46150
- startLanguageServer().catch((error51) => {
46151
- process.stderr.write(`${String(error51)}
47054
+ startLanguageServer().catch((error52) => {
47055
+ process.stderr.write(`${String(error52)}
46152
47056
  `);
46153
47057
  process.exitCode = 1;
46154
47058
  });