@neocompose/cli 0.5.2 → 0.5.4

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/neo.mjs +983 -220
  3. package/package.json +1 -1
package/dist/neo.mjs CHANGED
@@ -1185,9 +1185,29 @@ function normalizeDocumentFields(recordKind, value) {
1185
1185
  }
1186
1186
  if (current === void 0) normalized[field] = null;
1187
1187
  }
1188
+ if (recordKind === "member") {
1189
+ normalizeTypeInfoBindings(normalized.returnTypeInfo);
1190
+ if (Array.isArray(normalized.argumentTypes)) {
1191
+ for (const argument2 of normalized.argumentTypes) {
1192
+ normalizeTypeInfoBindings(argument2);
1193
+ }
1194
+ }
1195
+ }
1188
1196
  omitRedundantDeclarationOrder(recordKind, normalized);
1189
1197
  return normalized;
1190
1198
  }
1199
+ function normalizeTypeInfoBindings(value) {
1200
+ if (!isRecord(value)) return;
1201
+ const bindings = value.typeArguments;
1202
+ if (bindings === null || isRecord(bindings) && Object.keys(bindings).length === 0) {
1203
+ delete value.typeArguments;
1204
+ } else if (isRecord(bindings)) {
1205
+ for (const binding of Object.values(bindings)) {
1206
+ normalizeTypeInfoBindings(binding);
1207
+ }
1208
+ }
1209
+ normalizeTypeInfoBindings(value.entryTypeInfo);
1210
+ }
1191
1211
  function memberDefaultApplies(field, type) {
1192
1212
  if (field === "isVirtual" || field === "isAbstract" || field === "locked" || field === "required") {
1193
1213
  return true;
@@ -12341,6 +12361,151 @@ var init_project_source_ast = __esm({
12341
12361
  }
12342
12362
  });
12343
12363
 
12364
+ // ../packages/neoscript-language/src/project-source-tokens.ts
12365
+ function rangeContains(range2, position) {
12366
+ return positionCompare(range2.start, position) <= 0 && positionCompare(position, range2.end) <= 0;
12367
+ }
12368
+ function rangeSize(range2) {
12369
+ return (range2.end.line - range2.start.line) * 1e6 + range2.end.character - range2.start.character;
12370
+ }
12371
+ function documentPrefix(text, position) {
12372
+ const lines = text.split("\n");
12373
+ return [
12374
+ ...lines.slice(0, position.line),
12375
+ (lines[position.line] ?? "").slice(0, position.character)
12376
+ ].join("\n");
12377
+ }
12378
+ function projectTokenAt(document, position) {
12379
+ const offset = new SourceText(document.text).offsetAt(position);
12380
+ const tokens = projectTokens(document);
12381
+ const containing = tokens.find(
12382
+ (token) => token.start <= offset && offset < token.end
12383
+ );
12384
+ if (containing?.kind === "identifier") return containing;
12385
+ const touching = tokens.find(
12386
+ (token) => token.kind === "identifier" && token.end === offset
12387
+ );
12388
+ return touching ?? containing;
12389
+ }
12390
+ function projectTokens(document) {
12391
+ const cached = PROJECT_TOKEN_CACHE.get(document);
12392
+ if (cached) return cached;
12393
+ const source = new SourceText(document.text);
12394
+ const tokens = lex(document.text).tokens.flatMap(
12395
+ (token) => {
12396
+ if (token.kind !== "string" || !token.raw.startsWith('"""')) {
12397
+ return [token];
12398
+ }
12399
+ const result = [];
12400
+ const contentEnd = token.raw.endsWith('"""') ? token.end - 3 : token.end;
12401
+ let segmentStart = token.start;
12402
+ let cursor = token.start + 3;
12403
+ while (cursor < contentEnd) {
12404
+ if (document.text[cursor] !== "{" || document.text[cursor + 1] === "{") {
12405
+ cursor++;
12406
+ continue;
12407
+ }
12408
+ const close = tripleInterpolationEnd(
12409
+ document.text,
12410
+ cursor + 1,
12411
+ contentEnd
12412
+ );
12413
+ if (close === null) break;
12414
+ if (segmentStart < cursor + 1) {
12415
+ result.push(
12416
+ projectToken(
12417
+ "string",
12418
+ document.text,
12419
+ source,
12420
+ segmentStart,
12421
+ cursor + 1
12422
+ )
12423
+ );
12424
+ }
12425
+ const expressionStart = cursor + 1;
12426
+ const expression = document.text.slice(expressionStart, close);
12427
+ for (const nested of lex(expression).tokens) {
12428
+ if (nested.kind === "eof") continue;
12429
+ const start = expressionStart + nested.start;
12430
+ const end = expressionStart + nested.end;
12431
+ result.push({
12432
+ ...nested,
12433
+ start,
12434
+ end,
12435
+ raw: document.text.slice(start, end),
12436
+ range: source.range(start, end)
12437
+ });
12438
+ }
12439
+ segmentStart = close;
12440
+ cursor = close + 1;
12441
+ }
12442
+ if (segmentStart < token.end) {
12443
+ result.push(
12444
+ projectToken(
12445
+ "string",
12446
+ document.text,
12447
+ source,
12448
+ segmentStart,
12449
+ token.end
12450
+ )
12451
+ );
12452
+ }
12453
+ return result;
12454
+ }
12455
+ );
12456
+ PROJECT_TOKEN_CACHE.set(document, tokens);
12457
+ return tokens;
12458
+ }
12459
+ function projectToken(kind, text, source, start, end) {
12460
+ const raw = text.slice(start, end);
12461
+ return { kind, text: raw, raw, start, end, range: source.range(start, end) };
12462
+ }
12463
+ function tripleInterpolationEnd(text, start, limit) {
12464
+ let depth = 0;
12465
+ let cursor = start;
12466
+ while (cursor < limit) {
12467
+ const char = text[cursor];
12468
+ const next = text[cursor + 1];
12469
+ if (char === '"') {
12470
+ cursor++;
12471
+ while (cursor < limit) {
12472
+ if (text[cursor] === "\\") cursor += 2;
12473
+ else if (text[cursor] === '"') {
12474
+ cursor++;
12475
+ break;
12476
+ } else cursor++;
12477
+ }
12478
+ continue;
12479
+ }
12480
+ if (char === "/" && next === "/") {
12481
+ while (cursor < limit && text[cursor] !== "\n") cursor++;
12482
+ continue;
12483
+ }
12484
+ if (char === "{") depth++;
12485
+ else if (char === "}") {
12486
+ if (depth === 0) return cursor;
12487
+ depth--;
12488
+ }
12489
+ cursor++;
12490
+ }
12491
+ return null;
12492
+ }
12493
+ function rangesEqual(left, right) {
12494
+ return positionCompare(left.start, right.start) === 0 && positionCompare(left.end, right.end) === 0;
12495
+ }
12496
+ function positionCompare(left, right) {
12497
+ return left.line === right.line ? left.character - right.character : left.line - right.line;
12498
+ }
12499
+ var PROJECT_TOKEN_CACHE;
12500
+ var init_project_source_tokens = __esm({
12501
+ "../packages/neoscript-language/src/project-source-tokens.ts"() {
12502
+ "use strict";
12503
+ init_lexer();
12504
+ init_source_text();
12505
+ PROJECT_TOKEN_CACHE = /* @__PURE__ */ new WeakMap();
12506
+ }
12507
+ });
12508
+
12344
12509
  // ../packages/neoscript-language/src/project-source-parser.ts
12345
12510
  function parseNeoProjectSource(sourceValue, kind) {
12346
12511
  const lexed = lex(sourceValue);
@@ -18792,7 +18957,13 @@ function analyzeNeoProjectSources(inputs) {
18792
18957
  const symbols = [];
18793
18958
  for (const [uri, document] of documents) {
18794
18959
  for (const declaration of document.declarations) {
18795
- collectDeclarationSymbols(uri, declaration, symbols, diagnostics);
18960
+ collectDeclarationSymbols(
18961
+ uri,
18962
+ document,
18963
+ declaration,
18964
+ symbols,
18965
+ diagnostics
18966
+ );
18796
18967
  }
18797
18968
  }
18798
18969
  validateSymbolUniqueness(symbols, diagnostics);
@@ -18802,7 +18973,7 @@ function analyzeNeoProjectSources(inputs) {
18802
18973
  diagnostics.push(...compileProjectSourceBodies(documents).diagnostics);
18803
18974
  return { documents, symbols, diagnostics };
18804
18975
  }
18805
- function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
18976
+ function collectDeclarationSymbols(uri, document, declaration, symbols, diagnostics) {
18806
18977
  const declarationKind = declaration.kind;
18807
18978
  collectSymbol(
18808
18979
  uri,
@@ -18812,7 +18983,9 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
18812
18983
  declaration.annotations,
18813
18984
  void 0,
18814
18985
  symbols,
18815
- diagnostics
18986
+ diagnostics,
18987
+ void 0,
18988
+ declaration.kind === "global" ? declaration.type.name : void 0
18816
18989
  );
18817
18990
  if (declaration.kind === "enum") {
18818
18991
  for (const option of declaration.options) {
@@ -18829,7 +19002,10 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
18829
19002
  }
18830
19003
  return;
18831
19004
  }
18832
- if (declaration.kind === "global") return;
19005
+ if (declaration.kind === "global") {
19006
+ collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics);
19007
+ return;
19008
+ }
18833
19009
  if (declaration.kind === "class") {
18834
19010
  for (const parameter3 of declaration.genericParameters) {
18835
19011
  collectSymbol(
@@ -18886,6 +19062,104 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
18886
19062
  }
18887
19063
  }
18888
19064
  }
19065
+ function collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics) {
19066
+ if (declaration.type.name === "Root") return;
19067
+ const initializer = declaration.initializer;
19068
+ const tokens = lex(document.sourceText).tokens.filter(
19069
+ (token) => token.kind !== "comment" && token.kind !== "eof" && rangeWithin(initializer.range, token.range)
19070
+ );
19071
+ let braceDepth = 0;
19072
+ let groupDepth = 0;
19073
+ let pendingAnnotations = [];
19074
+ for (let index = 0; index < tokens.length; index++) {
19075
+ const token = tokens[index];
19076
+ if (token.text === "{") {
19077
+ braceDepth++;
19078
+ continue;
19079
+ }
19080
+ if (token.text === "}") {
19081
+ braceDepth--;
19082
+ continue;
19083
+ }
19084
+ if (braceDepth !== 1) continue;
19085
+ if (token.text === "(" || token.text === "[") {
19086
+ groupDepth++;
19087
+ continue;
19088
+ }
19089
+ if (token.text === ")" || token.text === "]") {
19090
+ groupDepth--;
19091
+ continue;
19092
+ }
19093
+ if (groupDepth !== 0) continue;
19094
+ if (token.text === ";") {
19095
+ pendingAnnotations = [];
19096
+ continue;
19097
+ }
19098
+ if (token.text === "@") {
19099
+ const annotation2 = scanAnnotation(tokens, index);
19100
+ if (annotation2) {
19101
+ pendingAnnotations.push(annotation2.annotation);
19102
+ index = annotation2.endIndex;
19103
+ }
19104
+ continue;
19105
+ }
19106
+ const name = tokens[index + 1];
19107
+ if ((token.kind === "type" || token.kind === "identifier") && name?.kind === "identifier" && tokens[index + 2]?.text === "=" && tokens[index + 3]?.text !== "=" && // A pending annotation or statement boundary precedes a declaration;
19108
+ // `key: value` fields and expression member accesses never do.
19109
+ tokens[index - 1]?.text !== "." && tokens[index - 1]?.text !== ":") {
19110
+ collectSymbol(
19111
+ uri,
19112
+ "graphChild",
19113
+ name.text,
19114
+ name.range,
19115
+ pendingAnnotations,
19116
+ declaration.name,
19117
+ symbols,
19118
+ diagnostics,
19119
+ void 0,
19120
+ token.text
19121
+ );
19122
+ pendingAnnotations = [];
19123
+ index += 2;
19124
+ }
19125
+ }
19126
+ }
19127
+ function scanAnnotation(tokens, atIndex) {
19128
+ const marker = tokens[atIndex];
19129
+ const name = tokens[atIndex + 1];
19130
+ if (!name || name.kind !== "identifier" && name.kind !== "keyword") {
19131
+ return null;
19132
+ }
19133
+ const argumentsList2 = [];
19134
+ let endIndex = atIndex + 1;
19135
+ let endRange = name.range;
19136
+ if (tokens[atIndex + 2]?.text === "(") {
19137
+ let depth = 0;
19138
+ for (let index = atIndex + 2; index < tokens.length; index++) {
19139
+ const token = tokens[index];
19140
+ if (token.text === "(") depth++;
19141
+ else if (token.text === ")" && --depth === 0) {
19142
+ endIndex = index;
19143
+ endRange = token.range;
19144
+ break;
19145
+ } else if (depth === 1 && token.kind === "string") {
19146
+ argumentsList2.push({ text: token.raw, range: token.range });
19147
+ }
19148
+ }
19149
+ }
19150
+ return {
19151
+ annotation: {
19152
+ name: name.text,
19153
+ nameRange: name.range,
19154
+ arguments: argumentsList2,
19155
+ range: { start: marker.range.start, end: endRange.end }
19156
+ },
19157
+ endIndex
19158
+ };
19159
+ }
19160
+ function rangeWithin(outer, inner) {
19161
+ return positionCompare(outer.start, inner.start) <= 0 && positionCompare(inner.end, outer.end) <= 0;
19162
+ }
18889
19163
  function collectFlowSymbols(uri, content, ownerName, scopeRange, symbols, diagnostics) {
18890
19164
  for (const binding of content.bindings) {
18891
19165
  collectSymbol(
@@ -19177,6 +19451,8 @@ var init_project_source_analysis = __esm({
19177
19451
  "../packages/neoscript-language/src/project-source-analysis.ts"() {
19178
19452
  "use strict";
19179
19453
  init_language_spec();
19454
+ init_lexer();
19455
+ init_project_source_tokens();
19180
19456
  init_project_source_parser();
19181
19457
  init_project_source_semantics();
19182
19458
  init_project_source_script_compiler();
@@ -21242,151 +21518,6 @@ var init_project_schema_manifest = __esm({
21242
21518
  }
21243
21519
  });
21244
21520
 
21245
- // ../packages/neoscript-language/src/project-source-tokens.ts
21246
- function rangeContains(range2, position) {
21247
- return positionCompare(range2.start, position) <= 0 && positionCompare(position, range2.end) <= 0;
21248
- }
21249
- function rangeSize(range2) {
21250
- return (range2.end.line - range2.start.line) * 1e6 + range2.end.character - range2.start.character;
21251
- }
21252
- function documentPrefix(text, position) {
21253
- const lines = text.split("\n");
21254
- return [
21255
- ...lines.slice(0, position.line),
21256
- (lines[position.line] ?? "").slice(0, position.character)
21257
- ].join("\n");
21258
- }
21259
- function projectTokenAt(document, position) {
21260
- const offset = new SourceText(document.text).offsetAt(position);
21261
- const tokens = projectTokens(document);
21262
- const containing = tokens.find(
21263
- (token) => token.start <= offset && offset < token.end
21264
- );
21265
- if (containing?.kind === "identifier") return containing;
21266
- const touching = tokens.find(
21267
- (token) => token.kind === "identifier" && token.end === offset
21268
- );
21269
- return touching ?? containing;
21270
- }
21271
- function projectTokens(document) {
21272
- const cached = PROJECT_TOKEN_CACHE.get(document);
21273
- if (cached) return cached;
21274
- const source = new SourceText(document.text);
21275
- const tokens = lex(document.text).tokens.flatMap(
21276
- (token) => {
21277
- if (token.kind !== "string" || !token.raw.startsWith('"""')) {
21278
- return [token];
21279
- }
21280
- const result = [];
21281
- const contentEnd = token.raw.endsWith('"""') ? token.end - 3 : token.end;
21282
- let segmentStart = token.start;
21283
- let cursor = token.start + 3;
21284
- while (cursor < contentEnd) {
21285
- if (document.text[cursor] !== "{" || document.text[cursor + 1] === "{") {
21286
- cursor++;
21287
- continue;
21288
- }
21289
- const close = tripleInterpolationEnd(
21290
- document.text,
21291
- cursor + 1,
21292
- contentEnd
21293
- );
21294
- if (close === null) break;
21295
- if (segmentStart < cursor + 1) {
21296
- result.push(
21297
- projectToken(
21298
- "string",
21299
- document.text,
21300
- source,
21301
- segmentStart,
21302
- cursor + 1
21303
- )
21304
- );
21305
- }
21306
- const expressionStart = cursor + 1;
21307
- const expression = document.text.slice(expressionStart, close);
21308
- for (const nested of lex(expression).tokens) {
21309
- if (nested.kind === "eof") continue;
21310
- const start = expressionStart + nested.start;
21311
- const end = expressionStart + nested.end;
21312
- result.push({
21313
- ...nested,
21314
- start,
21315
- end,
21316
- raw: document.text.slice(start, end),
21317
- range: source.range(start, end)
21318
- });
21319
- }
21320
- segmentStart = close;
21321
- cursor = close + 1;
21322
- }
21323
- if (segmentStart < token.end) {
21324
- result.push(
21325
- projectToken(
21326
- "string",
21327
- document.text,
21328
- source,
21329
- segmentStart,
21330
- token.end
21331
- )
21332
- );
21333
- }
21334
- return result;
21335
- }
21336
- );
21337
- PROJECT_TOKEN_CACHE.set(document, tokens);
21338
- return tokens;
21339
- }
21340
- function projectToken(kind, text, source, start, end) {
21341
- const raw = text.slice(start, end);
21342
- return { kind, text: raw, raw, start, end, range: source.range(start, end) };
21343
- }
21344
- function tripleInterpolationEnd(text, start, limit) {
21345
- let depth = 0;
21346
- let cursor = start;
21347
- while (cursor < limit) {
21348
- const char = text[cursor];
21349
- const next = text[cursor + 1];
21350
- if (char === '"') {
21351
- cursor++;
21352
- while (cursor < limit) {
21353
- if (text[cursor] === "\\") cursor += 2;
21354
- else if (text[cursor] === '"') {
21355
- cursor++;
21356
- break;
21357
- } else cursor++;
21358
- }
21359
- continue;
21360
- }
21361
- if (char === "/" && next === "/") {
21362
- while (cursor < limit && text[cursor] !== "\n") cursor++;
21363
- continue;
21364
- }
21365
- if (char === "{") depth++;
21366
- else if (char === "}") {
21367
- if (depth === 0) return cursor;
21368
- depth--;
21369
- }
21370
- cursor++;
21371
- }
21372
- return null;
21373
- }
21374
- function rangesEqual(left, right) {
21375
- return positionCompare(left.start, right.start) === 0 && positionCompare(left.end, right.end) === 0;
21376
- }
21377
- function positionCompare(left, right) {
21378
- return left.line === right.line ? left.character - right.character : left.line - right.line;
21379
- }
21380
- var PROJECT_TOKEN_CACHE;
21381
- var init_project_source_tokens = __esm({
21382
- "../packages/neoscript-language/src/project-source-tokens.ts"() {
21383
- "use strict";
21384
- init_lexer();
21385
- init_source_text();
21386
- PROJECT_TOKEN_CACHE = /* @__PURE__ */ new WeakMap();
21387
- }
21388
- });
21389
-
21390
21521
  // ../packages/neoscript-language/src/quick-fixes.ts
21391
21522
  function quickFixFor(document, diagnostic) {
21392
21523
  if (diagnostic.code === "missing-semicolon") {
@@ -21703,11 +21834,17 @@ function projectMemberCompletions(analysis, document, position) {
21703
21834
  if (!owner || owner.kind !== "identifier") return null;
21704
21835
  const resolvedOwner = projectSymbolAt(analysis, document, owner.range.start);
21705
21836
  if (!resolvedOwner) return null;
21837
+ const ownerNames = /* @__PURE__ */ new Set();
21706
21838
  const typeName = projectSymbolTypeName(resolvedOwner.symbol);
21707
- if (!typeName) return null;
21708
- return analysis.symbols.filter(
21709
- (symbol) => symbol.kind === "member" && symbol.ownerName === typeName
21839
+ if (typeName) ownerNames.add(typeName);
21840
+ if (resolvedOwner.symbol.kind === "global") {
21841
+ ownerNames.add(resolvedOwner.symbol.name);
21842
+ }
21843
+ if (ownerNames.size === 0) return null;
21844
+ const members = analysis.symbols.filter(
21845
+ (symbol) => (symbol.kind === "member" || symbol.kind === "graphChild") && symbol.ownerName !== void 0 && ownerNames.has(symbol.ownerName)
21710
21846
  );
21847
+ return members.length > 0 ? members : null;
21711
21848
  }
21712
21849
  function projectConstructorArgumentCompletions(analysis, document, position) {
21713
21850
  const tokens = lex(document.text).tokens.filter(
@@ -21799,6 +21936,15 @@ function graphConstructorNamedArguments(typeName) {
21799
21936
  { name: "reason", type: "string" },
21800
21937
  { name: "duration", type: "decimal?" }
21801
21938
  ];
21939
+ case "Vector2":
21940
+ case "Vector2Int":
21941
+ case "Vector3":
21942
+ case "Vector3Int":
21943
+ case "Color":
21944
+ return graphConstructorParameters(typeName).map((parameter3) => ({
21945
+ name: parameter3.name,
21946
+ type: parameter3.type
21947
+ }));
21802
21948
  default:
21803
21949
  return null;
21804
21950
  }
@@ -22234,6 +22380,19 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
22234
22380
  return { token, symbol: visibleCandidates[0] };
22235
22381
  }
22236
22382
  if (visibleCandidates.length === 0) return null;
22383
+ const sourceTokens = projectTokens(document);
22384
+ const tokenIndex = sourceTokens.findIndex(
22385
+ (candidate) => candidate.start === token.start && candidate.end === token.end
22386
+ );
22387
+ if (sourceTokens[tokenIndex + 1]?.text === "=" && sourceTokens[tokenIndex + 2]?.text !== "=") {
22388
+ const constructed = constructionMemberSymbol(
22389
+ analysis,
22390
+ document,
22391
+ token,
22392
+ visibleCandidates
22393
+ );
22394
+ if (constructed) return { token, symbol: constructed };
22395
+ }
22237
22396
  const source = analysis.documents.get(document.uri);
22238
22397
  const owner = source ? declarationContaining(source, token.range.start)?.name : void 0;
22239
22398
  if (owner) {
@@ -22242,10 +22401,6 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
22242
22401
  );
22243
22402
  if (owned.length === 1) return { token, symbol: owned[0] };
22244
22403
  }
22245
- const sourceTokens = projectTokens(document);
22246
- const tokenIndex = sourceTokens.findIndex(
22247
- (candidate) => candidate.start === token.start && candidate.end === token.end
22248
- );
22249
22404
  const dotOwner = sourceTokens[tokenIndex - 1]?.text === "." ? sourceTokens[tokenIndex - 2] : void 0;
22250
22405
  if (dotOwner) {
22251
22406
  const resolvedOwner = indexedProjectSymbolAt(
@@ -22254,15 +22409,39 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
22254
22409
  dotOwner.range.start,
22255
22410
  index
22256
22411
  );
22257
- const ownerType = resolvedOwner ? projectSymbolTypeName(resolvedOwner.symbol) : dotOwner.text;
22412
+ const ownerNames = /* @__PURE__ */ new Set();
22413
+ if (resolvedOwner) {
22414
+ const typeName = projectSymbolTypeName(resolvedOwner.symbol);
22415
+ if (typeName) ownerNames.add(typeName);
22416
+ if (resolvedOwner.symbol.kind === "global") {
22417
+ ownerNames.add(resolvedOwner.symbol.name);
22418
+ }
22419
+ } else {
22420
+ ownerNames.add(dotOwner.text);
22421
+ }
22258
22422
  const qualified = visibleCandidates.filter(
22259
- (symbol) => symbol.ownerName === ownerType
22423
+ (symbol) => symbol.ownerName !== void 0 && ownerNames.has(symbol.ownerName)
22260
22424
  );
22261
22425
  if (qualified.length === 1) return { token, symbol: qualified[0] };
22262
22426
  }
22263
22427
  const projectLevel = visibleCandidates.filter((symbol) => !symbol.ownerName);
22264
22428
  return projectLevel.length === 1 ? { token, symbol: projectLevel[0] } : null;
22265
22429
  }
22430
+ function constructionMemberSymbol(analysis, document, token, candidates) {
22431
+ const site = constructionSiteAt(analysis, document, token.range.start);
22432
+ let current = site?.enclosingTypeName ?? null;
22433
+ const visited = /* @__PURE__ */ new Set();
22434
+ while (current !== null && !visited.has(current)) {
22435
+ visited.add(current);
22436
+ const owned = candidates.find(
22437
+ (symbol) => symbol.kind === "member" && symbol.ownerName === current
22438
+ );
22439
+ if (owned) return owned;
22440
+ const declaration = findTypeDeclaration(analysis, current);
22441
+ current = declaration?.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
22442
+ }
22443
+ return null;
22444
+ }
22266
22445
  function projectSymbolTypeName(symbol) {
22267
22446
  switch (symbol.kind) {
22268
22447
  case "class":
@@ -22360,21 +22539,219 @@ function signatureResult(name, parameters, activeParameter) {
22360
22539
  };
22361
22540
  }
22362
22541
  function contextualConstructorType(analysis, document, position) {
22542
+ return constructionSiteAt(analysis, document, position)?.expectedTypeName ?? null;
22543
+ }
22544
+ function initializerRootAt(analysis, document, position) {
22363
22545
  const source = analysis.documents.get(document.uri);
22364
22546
  if (!source) return null;
22365
22547
  for (const declaration of source.declarations) {
22366
22548
  if (declaration.kind === "global") {
22367
22549
  if (rangeContains(declaration.initializer.range, position)) {
22368
- return declaration.type.name;
22550
+ return {
22551
+ type: declaration.type,
22552
+ range: declaration.initializer.range
22553
+ };
22369
22554
  }
22370
22555
  continue;
22371
22556
  }
22372
22557
  if (declaration.kind === "enum") continue;
22373
22558
  for (const member of declaration.members) {
22374
22559
  if (member.kind === "field" && member.initializer && rangeContains(member.initializer.range, position)) {
22375
- return member.type.name;
22560
+ return { type: member.type, range: member.initializer.range };
22561
+ }
22562
+ }
22563
+ }
22564
+ return null;
22565
+ }
22566
+ function constructionSiteAt(analysis, document, position) {
22567
+ const root = initializerRootAt(analysis, document, position);
22568
+ if (!root) return null;
22569
+ const tokens = projectTokens(document).filter(
22570
+ (token) => token.kind !== "comment" && token.kind !== "eof" && rangeContains(root.range, token.range.start) && positionCompare(token.range.start, position) < 0
22571
+ );
22572
+ const stack = [];
22573
+ const expectedType = () => {
22574
+ const frame = stack.at(-1);
22575
+ if (!frame) return root.type;
22576
+ switch (frame.kind) {
22577
+ case "object":
22578
+ case "dictionary":
22579
+ return frame.slotType;
22580
+ case "list":
22581
+ return frame.elementType;
22582
+ case "call":
22583
+ return constructorArgumentType(analysis, frame);
22584
+ case "opaque":
22585
+ return null;
22586
+ }
22587
+ };
22588
+ let sawNew = false;
22589
+ let pendingNewTypeName = null;
22590
+ let closedConstructorTypeName = null;
22591
+ for (let index = 0; index < tokens.length; index++) {
22592
+ const token = tokens[index];
22593
+ if (token.text === "@") {
22594
+ if ((tokens[index + 1]?.kind === "identifier" || tokens[index + 1]?.kind === "keyword") && tokens[index + 2]?.text === "(") {
22595
+ let depth = 0;
22596
+ index += 2;
22597
+ for (; index < tokens.length; index++) {
22598
+ if (tokens[index].text === "(") depth++;
22599
+ else if (tokens[index].text === ")" && --depth === 0) break;
22600
+ }
22601
+ } else if (tokens[index + 1]?.kind === "identifier") {
22602
+ index += 1;
22603
+ }
22604
+ continue;
22605
+ }
22606
+ if (token.text === "new") {
22607
+ sawNew = true;
22608
+ pendingNewTypeName = expectedType()?.name ?? null;
22609
+ closedConstructorTypeName = null;
22610
+ continue;
22611
+ }
22612
+ if (sawNew && (token.kind === "identifier" || token.kind === "type")) {
22613
+ pendingNewTypeName = token.text;
22614
+ continue;
22615
+ }
22616
+ if (sawNew && token.text === "<") {
22617
+ let depth = 0;
22618
+ for (; index < tokens.length; index++) {
22619
+ if (tokens[index].text === "<") depth++;
22620
+ else if (tokens[index].text === ">" && --depth === 0) break;
22621
+ }
22622
+ continue;
22623
+ }
22624
+ if (token.text === "{") {
22625
+ if (sawNew || closedConstructorTypeName !== null) {
22626
+ stack.push({
22627
+ kind: "object",
22628
+ typeName: pendingNewTypeName ?? closedConstructorTypeName,
22629
+ slotType: null
22630
+ });
22631
+ sawNew = false;
22632
+ pendingNewTypeName = null;
22633
+ } else {
22634
+ const expected = expectedType();
22635
+ if (expected?.name === "Dictionary") {
22636
+ stack.push({
22637
+ kind: "dictionary",
22638
+ valueType: expected.typeArguments[1] ?? null,
22639
+ slotType: null
22640
+ });
22641
+ } else {
22642
+ stack.push({ kind: "opaque" });
22643
+ }
22376
22644
  }
22645
+ closedConstructorTypeName = null;
22646
+ continue;
22647
+ }
22648
+ if (token.text === "(") {
22649
+ if (sawNew) {
22650
+ stack.push({
22651
+ kind: "call",
22652
+ typeName: pendingNewTypeName,
22653
+ argumentIndex: 0,
22654
+ argumentName: null
22655
+ });
22656
+ sawNew = false;
22657
+ pendingNewTypeName = null;
22658
+ } else {
22659
+ stack.push({ kind: "opaque" });
22660
+ }
22661
+ closedConstructorTypeName = null;
22662
+ continue;
22663
+ }
22664
+ if (token.text === "[") {
22665
+ stack.push({
22666
+ kind: "list",
22667
+ elementType: collectionElementType2(expectedType())
22668
+ });
22669
+ closedConstructorTypeName = null;
22670
+ continue;
22671
+ }
22672
+ if (token.text === ")") {
22673
+ const frame2 = stack.pop();
22674
+ closedConstructorTypeName = frame2?.kind === "call" ? frame2.typeName : null;
22675
+ continue;
22676
+ }
22677
+ if (token.text === "}" || token.text === "]") {
22678
+ stack.pop();
22679
+ closedConstructorTypeName = null;
22680
+ continue;
22681
+ }
22682
+ closedConstructorTypeName = null;
22683
+ const frame = stack.at(-1);
22684
+ if (!frame) continue;
22685
+ if (frame.kind === "object") {
22686
+ if (token.text === "=" && tokens[index + 1]?.text !== "=") {
22687
+ const nameToken = tokens[index - 1];
22688
+ frame.slotType = nameToken && (nameToken.kind === "identifier" || nameToken.kind === "type") ? declaredFieldType(analysis, frame.typeName, nameToken.text) : null;
22689
+ } else if (token.text === ",") {
22690
+ frame.slotType = null;
22691
+ }
22692
+ } else if (frame.kind === "dictionary") {
22693
+ if (token.text === ":") frame.slotType = frame.valueType;
22694
+ else if (token.text === ",") frame.slotType = null;
22695
+ } else if (frame.kind === "call") {
22696
+ if (token.text === ",") {
22697
+ frame.argumentIndex++;
22698
+ frame.argumentName = null;
22699
+ } else if (token.text === ":") {
22700
+ const nameToken = tokens[index - 1];
22701
+ frame.argumentName = nameToken?.kind === "identifier" ? nameToken.text : null;
22702
+ }
22703
+ }
22704
+ }
22705
+ const enclosing = [...stack].reverse().find(
22706
+ (frame) => frame.kind === "object"
22707
+ );
22708
+ return {
22709
+ expectedTypeName: expectedType()?.name ?? null,
22710
+ enclosingTypeName: enclosing?.typeName ?? null
22711
+ };
22712
+ }
22713
+ function collectionElementType2(type) {
22714
+ if (!type) return null;
22715
+ if (type.name === "List" || type.name === "Set") {
22716
+ return type.typeArguments[0] ?? null;
22717
+ }
22718
+ return null;
22719
+ }
22720
+ function constructorArgumentType(analysis, frame) {
22721
+ if (!frame.typeName) return null;
22722
+ const declaration = findTypeDeclaration(analysis, frame.typeName);
22723
+ if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
22724
+ return null;
22725
+ }
22726
+ const fields = declaration.members.filter(
22727
+ (member) => member.kind === "field" && !member.modifiers.includes("static")
22728
+ );
22729
+ if (frame.argumentName !== null) {
22730
+ return fields.find((field) => field.name === frame.argumentName)?.type ?? null;
22731
+ }
22732
+ return fields[frame.argumentIndex]?.type ?? null;
22733
+ }
22734
+ function declaredFieldType(analysis, typeName, fieldName) {
22735
+ let current = typeName;
22736
+ const visited = /* @__PURE__ */ new Set();
22737
+ while (current !== null && !visited.has(current)) {
22738
+ visited.add(current);
22739
+ const declaration = findTypeDeclaration(analysis, current);
22740
+ if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
22741
+ return null;
22377
22742
  }
22743
+ const member = declaration.members.find(
22744
+ (candidate) => candidate.kind === "field" && candidate.name === fieldName
22745
+ );
22746
+ if (member) return member.type;
22747
+ current = declaration.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
22748
+ }
22749
+ return null;
22750
+ }
22751
+ function resolvableBaseClassName(analysis, declaration) {
22752
+ for (const base of declaration.baseTypes) {
22753
+ const resolved = findTypeDeclaration(analysis, base.name);
22754
+ if (resolved?.kind === "class") return base.name;
22378
22755
  }
22379
22756
  return null;
22380
22757
  }
@@ -22448,6 +22825,35 @@ function graphConstructorParameters(typeName) {
22448
22825
  { type: "string", name: "reason" },
22449
22826
  { type: "decimal?", name: "duration" }
22450
22827
  ];
22828
+ case "Vector2":
22829
+ return [
22830
+ { type: "float", name: "x" },
22831
+ { type: "float", name: "y" }
22832
+ ];
22833
+ case "Vector2Int":
22834
+ return [
22835
+ { type: "int", name: "x" },
22836
+ { type: "int", name: "y" }
22837
+ ];
22838
+ case "Vector3":
22839
+ return [
22840
+ { type: "float", name: "x" },
22841
+ { type: "float", name: "y" },
22842
+ { type: "float", name: "z" }
22843
+ ];
22844
+ case "Vector3Int":
22845
+ return [
22846
+ { type: "int", name: "x" },
22847
+ { type: "int", name: "y" },
22848
+ { type: "int", name: "z" }
22849
+ ];
22850
+ case "Color":
22851
+ return [
22852
+ { type: "float", name: "r" },
22853
+ { type: "float", name: "g" },
22854
+ { type: "float", name: "b" },
22855
+ { type: "float", name: "a" }
22856
+ ];
22451
22857
  default:
22452
22858
  return [];
22453
22859
  }
@@ -26945,7 +27351,8 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
26945
27351
  declaration.initializer,
26946
27352
  declaration.type,
26947
27353
  ownerClass,
26948
- base
27354
+ base,
27355
+ id2
26949
27356
  )
26950
27357
  };
26951
27358
  const settings = annotation(declaration.annotations, "settings");
@@ -26994,7 +27401,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
26994
27401
  return {
26995
27402
  ...common,
26996
27403
  kind: primitive3,
26997
- templateId: referenceIdArgument(settings, "template") ?? (base?.kind === primitive3 ? base.templateId : null)
27404
+ templateId: referenceIdArgument(settings, "template") ?? templateSymbolArgument(context, settings, ownerClass, declaration) ?? (base?.kind === primitive3 ? base.templateId : null)
26998
27405
  };
26999
27406
  }
27000
27407
  if (primitive3) return { ...common, kind: primitive3 };
@@ -27261,10 +27668,13 @@ function lowerType(context, type, ownerClass) {
27261
27668
  if (type.name === "object") return { kind: "unknown", nullable };
27262
27669
  throw new Error(`Unknown Neo type ${JSON.stringify(type.name)}.`);
27263
27670
  }
27264
- function lowerDefault(context, initializer, type, ownerClass, base) {
27671
+ function lowerDefault(context, initializer, type, ownerClass, base, memberId) {
27265
27672
  if (initializer === null) {
27266
27673
  return base?.defaultValue && "serverValueId" in base.defaultValue ? base.defaultValue : null;
27267
27674
  }
27675
+ if (context.rowBackedDefaultMemberIds.has(memberId) && base?.defaultValue && !("serverValueId" in base.defaultValue)) {
27676
+ return base.defaultValue;
27677
+ }
27268
27678
  const expression = parseExpression(initializer);
27269
27679
  let value = lowerExpressionValue(context, expression, type, ownerClass);
27270
27680
  if (value !== null && context.enumIdsByName.has(type.name) && !Array.isArray(value)) {
@@ -27401,16 +27811,25 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
27401
27811
  const idArgument = expression.args[index >= 0 ? index : 0];
27402
27812
  if (idArgument?.kind === "litString") return idArgument.value;
27403
27813
  }
27404
- if (expression.callee.kind === "member" && expression.callee.name === "Slice" && expression.callee.receiver.kind === "call") {
27405
- const receiver = expression.callee.receiver;
27406
- const index = receiver.argumentNames?.findIndex((name) => name === "id") ?? -1;
27407
- const fileId = receiver.args[index >= 0 ? index : 0];
27814
+ if (expression.callee.kind === "member" && expression.callee.name === "Slice") {
27408
27815
  const sliceIndex = expression.args[0];
27409
- if (fileId?.kind === "litString" && (sliceIndex?.kind === "litInt" || sliceIndex === void 0)) {
27410
- return {
27411
- fileId: fileId.value,
27412
- sliceIndex: sliceIndex?.value ?? 0
27413
- };
27816
+ if (sliceIndex !== void 0 && sliceIndex.kind !== "litInt") {
27817
+ throw new Error("Sprite Slice defaults require an int literal.");
27818
+ }
27819
+ const receiver = expression.callee.receiver;
27820
+ if (receiver.kind === "call") {
27821
+ const index = receiver.argumentNames?.findIndex((name) => name === "id") ?? -1;
27822
+ const fileId2 = receiver.args[index >= 0 ? index : 0];
27823
+ if (fileId2?.kind === "litString") {
27824
+ return {
27825
+ fileId: fileId2.value,
27826
+ sliceIndex: sliceIndex?.value ?? 0
27827
+ };
27828
+ }
27829
+ }
27830
+ const fileId = projectFileIdForPath(context, receiver);
27831
+ if (fileId !== null) {
27832
+ return { fileId, sliceIndex: sliceIndex?.value ?? 0 };
27414
27833
  }
27415
27834
  }
27416
27835
  throw new Error(
@@ -27418,6 +27837,8 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
27418
27837
  );
27419
27838
  }
27420
27839
  case "member": {
27840
+ const fileId = projectFileIdForPath(context, expression);
27841
+ if (fileId !== null) return { fileId };
27421
27842
  if (expression.name === "Slice" || expression.receiver.kind === "call") {
27422
27843
  throw new Error(
27423
27844
  "File defaults are lowered by the project-file compiler."
@@ -27431,6 +27852,17 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
27431
27852
  );
27432
27853
  }
27433
27854
  }
27855
+ function projectFileIdForPath(context, expression) {
27856
+ const path = expressionMemberPath(expression);
27857
+ if (path === null) return null;
27858
+ return context.projectFileIdsBySymbol.get(path) ?? null;
27859
+ }
27860
+ function expressionMemberPath(expression) {
27861
+ if (expression.kind === "ident") return expression.name;
27862
+ if (expression.kind !== "member") return null;
27863
+ const receiver = expressionMemberPath(expression.receiver);
27864
+ return receiver === null ? null : `${receiver}.${expression.name}`;
27865
+ }
27434
27866
  function manifestTypeForMember(context, member) {
27435
27867
  const nullable = !member.required;
27436
27868
  if (primitiveMemberKinds.has(member.kind)) {
@@ -27647,6 +28079,19 @@ function referenceIdArgument(value, name) {
27647
28079
  const raw = argument(value, name);
27648
28080
  return raw === null ? null : referenceId(raw);
27649
28081
  }
28082
+ function templateSymbolArgument(context, settings, ownerClass, declaration) {
28083
+ const raw = argument(settings, "template");
28084
+ if (raw === null) return null;
28085
+ const expression = parseAnnotationExpression(raw);
28086
+ if (expression.kind !== "ident") return null;
28087
+ const templateId = context.templateIdsByName.get(expression.name);
28088
+ if (templateId === void 0) {
28089
+ throw new Error(
28090
+ `Member ${ownerClass.name}.${declaration.name} references unknown template ${JSON.stringify(expression.name)}.`
28091
+ );
28092
+ }
28093
+ return templateId;
28094
+ }
27650
28095
  function referenceId(raw) {
27651
28096
  try {
27652
28097
  const expression = parseExpression(raw);
@@ -28177,7 +28622,24 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
28177
28622
  enumOptionsByName,
28178
28623
  loweredMembers: /* @__PURE__ */ new Map(),
28179
28624
  placements: /* @__PURE__ */ new Map(),
28180
- staticValueIdsBySymbol: options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map()
28625
+ staticValueIdsBySymbol: options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map(),
28626
+ templateIdsByName: new Map(
28627
+ analysis.configuration.globals.flatMap(
28628
+ (global) => global.type.name === "TextureTemplate" ? [
28629
+ [
28630
+ global.name,
28631
+ materializedId(global, "texture-template", global.name)
28632
+ ]
28633
+ ] : global.type.name === "AudioTemplate" ? [
28634
+ [
28635
+ global.name,
28636
+ materializedId(global, "audio-template", global.name)
28637
+ ]
28638
+ ] : []
28639
+ )
28640
+ ),
28641
+ projectFileIdsBySymbol: options.projectFileIdsBySymbol ?? /* @__PURE__ */ new Map(),
28642
+ rowBackedDefaultMemberIds: options.rowBackedDefaultMemberIds ?? /* @__PURE__ */ new Set()
28181
28643
  };
28182
28644
  const classes = analysis.schema.classes.map(
28183
28645
  (declaration) => lowerClass(context, declaration)
@@ -28326,7 +28788,14 @@ function emitProjectSourcesV4(manifest, options = {}) {
28326
28788
  interfaces: new Map(manifest.interfaces.map((entry) => [entry.id, entry])),
28327
28789
  enums: new Map(manifest.enums.map((entry) => [entry.id, entry])),
28328
28790
  members: new Map(manifest.members.map((entry) => [entry.id, entry])),
28329
- staticInitializers: options.staticInitializers ?? /* @__PURE__ */ new Map()
28791
+ staticInitializers: options.staticInitializers ?? /* @__PURE__ */ new Map(),
28792
+ defaultInitializers: options.defaultInitializers ?? /* @__PURE__ */ new Map(),
28793
+ fileSymbols: options.fileSymbols ?? /* @__PURE__ */ new Map(),
28794
+ templateNames: new Map(
28795
+ [...manifest.textureTemplates, ...manifest.audioTemplates].map(
28796
+ (template) => [template.id, template.name]
28797
+ )
28798
+ )
28330
28799
  };
28331
28800
  const files = [];
28332
28801
  const localizationStatusNames = new Map(
@@ -28661,7 +29130,7 @@ ${indentNeoSourceNonEmptyLines(tracked.trim(), 2)}
28661
29130
  ${body ? `${signature} ${body}` : abstractContract ? `${signature};` : `native ${signature};`}`;
28662
29131
  }
28663
29132
  const type = renderMemberType(context, member);
28664
- const initializer = (member.isStatic ? context.staticInitializers.get(member.id) : void 0) ?? renderDefault(context, member);
29133
+ const initializer = (member.isStatic ? context.staticInitializers.get(member.id) : void 0) ?? context.defaultInitializers.get(member.id) ?? renderDefault(context, member);
28665
29134
  return `${annotations.join("\n")}
28666
29135
  ${prefix}${type} ${member.name}${initializer === null ? ";" : ` = ${initializer};`}`;
28667
29136
  }
@@ -28722,7 +29191,10 @@ function memberSettings(context, member) {
28722
29191
  }
28723
29192
  if (member.multiselect) settings.push("multiselect: true");
28724
29193
  } else if ((member.kind === "sprite" || member.kind === "audio") && member.templateId) {
28725
- settings.push(`template: Reference<Type>(id: ${quote(member.templateId)})`);
29194
+ const templateName = context.templateNames.get(member.templateId);
29195
+ settings.push(
29196
+ templateName !== void 0 ? `template: ${templateName}` : `template: Reference<Type>(id: ${quote(member.templateId)})`
29197
+ );
28726
29198
  }
28727
29199
  return settings.length ? [`@settings(${settings.join(", ")})`] : [];
28728
29200
  }
@@ -28900,6 +29372,13 @@ function renderDefaultValue(context, member, wrapper) {
28900
29372
  );
28901
29373
  return member.multiselect ? `[${values.join(", ")}]` : values[0] ?? "null";
28902
29374
  }
29375
+ if (member.kind === "enum" && typeof value === "string") {
29376
+ const schemaEnum = required(context.enums, member.enumId, "enum");
29377
+ const option = schemaEnum.options.find(
29378
+ (candidate) => candidate.id === value || candidate.key === value
29379
+ );
29380
+ if (option !== void 0) return `.${option.name}`;
29381
+ }
28903
29382
  if (member.kind === "list" && Array.isArray(value)) {
28904
29383
  const entry = required(context.members, member.entryMemberId, "list entry");
28905
29384
  return `[${value.map((item) => renderNestedValue(context, entry, item)).join(", ")}]`;
@@ -28931,7 +29410,9 @@ function renderDefaultValue(context, member, wrapper) {
28931
29410
  return member.multiselect ? `[${refs.join(", ")}]` : refs[0] ?? "null";
28932
29411
  }
28933
29412
  if ((member.kind === "sprite" || member.kind === "audio") && isObject(value) && typeof value.fileId === "string") {
28934
- return member.kind === "sprite" ? `Reference<NeoImage>(id: ${quote(value.fileId)}).Slice(${typeof value.sliceIndex === "number" ? value.sliceIndex : 0})` : `Reference<NeoAudioClip>(id: ${quote(value.fileId)})`;
29413
+ const symbol = context.fileSymbols.get(value.fileId);
29414
+ const target = symbol ?? (member.kind === "sprite" ? `Reference<NeoImage>(id: ${quote(value.fileId)})` : `Reference<NeoAudioClip>(id: ${quote(value.fileId)})`);
29415
+ return member.kind === "sprite" ? `${target}.Slice(${typeof value.sliceIndex === "number" ? value.sliceIndex : 0})` : target;
28935
29416
  }
28936
29417
  if (isObject(value) && ["vector2", "vector2Int", "vector3", "vector3Int", "color"].includes(
28937
29418
  member.kind
@@ -30042,27 +30523,27 @@ var init_project_files = __esm({
30042
30523
  }
30043
30524
  });
30044
30525
 
30045
- // ../../../neo-compose/node_modules/uuid/dist-node/regex.js
30526
+ // ../node_modules/uuid/dist-node/regex.js
30046
30527
  var regex_default;
30047
30528
  var init_regex = __esm({
30048
- "../../../neo-compose/node_modules/uuid/dist-node/regex.js"() {
30529
+ "../node_modules/uuid/dist-node/regex.js"() {
30049
30530
  regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
30050
30531
  }
30051
30532
  });
30052
30533
 
30053
- // ../../../neo-compose/node_modules/uuid/dist-node/validate.js
30534
+ // ../node_modules/uuid/dist-node/validate.js
30054
30535
  function validate(uuid) {
30055
30536
  return typeof uuid === "string" && regex_default.test(uuid);
30056
30537
  }
30057
30538
  var validate_default;
30058
30539
  var init_validate2 = __esm({
30059
- "../../../neo-compose/node_modules/uuid/dist-node/validate.js"() {
30540
+ "../node_modules/uuid/dist-node/validate.js"() {
30060
30541
  init_regex();
30061
30542
  validate_default = validate;
30062
30543
  }
30063
30544
  });
30064
30545
 
30065
- // ../../../neo-compose/node_modules/uuid/dist-node/parse.js
30546
+ // ../node_modules/uuid/dist-node/parse.js
30066
30547
  function parse(uuid) {
30067
30548
  if (!validate_default(uuid)) {
30068
30549
  throw TypeError("Invalid UUID");
@@ -30072,19 +30553,19 @@ function parse(uuid) {
30072
30553
  }
30073
30554
  var parse_default;
30074
30555
  var init_parse = __esm({
30075
- "../../../neo-compose/node_modules/uuid/dist-node/parse.js"() {
30556
+ "../node_modules/uuid/dist-node/parse.js"() {
30076
30557
  init_validate2();
30077
30558
  parse_default = parse;
30078
30559
  }
30079
30560
  });
30080
30561
 
30081
- // ../../../neo-compose/node_modules/uuid/dist-node/stringify.js
30562
+ // ../node_modules/uuid/dist-node/stringify.js
30082
30563
  function unsafeStringify(arr, offset = 0) {
30083
30564
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
30084
30565
  }
30085
30566
  var byteToHex;
30086
30567
  var init_stringify = __esm({
30087
- "../../../neo-compose/node_modules/uuid/dist-node/stringify.js"() {
30568
+ "../node_modules/uuid/dist-node/stringify.js"() {
30088
30569
  byteToHex = [];
30089
30570
  for (let i = 0; i < 256; ++i) {
30090
30571
  byteToHex.push((i + 256).toString(16).slice(1));
@@ -30092,18 +30573,18 @@ var init_stringify = __esm({
30092
30573
  }
30093
30574
  });
30094
30575
 
30095
- // ../../../neo-compose/node_modules/uuid/dist-node/rng.js
30576
+ // ../node_modules/uuid/dist-node/rng.js
30096
30577
  function rng() {
30097
30578
  return crypto.getRandomValues(rnds8);
30098
30579
  }
30099
30580
  var rnds8;
30100
30581
  var init_rng = __esm({
30101
- "../../../neo-compose/node_modules/uuid/dist-node/rng.js"() {
30582
+ "../node_modules/uuid/dist-node/rng.js"() {
30102
30583
  rnds8 = new Uint8Array(16);
30103
30584
  }
30104
30585
  });
30105
30586
 
30106
- // ../../../neo-compose/node_modules/uuid/dist-node/v35.js
30587
+ // ../node_modules/uuid/dist-node/v35.js
30107
30588
  function stringToBytes(str) {
30108
30589
  str = unescape(encodeURIComponent(str));
30109
30590
  const bytes = new Uint8Array(str.length);
@@ -30141,7 +30622,7 @@ function v35(version, hash, value, namespace, buf, offset) {
30141
30622
  }
30142
30623
  var DNS, URL2;
30143
30624
  var init_v35 = __esm({
30144
- "../../../neo-compose/node_modules/uuid/dist-node/v35.js"() {
30625
+ "../node_modules/uuid/dist-node/v35.js"() {
30145
30626
  init_parse();
30146
30627
  init_stringify();
30147
30628
  DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
@@ -30149,7 +30630,7 @@ var init_v35 = __esm({
30149
30630
  }
30150
30631
  });
30151
30632
 
30152
- // ../../../neo-compose/node_modules/uuid/dist-node/v4.js
30633
+ // ../node_modules/uuid/dist-node/v4.js
30153
30634
  function v4(options, buf, offset) {
30154
30635
  if (!buf && !options && crypto.randomUUID) {
30155
30636
  return crypto.randomUUID();
@@ -30178,14 +30659,14 @@ function _v4(options, buf, offset) {
30178
30659
  }
30179
30660
  var v4_default;
30180
30661
  var init_v4 = __esm({
30181
- "../../../neo-compose/node_modules/uuid/dist-node/v4.js"() {
30662
+ "../node_modules/uuid/dist-node/v4.js"() {
30182
30663
  init_rng();
30183
30664
  init_stringify();
30184
30665
  v4_default = v4;
30185
30666
  }
30186
30667
  });
30187
30668
 
30188
- // ../../../neo-compose/node_modules/uuid/dist-node/sha1.js
30669
+ // ../node_modules/uuid/dist-node/sha1.js
30189
30670
  import { createHash as createHash2 } from "node:crypto";
30190
30671
  function sha1(bytes) {
30191
30672
  if (Array.isArray(bytes)) {
@@ -30197,18 +30678,18 @@ function sha1(bytes) {
30197
30678
  }
30198
30679
  var sha1_default;
30199
30680
  var init_sha1 = __esm({
30200
- "../../../neo-compose/node_modules/uuid/dist-node/sha1.js"() {
30681
+ "../node_modules/uuid/dist-node/sha1.js"() {
30201
30682
  sha1_default = sha1;
30202
30683
  }
30203
30684
  });
30204
30685
 
30205
- // ../../../neo-compose/node_modules/uuid/dist-node/v5.js
30686
+ // ../node_modules/uuid/dist-node/v5.js
30206
30687
  function v5(value, namespace, buf, offset) {
30207
30688
  return v35(80, sha1_default, value, namespace, buf, offset);
30208
30689
  }
30209
30690
  var v5_default;
30210
30691
  var init_v5 = __esm({
30211
- "../../../neo-compose/node_modules/uuid/dist-node/v5.js"() {
30692
+ "../node_modules/uuid/dist-node/v5.js"() {
30212
30693
  init_sha1();
30213
30694
  init_v35();
30214
30695
  v5.DNS = DNS;
@@ -30217,9 +30698,9 @@ var init_v5 = __esm({
30217
30698
  }
30218
30699
  });
30219
30700
 
30220
- // ../../../neo-compose/node_modules/uuid/dist-node/index.js
30701
+ // ../node_modules/uuid/dist-node/index.js
30221
30702
  var init_dist_node = __esm({
30222
- "../../../neo-compose/node_modules/uuid/dist-node/index.js"() {
30703
+ "../node_modules/uuid/dist-node/index.js"() {
30223
30704
  init_v4();
30224
30705
  init_v5();
30225
30706
  }
@@ -38746,7 +39227,7 @@ function emitStaticValueSourcesV4(records2) {
38746
39227
  );
38747
39228
  return emitStoredValueBindingSourcesV4(records2, memberIds);
38748
39229
  }
38749
- function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
39230
+ function buildValueEmitContext(records2) {
38750
39231
  const members = dataById(records2, "member");
38751
39232
  const classes = dataById(records2, "class");
38752
39233
  const values = dataById(records2, "value");
@@ -38754,7 +39235,7 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
38754
39235
  const localizedTexts = dataById(records2, "localized-text");
38755
39236
  const dialogues = dataById(records2, "dialogue");
38756
39237
  const symbolsByValueId = staticSymbols(classes, members);
38757
- const context = {
39238
+ return {
38758
39239
  members,
38759
39240
  classes,
38760
39241
  values,
@@ -38771,6 +39252,10 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
38771
39252
  referencedValueIds: externallyReferencedValueIds(records2),
38772
39253
  localizedTextIds: /* @__PURE__ */ new Set()
38773
39254
  };
39255
+ }
39256
+ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
39257
+ const context = buildValueEmitContext(records2);
39258
+ const members = context.members;
38774
39259
  const initializers = /* @__PURE__ */ new Map();
38775
39260
  const recordKeysByMember = /* @__PURE__ */ new Map();
38776
39261
  for (const memberId of memberIds) {
@@ -38800,6 +39285,102 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
38800
39285
  }
38801
39286
  return { initializers, recordKeysByMember };
38802
39287
  }
39288
+ function rowBackedDefaultBody(member, isPulledValueRow) {
39289
+ if (member.isStatic === true) return null;
39290
+ const defaultValue = member.defaultValue;
39291
+ if (!isObjectRecord2(defaultValue)) return null;
39292
+ const body = defaultValue.value;
39293
+ const referencesRows = (children) => children.length > 0 && children.every(
39294
+ (child) => typeof child === "string" && isPulledValueRow(child)
39295
+ );
39296
+ if (member.kind === MEMBER_KIND_CLASS && isObjectRecord2(body)) {
39297
+ return referencesRows(Object.values(body)) ? { kind: "class", body } : null;
39298
+ }
39299
+ if (member.kind === MEMBER_KIND_LIST && member.listKind !== "unordered" && Array.isArray(body)) {
39300
+ const rows = body.filter(
39301
+ (child) => typeof child === "string" && isPulledValueRow(child)
39302
+ );
39303
+ return rows.length > 0 && rows.length === body.length ? { kind: "list", body: rows } : null;
39304
+ }
39305
+ if (member.kind === MEMBER_KIND_DICTIONARY && isObjectRecord2(body)) {
39306
+ return referencesRows(Object.values(body)) ? { kind: "dictionary", body } : null;
39307
+ }
39308
+ return null;
39309
+ }
39310
+ function rowBackedDefaultMemberIdsV4(state) {
39311
+ const values = /* @__PURE__ */ new Set();
39312
+ for (const record3 of Object.values(state)) {
39313
+ if (record3.recordKind === "value") values.add(record3.recordId);
39314
+ }
39315
+ const result = /* @__PURE__ */ new Set();
39316
+ for (const record3 of Object.values(state)) {
39317
+ if (record3.recordKind !== "member" || !isObjectRecord2(record3.data)) {
39318
+ continue;
39319
+ }
39320
+ if (rowBackedDefaultBody(record3.data, (id2) => values.has(id2)) !== null) {
39321
+ result.add(record3.recordId);
39322
+ }
39323
+ }
39324
+ return result;
39325
+ }
39326
+ function emitMemberDefaultSourcesV4(records2) {
39327
+ const context = buildValueEmitContext(records2);
39328
+ const initializers = /* @__PURE__ */ new Map();
39329
+ const recordKeysByMember = /* @__PURE__ */ new Map();
39330
+ for (const record3 of records2.values()) {
39331
+ if (record3.deleted || record3.recordKind !== "member" || !isObjectRecord2(record3.data)) {
39332
+ continue;
39333
+ }
39334
+ const member = record3.data;
39335
+ const backed = rowBackedDefaultBody(member, (id2) => context.values.has(id2));
39336
+ if (backed === null) continue;
39337
+ const visited = /* @__PURE__ */ new Set();
39338
+ const defaultValue = isObjectRecord2(member.defaultValue) ? member.defaultValue : {};
39339
+ let expression;
39340
+ if (backed.kind === "class") {
39341
+ expression = classValue(
39342
+ context,
39343
+ member,
39344
+ { classId: defaultValue.classId ?? null, value: backed.body },
39345
+ visited,
39346
+ false
39347
+ );
39348
+ } else if (backed.kind === "list") {
39349
+ expression = listValue(context, member, { value: backed.body }, visited);
39350
+ } else {
39351
+ expression = dictionaryValue(context, member, backed.body, visited);
39352
+ }
39353
+ initializers.set(record3.recordId, expression);
39354
+ recordKeysByMember.set(
39355
+ record3.recordId,
39356
+ /* @__PURE__ */ new Set([
39357
+ ...[...visited].map((id2) => `value:${id2}`),
39358
+ ...[...context.localizedTextIds].map((id2) => `localized-text:${id2}`)
39359
+ ])
39360
+ );
39361
+ context.localizedTextIds.clear();
39362
+ }
39363
+ return { initializers, recordKeysByMember };
39364
+ }
39365
+ function qualifiedProjectFileSymbolsV4(records2) {
39366
+ const symbols = projectFileSymbols(records2);
39367
+ const result = /* @__PURE__ */ new Map();
39368
+ for (const record3 of records2.values()) {
39369
+ if (record3.deleted || record3.recordKind !== "project-file" || !isObjectRecord2(record3.data)) {
39370
+ continue;
39371
+ }
39372
+ const kind = record3.data.fileType;
39373
+ const symbol = symbols.get(record3.recordId);
39374
+ if (symbol === void 0 || kind !== "image" && kind !== "audio") {
39375
+ continue;
39376
+ }
39377
+ result.set(
39378
+ record3.recordId,
39379
+ `${kind === "image" ? "Images" : "AudioClips"}.${symbol}`
39380
+ );
39381
+ }
39382
+ return result;
39383
+ }
38803
39384
  function lowerStaticValueSourcesV4(state, analysis, manifest) {
38804
39385
  const bindings = [];
38805
39386
  for (const sourceClass of analysis.schema.classes) {
@@ -38822,7 +39403,7 @@ function lowerStaticValueSourcesV4(state, analysis, manifest) {
38822
39403
  }
38823
39404
  return lowerStoredValueBindingsV4(state, manifest, bindings, { analysis });
38824
39405
  }
38825
- function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
39406
+ function buildValueLowerContext(state, manifest, options = {}) {
38826
39407
  const members = new Map(
38827
39408
  manifest.members.map((member) => [member.id, member])
38828
39409
  );
@@ -38836,7 +39417,7 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
38836
39417
  manifest,
38837
39418
  parsedInitializers
38838
39419
  );
38839
- const context = {
39420
+ return {
38840
39421
  state,
38841
39422
  members,
38842
39423
  classes,
@@ -38860,6 +39441,9 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
38860
39441
  parsedInitializers,
38861
39442
  reconstructed: /* @__PURE__ */ new Map()
38862
39443
  };
39444
+ }
39445
+ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
39446
+ const context = buildValueLowerContext(state, manifest, options);
38863
39447
  const memberValueIds = /* @__PURE__ */ new Map();
38864
39448
  const seeds = /* @__PURE__ */ new Map();
38865
39449
  for (const binding of bindings) {
@@ -38871,6 +39455,143 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
38871
39455
  seeds
38872
39456
  };
38873
39457
  }
39458
+ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
39459
+ const context = buildValueLowerContext(state, manifest, { analysis });
39460
+ const pulledValueIds = /* @__PURE__ */ new Set();
39461
+ for (const record3 of Object.values(state)) {
39462
+ if (record3.recordKind === "value") pulledValueIds.add(record3.recordId);
39463
+ }
39464
+ const memberDefaultValues = /* @__PURE__ */ new Map();
39465
+ for (const sourceClass of analysis.schema.classes) {
39466
+ for (const declaration of sourceClass.members) {
39467
+ if (declaration.kind !== "field" || declaration.initializer === null) {
39468
+ continue;
39469
+ }
39470
+ if (declaration.modifiers.includes("static")) continue;
39471
+ const label = `${sourceClass.name}.${declaration.name}`;
39472
+ const memberId = sourceIdentityId(declaration, "member", label);
39473
+ const baseData3 = stateData(context, "member", memberId);
39474
+ if (baseData3 === null) continue;
39475
+ const backed = rowBackedDefaultBody(
39476
+ baseData3,
39477
+ (id2) => pulledValueIds.has(id2)
39478
+ );
39479
+ if (backed === null) continue;
39480
+ const member = context.members.get(memberId);
39481
+ if (member === void 0) continue;
39482
+ const binding = {
39483
+ memberId,
39484
+ initializer: declaration.initializer,
39485
+ source: declaration.source,
39486
+ label
39487
+ };
39488
+ memberDefaultValues.set(
39489
+ memberId,
39490
+ lowerRowBackedDefault(context, member, backed, baseData3, binding)
39491
+ );
39492
+ }
39493
+ }
39494
+ return {
39495
+ records: [...context.reconstructed.values()],
39496
+ memberDefaultValues
39497
+ };
39498
+ }
39499
+ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
39500
+ const baseDefault = isObjectRecord2(baseData3.defaultValue) ? baseData3.defaultValue : {};
39501
+ const storedClassId = stringOrNull(baseDefault.classId);
39502
+ const expression = annotatedValue(
39503
+ parseCachedInitializer(context.parsedInitializers, binding.initializer)
39504
+ ).expression;
39505
+ if (member.kind === "class" && backed.kind === "class") {
39506
+ if (expression.kind !== "new") {
39507
+ throw new Error(`Default value ${binding.label} requires new(...).`);
39508
+ }
39509
+ const currentClassId = storedClassId ?? member.classId;
39510
+ const classId = expression.className === null ? currentClassId : requiredClassByName(context, expression.className).id;
39511
+ const baseBody = backed.body;
39512
+ const body = {};
39513
+ for (const assignment of expression.initializer ?? []) {
39514
+ const childMember = classMemberByName(context, classId, assignment.name);
39515
+ const existingId = isObjectRecord2(baseBody) ? baseBody[assignment.name] : void 0;
39516
+ const childId = typeof existingId === "string" ? existingId : annotatedValue(assignment.value).id;
39517
+ if (childId === null || childId === void 0) {
39518
+ throw new Error(
39519
+ `Default value ${binding.label}.${assignment.name} has no existing owned value row. Creating new default rows from source is not implemented by this slice.`
39520
+ );
39521
+ }
39522
+ body[assignment.name] = lowerValueRow(
39523
+ context,
39524
+ childMember,
39525
+ assignment.value,
39526
+ childId,
39527
+ binding
39528
+ );
39529
+ }
39530
+ return {
39531
+ value: body,
39532
+ classId: classId === currentClassId ? storedClassId : classId
39533
+ };
39534
+ }
39535
+ if (member.kind === "list" && backed.kind === "list") {
39536
+ if (expression.kind !== "litList") {
39537
+ throw new Error(`Default value ${binding.label} requires [...].`);
39538
+ }
39539
+ const entryMember = requiredMember(context, member.entryMemberId);
39540
+ const existingIds = new Set(backed.body);
39541
+ const ids = expression.elements.map((element, index) => {
39542
+ const symbolId = sourceValueSymbol(context, element);
39543
+ if (symbolId !== null) {
39544
+ if (!existingIds.has(symbolId)) {
39545
+ throw new Error(
39546
+ `Default list ${binding.label} adds value ${symbolId}. Changing default value placement is not implemented by this slice.`
39547
+ );
39548
+ }
39549
+ return symbolId;
39550
+ }
39551
+ const itemId = annotatedValue(element).id;
39552
+ if (itemId === null) {
39553
+ throw new Error(
39554
+ `Default list ${binding.label}[${index}] has no @id. Creating new default rows from source is not implemented by this slice.`
39555
+ );
39556
+ }
39557
+ return lowerValueRow(context, entryMember, element, itemId, binding);
39558
+ });
39559
+ return { value: ids, classId: storedClassId };
39560
+ }
39561
+ if (member.kind === "dictionary" && backed.kind === "dictionary") {
39562
+ if (expression.kind !== "litDict") {
39563
+ throw new Error(`Default value ${binding.label} requires {...}.`);
39564
+ }
39565
+ const entryMember = requiredMember(context, member.entryMemberId);
39566
+ const baseBody = backed.body;
39567
+ const body = {};
39568
+ for (const entry of expression.entries) {
39569
+ if (entry.key.kind !== "litString") {
39570
+ throw new Error(
39571
+ `Default dictionary ${binding.label} requires string keys.`
39572
+ );
39573
+ }
39574
+ const existingId = isObjectRecord2(baseBody) ? baseBody[entry.key.value] : void 0;
39575
+ const entryId = typeof existingId === "string" ? existingId : annotatedValue(entry.value).id;
39576
+ if (entryId === null || entryId === void 0) {
39577
+ throw new Error(
39578
+ `Default dictionary ${binding.label}[${JSON.stringify(entry.key.value)}] has no existing owned value row. Creating new default rows from source is not implemented by this slice.`
39579
+ );
39580
+ }
39581
+ body[entry.key.value] = lowerValueRow(
39582
+ context,
39583
+ entryMember,
39584
+ entry.value,
39585
+ entryId,
39586
+ binding
39587
+ );
39588
+ }
39589
+ return { value: body, classId: storedClassId };
39590
+ }
39591
+ throw new Error(
39592
+ `Default value ${binding.label} does not match its persisted ${member.kind} container shape.`
39593
+ );
39594
+ }
38874
39595
  function lowerStoredBinding(context, binding, memberValueIds, seeds) {
38875
39596
  const member = context.members.get(binding.memberId);
38876
39597
  if (member === void 0) {
@@ -39145,18 +39866,7 @@ function lowerClassValue(context, member, expression, base, source) {
39145
39866
  const baseBody = isObjectRecord2(base.value) ? base.value : {};
39146
39867
  const body = { ...baseBody };
39147
39868
  for (const assignment of expression.initializer ?? []) {
39148
- const childMemberId = schemaClass2.schema[assignment.name];
39149
- if (typeof childMemberId !== "string") {
39150
- throw new Error(
39151
- `Class ${schemaClass2.name} has no stored member ${assignment.name}.`
39152
- );
39153
- }
39154
- const childMember = context.members.get(childMemberId);
39155
- if (childMember === void 0) {
39156
- throw new Error(
39157
- `Class ${schemaClass2.name}.${assignment.name} is missing its member record.`
39158
- );
39159
- }
39869
+ const childMember = classMemberByName(context, classId, assignment.name);
39160
39870
  const childId = baseBody[assignment.name];
39161
39871
  if (typeof childId !== "string") {
39162
39872
  throw new Error(
@@ -40001,7 +40711,7 @@ function classValue(context, member, value, visited, targetTyped) {
40001
40711
  ...Object.keys(value.value).filter((key2) => !order.includes(key2))
40002
40712
  ]) {
40003
40713
  const childId = value.value[key];
40004
- const childMemberId = schema[key];
40714
+ const childMemberId = schema[key] ?? inheritedSchemaMemberId(context, schemaClass2, key);
40005
40715
  if (typeof childId !== "string" || typeof childMemberId !== "string")
40006
40716
  continue;
40007
40717
  const childMember = context.members.get(childMemberId);
@@ -40015,9 +40725,23 @@ function classValue(context, member, value, visited, targetTyped) {
40015
40725
  );
40016
40726
  }
40017
40727
  return fields.length === 0 ? targetTyped ? "new()" : `new ${name}()` : `${targetTyped ? "new()" : `new ${name}`} {
40018
- ${fields.map((field) => indentNeoSource(field, 2)).join(",\n")}
40728
+ ${fields.map((field) => indentNeoSourceNonEmptyLines(field, 2)).join(",\n")}
40019
40729
  }`;
40020
40730
  }
40731
+ function inheritedSchemaMemberId(context, schemaClass2, key) {
40732
+ const visited = /* @__PURE__ */ new Set();
40733
+ let current = typeof schemaClass2.extendsClassId === "string" ? schemaClass2.extendsClassId : void 0;
40734
+ while (current !== void 0 && !visited.has(current)) {
40735
+ visited.add(current);
40736
+ const parent = context.classes.get(current);
40737
+ if (parent === void 0) return void 0;
40738
+ const schema = isObjectRecord2(parent.schema) ? parent.schema : {};
40739
+ const memberId = schema[key];
40740
+ if (typeof memberId === "string") return memberId;
40741
+ current = typeof parent.extendsClassId === "string" ? parent.extendsClassId : void 0;
40742
+ }
40743
+ return void 0;
40744
+ }
40021
40745
  function listValue(context, member, value, visited) {
40022
40746
  if (value.value === null) return "null";
40023
40747
  const entryMember = context.members.get(stringField2(member, "entryMemberId"));
@@ -40029,7 +40753,7 @@ function listValue(context, member, value, visited) {
40029
40753
  if (ids.length === 0) return "[]";
40030
40754
  return `[
40031
40755
  ${ids.map(
40032
- (id2) => indentNeoSource(
40756
+ (id2) => indentNeoSourceNonEmptyLines(
40033
40757
  emitValue(context, entryMember, id2, {
40034
40758
  exposeIdentity: context.symbolsByValueId.get(id2) === void 0,
40035
40759
  visited
@@ -40052,7 +40776,7 @@ function dictionaryValue(context, member, body, visited) {
40052
40776
  return `{
40053
40777
  ${entries.flatMap(
40054
40778
  ([key, id2]) => typeof id2 === "string" ? [
40055
- indentNeoSource(
40779
+ indentNeoSourceNonEmptyLines(
40056
40780
  `${quote4(key)}: ${emitValue(context, entryMember, id2, {
40057
40781
  exposeIdentity: !context.symbolsByValueId.has(id2) && context.referencedValueIds.has(id2),
40058
40782
  visited
@@ -40243,6 +40967,7 @@ function numberOr2(value, fallback) {
40243
40967
  function quote4(value) {
40244
40968
  return quoteNeoString(value);
40245
40969
  }
40970
+ var MEMBER_KIND_DICTIONARY, MEMBER_KIND_LIST, MEMBER_KIND_CLASS;
40246
40971
  var init_value_sources = __esm({
40247
40972
  "src/project-source/value-sources.ts"() {
40248
40973
  "use strict";
@@ -40251,6 +40976,9 @@ var init_value_sources = __esm({
40251
40976
  init_project_files();
40252
40977
  init_lower_members();
40253
40978
  init_source_format();
40979
+ MEMBER_KIND_DICTIONARY = 5;
40980
+ MEMBER_KIND_LIST = 6;
40981
+ MEMBER_KIND_CLASS = 7;
40254
40982
  }
40255
40983
  });
40256
40984
 
@@ -40433,8 +41161,11 @@ function emitProjectDocumentFilesV4(records2) {
40433
41161
  }
40434
41162
  const manifest = documentsToProjectSchemaManifest(schemaRecords);
40435
41163
  const staticValues = emitStaticValueSourcesV4(records2);
41164
+ const memberDefaults = emitMemberDefaultSourcesV4(records2);
40436
41165
  const baseSource = emitProjectSourcesV4(manifest, {
40437
41166
  staticInitializers: staticValues.initializers,
41167
+ defaultInitializers: memberDefaults.initializers,
41168
+ fileSymbols: qualifiedProjectFileSymbolsV4(records2),
40438
41169
  relationEndpointExpressions: relationEndpointExpressions(records2)
40439
41170
  });
40440
41171
  const source = {
@@ -40442,7 +41173,11 @@ function emitProjectDocumentFilesV4(records2) {
40442
41173
  files: baseSource.files.map((file) => {
40443
41174
  const ownedKeys = file.recordKeys.flatMap((key) => {
40444
41175
  if (!key.startsWith("member:")) return [];
40445
- return [...staticValues.recordKeysByMember.get(key.slice(7)) ?? []];
41176
+ const memberId = key.slice(7);
41177
+ return [
41178
+ ...staticValues.recordKeysByMember.get(memberId) ?? [],
41179
+ ...memberDefaults.recordKeysByMember.get(memberId) ?? []
41180
+ ];
40446
41181
  });
40447
41182
  return ownedKeys.length === 0 ? file : { ...file, recordKeys: [...file.recordKeys, ...ownedKeys] };
40448
41183
  })
@@ -42734,6 +43469,10 @@ function computeWorkspaceStatus(workspace, options = {}) {
42734
43469
  let manifest;
42735
43470
  let staticValueSeeds = /* @__PURE__ */ new Map();
42736
43471
  let staticMemberValueIds = /* @__PURE__ */ new Map();
43472
+ let memberDefaults = {
43473
+ records: [],
43474
+ memberDefaultValues: /* @__PURE__ */ new Map()
43475
+ };
42737
43476
  let projectAnalysisV4 = null;
42738
43477
  try {
42739
43478
  if (!baseManifest) {
@@ -42797,8 +43536,26 @@ function computeWorkspaceStatus(workspace, options = {}) {
42797
43536
  };
42798
43537
  }
42799
43538
  manifest = lowerProjectSchemaV4(baseManifest, analysis, {
42800
- staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records)
43539
+ staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records),
43540
+ projectFileIdsBySymbol: projectFileIdsBySymbol(workspace.state.records),
43541
+ rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(
43542
+ workspace.state.records
43543
+ )
42801
43544
  });
43545
+ memberDefaults = lowerMemberDefaultSourcesV4(
43546
+ workspace.state.records,
43547
+ analysis,
43548
+ manifest
43549
+ );
43550
+ if (memberDefaults.memberDefaultValues.size > 0) {
43551
+ manifest = {
43552
+ ...manifest,
43553
+ members: manifest.members.map((member) => {
43554
+ const lowered = memberDefaults.memberDefaultValues.get(member.id);
43555
+ return lowered === void 0 ? member : { ...member, defaultValue: lowered };
43556
+ })
43557
+ };
43558
+ }
42802
43559
  (options.writeProjectAnalysisCache ?? writeProjectSourceAnalysisCacheV4)(
42803
43560
  workspace.root,
42804
43561
  analysis
@@ -42880,7 +43637,12 @@ function computeWorkspaceStatus(workspace, options = {}) {
42880
43637
  const dialogueState = overlayProspectiveSourceRecords(
42881
43638
  workspace.state.records,
42882
43639
  documents,
42883
- [...staticValues.records, ...rootRecords, ...supplementalRecords],
43640
+ [
43641
+ ...staticValues.records,
43642
+ ...memberDefaults.records,
43643
+ ...rootRecords,
43644
+ ...supplementalRecords
43645
+ ],
42884
43646
  staticMemberValueIds
42885
43647
  );
42886
43648
  const dialogueRecords = lowerDialogueProjectSourcesV4(
@@ -42889,6 +43651,7 @@ function computeWorkspaceStatus(workspace, options = {}) {
42889
43651
  );
42890
43652
  records2.push(
42891
43653
  ...staticValues.records,
43654
+ ...memberDefaults.records,
42892
43655
  ...rootRecords,
42893
43656
  ...supplementalRecords,
42894
43657
  ...dialogueRecords