@doenet/v06-to-v07 0.7.26-dev.571 → 0.7.26-dev.573

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 (51) hide show
  1. package/apply-assign-name-renames.d.ts +14 -0
  2. package/apply-assign-name-renames.d.ts.map +1 -0
  3. package/assign-names/apply-renames.d.ts +21 -0
  4. package/assign-names/apply-renames.d.ts.map +1 -0
  5. package/assign-names/break-into-pieces.d.ts +34 -0
  6. package/assign-names/break-into-pieces.d.ts.map +1 -0
  7. package/assign-names/composite-info.d.ts +61 -0
  8. package/assign-names/composite-info.d.ts.map +1 -0
  9. package/assign-names/context.d.ts +103 -0
  10. package/assign-names/context.d.ts.map +1 -0
  11. package/assign-names/prop-access-parts.d.ts +14 -0
  12. package/assign-names/prop-access-parts.d.ts.map +1 -0
  13. package/assign-names/register-assign-names.d.ts +38 -0
  14. package/assign-names/register-assign-names.d.ts.map +1 -0
  15. package/assign-names/register-composite.d.ts +26 -0
  16. package/assign-names/register-composite.d.ts.map +1 -0
  17. package/assign-names/rename-registry.d.ts +90 -0
  18. package/assign-names/rename-registry.d.ts.map +1 -0
  19. package/assign-names/visit-all.d.ts +35 -0
  20. package/assign-names/visit-all.d.ts.map +1 -0
  21. package/core-info/core.d.ts +1 -0
  22. package/core-info/core.d.ts.map +1 -1
  23. package/core-info/determine-prop-type.d.ts +9 -0
  24. package/core-info/determine-prop-type.d.ts.map +1 -1
  25. package/{index-Cxf3BQNw.js → index-4M4L_2sg.js} +2286 -318
  26. package/{index-Cxf3BQNw.js.map → index-4M4L_2sg.js.map} +1 -1
  27. package/index.d.ts.map +1 -1
  28. package/index.js +1 -1
  29. package/normalize-capitalization.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/{sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js → sha256-8sXzDnE0-BtProggv-BVCPcIg2.js} +2 -2
  32. package/{sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js.map → sha256-8sXzDnE0-BtProggv-BVCPcIg2.js.map} +1 -1
  33. package/slash-to-dot.d.ts.map +1 -1
  34. package/upgrade-assign-names.d.ts +32 -0
  35. package/upgrade-assign-names.d.ts.map +1 -0
  36. package/upgrade-attribute-syntax.d.ts +4 -1
  37. package/upgrade-attribute-syntax.d.ts.map +1 -1
  38. package/upgrade-collect-element.d.ts +4 -1
  39. package/upgrade-collect-element.d.ts.map +1 -1
  40. package/upgrade-copy-elements.d.ts +45 -0
  41. package/upgrade-copy-elements.d.ts.map +1 -0
  42. package/upgrade-copy-syntax.d.ts.map +1 -1
  43. package/upgrade-deprecated-attributes.d.ts +12 -0
  44. package/upgrade-deprecated-attributes.d.ts.map +1 -0
  45. package/upgrade-list-props.d.ts +4 -0
  46. package/upgrade-list-props.d.ts.map +1 -0
  47. package/upgrade-map-element.d.ts +4 -1
  48. package/upgrade-map-element.d.ts.map +1 -1
  49. package/upgrade-module-element.d.ts.map +1 -1
  50. package/utils.d.ts +34 -2
  51. package/utils.d.ts.map +1 -1
@@ -1849,16 +1849,16 @@ function findNodesWithPositionInfo(nodes) {
1849
1849
  }
1850
1850
  return ret;
1851
1851
  }
1852
- function macroToString(node) {
1852
+ function macroToString(node, forceParens = false) {
1853
1853
  if (Array.isArray(node)) {
1854
- return node.map((n2) => macroToString(n2)).join("");
1854
+ return arrayToString(node);
1855
1855
  }
1856
1856
  switch (node.type) {
1857
1857
  case "macro": {
1858
1858
  const macro = unwrappedMacroToString$1(node);
1859
1859
  let start = "$";
1860
1860
  let end = "";
1861
- if (macroNeedsParens$1(node)) {
1861
+ if (macroNeedsParens$1(node) || forceParens) {
1862
1862
  start += "(";
1863
1863
  end += ")";
1864
1864
  }
@@ -1868,11 +1868,11 @@ function macroToString(node) {
1868
1868
  const macro = unwrappedMacroToString$1(node.macro);
1869
1869
  let start = "$$";
1870
1870
  let end = "";
1871
- if (macroNeedsParens$1(node)) {
1871
+ if (macroNeedsParens$1(node) || forceParens) {
1872
1872
  start += "(";
1873
1873
  end += ")";
1874
1874
  }
1875
- const args = node.input ? `(${node.input.map(macroToString).join(", ")})` : "";
1875
+ const args = node.input ? `(${node.input.map((arg) => macroToString(arg)).join(", ")})` : "";
1876
1876
  return start + macro + end + args;
1877
1877
  }
1878
1878
  case "text":
@@ -1898,12 +1898,29 @@ function macroPathToString$1(path) {
1898
1898
  function macroPathPartToString$1(pathPart) {
1899
1899
  return pathPart.name + pathPart.index.map((part) => `[${macroToString(part.value)}]`).join("");
1900
1900
  }
1901
+ function arrayToString(nodes) {
1902
+ const parts = nodes.map((n2) => macroToString(n2));
1903
+ let nextChar = "";
1904
+ for (let i2 = parts.length - 1; i2 >= 0; i2--) {
1905
+ const child = nodes[i2];
1906
+ if ((child.type === "macro" || child.type === "function") && isNameChar$1(nextChar) && isNameChar$1(parts[i2].slice(-1))) {
1907
+ parts[i2] = macroToString(child, true);
1908
+ }
1909
+ if (parts[i2]) {
1910
+ nextChar = parts[i2][0];
1911
+ }
1912
+ }
1913
+ return parts.join("");
1914
+ }
1915
+ function isNameChar$1(char) {
1916
+ return /^[a-zA-Z0-9_]$/.test(char);
1917
+ }
1901
1918
  function attrToString$1(attr) {
1902
1919
  const name2 = attr.name;
1903
1920
  if (attr.children.length === 0) {
1904
1921
  return name2;
1905
1922
  }
1906
- const value = attr.children.map(macroToString).join("");
1923
+ const value = arrayToString(attr.children);
1907
1924
  return `${name2}=${quote(value)}`;
1908
1925
  }
1909
1926
  function macroNeedsParens$1(macro) {
@@ -1923,10 +1940,22 @@ function toXml(tree, options) {
1923
1940
  const node = Array.isArray(tree) ? { type: "root", children: tree } : tree;
1924
1941
  return nodesToXml(node, options);
1925
1942
  }
1926
- function nodesToXml(node, options) {
1943
+ function nodesToXml(node, options, forceParens = false) {
1927
1944
  if (Array.isArray(node)) {
1928
1945
  if (!node.some((n2) => n2.type === "pathPart")) {
1929
- return mergeAdjacentTextInArray(node).map((child) => nodesToXml(child, options)).join("");
1946
+ const children = mergeAdjacentTextInArray(node);
1947
+ const parts = children.map((child) => nodesToXml(child, options));
1948
+ let nextChar = "";
1949
+ for (let i2 = parts.length - 1; i2 >= 0; i2--) {
1950
+ const child = children[i2];
1951
+ if ((child.type === "macro" || child.type === "function") && isNameChar(nextChar) && isNameChar(parts[i2].slice(-1))) {
1952
+ parts[i2] = nodesToXml(child, options, true);
1953
+ }
1954
+ if (parts[i2]) {
1955
+ nextChar = parts[i2][0];
1956
+ }
1957
+ }
1958
+ return parts.join("");
1930
1959
  } else {
1931
1960
  return node.map((part) => nodesToXml(part, options)).join(".");
1932
1961
  }
@@ -2011,12 +2040,12 @@ function nodesToXml(node, options) {
2011
2040
  }
2012
2041
  case "macro": {
2013
2042
  if (node.version === "0.6") {
2014
- return macroToString(node);
2043
+ return macroToString(node, forceParens);
2015
2044
  }
2016
2045
  const macro = unwrappedMacroToString(node, options);
2017
2046
  let start = "$";
2018
2047
  let end = "";
2019
- if (macroNeedsParens(node)) {
2048
+ if (macroNeedsParens(node) || forceParens) {
2020
2049
  start += "(";
2021
2050
  end += ")";
2022
2051
  }
@@ -2024,12 +2053,12 @@ function nodesToXml(node, options) {
2024
2053
  }
2025
2054
  case "function": {
2026
2055
  if (node.version === "0.6") {
2027
- return macroToString(node);
2056
+ return macroToString(node, forceParens);
2028
2057
  }
2029
2058
  const macro = unwrappedMacroToString(node, options);
2030
2059
  let start = "$$";
2031
2060
  let end = "";
2032
- if (macroNeedsParens(node)) {
2061
+ if (macroNeedsParens(node) || forceParens) {
2033
2062
  start += "(";
2034
2063
  end += ")";
2035
2064
  }
@@ -2082,6 +2111,9 @@ function attrToString(attr, options) {
2082
2111
  function macroNeedsParens(macro) {
2083
2112
  return macro.path.some((part) => part.name.includes("-"));
2084
2113
  }
2114
+ function isNameChar(char) {
2115
+ return /^[a-zA-Z0-9_]$/.test(char);
2116
+ }
2085
2117
  const StartTag = 1, StartCloseTag = 2, MissingCloseTag = 3, mismatchedStartCloseTag = 4, incompleteStartCloseTag = 5, commentContent$1 = 36, piContent$1 = 37, cdataContent$1 = 38, Text$1 = 7, Element = 12, EndTag = 13, OpenTag = 14, TagName = 15, Attribute = 16, AttributeValue = 19, CloseTag = 20, SelfCloseEndTag = 21, SelfClosingTag = 22, MismatchedCloseTag = 25;
2086
2118
  const DefaultBufferLength = 1024;
2087
2119
  let nextPropID = 0;
@@ -31765,7 +31797,7 @@ var init_before = __esmMin((() => {
31765
31797
  })), once_default, init_once = __esmMin((() => {
31766
31798
  init_partial(), init_before(), once_default = partial(before, 2);
31767
31799
  }));
31768
- function findKey(t4, n2, r2) {
31800
+ function findKey$2(t4, n2, r2) {
31769
31801
  n2 = cb(n2, r2);
31770
31802
  for (var i2 = keys$1(t4), a2, o2 = 0, s2 = i2.length; o2 < s2; o2++) if (a2 = i2[o2], n2(t4[a2], a2, t4)) return a2;
31771
31803
  }
@@ -31815,7 +31847,7 @@ var init__createIndexFinder = __esmMin((() => {
31815
31847
  init_findLastIndex(), init__createIndexFinder(), lastIndexOf_default = createIndexFinder(-1, findLastIndex_default);
31816
31848
  }));
31817
31849
  function find$1(t4, n2, r2) {
31818
- var i2 = (_isArrayLike_default(t4) ? findIndex_default : findKey)(t4, n2, r2);
31850
+ var i2 = (_isArrayLike_default(t4) ? findIndex_default : findKey$2)(t4, n2, r2);
31819
31851
  if (i2 !== void 0 && i2 !== -1) return t4[i2];
31820
31852
  }
31821
31853
  var init_find = __esmMin((() => {
@@ -32199,11 +32231,11 @@ var init_mixin = __esmMin((() => {
32199
32231
  return t5 != null && (t5 = n2.apply(t5, arguments)), chainResult(this, t5);
32200
32232
  };
32201
32233
  }), underscore_array_methods_default = _$1$1;
32202
- })), modules_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => underscore_array_methods_default, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_modules = __esmMin((() => {
32234
+ })), modules_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => underscore_array_methods_default, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey$2, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_modules = __esmMin((() => {
32203
32235
  init__setup(), init_restArguments(), init_isObject(), init_isNull(), init_isUndefined(), init_isBoolean(), init_isElement(), init_isString(), init_isNumber(), init_isDate(), init_isRegExp(), init_isError(), init_isSymbol(), init_isArrayBuffer(), init_isDataView(), init_isArray(), init_isFunction(), init_isArguments(), init_isFinite(), init_isNaN(), init_isTypedArray(), init_isEmpty(), init_isMatch(), init_isEqual(), init_isMap(), init_isWeakMap(), init_isSet(), init_isWeakSet(), init_keys(), init_allKeys(), init_values(), init_pairs(), init_invert(), init_functions(), init_extend(), init_extendOwn(), init_defaults(), init_create(), init_clone(), init_tap(), init_get(), init_has(), init_mapObject(), init_identity(), init_constant(), init_noop(), init_toPath(), init_property(), init_propertyOf(), init_matcher(), init_times(), init_random(), init_now(), init_escape(), init_unescape(), init_templateSettings(), init_template(), init_result(), init_uniqueId(), init_chain(), init_iteratee(), init_partial(), init_bind(), init_bindAll(), init_memoize(), init_delay(), init_defer(), init_throttle(), init_debounce(), init_wrap(), init_negate(), init_compose(), init_after(), init_before(), init_once(), init_findKey(), init_findIndex(), init_findLastIndex(), init_sortedIndex(), init_indexOf(), init_lastIndexOf(), init_find(), init_findWhere(), init_each(), init_map(), init_reduce(), init_reduceRight(), init_filter(), init_reject(), init_every(), init_some(), init_contains(), init_invoke(), init_pluck(), init_where(), init_max(), init_min(), init_shuffle(), init_sample(), init_sortBy(), init_groupBy(), init_indexBy(), init_countBy(), init_partition(), init_toArray(), init_size(), init_pick(), init_omit(), init_first(), init_initial(), init_last(), init_rest(), init_compact(), init_flatten(), init_without(), init_uniq(), init_union(), init_intersection(), init_difference(), init_unzip(), init_zip(), init_object(), init_range(), init_chunk(), init_mixin(), init_underscore_array_methods();
32204
32236
  })), _$2, init_index_default = __esmMin((() => {
32205
32237
  init_modules(), _$2 = mixin(modules_exports), _$2._ = _$2;
32206
- })), index_all_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => _$2, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_index_all = __esmMin((() => {
32238
+ })), index_all_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => _$2, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey$2, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_index_all = __esmMin((() => {
32207
32239
  init_index_default(), init_modules();
32208
32240
  }));
32209
32241
  init_index_all();
@@ -47324,7 +47356,7 @@ async function cidFromArrayBuffer(data) {
47324
47356
  await crypto.subtle.digest("SHA-256", new Uint8Array());
47325
47357
  digest = (data2) => crypto.subtle.digest("SHA-256", data2);
47326
47358
  } catch (e22) {
47327
- const sha256 = (await import("./sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js").then((n2) => n2.s)).default;
47359
+ const sha256 = (await import("./sha256-8sXzDnE0-BtProggv-BVCPcIg2.js").then((n2) => n2.s)).default;
47328
47360
  digest = (data2) => sha256(data2, {
47329
47361
  asBytes: true
47330
47362
  });
@@ -83761,6 +83793,97 @@ function aggregateCreditOverScoredDescendants(dependencyValues, variableName, cr
83761
83793
  }
83762
83794
  return totalWeight > 0 ? creditSum / totalWeight : creditWhenNothingScored;
83763
83795
  }
83796
+ function aggregateCreditForCheckWork(dependencyValues) {
83797
+ const descendants = dependencyValues.scoredDescendants;
83798
+ const totalWeight = descendants.reduce(
83799
+ (sum2, descendant) => sum2 + descendant.stateValues.weight,
83800
+ 0
83801
+ );
83802
+ const useUnitWeights = !(totalWeight > 0);
83803
+ const weightSum = useUnitWeights ? descendants.length : totalWeight;
83804
+ let creditSum = 0;
83805
+ for (const [ind, descendant] of descendants.entries()) {
83806
+ const { stateValues } = dependencyValues["creditForCheckWork" + ind];
83807
+ const credit = stateValues.creditAchievedForCheckWork ?? stateValues.creditAchieved;
83808
+ creditSum += credit * (useUnitWeights ? 1 : descendant.stateValues.weight);
83809
+ }
83810
+ return creditSum / weightSum;
83811
+ }
83812
+ function checkWorkCreditNeedsAggregating(stateValues, alwaysAggregate) {
83813
+ if (!stateValues.suppressAnswerSubmitButtons) {
83814
+ return false;
83815
+ }
83816
+ if (!alwaysAggregate && !stateValues.aggregateScores) {
83817
+ return false;
83818
+ }
83819
+ const descendants = stateValues.scoredDescendants;
83820
+ if (descendants.length === 0) {
83821
+ return false;
83822
+ }
83823
+ const anyPositiveWeight = descendants.some(
83824
+ (descendant) => descendant.stateValues.weight > 0
83825
+ );
83826
+ const anyAggregatingDescendant = descendants.some(
83827
+ // The same test `scoredDescendants` uses to tell a container it keeps
83828
+ // from a leaf it cannot look inside.
83829
+ (descendant) => descendant.stateValues.scoredDescendants !== void 0
83830
+ );
83831
+ return !anyPositiveWeight || anyAggregatingDescendant;
83832
+ }
83833
+ function returnCheckWorkCreditStateVariableDefinition({
83834
+ alwaysAggregate = false
83835
+ } = {}) {
83836
+ const stateVariablesDeterminingDependencies = [
83837
+ "suppressAnswerSubmitButtons",
83838
+ "scoredDescendants"
83839
+ ];
83840
+ if (!alwaysAggregate) {
83841
+ stateVariablesDeterminingDependencies.push("aggregateScores");
83842
+ }
83843
+ return {
83844
+ forRenderer: true,
83845
+ defaultValue: null,
83846
+ stateVariablesDeterminingDependencies,
83847
+ returnDependencies({ stateValues }) {
83848
+ if (!checkWorkCreditNeedsAggregating(stateValues, alwaysAggregate)) {
83849
+ return {};
83850
+ }
83851
+ const dependencies2 = {
83852
+ scoredDescendants: {
83853
+ dependencyType: "stateVariable",
83854
+ variableName: "scoredDescendants"
83855
+ }
83856
+ };
83857
+ for (const [
83858
+ ind,
83859
+ descendant
83860
+ ] of stateValues.scoredDescendants.entries()) {
83861
+ dependencies2["creditForCheckWork" + ind] = {
83862
+ dependencyType: "multipleStateVariables",
83863
+ componentIdx: descendant.componentIdx,
83864
+ variableNames: [
83865
+ "creditAchievedForCheckWork",
83866
+ "creditAchieved"
83867
+ ],
83868
+ // An `<answer>` has only the latter, which is what its
83869
+ // check-work credit would be anyway.
83870
+ variablesOptional: true
83871
+ };
83872
+ }
83873
+ return dependencies2;
83874
+ },
83875
+ definition({ dependencyValues }) {
83876
+ if (dependencyValues.scoredDescendants === void 0) {
83877
+ return { setValue: { creditAchievedForCheckWork: null } };
83878
+ }
83879
+ return {
83880
+ setValue: {
83881
+ creditAchievedForCheckWork: aggregateCreditForCheckWork(dependencyValues)
83882
+ }
83883
+ };
83884
+ }
83885
+ };
83886
+ }
83764
83887
  function returnScoredSectionAttributes() {
83765
83888
  return {
83766
83889
  aggregateScores: {
@@ -84215,6 +84338,7 @@ function returnScoredSectionStateVariableDefinition() {
84215
84338
  };
84216
84339
  }
84217
84340
  };
84341
+ stateVariableDefinitions.creditAchievedForCheckWork = returnCheckWorkCreditStateVariableDefinition();
84218
84342
  stateVariableDefinitions.creditAchievedIfSubmit = {
84219
84343
  defaultValue: 0,
84220
84344
  stateVariablesDeterminingDependencies: [
@@ -127352,6 +127476,11 @@ class Input extends InlineComponent {
127352
127476
  componentIdx: stateValues.sectionDeterminingColorCorrectness,
127353
127477
  variableNames: [
127354
127478
  "justSubmitted",
127479
+ // The section colors its inputs by the same credit
127480
+ // its button reports, so the two can never disagree;
127481
+ // it is `null` wherever the score already says it,
127482
+ // hence the fallback below.
127483
+ "creditAchievedForCheckWork",
127355
127484
  "creditAchieved",
127356
127485
  "showCorrectness",
127357
127486
  "colorCorrectness"
@@ -127494,7 +127623,7 @@ class Input extends InlineComponent {
127494
127623
  let creditAchieved = 0;
127495
127624
  const comp = dependencyValues.componentDeterminingDisplayedCorrectness;
127496
127625
  if (comp) {
127497
- const overallCredit = comp.stateValues.creditAchieved ?? 0;
127626
+ const overallCredit = comp.stateValues.creditAchievedForCheckWork ?? comp.stateValues.creditAchieved ?? 0;
127498
127627
  const creditAchievedPerInput = dependencyValues.answerCreditAchievedPerInput?.stateValues.creditAchievedPerInput ?? (dependencyValues.answerColoringState?.stateValues?.colorInputsSeparately ? dependencyValues.answerColoringState.stateValues.creditAchievedPerInput : void 0);
127499
127628
  if (comp.stateValues.colorInputsSeparately && creditAchievedPerInput) {
127500
127629
  const key = `${componentIdx}/${variableForImplicitProp}`;
@@ -133101,6 +133230,9 @@ class Document extends BaseComponent {
133101
133230
  return { setValue: { creditAchieved, percentCreditAchieved } };
133102
133231
  }
133103
133232
  };
133233
+ stateVariableDefinitions.creditAchievedForCheckWork = returnCheckWorkCreditStateVariableDefinition({
133234
+ alwaysAggregate: true
133235
+ });
133104
133236
  stateVariableDefinitions.creditAchievedIfSubmit = {
133105
133237
  defaultValue: 0,
133106
133238
  stateVariablesDeterminingDependencies: ["scoredDescendants"],
@@ -244029,6 +244161,17 @@ const correctAttributeCapitalization = () => {
244029
244161
  });
244030
244162
  };
244031
244163
  };
244164
+ const LEGACY_V06_ELEMENT_NAMES = [
244165
+ "copy",
244166
+ "map",
244167
+ "template",
244168
+ "sources",
244169
+ "extract",
244170
+ "customAttribute",
244171
+ "constraints",
244172
+ "styleDefinitions",
244173
+ "feedbackDefinitions"
244174
+ ];
244032
244175
  const correctElementCapitalization = () => {
244033
244176
  const componentInfoObjects2 = createComponentInfoObjects();
244034
244177
  const correctCapitalization = Object.keys(
@@ -244037,6 +244180,9 @@ const correctElementCapitalization = () => {
244037
244180
  const correctCapitalizationMap = Object.fromEntries(
244038
244181
  correctCapitalization.map((name2) => [name2.toLowerCase(), name2])
244039
244182
  );
244183
+ for (const name2 of LEGACY_V06_ELEMENT_NAMES) {
244184
+ correctCapitalizationMap[name2.toLowerCase()] ??= name2;
244185
+ }
244040
244186
  return (tree) => {
244041
244187
  visit(tree, (node) => {
244042
244188
  if (!isDastElement(node)) {
@@ -244097,34 +244243,6 @@ function renameAttrInPlace(elm, oldName, newName) {
244097
244243
  );
244098
244244
  elm.attributes = newAttrs;
244099
244245
  }
244100
- function getUniqueName(tree, baseName) {
244101
- const allNames = /* @__PURE__ */ new Set();
244102
- visit(tree, (node) => {
244103
- if (!isDastElement(node)) {
244104
- return;
244105
- }
244106
- if (node.attributes["name"]) {
244107
- allNames.add(toXml(node.attributes["name"].children).trim());
244108
- }
244109
- if (node.attributes["assignNames"]) {
244110
- const assignNames = toXml(
244111
- node.attributes["assignNames"].children
244112
- ).trim();
244113
- if (assignNames) {
244114
- for (const name22 of assignNames.split(/\s+/)) {
244115
- allNames.add(name22);
244116
- }
244117
- }
244118
- }
244119
- });
244120
- let name2 = baseName;
244121
- let i2 = 1;
244122
- while (allNames.has(name2)) {
244123
- name2 = `${baseName}${i2}`;
244124
- i2++;
244125
- }
244126
- return name2;
244127
- }
244128
244246
  const componentInfoObjects = createComponentInfoObjects();
244129
244247
  function determinePropType(componentType, propName, nIndices = 0) {
244130
244248
  const publicStateVariableInfo = componentInfoObjects.publicStateVariableInfo[componentType];
@@ -244207,10 +244325,889 @@ function componentTypeFromWrapping(wrappingComponents, nDimensions, nIndices) {
244207
244325
  }
244208
244326
  return { foundComponentType: false };
244209
244327
  }
244210
- const upgradeCollectElement = () => {
244328
+ function isModuleComponentType(componentType) {
244329
+ return componentInfoObjects.isInheritedComponentType({
244330
+ inheritedComponentType: componentType,
244331
+ baseComponentType: "module"
244332
+ });
244333
+ }
244334
+ function breakStringInPiecesBySpacesOrParens(string) {
244335
+ if (typeof string !== "string") {
244336
+ return { success: false };
244337
+ }
244338
+ let numParens = 0;
244339
+ const pieces = [];
244340
+ string = string.trim();
244341
+ let beginInd = 0;
244342
+ for (let ind = 0; ind < string.length; ind++) {
244343
+ const char = string[ind];
244344
+ if (char === "(") {
244345
+ if (numParens === 0) {
244346
+ const newPiece2 = string.substring(beginInd, ind).trim();
244347
+ if (newPiece2.length > 0) {
244348
+ pieces.push(newPiece2);
244349
+ }
244350
+ beginInd = ind;
244351
+ }
244352
+ numParens++;
244353
+ } else if (char === ")") {
244354
+ if (numParens === 0) {
244355
+ return { success: false };
244356
+ }
244357
+ if (numParens === 1) {
244358
+ const newPiece2 = string.substring(beginInd + 1, ind).trim();
244359
+ if (newPiece2.length > 0) {
244360
+ const result2 = breakStringInPiecesBySpacesOrParens(newPiece2);
244361
+ if (result2.success === true) {
244362
+ pieces.push(result2.pieces);
244363
+ } else {
244364
+ pieces.push(newPiece2);
244365
+ }
244366
+ }
244367
+ beginInd = ind + 1;
244368
+ }
244369
+ numParens--;
244370
+ } else if (numParens === 0 && char.match(/\s/)) {
244371
+ const newPiece2 = string.substring(beginInd, ind).trim();
244372
+ if (newPiece2.length > 0) {
244373
+ pieces.push(newPiece2);
244374
+ }
244375
+ beginInd = ind;
244376
+ }
244377
+ }
244378
+ if (numParens !== 0) {
244379
+ return { success: false };
244380
+ }
244381
+ const newPiece = string.substring(beginInd, string.length).trim();
244382
+ if (newPiece.length > 0) {
244383
+ pieces.push(newPiece);
244384
+ }
244385
+ return { success: true, pieces };
244386
+ }
244387
+ function firstLeafName(pieces) {
244388
+ for (const piece of pieces) {
244389
+ if (typeof piece === "string") {
244390
+ return piece;
244391
+ }
244392
+ const nested = firstLeafName(piece);
244393
+ if (nested !== void 0) {
244394
+ return nested;
244395
+ }
244396
+ }
244397
+ return void 0;
244398
+ }
244399
+ const VALID_REFERENCEABLE_NAME = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
244400
+ function isValidReferenceableName(name2) {
244401
+ return VALID_REFERENCEABLE_NAME.test(name2);
244402
+ }
244403
+ function makeIndexedPathPart(name2, indices) {
244404
+ return {
244405
+ type: "pathPart",
244406
+ name: name2,
244407
+ index: indices.map((i2) => ({
244408
+ type: "index",
244409
+ value: [{ type: "text", value: `${i2}` }]
244410
+ }))
244411
+ };
244412
+ }
244413
+ class RenameRegistry {
244414
+ constructor(existingNames = /* @__PURE__ */ new Set()) {
244415
+ this._renames = /* @__PURE__ */ new Map();
244416
+ this._matched = /* @__PURE__ */ new Set();
244417
+ this._existingNames = existingNames;
244418
+ }
244419
+ /**
244420
+ * Register that `oldName` should be replaced by `replacement` wherever it appears in
244421
+ * a macro path. The first registration of a name wins; a later one warns.
244422
+ *
244423
+ * Pass `undefined` for `replacement` to claim the name without rewriting anything,
244424
+ * which is what a composite that simply took the assigned name as its own `name`
244425
+ * needs: references already resolve, but a later composite assigning the same name
244426
+ * must not silently redirect them.
244427
+ */
244428
+ register(oldName, replacement, origin, file) {
244429
+ if (!oldName) {
244430
+ return;
244431
+ }
244432
+ const existing = this._renames.get(oldName) ?? [];
244433
+ const scope = origin.ancestorNames ?? [];
244434
+ const sameScope = existing.find(
244435
+ (target) => sameScopeAs(target.origin.ancestorNames ?? [], scope)
244436
+ );
244437
+ if (sameScope) {
244438
+ file.message(
244439
+ `The name "${oldName}" is assigned by both <${sameScope.origin.elementName}> and <${origin.elementName}> in the same place; references to it were converted as if they referred to the first.`,
244440
+ {
244441
+ place: origin.position,
244442
+ ruleId: "assign-names/duplicate-name",
244443
+ source: "v06-to-v07"
244444
+ }
244445
+ );
244446
+ return;
244447
+ }
244448
+ if (existing.length === 0 && this._existingNames.has(oldName)) {
244449
+ file.message(
244450
+ `The name "${oldName}" assigned by <${origin.elementName}> is also used as the "name" of another component; all references to "${oldName}" were converted to point at the <${origin.elementName}> replacement.`,
244451
+ {
244452
+ place: origin.position,
244453
+ ruleId: "assign-names/shadows-existing-name",
244454
+ source: "v06-to-v07"
244455
+ }
244456
+ );
244457
+ }
244458
+ existing.push({ replacement, origin });
244459
+ this._renames.set(oldName, existing);
244460
+ }
244461
+ /**
244462
+ * The rename for `name`, chosen by which of them the reference is reaching into.
244463
+ *
244464
+ * `precedingNames` are the path parts written before it, so `$g2.a` looks up `a` with
244465
+ * `["g2"]`. The registration whose enclosing names are the longest match at the end of
244466
+ * that wins; one recorded with no enclosing names matches anything, which is what
244467
+ * keeps an unscoped document behaving exactly as before.
244468
+ */
244469
+ get(name2, precedingNames = [], writtenOn) {
244470
+ const targets = this._renames.get(name2);
244471
+ if (!targets || targets.length === 0) {
244472
+ return void 0;
244473
+ }
244474
+ let best;
244475
+ let bestScore = -1;
244476
+ for (const target of targets) {
244477
+ if (writtenOn && target.origin.element === writtenOn) {
244478
+ continue;
244479
+ }
244480
+ const scope = target.origin.ancestorNames ?? [];
244481
+ if (!isSuffixOf(scope, precedingNames)) {
244482
+ continue;
244483
+ }
244484
+ if (scope.length > bestScore) {
244485
+ best = target;
244486
+ bestScore = scope.length;
244487
+ }
244488
+ }
244489
+ if (best) {
244490
+ this._matched.add(name2);
244491
+ }
244492
+ return best;
244493
+ }
244494
+ /** Whether `name` is registered *and* some registration rewrites references to it. */
244495
+ hasReplacement(name2) {
244496
+ return (this._renames.get(name2) ?? []).some(
244497
+ (target) => target.replacement !== void 0
244498
+ );
244499
+ }
244500
+ get size() {
244501
+ return this._renames.size;
244502
+ }
244503
+ /** Registered names that were never referenced anywhere in the document. */
244504
+ unused() {
244505
+ return [...this._renames.keys()].filter((n2) => !this._matched.has(n2));
244506
+ }
244507
+ }
244508
+ function sameScopeAs(a2, b2) {
244509
+ return a2.length === b2.length && a2.every((name2, i2) => name2 === b2[i2]);
244510
+ }
244511
+ function isSuffixOf(scope, path) {
244512
+ if (scope.length > path.length) {
244513
+ return false;
244514
+ }
244515
+ const offset = path.length - scope.length;
244516
+ return scope.every((name2, i2) => name2 === path[offset + i2]);
244517
+ }
244518
+ function collectExistingNames(tree) {
244519
+ const names = /* @__PURE__ */ new Set();
244520
+ visit(tree, (node) => {
244521
+ if (!isDastElement(node)) {
244522
+ return;
244523
+ }
244524
+ const nameAttr = Object.entries(node.attributes).find(
244525
+ ([name2]) => name2.toLowerCase() === "name"
244526
+ )?.[1];
244527
+ if (nameAttr) {
244528
+ const name2 = toXml(nameAttr.children).trim();
244529
+ if (name2) {
244530
+ names.add(name2);
244531
+ }
244532
+ }
244533
+ });
244534
+ return names;
244535
+ }
244536
+ function collectAllNames(tree) {
244537
+ const names = collectExistingNames(tree);
244538
+ visit(tree, (node) => {
244539
+ if (!isDastElement(node)) {
244540
+ return;
244541
+ }
244542
+ const assignNamesAttr = Object.entries(node.attributes).find(
244543
+ ([name2]) => name2.toLowerCase() === "assignnames"
244544
+ )?.[1];
244545
+ if (!assignNamesAttr) {
244546
+ return;
244547
+ }
244548
+ const assignNames = toXml(assignNamesAttr.children).trim();
244549
+ for (const name2 of assignNames.split(/[\s()]+/)) {
244550
+ if (name2) {
244551
+ names.add(name2);
244552
+ }
244553
+ }
244554
+ });
244555
+ return names;
244556
+ }
244557
+ function createUniqueNameFactory(tree) {
244558
+ const used = collectAllNames(tree);
244559
+ return (baseName) => {
244560
+ let name2 = baseName;
244561
+ let i2 = 1;
244562
+ while (used.has(name2)) {
244563
+ name2 = `${baseName}${i2}`;
244564
+ i2++;
244565
+ }
244566
+ used.add(name2);
244567
+ return name2;
244568
+ };
244569
+ }
244570
+ function isV06True(attr) {
244571
+ if (!attr) {
244572
+ return false;
244573
+ }
244574
+ const value = toXml(attr.children).trim().toLowerCase();
244575
+ return value === "" || value === "true";
244576
+ }
244577
+ const COMPOSITES = {
244578
+ select: {
244579
+ name: "select",
244580
+ count: { kind: "attr", attr: "numToSelect" },
244581
+ grouping: { childName: "option" }
244582
+ },
244583
+ selectfromsequence: {
244584
+ name: "selectFromSequence",
244585
+ count: { kind: "attr", attr: "numToSelect" }
244586
+ },
244587
+ selectrandomnumbers: {
244588
+ name: "selectRandomNumbers",
244589
+ count: { kind: "attr", attr: "numToSelect" }
244590
+ },
244591
+ samplerandomnumbers: {
244592
+ name: "sampleRandomNumbers",
244593
+ count: { kind: "attr", attr: "numSamples" }
244594
+ },
244595
+ selectprimenumbers: {
244596
+ name: "selectPrimeNumbers",
244597
+ count: { kind: "attr", attr: "numToSelect" }
244598
+ },
244599
+ sampleprimenumbers: {
244600
+ name: "samplePrimeNumbers",
244601
+ count: { kind: "attr", attr: "numSamples" }
244602
+ },
244603
+ conditionalcontent: {
244604
+ name: "conditionalContent",
244605
+ count: { kind: "always-one" },
244606
+ grouping: { childName: "case", alsoMatch: ["else"] }
244607
+ },
244608
+ lorem: { name: "lorem", count: { kind: "unknown" } },
244609
+ sort: { name: "sort", count: { kind: "unknown" } },
244610
+ shuffle: { name: "shuffle", count: { kind: "unknown" } },
244611
+ group: { name: "group", count: { kind: "unknown" } },
244612
+ sequence: { name: "sequence", count: { kind: "unknown" } },
244613
+ substitute: { name: "substitute", count: { kind: "unknown" } },
244614
+ split: { name: "split", count: { kind: "unknown" } },
244615
+ intersection: { name: "intersection", count: { kind: "unknown" } },
244616
+ extract: {
244617
+ name: "extract",
244618
+ count: { kind: "unknown" },
244619
+ noV07Equivalent: true
244620
+ }
244621
+ };
244622
+ function lookupComposite(node) {
244623
+ return COMPOSITES[node.name.toLowerCase()];
244624
+ }
244625
+ function producesSingleReplacement(node, spec) {
244626
+ if (spec.count.kind === "always-one") {
244627
+ return true;
244628
+ }
244629
+ if (spec.count.kind === "unknown") {
244630
+ return false;
244631
+ }
244632
+ const attr = findAttribute(node, spec.count.attr);
244633
+ if (!attr) {
244634
+ return true;
244635
+ }
244636
+ const raw = toXml(attr.children).trim();
244637
+ return raw === "" || raw === "1";
244638
+ }
244639
+ function findAttribute(node, attrName) {
244640
+ return Object.entries(node.attributes).find(
244641
+ ([name2]) => name2.toLowerCase() === attrName.toLowerCase()
244642
+ )?.[1];
244643
+ }
244644
+ function makePositionMap(node, spec, file) {
244645
+ if (!spec.grouping) {
244646
+ return void 0;
244647
+ }
244648
+ const names = [
244649
+ spec.grouping.childName,
244650
+ ...spec.grouping.alsoMatch || []
244651
+ ].map((n2) => n2.toLowerCase());
244652
+ const branches = node.children.filter(
244653
+ (child) => isDastElement(child) && names.includes(child.name.toLowerCase())
244654
+ );
244655
+ if (branches.length === 0) {
244656
+ return void 0;
244657
+ }
244658
+ return positionMapForBranches(
244659
+ branches.map((branch) => branch.children),
244660
+ node,
244661
+ file
244662
+ );
244663
+ }
244664
+ function makeTemplatePositionMap(template2, node, file) {
244665
+ return positionMapForBranches([template2.children], node, file);
244666
+ }
244667
+ function positionMapForBranches(branches, node, file) {
244668
+ const maps = branches.map((children) => branchPositionMap(children));
244669
+ const first2 = maps[0];
244670
+ if (maps.every((m2) => isIdentity(m2))) {
244671
+ return void 0;
244672
+ }
244673
+ if (!maps.every((m2) => sameMap(m2, first2))) {
244674
+ file.message(
244675
+ `The branches of <${node.name}> mix plain text with components differently, so the positions that assignNames referred to cannot be determined; the first branch was used.`,
244676
+ {
244677
+ place: node.position,
244678
+ ruleId: "assign-names/branch-index-skew",
244679
+ source: "v06-to-v07"
244680
+ }
244681
+ );
244682
+ }
244683
+ file.message(
244684
+ `<${node.name}> has a branch that mixes plain text with components. v0.6 skipped the text when assigning names but v0.7 counts it, so the converted indices are a best guess and should be checked.`,
244685
+ {
244686
+ place: node.position,
244687
+ ruleId: "assign-names/primitive-skew",
244688
+ source: "v06-to-v07"
244689
+ }
244690
+ );
244691
+ const insideGroupingDepth = 2;
244692
+ return (depth, ordinal) => {
244693
+ if (depth !== insideGroupingDepth) {
244694
+ return ordinal;
244695
+ }
244696
+ return first2[ordinal - 1];
244697
+ };
244698
+ }
244699
+ function branchPositionMap(children) {
244700
+ const result2 = [];
244701
+ let position2 = 0;
244702
+ for (const child of children) {
244703
+ if (child.type === "text") {
244704
+ if (child.value.trim() === "") {
244705
+ continue;
244706
+ }
244707
+ position2++;
244708
+ continue;
244709
+ }
244710
+ if (child.type === "comment" || child.type === "instruction") {
244711
+ continue;
244712
+ }
244713
+ position2++;
244714
+ result2.push(position2);
244715
+ }
244716
+ return result2;
244717
+ }
244718
+ function isIdentity(map2) {
244719
+ return map2.every((v2, i2) => v2 === i2 + 1);
244720
+ }
244721
+ function sameMap(a2, b2) {
244722
+ return a2.length === b2.length && a2.every((v2, i2) => v2 === b2[i2]);
244723
+ }
244724
+ function createAssignNamesContext(tree) {
244725
+ const existingNames = collectExistingNames(tree);
244726
+ const namespaceElements = /* @__PURE__ */ new WeakMap();
244727
+ let unnamedCount = 0;
244728
+ visit(tree, (node) => {
244729
+ if (!isDastElement(node)) {
244730
+ return;
244731
+ }
244732
+ const newNamespaceKey = Object.keys(node.attributes).find(
244733
+ (key) => key.toLowerCase() === "newnamespace"
244734
+ );
244735
+ if (newNamespaceKey === void 0) {
244736
+ return;
244737
+ }
244738
+ const newNamespaceValue = toXml(
244739
+ node.attributes[newNamespaceKey].children
244740
+ ).trim().toLowerCase();
244741
+ if (newNamespaceValue !== "" && newNamespaceValue !== "true") {
244742
+ return;
244743
+ }
244744
+ const nameAttr = findAttribute(node, "name");
244745
+ const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
244746
+ namespaceElements.set(node, name2 || `\0ns${++unnamedCount}`);
244747
+ });
244748
+ const context = {
244749
+ registry: new RenameRegistry(existingNames),
244750
+ uniqueName: createUniqueNameFactory(tree),
244751
+ existingNames,
244752
+ claimedNames: /* @__PURE__ */ new Set(),
244753
+ namespaceElements,
244754
+ existingNameScopes: /* @__PURE__ */ new Map()
244755
+ };
244756
+ visit(tree, (node, info) => {
244757
+ if (!isDastElement(node)) {
244758
+ return;
244759
+ }
244760
+ const nameAttr = findAttribute(node, "name");
244761
+ const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
244762
+ if (!name2) {
244763
+ return;
244764
+ }
244765
+ const scopes = context.existingNameScopes.get(name2) ?? [];
244766
+ scopes.push(namespaceChainOf(info.parents, context));
244767
+ context.existingNameScopes.set(name2, scopes);
244768
+ });
244769
+ return context;
244770
+ }
244771
+ function nameTakenInScope(context, name2, ancestorNames) {
244772
+ const scopes = context.existingNameScopes.get(name2);
244773
+ if (!scopes) {
244774
+ return false;
244775
+ }
244776
+ const here = ancestorNames ?? [];
244777
+ return scopes.some(
244778
+ (scope) => scope.length === here.length && scope.every((segment, i2) => segment === here[i2])
244779
+ );
244780
+ }
244781
+ function chooseCompositeName(node, pieces, fallbackBase, context, file) {
244782
+ const nameAttr = findAttribute(node, "name");
244783
+ const existingName = nameAttr ? toXml(nameAttr.children).trim() : "";
244784
+ if (existingName && isValidReferenceableName(existingName)) {
244785
+ return existingName;
244786
+ }
244787
+ if (existingName) {
244788
+ file?.message(
244789
+ `<${node.name}> is called "${existingName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A different name was used instead.`,
244790
+ {
244791
+ place: node.position,
244792
+ ruleId: "assign-names/invalid-name",
244793
+ source: "v06-to-v07"
244794
+ }
244795
+ );
244796
+ }
244797
+ const firstName = firstLeafName(pieces);
244798
+ if (firstName && isValidReferenceableName(firstName) && !context.existingNames.has(firstName) && !context.claimedNames.has(firstName)) {
244799
+ context.claimedNames.add(firstName);
244800
+ return firstName;
244801
+ }
244802
+ return context.uniqueName(fallbackBase);
244803
+ }
244804
+ function setCompositeName(node, name2) {
244805
+ const nameAttr = findAttribute(node, "name");
244806
+ const oldKey = assignNamesKey(node);
244807
+ if (nameAttr) {
244808
+ if (toXml(nameAttr.children) !== name2) {
244809
+ nameAttr.children = [{ type: "text", value: name2 }];
244810
+ }
244811
+ deleteAssignNames(node);
244812
+ return;
244813
+ }
244814
+ if (oldKey !== void 0) {
244815
+ renameAttrInPlace(node, oldKey, "name");
244816
+ node.attributes["name"].children = [{ type: "text", value: name2 }];
244817
+ return;
244818
+ }
244819
+ node.attributes["name"] = {
244820
+ type: "attribute",
244821
+ name: "name",
244822
+ children: [{ type: "text", value: name2 }]
244823
+ };
244824
+ }
244825
+ function readAssignNames(node) {
244826
+ const key = assignNamesKey(node);
244827
+ if (key === void 0) {
244828
+ return void 0;
244829
+ }
244830
+ return toXml(node.attributes[key].children).trim();
244831
+ }
244832
+ function deleteAssignNames(node) {
244833
+ const key = assignNamesKey(node);
244834
+ if (key !== void 0) {
244835
+ delete node.attributes[key];
244836
+ }
244837
+ }
244838
+ function assignNamesKey(node) {
244839
+ return Object.keys(node.attributes).find(
244840
+ (k2) => k2.toLowerCase() === "assignnames"
244841
+ );
244842
+ }
244843
+ function namespaceChainOf(parents, context) {
244844
+ const chain2 = [];
244845
+ for (const parent of parents) {
244846
+ const segment = context.namespaceElements.get(parent);
244847
+ if (segment !== void 0) {
244848
+ chain2.push(segment);
244849
+ }
244850
+ }
244851
+ return chain2.reverse();
244852
+ }
244853
+ function inheritNamespace(from, to2, context) {
244854
+ const segment = context.namespaceElements.get(from);
244855
+ if (segment !== void 0) {
244856
+ context.namespaceElements.set(to2, segment);
244857
+ }
244858
+ }
244859
+ const identityPositionMap = (_depth, ordinal) => ordinal;
244860
+ function registerAssignNames({
244861
+ assignNamesValue,
244862
+ compositeName,
244863
+ registry,
244864
+ origin,
244865
+ file,
244866
+ positionMap = identityPositionMap
244867
+ }) {
244868
+ const result2 = breakStringInPiecesBySpacesOrParens(assignNamesValue);
244869
+ if (!result2.success) {
244870
+ file.message(
244871
+ `Could not parse assignNames="${assignNamesValue}" on <${origin.elementName}> because its parentheses are unbalanced; references to those names were not converted.`,
244872
+ {
244873
+ place: origin.position,
244874
+ ruleId: "assign-names/unbalanced-parens",
244875
+ source: "v06-to-v07"
244876
+ }
244877
+ );
244878
+ return false;
244879
+ }
244880
+ registerPieces(result2.pieces, []);
244881
+ return true;
244882
+ function registerPieces(pieces, indexPath) {
244883
+ pieces.forEach((piece, i2) => {
244884
+ const depth = indexPath.length + 1;
244885
+ const position2 = positionMap(depth, i2 + 1);
244886
+ if (position2 === void 0) {
244887
+ reportNamesNothing(piece);
244888
+ return;
244889
+ }
244890
+ const indices = [...indexPath, position2];
244891
+ if (typeof piece === "string") {
244892
+ if (!isValidReferenceableName(piece)) {
244893
+ file.message(
244894
+ `The assignNames token "${piece}" on <${origin.elementName}> is not a valid v0.7 name, so references to it were not converted.`,
244895
+ {
244896
+ place: origin.position,
244897
+ ruleId: "assign-names/invalid-name",
244898
+ source: "v06-to-v07"
244899
+ }
244900
+ );
244901
+ return;
244902
+ }
244903
+ registry.register(
244904
+ piece,
244905
+ [makeIndexedPathPart(compositeName, indices)],
244906
+ origin,
244907
+ file
244908
+ );
244909
+ } else {
244910
+ registerPieces(piece, indices);
244911
+ }
244912
+ });
244913
+ }
244914
+ function reportNamesNothing(piece) {
244915
+ if (typeof piece !== "string") {
244916
+ piece.forEach(reportNamesNothing);
244917
+ return;
244918
+ }
244919
+ file.message(
244920
+ `The assignNames token "${piece}" on <${origin.elementName}> named nothing in v0.6 — the position it was given holds no component — so references to it were not converted.`,
244921
+ {
244922
+ place: origin.position,
244923
+ ruleId: "assign-names/names-nothing",
244924
+ source: "v06-to-v07"
244925
+ }
244926
+ );
244927
+ }
244928
+ }
244929
+ function registerCompositeAssignNames({
244930
+ node,
244931
+ assignNamesValue,
244932
+ fallbackBase,
244933
+ ancestorNames,
244934
+ context,
244935
+ file,
244936
+ positionMap
244937
+ }) {
244938
+ const origin = {
244939
+ elementName: node.name,
244940
+ position: node.position,
244941
+ ancestorNames,
244942
+ element: node
244943
+ };
244944
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
244945
+ if (!parsed.success) {
244946
+ registerAssignNames({
244947
+ assignNamesValue,
244948
+ compositeName: "",
244949
+ registry: context.registry,
244950
+ origin,
244951
+ file
244952
+ });
244953
+ return void 0;
244954
+ }
244955
+ if (firstLeafName(parsed.pieces) === void 0) {
244956
+ return void 0;
244957
+ }
244958
+ const compositeName = chooseCompositeName(
244959
+ node,
244960
+ parsed.pieces,
244961
+ fallbackBase,
244962
+ context,
244963
+ file
244964
+ );
244965
+ registerAssignNames({
244966
+ assignNamesValue,
244967
+ compositeName,
244968
+ registry: context.registry,
244969
+ origin,
244970
+ file,
244971
+ positionMap
244972
+ });
244973
+ return compositeName;
244974
+ }
244975
+ function visitAll(tree, visitor) {
244976
+ walk(tree, [], void 0);
244977
+ function walk(node, parents, attributeOwner) {
244978
+ const isMacro = node.type === "macro" || node.type === "function";
244979
+ if (!isMacro) {
244980
+ visitor(node, parents, attributeOwner);
244981
+ }
244982
+ const innerParents = isDastElement(node) ? [node, ...parents] : parents;
244983
+ if (isDastElement(node)) {
244984
+ for (const attr of Object.values(node.attributes)) {
244985
+ walkArray(attr.children, innerParents, node);
244986
+ }
244987
+ }
244988
+ if (node.type === "macro") {
244989
+ walkMacroAttributes(node, innerParents, attributeOwner);
244990
+ walkMacroPath(node, innerParents, attributeOwner);
244991
+ const accessedProp = node.accessedProp;
244992
+ if (accessedProp) {
244993
+ walk(accessedProp, innerParents, attributeOwner);
244994
+ }
244995
+ }
244996
+ if (node.type === "function") {
244997
+ const inner = node.macro;
244998
+ if (inner) {
244999
+ walk(inner, innerParents, attributeOwner);
245000
+ }
245001
+ walkMacroPath(node, innerParents, attributeOwner);
245002
+ for (const inputPart of node.input || []) {
245003
+ walkArray(
245004
+ inputPart,
245005
+ innerParents,
245006
+ attributeOwner
245007
+ );
245008
+ }
245009
+ }
245010
+ if ("children" in node && Array.isArray(node.children)) {
245011
+ walkArray(
245012
+ node.children,
245013
+ innerParents,
245014
+ isDastElement(node) ? void 0 : attributeOwner
245015
+ );
245016
+ }
245017
+ if (isMacro) {
245018
+ visitor(node, parents, attributeOwner);
245019
+ }
245020
+ }
245021
+ function walkMacroAttributes(node, parents, attributeOwner) {
245022
+ const attrs = Array.isArray(node.attributes) ? node.attributes : Object.values(node.attributes);
245023
+ for (const attr of attrs) {
245024
+ walkArray(attr.children, parents, attributeOwner);
245025
+ }
245026
+ }
245027
+ function walkMacroPath(node, parents, attributeOwner) {
245028
+ for (const part of node.path || []) {
245029
+ for (const index2 of part.index) {
245030
+ walkArray(index2.value, parents, attributeOwner);
245031
+ }
245032
+ }
245033
+ }
245034
+ function walkArray(nodes, parents, attributeOwner) {
245035
+ for (let i2 = 0; i2 < nodes.length; i2++) {
245036
+ walk(nodes[i2], parents, attributeOwner);
245037
+ }
245038
+ }
245039
+ }
245040
+ function visitAllMacros(tree, visitor) {
245041
+ visitAll(tree, (node, parents, attributeOwner) => {
245042
+ if (node.type !== "macro" && node.type !== "function") {
245043
+ return;
245044
+ }
245045
+ if (!Array.isArray(node.path)) {
245046
+ return;
245047
+ }
245048
+ visitor(node, parents, attributeOwner);
245049
+ });
245050
+ }
245051
+ const propAccessParts = /* @__PURE__ */ new WeakSet();
245052
+ function markAsPropAccess(part) {
245053
+ propAccessParts.add(part);
245054
+ }
245055
+ function isPropAccess(part) {
245056
+ return propAccessParts.has(part);
245057
+ }
245058
+ const rawPropPositions = /* @__PURE__ */ new WeakMap();
245059
+ function markRawPropPositions(node, attrName, positions) {
245060
+ let byAttr = rawPropPositions.get(node);
245061
+ if (!byAttr) {
245062
+ byAttr = /* @__PURE__ */ new Map();
245063
+ rawPropPositions.set(node, byAttr);
245064
+ }
245065
+ byAttr.set(attrName.toLowerCase(), positions);
245066
+ }
245067
+ function restoreRawPropPositions(node, attrName, path) {
245068
+ const positions = rawPropPositions.get(node)?.get(attrName.toLowerCase());
245069
+ if (!positions) {
245070
+ return;
245071
+ }
245072
+ for (const position2 of positions) {
245073
+ const part = path[position2];
245074
+ if (part) {
245075
+ markAsPropAccess(part);
245076
+ }
245077
+ }
245078
+ }
245079
+ const RAW_REFERENCE_ATTRS = {
245080
+ copy: ["source"],
245081
+ extract: ["source"]
245082
+ };
245083
+ function applyRefRenames(tree, registry, file, context) {
245084
+ if (registry.size === 0) {
245085
+ return;
245086
+ }
245087
+ visitAllMacros(tree, (node, parents, attributeOwner) => {
245088
+ node.path = renamePath(
245089
+ node.path,
245090
+ registry,
245091
+ file,
245092
+ node.position,
245093
+ namespaceChainOf(parents, context),
245094
+ // A reference written on an element cannot mean the name that element is
245095
+ // about to take: `<copy source="$x0" assignNames="x0">` reaches elsewhere
245096
+ // for the thing it copies. References among its *children* are a different
245097
+ // matter and keep their ownership clear, so `visitAll` reports none for them.
245098
+ attributeOwner
245099
+ );
245100
+ });
245101
+ visitAll(tree, (node, parents) => {
245102
+ if (!isDastElement(node)) {
245103
+ return;
245104
+ }
245105
+ const attrNames = RAW_REFERENCE_ATTRS[node.name.toLowerCase()];
245106
+ if (!attrNames) {
245107
+ return;
245108
+ }
245109
+ const enclosing = namespaceChainOf(parents, context);
245110
+ for (const attrName of attrNames) {
245111
+ renameRawReferenceAttribute(
245112
+ node,
245113
+ attrName,
245114
+ registry,
245115
+ file,
245116
+ enclosing
245117
+ );
245118
+ }
245119
+ });
245120
+ }
245121
+ function renameRawReferenceAttribute(node, attrName, registry, file, enclosingNames) {
245122
+ const attr = Object.entries(node.attributes).find(
245123
+ ([name2]) => name2.toLowerCase() === attrName.toLowerCase()
245124
+ )?.[1];
245125
+ if (!attr || attr.children.length !== 1) {
245126
+ return;
245127
+ }
245128
+ const child = attr.children[0];
245129
+ if (child.type !== "text") {
245130
+ return;
245131
+ }
245132
+ const value = child.value.trim();
245133
+ if (!value) {
245134
+ return;
245135
+ }
245136
+ if (!value.split(/[^A-Za-z0-9_-]+/).some((piece) => registry.hasReplacement(piece))) {
245137
+ return;
245138
+ }
245139
+ let path;
245140
+ try {
245141
+ path = parseReferencePath(value);
245142
+ } catch (e4) {
245143
+ file.message(
245144
+ `Could not convert a reference to an assignNames name in ${attrName}="${value}".`,
245145
+ {
245146
+ place: node.position,
245147
+ ruleId: "assign-names/unparsable-reference-attribute",
245148
+ source: "v06-to-v07"
245149
+ }
245150
+ );
245151
+ return;
245152
+ }
245153
+ restoreRawPropPositions(node, attrName, path);
245154
+ const asMacro = { type: "macro", path, attributes: {} };
245155
+ visitAllMacros(asMacro, (macro) => {
245156
+ macro.path = renamePath(
245157
+ macro.path,
245158
+ registry,
245159
+ file,
245160
+ node.position,
245161
+ enclosingNames,
245162
+ // A copy's `source` says what it copies, which is never the copy itself:
245163
+ // `<copy source="../x0" assignNames="x0">` names its result `x0` while
245164
+ // reaching out of the namespace for the `x0` it copies.
245165
+ node
245166
+ );
245167
+ });
245168
+ child.value = toXml(asMacro.path);
245169
+ }
245170
+ function renamePath(path, registry, file, place, enclosingNames = [], writtenOn) {
245171
+ if (!path.some((part) => registry.hasReplacement(part.name))) {
245172
+ return path;
245173
+ }
245174
+ return path.flatMap((part, partIndex) => {
245175
+ const target = registry.get(
245176
+ part.name,
245177
+ [...enclosingNames, ...path.slice(0, partIndex).map((p2) => p2.name)],
245178
+ writtenOn
245179
+ );
245180
+ if (!target?.replacement) {
245181
+ return [part];
245182
+ }
245183
+ if (partIndex > 0 && isPropAccess(part)) {
245184
+ return [part];
245185
+ }
245186
+ const replacement = structuredClone(
245187
+ target.replacement
245188
+ );
245189
+ const last2 = replacement[replacement.length - 1];
245190
+ last2.index = [...last2.index, ...part.index];
245191
+ return replacement;
245192
+ });
245193
+ }
245194
+ function parseReferencePath(value) {
245195
+ for (const candidate of [`$${value}`, `$(${value})`]) {
245196
+ let reparsed;
245197
+ try {
245198
+ reparsed = reparseAttribute(candidate);
245199
+ } catch (e4) {
245200
+ continue;
245201
+ }
245202
+ if (reparsed.length === 1 && reparsed[0].type === "macro") {
245203
+ return reparsed[0].path;
245204
+ }
245205
+ }
245206
+ throw new Error(`Could not parse "${value}" as a reference`);
245207
+ }
245208
+ const upgradeCollectElement = (context) => {
244211
245209
  return (tree, file) => {
244212
- const refsToRename = {};
244213
- visit(tree, (node) => {
245210
+ visit(tree, (node, info) => {
244214
245211
  if (!isDastElement(node)) {
244215
245212
  return;
244216
245213
  }
@@ -244220,50 +245217,45 @@ const upgradeCollectElement = () => {
244220
245217
  if (node.attributes["componentTypes"]) {
244221
245218
  renameAttrInPlace(node, "componentTypes", "componentType");
244222
245219
  }
244223
- if (node.attributes["source"]) {
244224
- renameAttrInPlace(node, "source", "from");
244225
- const fromValue = toXml(node.attributes["from"].children);
244226
- if (!fromValue.startsWith("$")) {
244227
- node.attributes["from"].children = reparseAttribute(
244228
- `$${fromValue}`
244229
- );
244230
- }
244231
- } else if (node.attributes["target"]) {
244232
- renameAttrInPlace(node, "target", "from");
244233
- const fromValue = toXml(node.attributes["from"].children);
244234
- if (!fromValue.startsWith("$")) {
244235
- node.attributes["from"].children = reparseAttribute(
244236
- `$${fromValue}`
244237
- );
245220
+ for (const oldKey of ["source", "target"]) {
245221
+ if (!node.attributes[oldKey]) {
245222
+ continue;
244238
245223
  }
245224
+ renameAttrInPlace(node, oldKey, "from");
245225
+ makeFromAReference(node, file);
245226
+ break;
244239
245227
  }
244240
- const assignNames = node.attributes["assignNames"];
244241
- if (!assignNames) {
245228
+ const assignNamesValue = readAssignNames(node);
245229
+ if (!assignNamesValue) {
245230
+ deleteAssignNames(node);
244242
245231
  return;
244243
245232
  }
244244
- delete node.attributes["assignNames"];
244245
- const assignedNames = toXml(assignNames.children).split(/\s+/).filter((n2) => n2);
244246
- assignedNames.forEach((name2, index2) => {
244247
- const strRepr = `$${toXml(node.attributes["name"].children)}[${index2 + 1}]`;
244248
- const attr = reparseAttribute(strRepr)?.[0];
244249
- if (!attr || attr.type !== "macro") {
244250
- throw new Error(
244251
- `Expected attribute to be a single macro, got: ${JSON.stringify(attr)}`
244252
- );
244253
- }
244254
- refsToRename[name2] = attr.path;
245233
+ const compositeName = registerCompositeAssignNames({
245234
+ node,
245235
+ assignNamesValue,
245236
+ fallbackBase: "collect",
245237
+ ancestorNames: namespaceChainOf(info.parents, context),
245238
+ context,
245239
+ file
244255
245240
  });
245241
+ if (compositeName === void 0) {
245242
+ deleteAssignNames(node);
245243
+ return;
245244
+ }
245245
+ setCompositeName(node, compositeName);
244256
245246
  });
244257
245247
  replaceNode(tree, (node) => {
244258
245248
  if (!isDastElement(node) || node.name !== "collect") {
244259
245249
  return;
244260
245250
  }
244261
- const propAttr = node.attributes["prop"];
244262
- const propName = toXml(propAttr?.children).trim();
245251
+ const propKey = Object.keys(node.attributes).find(
245252
+ (key) => key.toLowerCase() === "prop"
245253
+ );
245254
+ const propName = propKey ? toXml(node.attributes[propKey].children).trim() : "";
244263
245255
  if (!propName) {
244264
245256
  return;
244265
245257
  }
244266
- delete node.attributes["prop"];
245258
+ delete node.attributes[propKey];
244267
245259
  const setup = {
244268
245260
  type: "element",
244269
245261
  name: "setup",
@@ -244273,8 +245265,9 @@ const upgradeCollectElement = () => {
244273
245265
  const componentType = toXml(
244274
245266
  node.attributes["componentType"]?.children
244275
245267
  ).trim();
244276
- const listName = node.attributes["name"] ? toXml(node.attributes["name"].children) : getUniqueName(tree, "list");
244277
- const collectName = getUniqueName(tree, `collect_${listName}`);
245268
+ const authoredListName = node.attributes["name"] ? toXml(node.attributes["name"].children).trim() : "";
245269
+ const listName = authoredListName && isValidReferenceableName(authoredListName) ? authoredListName : context.uniqueName("list");
245270
+ const collectName = context.uniqueName(`collect_${listName}`);
244278
245271
  node.attributes["name"] = {
244279
245272
  type: "attribute",
244280
245273
  name: "name",
@@ -244284,7 +245277,11 @@ const upgradeCollectElement = () => {
244284
245277
  if (!listType) {
244285
245278
  file.message(
244286
245279
  `Could not determine type for prop "${propName}" of component type "${componentType}". Using "math" as default.`,
244287
- { place: node.position }
245280
+ {
245281
+ place: node.position,
245282
+ ruleId: "collect/unknown-prop-type",
245283
+ source: "v06-to-v07"
245284
+ }
244288
245285
  );
244289
245286
  listType = "math";
244290
245287
  }
@@ -244302,30 +245299,81 @@ const upgradeCollectElement = () => {
244302
245299
  extend: {
244303
245300
  type: "attribute",
244304
245301
  name: "extend",
244305
- children: reparseAttribute(
244306
- `$${collectName}.${propName}`
244307
- )
245302
+ children: [
245303
+ {
245304
+ type: "macro",
245305
+ path: [
245306
+ ...parseReferencePath(collectName),
245307
+ ...propPathParts(propName, node, file)
245308
+ ],
245309
+ attributes: {}
245310
+ }
245311
+ ]
244308
245312
  }
244309
245313
  },
244310
245314
  children: []
244311
245315
  };
244312
245316
  return [setup, list];
244313
245317
  });
244314
- visit(tree, (node) => {
244315
- if (node.type !== "macro") {
244316
- return;
244317
- }
244318
- if (!node.path.some((part) => refsToRename[part.name])) {
244319
- return;
244320
- }
244321
- node.path = node.path.flatMap((part) => {
244322
- return refsToRename[part.name] || [part];
244323
- });
244324
- });
244325
245318
  };
244326
245319
  };
245320
+ function makeFromAReference(node, file) {
245321
+ const attr = node.attributes["from"];
245322
+ const value = toXml(attr.children).trim();
245323
+ if (!value || value.startsWith("$")) {
245324
+ return;
245325
+ }
245326
+ try {
245327
+ attr.children = [
245328
+ {
245329
+ type: "macro",
245330
+ path: parseReferencePath(value),
245331
+ attributes: {}
245332
+ }
245333
+ ];
245334
+ } catch {
245335
+ file.message(
245336
+ `Could not read "${value}" as the name of what <collect> collects from.`,
245337
+ {
245338
+ place: node.position,
245339
+ ruleId: "collect/unparsable-from",
245340
+ source: "v06-to-v07"
245341
+ }
245342
+ );
245343
+ }
245344
+ }
245345
+ function propPathParts(propName, node, file) {
245346
+ let parts;
245347
+ try {
245348
+ parts = parseReferencePath(propName);
245349
+ } catch {
245350
+ file.message(
245351
+ `<collect prop="${propName}"> could not be turned into a reference, so the generated list extends a path that needs fixing by hand.`,
245352
+ {
245353
+ place: node.position,
245354
+ ruleId: "collect/unparsable-prop",
245355
+ source: "v06-to-v07"
245356
+ }
245357
+ );
245358
+ return [{ type: "pathPart", name: propName, index: [] }];
245359
+ }
245360
+ parts.forEach(markAsPropAccess);
245361
+ return parts;
245362
+ }
244327
245363
  const upgradePathSlashesToDots = () => {
244328
245364
  return (tree, file) => {
245365
+ const warnParentPath = (original) => {
245366
+ file.message(
245367
+ `There is no equivalent to the $(../x) syntax; a best-guess was made when converting ${macroToString(
245368
+ original
245369
+ )}`,
245370
+ {
245371
+ place: original.position,
245372
+ ruleId: "no-v07-equivalent/parent-path",
245373
+ source: "v06-to-v07"
245374
+ }
245375
+ );
245376
+ };
244329
245377
  visit(
244330
245378
  tree,
244331
245379
  // @ts-ignore
@@ -244336,44 +245384,17 @@ const upgradePathSlashesToDots = () => {
244336
245384
  }
244337
245385
  if (isDastElement(node)) {
244338
245386
  for (const attr of Object.values(node.attributes)) {
244339
- for (const child of attr.children) {
244340
- if (isV06MacroOrFunctionMacro(child)) {
244341
- macros.push(child);
244342
- }
244343
- }
245387
+ collectV06Macros(attr.children, macros);
244344
245388
  }
244345
245389
  }
244346
245390
  for (const node2 of macros) {
244347
- const macro = node2.type === "macro" ? v06MacroToV07Macro(node2) : v06FunctionMacroToV07FunctionMacro(node2);
245391
+ const macro = node2.type === "macro" ? v06MacroToV07Macro(node2, warnParentPath) : v06FunctionMacroToV07FunctionMacro(
245392
+ node2,
245393
+ warnParentPath
245394
+ );
244348
245395
  Object.keys(node2).forEach((key) => {
244349
245396
  delete node2[key];
244350
245397
  });
244351
- if (macro.path.some((p2) => p2.name === "..")) {
244352
- const newPath = [];
244353
- let errorMessageWritten = false;
244354
- for (const part of macro.path) {
244355
- if (part.name === "..") {
244356
- if (newPath.length > 0) {
244357
- newPath.pop();
244358
- if (!errorMessageWritten) {
244359
- errorMessageWritten = true;
244360
- file.message(
244361
- `There is no equivalent to the $(../x) syntax; a best-guess was made when converting ${macroToString(
244362
- macro
244363
- )}`,
244364
- {
244365
- start: node2.position?.start,
244366
- end: node2.position?.end
244367
- }
244368
- );
244369
- }
244370
- }
244371
- continue;
244372
- }
244373
- newPath.push(part);
244374
- }
244375
- macro.path = newPath;
244376
- }
244377
245398
  Object.assign(node2, macro);
244378
245399
  }
244379
245400
  }
@@ -244382,24 +245403,54 @@ const upgradePathSlashesToDots = () => {
244382
245403
  if (!isDastElement(node)) {
244383
245404
  return;
244384
245405
  }
245406
+ if (!ELEMENTS_WITH_REFERENCE_SOURCE.has(node.name.toLowerCase())) {
245407
+ return;
245408
+ }
244385
245409
  const sourceAttr = node.attributes["source"];
244386
245410
  if (!sourceAttr) {
244387
245411
  return;
244388
245412
  }
244389
245413
  const sourceName = toXml(sourceAttr.children).trim();
244390
- if (!sourceName.includes("/")) {
245414
+ const hasSlash = sourceName.includes("/");
245415
+ if (!hasSlash && !sourceName.includes(".")) {
244391
245416
  return;
244392
245417
  }
244393
245418
  const reparsedSource = parseMacrosV06(`$(${sourceName})`);
244394
245419
  if (reparsedSource.length !== 1 || reparsedSource[0].type !== "macro") {
244395
- file.message(
244396
- `Could not reparse "source" attribute that contains a slash: "${sourceName}".`,
244397
- { place: node.position }
244398
- );
245420
+ if (hasSlash) {
245421
+ file.message(
245422
+ `Could not reparse "source" attribute that contains a slash: "${sourceName}".`,
245423
+ {
245424
+ place: node.position,
245425
+ ruleId: "copy/unparsable-source",
245426
+ source: "v06-to-v07"
245427
+ }
245428
+ );
245429
+ }
244399
245430
  return;
244400
245431
  }
244401
- const upgradedSource = v06MacroToV07Macro(reparsedSource[0]);
245432
+ const upgradedSource = v06MacroToV07Macro(
245433
+ reparsedSource[0],
245434
+ () => file.message(
245435
+ `There is no equivalent to the ../x syntax; a best-guess was made when converting source="${sourceName}"`,
245436
+ {
245437
+ place: node.position,
245438
+ ruleId: "no-v07-equivalent/parent-path",
245439
+ source: "v06-to-v07"
245440
+ }
245441
+ )
245442
+ );
245443
+ markRawPropPositions(
245444
+ node,
245445
+ "source",
245446
+ upgradedSource.path.flatMap(
245447
+ (part, index2) => isPropAccess(part) ? [index2] : []
245448
+ )
245449
+ );
244402
245450
  const newSourceName = toXml(upgradedSource.path);
245451
+ if (newSourceName === sourceName) {
245452
+ return;
245453
+ }
244403
245454
  sourceAttr.children = [
244404
245455
  {
244405
245456
  type: "text",
@@ -244410,12 +245461,44 @@ const upgradePathSlashesToDots = () => {
244410
245461
  });
244411
245462
  };
244412
245463
  };
244413
- function v06MacroToV07Macro(macro) {
244414
- const path = flattenedAccessedProps(macro);
245464
+ function collectV06Macros(nodes, macros) {
245465
+ for (const node of nodes) {
245466
+ if (isV06MacroOrFunctionMacro(node)) {
245467
+ macros.push(node);
245468
+ }
245469
+ }
245470
+ }
245471
+ const ELEMENTS_WITH_REFERENCE_SOURCE = /* @__PURE__ */ new Set(["copy", "collect", "extract"]);
245472
+ function collapseParentPathParts(path, warn) {
245473
+ if (!path.some((part) => part.name === "..")) {
245474
+ return path;
245475
+ }
245476
+ const newPath = [];
245477
+ let warned = false;
245478
+ for (const part of path) {
245479
+ if (part.name === "..") {
245480
+ if (newPath.length > 0) {
245481
+ newPath.pop();
245482
+ }
245483
+ if (!warned) {
245484
+ warned = true;
245485
+ warn();
245486
+ }
245487
+ continue;
245488
+ }
245489
+ newPath.push(part);
245490
+ }
245491
+ return newPath;
245492
+ }
245493
+ function v06MacroToV07Macro(macro, warn, reportAs = macro) {
245494
+ const path = collapseParentPathParts(
245495
+ flattenedAccessedProps(macro, warn),
245496
+ () => warn(reportAs)
245497
+ );
244415
245498
  const { accessedProp, version: version2, attributes, ...rest2 } = macro;
244416
245499
  return {
244417
245500
  ...rest2,
244418
- attributes: v06AttributeToV07Attribute(mergeAttributes(macro)),
245501
+ attributes: v06AttributeToV07Attribute(mergeAttributes(macro), warn),
244419
245502
  path
244420
245503
  };
244421
245504
  }
@@ -244433,35 +245516,56 @@ function mergeAttributes(macro) {
244433
245516
  }
244434
245517
  return ret;
244435
245518
  }
244436
- function v06FunctionMacroToV07FunctionMacro(funcMacro) {
244437
- const macro = v06MacroToV07Macro(funcMacro.macro);
245519
+ function v06FunctionMacroToV07FunctionMacro(funcMacro, warn) {
245520
+ const macro = v06MacroToV07Macro(funcMacro.macro, warn, funcMacro);
244438
245521
  return {
244439
245522
  type: "function",
244440
245523
  path: macro.path,
244441
- // This cast may be incorrect, but we will leave it to the other processors to upgrade the
244442
- // the syntax of function arguments.
244443
- input: funcMacro.input,
245524
+ input: convertArguments(funcMacro.input, warn),
244444
245525
  position: funcMacro.position
244445
245526
  };
244446
245527
  }
244447
- function v06IndexToV07Index(index2) {
245528
+ function convertArguments(input, warn) {
245529
+ if (!input) {
245530
+ return null;
245531
+ }
245532
+ return input.map(
245533
+ (argument) => argument.map((node) => {
245534
+ if (isV06MacroOrFunctionMacro(node)) {
245535
+ return node.type === "macro" ? v06MacroToV07Macro(node, warn) : v06FunctionMacroToV07FunctionMacro(node, warn);
245536
+ }
245537
+ return node;
245538
+ })
245539
+ );
245540
+ }
245541
+ function v06IndexToV07Index(index2, warn) {
244448
245542
  return index2.map((ind) => ({
244449
245543
  ...ind,
244450
- value: ind.value.map(
244451
- (v2) => v2.type === "macro" ? v06MacroToV07Macro(v2) : v2
244452
- )
245544
+ // @ts-ignore -- see the note on `value` below
245545
+ // The DAST types say an index holds only text and plain macros, but the v0.6
245546
+ // parser does put a function macro in one (`$list[$$(g/h)(2)]`), so both have
245547
+ // to be converted here — this is the only pass that reaches them.
245548
+ value: ind.value.map((v2) => {
245549
+ if (v2.type === "macro") {
245550
+ return v06MacroToV07Macro(v2, warn);
245551
+ }
245552
+ if (v2.type === "function") {
245553
+ return v06FunctionMacroToV07FunctionMacro(v2, warn);
245554
+ }
245555
+ return v2;
245556
+ })
244453
245557
  }));
244454
245558
  }
244455
- function v06AttributeToV07Attribute(attrs) {
245559
+ function v06AttributeToV07Attribute(attrs, warn) {
244456
245560
  const ret = {};
244457
245561
  attrs = Array.isArray(attrs) ? attrs : Object.values(attrs);
244458
245562
  for (const attr of attrs) {
244459
245563
  const children = attr.children.map((c2) => {
244460
245564
  if (c2.type === "macro") {
244461
- return v06MacroToV07Macro(c2);
245565
+ return v06MacroToV07Macro(c2, warn);
244462
245566
  }
244463
245567
  if (c2.type === "function") {
244464
- return v06FunctionMacroToV07FunctionMacro(c2);
245568
+ return v06FunctionMacroToV07FunctionMacro(c2, warn);
244465
245569
  }
244466
245570
  return c2;
244467
245571
  });
@@ -244472,15 +245576,17 @@ function v06AttributeToV07Attribute(attrs) {
244472
245576
  }
244473
245577
  return ret;
244474
245578
  }
244475
- function flattenedAccessedProps(macro) {
245579
+ function flattenedAccessedProps(macro, warn) {
244476
245580
  const path = macro.path.map((p2) => {
244477
245581
  return {
244478
245582
  ...p2,
244479
- index: v06IndexToV07Index(p2.index)
245583
+ index: v06IndexToV07Index(p2.index, warn)
244480
245584
  };
244481
245585
  });
244482
245586
  if (macro.accessedProp) {
244483
- return [...path, ...flattenedAccessedProps(macro.accessedProp)];
245587
+ const propParts = flattenedAccessedProps(macro.accessedProp, warn);
245588
+ propParts.forEach(markAsPropAccess);
245589
+ return [...path, ...propParts];
244484
245590
  }
244485
245591
  return path;
244486
245592
  }
@@ -245235,9 +246341,26 @@ async function createCoreForLookup({ dast }) {
245235
246341
  const wasmBuffer = (await import("./lib_doenetml_worker_bg-BJtDoC-f.js")).default;
245236
246342
  await __wbg_init({ module_or_path: wasmBuffer });
245237
246343
  const rustCore = PublicDoenetMLCore.new();
245238
- dast = normalizeDocumentDast(structuredClone(dast), true);
245239
- rustCore.set_source(dast, toXml(dast));
245240
- const normalizedRoot = rustCore.return_normalized_dast_root();
246344
+ let core2;
246345
+ async function releaseCores() {
246346
+ try {
246347
+ await core2?.terminate();
246348
+ } catch (e4) {
246349
+ }
246350
+ try {
246351
+ rustCore.free();
246352
+ } catch (e4) {
246353
+ }
246354
+ }
246355
+ let normalizedRoot;
246356
+ try {
246357
+ dast = normalizeDocumentDast(structuredClone(dast), true);
246358
+ rustCore.set_source(dast, toXml(dast));
246359
+ normalizedRoot = rustCore.return_normalized_dast_root();
246360
+ } catch (e4) {
246361
+ await releaseCores();
246362
+ throw e4;
246363
+ }
245241
246364
  function resolvePath(path, origin, skip_parent_search) {
245242
246365
  return rustCore.resolve_path(path, origin, skip_parent_search);
245243
246366
  }
@@ -245248,44 +246371,62 @@ async function createCoreForLookup({ dast }) {
245248
246371
  rustCore.delete_nodes_from_resolver(node_list);
245249
246372
  }
245250
246373
  const flags = { ...defaultFlags };
245251
- const core2 = new PublicDoenetMLCore$1();
245252
- core2.setSource(toXml(dast));
245253
- core2.setFlags(flags);
245254
- await core2.initializeWorker({
245255
- activityId: "",
245256
- docId: "1",
245257
- requestedVariantIndex: 1,
245258
- attemptNumber: 1,
245259
- normalizedRoot,
245260
- addNodesToResolver,
245261
- deleteNodesFromResolver,
245262
- resolvePath
245263
- });
245264
- const dastResult = await core2.createCoreGenerateDast(
245265
- {
245266
- coreId: "",
245267
- cid: "",
245268
- initializeCounters: {},
245269
- theme: "light"
245270
- },
245271
- () => null,
245272
- () => null,
245273
- () => null,
245274
- () => null,
245275
- () => null,
245276
- () => null,
245277
- async () => ({ allowView: true })
245278
- );
245279
- if (!dastResult.success) {
245280
- throw Error(dastResult.errMsg);
246374
+ try {
246375
+ core2 = new PublicDoenetMLCore$1();
246376
+ core2.setSource(toXml(dast));
246377
+ core2.setFlags(flags);
246378
+ await core2.initializeWorker({
246379
+ activityId: "",
246380
+ docId: "1",
246381
+ requestedVariantIndex: 1,
246382
+ attemptNumber: 1,
246383
+ normalizedRoot,
246384
+ addNodesToResolver,
246385
+ deleteNodesFromResolver,
246386
+ resolvePath
246387
+ });
246388
+ const dastResult = await core2.createCoreGenerateDast(
246389
+ {
246390
+ coreId: "",
246391
+ cid: "",
246392
+ initializeCounters: {},
246393
+ theme: "light"
246394
+ },
246395
+ () => null,
246396
+ () => null,
246397
+ () => null,
246398
+ () => null,
246399
+ () => null,
246400
+ () => null,
246401
+ async () => ({ allowView: true })
246402
+ );
246403
+ if (!dastResult.success) {
246404
+ throw Error(dastResult.errMsg);
246405
+ }
246406
+ } catch (e4) {
246407
+ await releaseCores();
246408
+ throw e4;
246409
+ }
246410
+ const readyCore = core2;
246411
+ if (!readyCore) {
246412
+ await releaseCores();
246413
+ throw Error("The DoenetML core was not initialized.");
245281
246414
  }
245282
246415
  function resolvePathToNodeIdx(name2, origin = 0) {
245283
246416
  if (name2.startsWith("$")) {
245284
246417
  name2 = name2.slice(1);
245285
246418
  }
245286
- return resolvePathImmediatelyToNodeIdx(name2, rustCore, core2, origin);
246419
+ return resolvePathImmediatelyToNodeIdx(
246420
+ name2,
246421
+ rustCore,
246422
+ readyCore,
246423
+ origin
246424
+ );
245287
246425
  }
245288
- return { core: core2, rustCore, resolvePathToNodeIdx };
246426
+ async function dispose() {
246427
+ await releaseCores();
246428
+ }
246429
+ return { core: readyCore, rustCore, resolvePathToNodeIdx, dispose };
245289
246430
  }
245290
246431
  const upgradeCopySyntax = () => {
245291
246432
  return async (tree, file) => {
@@ -245302,91 +246443,128 @@ const upgradeCopySyntax = () => {
245302
246443
  if (skip) {
245303
246444
  return;
245304
246445
  }
245305
- const core2 = await createCoreForLookup({ dast: tree });
245306
- let referenced = [];
245307
- visit(tree, (node) => {
245308
- if (!isDastElement(node) || node.name !== "copy") {
245309
- return;
245310
- }
245311
- let referentName = toXml(node.attributes["source"]?.children);
245312
- if (!referentName) {
245313
- return;
245314
- }
245315
- if (node.attributes["prop"]) {
245316
- const propName = toXml(node.attributes["prop"].children).trim();
245317
- if (propName) {
245318
- referentName += `.${propName}`;
245319
- }
245320
- delete node.attributes["prop"];
245321
- }
245322
- if (node.attributes["assignNames"]) {
245323
- if (node.attributes["name"]) {
245324
- file.message(
245325
- `The <copy> tag with source="${referentName}" has both "name" and "assignNames" attributes. "name" will be ignored.`,
245326
- node.position?.start
245327
- );
245328
- delete node.attributes["name"];
246446
+ let core2;
246447
+ try {
246448
+ core2 = await createCoreForLookup({ dast: tree });
246449
+ } catch (e4) {
246450
+ file.message(
246451
+ `Could not load the document to work out what the <copy> tags refer to, so they were left as they are: ${e4}`,
246452
+ {
246453
+ ruleId: "copy/could-not-load-document",
246454
+ source: "v06-to-v07"
245329
246455
  }
245330
- renameAttrInPlace(node, "assignNames", "name");
246456
+ );
246457
+ return;
246458
+ }
246459
+ try {
246460
+ await resolveCopyTags(core2, tree, file);
246461
+ } finally {
246462
+ await core2.dispose();
246463
+ }
246464
+ };
246465
+ };
246466
+ async function resolveCopyTags(core2, tree, file) {
246467
+ const referenced = [];
246468
+ visit(tree, (node) => {
246469
+ if (!isDastElement(node) || node.name !== "copy") {
246470
+ return;
246471
+ }
246472
+ if (Object.keys(node.attributes).some(
246473
+ (key) => key.toLowerCase() === "uri"
246474
+ )) {
246475
+ return;
246476
+ }
246477
+ let referentName = toXml(node.attributes["source"]?.children).trim();
246478
+ if (!referentName) {
246479
+ return;
246480
+ }
246481
+ const propKey = Object.keys(node.attributes).find(
246482
+ (key) => key.toLowerCase() === "prop"
246483
+ );
246484
+ if (propKey) {
246485
+ const propName = toXml(node.attributes[propKey].children).trim();
246486
+ if (propName) {
246487
+ referentName += `.${propName}`;
245331
246488
  }
245332
- referenced.push({
245333
- node,
245334
- referentType: findReferentType(core2, referentName),
245335
- referentName
245336
- });
245337
- });
245338
- for (let {
246489
+ }
246490
+ referenced.push({
245339
246491
  node,
245340
- referentType: referentPromise,
245341
- referentName
245342
- } of referenced) {
245343
- try {
245344
- const referentType = await referentPromise;
245345
- const targetTag = toXml(
245346
- node.attributes["link"]?.children || []
245347
- ).toLowerCase() === "false" ? "copy" : "extend";
245348
- if (node.attributes["link"]) {
245349
- delete node.attributes["link"];
245350
- }
245351
- renameAttrInPlace(node, "source", targetTag);
245352
- if (!referentName.startsWith("$")) {
245353
- referentName = `$${referentName}`;
245354
- }
245355
- node.attributes[targetTag].children = reparseAttribute(referentName);
245356
- node.name = referentType;
245357
- } catch (e4) {
245358
- file.message(
245359
- `Could not resolve referent type for <copy> tag with source="${referentName}": ${e4}`,
245360
- node.position?.start
245361
- );
245362
- continue;
246492
+ referentType: findReferentType(core2, referentName),
246493
+ referentName,
246494
+ propKey
246495
+ });
246496
+ });
246497
+ for (let {
246498
+ node,
246499
+ referentType: referentPromise,
246500
+ referentName,
246501
+ propKey
246502
+ } of referenced) {
246503
+ try {
246504
+ const referentType = await referentPromise;
246505
+ if (propKey) {
246506
+ delete node.attributes[propKey];
246507
+ }
246508
+ const linkKey = Object.keys(node.attributes).find(
246509
+ (key) => key.toLowerCase() === "link"
246510
+ );
246511
+ const targetTag = linkKey ? isV06True(node.attributes[linkKey]) ? "extend" : "copy" : isModuleComponentType(referentType) ? "copy" : "extend";
246512
+ if (linkKey) {
246513
+ delete node.attributes[linkKey];
245363
246514
  }
246515
+ renameAttrInPlace(node, "source", targetTag);
246516
+ const bareName = referentName.startsWith("$") ? referentName.slice(1) : referentName;
246517
+ node.attributes[targetTag].children = [
246518
+ {
246519
+ type: "macro",
246520
+ path: parseReferencePath(bareName),
246521
+ attributes: {}
246522
+ }
246523
+ ];
246524
+ node.name = referentType;
246525
+ } catch (e4) {
246526
+ file.message(
246527
+ `Could not resolve referent type for <copy> tag with source="${referentName}": ${e4}`,
246528
+ {
246529
+ place: node.position,
246530
+ ruleId: "copy/unresolved-referent",
246531
+ source: "v06-to-v07"
246532
+ }
246533
+ );
246534
+ continue;
245364
246535
  }
245365
- };
245366
- };
245367
- async function findReferentType(core2, referentName) {
245368
- if (!referentName.startsWith("$")) {
245369
- referentName = `$${referentName}`;
245370
246536
  }
245371
- const reparsed = reparseAttribute(referentName);
245372
- const path = reparsed[0]?.type === "macro" ? reparsed[0].path : null;
245373
- if (!path) {
246537
+ }
246538
+ async function findReferentType(core2, referentName) {
246539
+ const bare = referentName.startsWith("$") ? referentName.slice(1) : referentName;
246540
+ let path;
246541
+ try {
246542
+ path = parseReferencePath(bare);
246543
+ } catch (e4) {
245374
246544
  throw new Error(`Could not parse referent name "${referentName}"`);
245375
246545
  }
245376
246546
  let unresolvedIndex = [];
245377
246547
  let unresolvedProps = [];
245378
246548
  let referentType = void 0;
245379
- for (let i2 = path.length; i2 > 0; i2--) {
246549
+ search: for (let i2 = path.length; i2 > 0; i2--) {
245380
246550
  const pathParts = path.slice(0, i2);
245381
- const pathStr = printPathWithoutIndices(pathParts);
245382
- const referentIdx = await core2.resolvePathToNodeIdx(pathStr);
245383
- if (referentIdx !== -1) {
245384
- referentType = core2.core.core?.components?.[referentIdx]?.componentType;
245385
- if (referentType) {
245386
- unresolvedIndex = pathParts[pathParts.length - 1].index;
245387
- unresolvedProps = path.slice(i2);
245388
- break;
246551
+ for (const keepIndices of [true, false]) {
246552
+ if (keepIndices && !hasOnlyLiteralIndices(pathParts)) {
246553
+ continue;
246554
+ }
246555
+ const pathStr = keepIndices ? printPath(pathParts) : printPathWithoutIndices(pathParts);
246556
+ const referentIdx = await core2.resolvePathToNodeIdx(pathStr);
246557
+ if (referentIdx === -1) {
246558
+ continue;
245389
246559
  }
246560
+ const foundType = core2.core.core?.components?.[referentIdx]?.componentType;
246561
+ if (!foundType || foundType.startsWith("_")) {
246562
+ continue;
246563
+ }
246564
+ referentType = foundType;
246565
+ unresolvedIndex = keepIndices ? [] : pathParts.flatMap((part) => part.index);
246566
+ unresolvedProps = path.slice(i2);
246567
+ break search;
245390
246568
  }
245391
246569
  }
245392
246570
  if (unresolvedIndex.length !== 0) {
@@ -245408,14 +246586,287 @@ async function findReferentType(core2, referentName) {
245408
246586
  }
245409
246587
  throw new Error(`Could not find referent type for "${referentName}"`);
245410
246588
  }
246589
+ function hasOnlyLiteralIndices(pathParts) {
246590
+ return pathParts.every(
246591
+ (part) => part.index.every(
246592
+ (index2) => index2.value.length === 1 && index2.value[0].type === "text" && /^\d+$/.test(index2.value[0].value.trim())
246593
+ )
246594
+ );
246595
+ }
246596
+ function printPath(pathParts) {
246597
+ return pathParts.map(
246598
+ (part) => part.name + part.index.map((index2) => `[${toXml(index2.value).trim()}]`).join("")
246599
+ ).join(".");
246600
+ }
245411
246601
  function printPathWithoutIndices(pathParts) {
245412
246602
  return pathParts.map((part) => {
245413
246603
  return part.name;
245414
246604
  }).join(".");
245415
246605
  }
245416
- const upgradeAttributeSyntax = () => {
246606
+ const upgradeCopyElements = (context) => {
246607
+ return (tree, file) => {
246608
+ visit(tree, (node, info) => {
246609
+ if (!isDastElement(node)) {
246610
+ return;
246611
+ }
246612
+ if (node.name.toLowerCase() === "ref") {
246613
+ warnAboutExternalRef(node, file);
246614
+ return;
246615
+ }
246616
+ if (node.name.toLowerCase() !== "copy") {
246617
+ return;
246618
+ }
246619
+ convertAssignNames(
246620
+ node,
246621
+ namespaceChainOf(info.parents, context),
246622
+ context,
246623
+ file
246624
+ );
246625
+ const uriKey = findKey$1(node, "uri");
246626
+ if (!uriKey) {
246627
+ return;
246628
+ }
246629
+ const uri = toXml(node.attributes[uriKey].children).trim();
246630
+ if (!uri.toLowerCase().startsWith("doenet:")) {
246631
+ return;
246632
+ }
246633
+ const passedAttributes = Object.keys(node.attributes).filter(
246634
+ (key) => !COPY_OWN_ATTRIBUTES.has(key.toLowerCase())
246635
+ );
246636
+ if (passedAttributes.length === 0) {
246637
+ file.message(
246638
+ `<copy uri="${uri}"> could not be converted: v0.7 loads external content with a "copy" attribute on an element of the same component type as the external document, and this copy passes no attributes to indicate what that type is. Replace it with, for example, <problem copy="doenet:<contentId>" /> once the target has been converted.`,
246639
+ {
246640
+ place: node.position,
246641
+ ruleId: "external-copy/unknown-component-type",
246642
+ source: "v06-to-v07"
246643
+ }
246644
+ );
246645
+ return;
246646
+ }
246647
+ const narrowing = Object.keys(node.attributes).filter(
246648
+ (key) => COPY_NARROWING_ATTRIBUTES.has(key.toLowerCase())
246649
+ );
246650
+ if (narrowing.length > 0) {
246651
+ file.message(
246652
+ `<copy uri="${uri}"> could not be converted because it also sets ${narrowing.join(
246653
+ ", "
246654
+ )}, which changes what it copies; v0.7 has no way to say that on the element that loads an external document. Convert it by hand.`,
246655
+ {
246656
+ place: node.position,
246657
+ ruleId: "external-copy/narrowed",
246658
+ source: "v06-to-v07"
246659
+ }
246660
+ );
246661
+ return;
246662
+ }
246663
+ const dropped = Object.keys(node.attributes).filter(
246664
+ (key) => COPY_CONTROL_ATTRIBUTES.has(key.toLowerCase())
246665
+ );
246666
+ for (const key of dropped) {
246667
+ delete node.attributes[key];
246668
+ }
246669
+ const linkKey = findKey$1(node, "link");
246670
+ const targetTag = linkKey && isV06True(node.attributes[linkKey]) ? "extend" : "copy";
246671
+ if (linkKey) {
246672
+ delete node.attributes[linkKey];
246673
+ }
246674
+ node.name = "module";
246675
+ renameAttrInPlace(node, uriKey, targetTag);
246676
+ if (dropped.length > 0) {
246677
+ file.message(
246678
+ `Dropped ${dropped.join(
246679
+ ", "
246680
+ )} from <copy uri="${uri}">: they controlled how v0.6 copied, and a <module ${targetTag}="doenet:..."> has no equivalent.`,
246681
+ {
246682
+ place: node.position,
246683
+ ruleId: "external-copy/dropped-copy-controls",
246684
+ source: "v06-to-v07"
246685
+ }
246686
+ );
246687
+ }
246688
+ file.message(
246689
+ `Converted <copy uri="${uri}"> to <module ${targetTag}="${uri}">, passing ${passedAttributes.join(", ")}. The identifier in the URI is a v0.6 one; replace it with the v0.7 content id of the converted module, and check that the target really is a <module>.`,
246690
+ {
246691
+ place: node.position,
246692
+ ruleId: "external-copy/needs-new-content-id",
246693
+ source: "v06-to-v07"
246694
+ }
246695
+ );
246696
+ });
246697
+ };
246698
+ };
246699
+ const COPY_NARROWING_ATTRIBUTES = /* @__PURE__ */ new Set([
246700
+ "componentindex",
246701
+ "createcomponentoftype",
246702
+ "numcomponents",
246703
+ "obtainpropfromcomposite",
246704
+ "prop",
246705
+ "propindex",
246706
+ "removeemptyarrayentries",
246707
+ "source",
246708
+ "sourceindex",
246709
+ "sourcesubnames",
246710
+ "sourcesubnamescomponentindex",
246711
+ "target",
246712
+ "tname"
246713
+ ]);
246714
+ const COPY_CONTROL_ATTRIBUTES = /* @__PURE__ */ new Set([
246715
+ "assignnamesskip",
246716
+ "assignnewnamespaces",
246717
+ "sourceattributestoignore"
246718
+ ]);
246719
+ const COPY_OWN_ATTRIBUTES = /* @__PURE__ */ new Set([
246720
+ "assignnames",
246721
+ "assignnamesskip",
246722
+ "assignnewnamespaces",
246723
+ "componentindex",
246724
+ "createcomponentoftype",
246725
+ "link",
246726
+ "name",
246727
+ "newnamespace",
246728
+ "numcomponents",
246729
+ "obtainpropfromcomposite",
246730
+ "prop",
246731
+ "propindex",
246732
+ "removeemptyarrayentries",
246733
+ "source",
246734
+ "sourceattributestoignore",
246735
+ "sourceindex",
246736
+ "sourcesubnames",
246737
+ "sourcesubnamescomponentindex",
246738
+ "target",
246739
+ "tname",
246740
+ "uri"
246741
+ ]);
246742
+ function convertAssignNames(node, ancestorNames, context, file) {
246743
+ const assignNamesValue = readAssignNames(node);
246744
+ if (!assignNamesValue) {
246745
+ deleteAssignNames(node);
246746
+ return;
246747
+ }
246748
+ const origin = {
246749
+ elementName: node.name,
246750
+ position: node.position,
246751
+ ancestorNames,
246752
+ element: node
246753
+ };
246754
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
246755
+ const names = parsed.success && parsed.pieces.every((p2) => typeof p2 === "string") ? parsed.pieces : void 0;
246756
+ if (!names || names.length !== 1) {
246757
+ file.message(
246758
+ `assignNames="${assignNamesValue}" on <${node.name}> could not be converted: the names refer to the replacements of the copied component, and this converter cannot tell how many of those there are. References to those names need fixing by hand.`,
246759
+ {
246760
+ place: node.position,
246761
+ ruleId: "copy/unmapped-assign-names",
246762
+ source: "v06-to-v07"
246763
+ }
246764
+ );
246765
+ deleteAssignNames(node);
246766
+ return;
246767
+ }
246768
+ const [assignedName] = names;
246769
+ const existingName = toXml(
246770
+ node.attributes[findKey$1(node, "name") ?? ""]?.children ?? []
246771
+ ).trim();
246772
+ const nameIsUnusable = !isValidReferenceableName(assignedName);
246773
+ const nameBelongsToAnother = nameIsUnusable || nameTakenInScope(context, assignedName, ancestorNames);
246774
+ const nameIsTaken = nameBelongsToAnother || context.existingNames.has(assignedName) || context.claimedNames.has(assignedName);
246775
+ if (existingName && !isValidReferenceableName(existingName)) {
246776
+ file.message(
246777
+ `<${node.name}> is called "${existingName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A generated name was used instead and references to "${assignedName}" were left alone.`,
246778
+ {
246779
+ place: node.position,
246780
+ ruleId: "assign-names/invalid-name",
246781
+ source: "v06-to-v07"
246782
+ }
246783
+ );
246784
+ deleteAssignNames(node);
246785
+ setCompositeName(node, context.uniqueName("copy"));
246786
+ return;
246787
+ }
246788
+ if (existingName) {
246789
+ if (existingName !== assignedName && !nameBelongsToAnother) {
246790
+ context.registry.register(
246791
+ assignedName,
246792
+ [makeIndexedPathPart(existingName, [])],
246793
+ origin,
246794
+ file
246795
+ );
246796
+ } else if (existingName !== assignedName) {
246797
+ reportUnusableName(node, assignedName, nameIsUnusable, file);
246798
+ }
246799
+ deleteAssignNames(node);
246800
+ setCompositeName(node, existingName);
246801
+ return;
246802
+ }
246803
+ if (nameIsTaken) {
246804
+ const generated = context.uniqueName("copy");
246805
+ if (nameBelongsToAnother) {
246806
+ reportUnusableName(node, assignedName, nameIsUnusable, file);
246807
+ } else {
246808
+ context.registry.register(
246809
+ assignedName,
246810
+ [makeIndexedPathPart(generated, [])],
246811
+ origin,
246812
+ file
246813
+ );
246814
+ }
246815
+ deleteAssignNames(node);
246816
+ setCompositeName(node, generated);
246817
+ return;
246818
+ }
246819
+ context.claimedNames.add(assignedName);
246820
+ context.registry.register(assignedName, void 0, origin, file);
246821
+ setCompositeName(node, assignedName);
246822
+ }
246823
+ function warnAboutExternalRef(node, file) {
246824
+ const toKey = findKey$1(node, "to");
246825
+ if (!toKey) {
246826
+ return;
246827
+ }
246828
+ const target = toXml(node.attributes[toKey].children).trim();
246829
+ if (!/^doenet:.*(activityId|doenetId|cid|pageId)=/i.test(target)) {
246830
+ return;
246831
+ }
246832
+ file.message(
246833
+ `<ref to="${target}"> points at a v0.6 activity; replace the identifier with the v0.7 content id (or a doenet.org URL) of the converted document.`,
246834
+ {
246835
+ place: node.position,
246836
+ ruleId: "external-ref/needs-new-content-id",
246837
+ source: "v06-to-v07"
246838
+ }
246839
+ );
246840
+ }
246841
+ function reportUnusableName(node, assignedName, nameIsUnusable, file) {
246842
+ if (nameIsUnusable) {
246843
+ file.message(
246844
+ `<${node.name}> assigns the name "${assignedName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A generated name was used instead and references to "${assignedName}" were left alone.`,
246845
+ {
246846
+ place: node.position,
246847
+ ruleId: "assign-names/invalid-name",
246848
+ source: "v06-to-v07"
246849
+ }
246850
+ );
246851
+ return;
246852
+ }
246853
+ file.message(
246854
+ `<${node.name}> assigns the name "${assignedName}", but something else in the document is already called that. References to "${assignedName}" were left pointing where they already pointed.`,
246855
+ {
246856
+ place: node.position,
246857
+ ruleId: "copy/name-already-taken",
246858
+ source: "v06-to-v07"
246859
+ }
246860
+ );
246861
+ }
246862
+ function findKey$1(node, attrName) {
246863
+ return Object.keys(node.attributes).find(
246864
+ (key) => key.toLowerCase() === attrName.toLowerCase()
246865
+ );
246866
+ }
246867
+ const upgradeAttributeSyntax = (context) => {
245417
246868
  return async (tree, file) => {
245418
- visit(tree, (node) => {
246869
+ visit(tree, (node, info) => {
245419
246870
  if (node.type !== "macro") {
245420
246871
  return;
245421
246872
  }
@@ -245441,6 +246892,18 @@ const upgradeAttributeSyntax = () => {
245441
246892
  }
245442
246893
  });
245443
246894
  Object.assign(node, copy2);
246895
+ const assigned = readAssignNames(node);
246896
+ convertAssignNames(
246897
+ node,
246898
+ namespaceChainOf(info.parents, context),
246899
+ context,
246900
+ file
246901
+ );
246902
+ warnIfNameCouldNotBeKept(
246903
+ node,
246904
+ assigned,
246905
+ file
246906
+ );
245444
246907
  });
245445
246908
  const macrosInAttributes = [];
245446
246909
  visit(tree, (node, info) => {
@@ -245534,39 +246997,34 @@ const upgradeAttributeSyntax = () => {
245534
246997
  documentElement.children.unshift(setupTag);
245535
246998
  };
245536
246999
  };
245537
- const upgradeMapElement = () => {
247000
+ function warnIfNameCouldNotBeKept(node, assigned, file) {
247001
+ if (!assigned) {
247002
+ return;
247003
+ }
247004
+ const name2 = toXml(node.attributes["name"]?.children ?? []).trim();
247005
+ if (name2 === assigned.trim()) {
247006
+ return;
247007
+ }
247008
+ file.message(
247009
+ `A reference wrote assignNames="${assigned}" in its attributes, and that name could not be kept${name2 ? ` (the element is now named "${name2}")` : ""}. References to "${assigned}" need fixing by hand.`,
247010
+ {
247011
+ place: node.position,
247012
+ ruleId: "assign-names/late-attribute-assignment",
247013
+ source: "v06-to-v07"
247014
+ }
247015
+ );
247016
+ }
247017
+ const upgradeMapElement = (context) => {
245538
247018
  return (tree, file) => {
245539
- const refsToRename = {};
245540
- replaceNode(tree, (node) => {
247019
+ replaceNode(tree, (node, info) => {
245541
247020
  if (!isDastElement(node)) {
245542
247021
  return;
245543
247022
  }
245544
- if (node.name !== "map") {
247023
+ if (node.name.toLowerCase() !== "map") {
245545
247024
  return;
245546
247025
  }
245547
- const name2 = toXml(node.attributes["name"]?.children).trim();
245548
- const assignNames = toXml(node.attributes["assignNames"]?.children).trim().split(/\s+/);
245549
- if (name2 && assignNames.length > 0) {
245550
- assignNames.forEach((assignName, index2) => {
245551
- refsToRename[assignName] = [
245552
- {
245553
- type: "pathPart",
245554
- name: name2,
245555
- index: [
245556
- {
245557
- type: "index",
245558
- value: [
245559
- {
245560
- type: "text",
245561
- value: `${index2 + 1}`
245562
- }
245563
- ]
245564
- }
245565
- ]
245566
- }
245567
- ];
245568
- });
245569
- }
247026
+ let name2 = toXml(node.attributes["name"]?.children).trim();
247027
+ const assignNamesValue = readAssignNames(node);
245570
247028
  const templateNode = node.children.find(
245571
247029
  (child) => isDastElement(child) && child.name === "template"
245572
247030
  );
@@ -245576,10 +247034,32 @@ const upgradeMapElement = () => {
245576
247034
  if (!templateNode || !isDastElement(templateNode) || !sourcesNode || !isDastElement(sourcesNode)) {
245577
247035
  file.message(
245578
247036
  `Map element must have both a template and sources children to be converted`,
245579
- { place: node.position }
247037
+ {
247038
+ place: node.position,
247039
+ ruleId: "map/missing-template-or-sources",
247040
+ source: "v06-to-v07"
247041
+ }
245580
247042
  );
245581
247043
  return;
245582
247044
  }
247045
+ if (assignNamesValue) {
247046
+ name2 = registerCompositeAssignNames({
247047
+ node,
247048
+ assignNamesValue,
247049
+ fallbackBase: "repeat",
247050
+ ancestorNames: namespaceChainOf(info.parents, context),
247051
+ context,
247052
+ file,
247053
+ // A nested name such as `assignNames="(a b)"` counts positions
247054
+ // inside one iteration, which are the template's children — and
247055
+ // v0.6 skipped bare text there while v0.7 counts it.
247056
+ positionMap: makeTemplatePositionMap(
247057
+ templateNode,
247058
+ node,
247059
+ file
247060
+ )
247061
+ }) ?? name2;
247062
+ }
245583
247063
  const valueName = toXml(
245584
247064
  sourcesNode.attributes["alias"]?.children
245585
247065
  ).trim();
@@ -245591,6 +247071,7 @@ const upgradeMapElement = () => {
245591
247071
  (child) => isDastElement(child) && child.name === "sequence"
245592
247072
  )) {
245593
247073
  if (name2) {
247074
+ warnIfNameLost(sequenceNode, name2, file);
245594
247075
  sequenceNode.attributes["name"] = {
245595
247076
  type: "attribute",
245596
247077
  name: "name",
@@ -245598,6 +247079,7 @@ const upgradeMapElement = () => {
245598
247079
  };
245599
247080
  }
245600
247081
  sequenceNode.name = "repeatForSequence";
247082
+ inheritNamespace(templateNode, sequenceNode, context);
245601
247083
  if (valueName) {
245602
247084
  sequenceNode.attributes["valueName"] = {
245603
247085
  type: "attribute",
@@ -245627,12 +247109,15 @@ const upgradeMapElement = () => {
245627
247109
  attributes: {},
245628
247110
  children: [groupTag]
245629
247111
  };
245630
- const groupName = getUniqueName(tree, "group");
247112
+ const groupName = context.uniqueName("group");
245631
247113
  groupTag.attributes["name"] = {
245632
247114
  type: "attribute",
245633
247115
  name: "name",
245634
247116
  children: reparseAttribute(groupName)
245635
247117
  };
247118
+ if (name2) {
247119
+ warnIfNameLost(templateNode, name2, file);
247120
+ }
245636
247121
  templateNode.name = "repeat";
245637
247122
  templateNode.attributes["for"] = {
245638
247123
  type: "attribute",
@@ -245663,19 +247148,22 @@ const upgradeMapElement = () => {
245663
247148
  return [setupTag, templateNode];
245664
247149
  }
245665
247150
  });
245666
- visit(tree, (node) => {
245667
- if (node.type !== "macro") {
245668
- return;
245669
- }
245670
- if (!node.path.some((part) => refsToRename[part.name])) {
245671
- return;
245672
- }
245673
- node.path = node.path.flatMap((part) => {
245674
- return refsToRename[part.name] || [part];
245675
- });
245676
- });
245677
247151
  };
245678
247152
  };
247153
+ function warnIfNameLost(node, newName, file) {
247154
+ const existing = toXml(node.attributes["name"]?.children).trim();
247155
+ if (!existing || existing === newName) {
247156
+ return;
247157
+ }
247158
+ file.message(
247159
+ `<${node.name} name="${existing}"> becomes the <repeat> that takes the name "${newName}", so "${existing}" is gone; references to it need fixing by hand.`,
247160
+ {
247161
+ place: node.position,
247162
+ ruleId: "map/name-overwritten",
247163
+ source: "v06-to-v07"
247164
+ }
247165
+ );
247166
+ }
245679
247167
  const upgradeModuleElement = () => {
245680
247168
  return (tree, file) => {
245681
247169
  visit(tree, (node) => {
@@ -245691,14 +247179,30 @@ const upgradeModuleElement = () => {
245691
247179
  if (!setupNode) {
245692
247180
  return;
245693
247181
  }
245694
- node.children.filter(
245695
- (child) => !isDastElement(child) || child.name !== "setup"
245696
- );
247182
+ const isCustomAttribute = (child) => isDastElement(child) && child.name === "customAttribute";
245697
247183
  const customAttributeNodes = setupNode.children.filter(
245698
- (child) => isDastElement(child) && child.name === "customAttribute"
247184
+ (child) => isCustomAttribute(child)
247185
+ );
247186
+ const otherSetupChildren = setupNode.children.filter(
247187
+ (child) => !isCustomAttribute(child)
245699
247188
  );
245700
247189
  setupNode.children = [];
245701
247190
  setupNode.name = "moduleAttributes";
247191
+ if (otherSetupChildren.some(
247192
+ (child) => child.type !== "text" || child.value.trim() !== ""
247193
+ )) {
247194
+ const newSetup = {
247195
+ type: "element",
247196
+ name: "setup",
247197
+ attributes: {},
247198
+ children: otherSetupChildren
247199
+ };
247200
+ node.children.splice(
247201
+ node.children.indexOf(setupNode) + 1,
247202
+ 0,
247203
+ newSetup
247204
+ );
247205
+ }
245702
247206
  for (const customAttributeNode of customAttributeNodes) {
245703
247207
  const name2 = toXml(
245704
247208
  customAttributeNode.attributes["assignNames"]?.children
@@ -245710,7 +247214,9 @@ const upgradeModuleElement = () => {
245710
247214
  file.message(
245711
247215
  `Module "customAttribute" is missing a "componentType"; the syntax cannot be upgraded with a "componentType".`,
245712
247216
  {
245713
- place: customAttributeNode.position
247217
+ place: customAttributeNode.position,
247218
+ ruleId: "module/custom-attribute-without-type",
247219
+ source: "v06-to-v07"
245714
247220
  }
245715
247221
  );
245716
247222
  continue;
@@ -245773,10 +247279,459 @@ const removeDefinitionsElement = () => {
245773
247279
  });
245774
247280
  };
245775
247281
  };
247282
+ const GLOBAL_RULES = {
247283
+ // v0.6 renamed `targets*` to `sources*`; v0.7 renamed them again to `references*`.
247284
+ sourcesareresponses: {
247285
+ kind: "renameToReferenceList",
247286
+ to: "referencesAreResponses"
247287
+ },
247288
+ targetsareresponses: {
247289
+ kind: "renameToReferenceList",
247290
+ to: "referencesAreResponses"
247291
+ },
247292
+ sourcesarefunctionsymbols: {
247293
+ kind: "renameToReferenceList",
247294
+ to: "referencesAreFunctionSymbols"
247295
+ },
247296
+ targetsarefunctionsymbols: {
247297
+ kind: "renameToReferenceList",
247298
+ to: "referencesAreFunctionSymbols"
247299
+ },
247300
+ triggerwithtargets: { kind: "renameToReferenceList", to: "triggerWith" },
247301
+ triggerwithtnames: { kind: "renameToReferenceList", to: "triggerWith" },
247302
+ updatewithtname: { kind: "rename", to: "updateWith" },
247303
+ updatewithtarget: { kind: "rename", to: "updateWith" },
247304
+ // `tname` was the pre-v0.6 spelling of the attribute naming what to act on. On
247305
+ // components that *copy*, it became `source`; everywhere else it became `target`.
247306
+ // The element-specific tables below override this for the copying components.
247307
+ tname: { kind: "rename", to: "target" }
247308
+ };
247309
+ const ELEMENT_RULES = {
247310
+ copy: { tname: { kind: "rename", to: "source" } },
247311
+ collect: {
247312
+ tname: { kind: "rename", to: "source" },
247313
+ draggable: {
247314
+ kind: "remove",
247315
+ because: "<collect> does not take `draggable` in v0.7"
247316
+ }
247317
+ },
247318
+ extract: { tname: { kind: "rename", to: "source" } },
247319
+ updatevalue: {
247320
+ // `<updateValue target="x" prop="y">` is a single path in v0.7.
247321
+ prop: { kind: "mergeInto", target: "target" }
247322
+ },
247323
+ animatefromsequence: { prop: { kind: "mergeInto", target: "target" } },
247324
+ ref: {
247325
+ page: {
247326
+ kind: "remove",
247327
+ because: "v0.7 documents are not paginated, so <ref> has no `page`; link to the individual document instead",
247328
+ ruleId: "deprecated/ref-page"
247329
+ }
247330
+ },
247331
+ variantcontrol: { nvariants: { kind: "rename", to: "numVariants" } },
247332
+ option: {
247333
+ selectforvariantnames: { kind: "rename", to: "selectForVariants" }
247334
+ },
247335
+ graph: {
247336
+ xlabel: { kind: "toChildElement", elementName: "xLabel" },
247337
+ ylabel: { kind: "toChildElement", elementName: "yLabel" },
247338
+ height: {
247339
+ kind: "remove",
247340
+ because: "v0.7 graphs are sized with `size`, `width` and `aspectRatio`"
247341
+ }
247342
+ },
247343
+ image: {
247344
+ // v0.6 rendered `description` as the image's `alt` text. v0.7 carries that in a
247345
+ // `<shortDescription>` child, which the reference pages describe as required for
247346
+ // accessibility, so this must be converted rather than dropped.
247347
+ description: {
247348
+ kind: "toChildElement",
247349
+ elementName: "shortDescription"
247350
+ }
247351
+ },
247352
+ conditionalcontent: {
247353
+ maximumnumbertoshow: {
247354
+ kind: "remove",
247355
+ because: "v0.7 <conditionalContent> always shows one case"
247356
+ }
247357
+ },
247358
+ embed: {
247359
+ encodedgeogebracontent: {
247360
+ kind: "unsupported",
247361
+ because: "v0.7 has no <embed> element and no GeoGebra support; this content must be replaced by hand",
247362
+ ruleId: "no-v07-equivalent/embed-geogebra"
247363
+ }
247364
+ },
247365
+ point: {
247366
+ link: {
247367
+ kind: "remove",
247368
+ because: "`link` only means something alongside `copySource`",
247369
+ // `copySourceToExtendOrCopy` needs `link` when there is a `copySource`.
247370
+ when: (_value, node) => !findAttrKey(node, "copySource") && !findAttrKey(node, "source")
247371
+ }
247372
+ },
247373
+ tabular: removeSides(),
247374
+ row: removeSides(),
247375
+ cell: removeSides()
247376
+ };
247377
+ function removeSides() {
247378
+ const rule = {
247379
+ kind: "remove",
247380
+ because: "v0.7 tables do not take per-side border attributes"
247381
+ };
247382
+ return { top: rule, bottom: rule, left: rule, right: rule };
247383
+ }
247384
+ const upgradeDeprecatedAttributes = () => {
247385
+ return (tree, file) => {
247386
+ visit(tree, (node) => {
247387
+ if (!isDastElement(node)) {
247388
+ return;
247389
+ }
247390
+ const elm = node;
247391
+ const rules = {
247392
+ ...GLOBAL_RULES,
247393
+ ...ELEMENT_RULES[elm.name.toLowerCase()] || {}
247394
+ };
247395
+ const keys2 = Object.keys(elm.attributes);
247396
+ const isMerge = (key) => rules[key.toLowerCase()]?.kind === "mergeInto";
247397
+ for (const key of [
247398
+ ...keys2.filter((k2) => !isMerge(k2)),
247399
+ ...keys2.filter(isMerge)
247400
+ ]) {
247401
+ const rule = rules[key.toLowerCase()];
247402
+ if (!rule) {
247403
+ continue;
247404
+ }
247405
+ const attr = elm.attributes[key];
247406
+ if (!attr) {
247407
+ continue;
247408
+ }
247409
+ const value = toXml(attr.children).trim();
247410
+ if (rule.when && !rule.when(value, elm)) {
247411
+ continue;
247412
+ }
247413
+ applyRule(elm, key, attr, value, rule, file);
247414
+ }
247415
+ });
247416
+ };
247417
+ };
247418
+ const prependedChildCount = /* @__PURE__ */ new WeakMap();
247419
+ function applyRule(elm, key, attr, value, rule, file) {
247420
+ switch (rule.kind) {
247421
+ case "rename": {
247422
+ renameAttrInPlace(elm, key, rule.to);
247423
+ return;
247424
+ }
247425
+ case "renameToReferenceList": {
247426
+ renameAttrInPlace(elm, key, rule.to);
247427
+ const dollared = value.split(/\s+/).filter((t4) => t4).map(referenceTo).join(" ");
247428
+ elm.attributes[rule.to].children = reparseAttributeV6(dollared);
247429
+ return;
247430
+ }
247431
+ case "mergeInto": {
247432
+ const targetKey = findAttrKey(elm, rule.target);
247433
+ if (!targetKey || !value) {
247434
+ return;
247435
+ }
247436
+ const targetValue = toXml(
247437
+ elm.attributes[targetKey].children
247438
+ ).trim();
247439
+ elm.attributes[targetKey].children = reparseAttributeV6(
247440
+ `${targetValue}.${value}`
247441
+ );
247442
+ delete elm.attributes[key];
247443
+ return;
247444
+ }
247445
+ case "toChildElement": {
247446
+ if (!value) {
247447
+ delete elm.attributes[key];
247448
+ return;
247449
+ }
247450
+ const child = {
247451
+ type: "element",
247452
+ name: rule.elementName,
247453
+ attributes: {},
247454
+ children: attr.children,
247455
+ position: attr.position
247456
+ };
247457
+ const alreadyPrepended = prependedChildCount.get(elm) || 0;
247458
+ elm.children.splice(alreadyPrepended, 0, child);
247459
+ prependedChildCount.set(elm, alreadyPrepended + 1);
247460
+ delete elm.attributes[key];
247461
+ return;
247462
+ }
247463
+ case "remove": {
247464
+ delete elm.attributes[key];
247465
+ file.message(
247466
+ `Removed ${key}="${value}" from <${elm.name}>: ${rule.because}.`,
247467
+ {
247468
+ place: elm.position,
247469
+ ruleId: rule.ruleId || `deprecated/${key.toLowerCase()}`,
247470
+ source: "v06-to-v07"
247471
+ }
247472
+ );
247473
+ return;
247474
+ }
247475
+ case "unsupported": {
247476
+ file.message(
247477
+ `<${elm.name} ${key}="..."> was left unchanged: ${rule.because}.`,
247478
+ {
247479
+ place: elm.position,
247480
+ ruleId: rule.ruleId || `no-v07-equivalent/${key.toLowerCase()}`,
247481
+ source: "v06-to-v07"
247482
+ }
247483
+ );
247484
+ return;
247485
+ }
247486
+ }
247487
+ }
247488
+ function findAttrKey(elm, attrName) {
247489
+ return Object.keys(elm.attributes).find(
247490
+ (key) => key.toLowerCase() === attrName.toLowerCase()
247491
+ );
247492
+ }
247493
+ function referenceTo(token) {
247494
+ if (token.startsWith("$(")) {
247495
+ return token;
247496
+ }
247497
+ const name2 = token.startsWith("$") ? token.slice(1) : token;
247498
+ return /^[a-zA-Z0-9_]+$/.test(name2) ? `$${name2}` : `$(${name2})`;
247499
+ }
247500
+ const ALL_ITEMS_PROPS = /* @__PURE__ */ new Set(["maths", "texts", "numbers", "booleans"]);
247501
+ const NUMBERED_ITEM_PROP = /^(math|text|number|boolean)(\d+)$/;
247502
+ const ELEMENTS_WITH_PROP = /* @__PURE__ */ new Set(["copy", "extract"]);
247503
+ const upgradeListProps = () => {
247504
+ return (tree, file) => {
247505
+ visitAllMacros(tree, (node) => {
247506
+ node.path = rewritePath(node.path);
247507
+ });
247508
+ visitAll(tree, (node) => {
247509
+ if (!isDastElement(node) || !ELEMENTS_WITH_PROP.has(node.name.toLowerCase())) {
247510
+ return;
247511
+ }
247512
+ rewritePropAttribute(node, file);
247513
+ rewriteRawSourceAttribute(node);
247514
+ });
247515
+ };
247516
+ };
247517
+ const ELEMENTS_WITH_RAW_SOURCE = /* @__PURE__ */ new Set(["copy", "extract"]);
247518
+ function rewriteRawSourceAttribute(node) {
247519
+ if (!ELEMENTS_WITH_RAW_SOURCE.has(node.name.toLowerCase())) {
247520
+ return;
247521
+ }
247522
+ const sourceKey = findKey(node, "source");
247523
+ if (!sourceKey) {
247524
+ return;
247525
+ }
247526
+ const attr = node.attributes[sourceKey];
247527
+ if (attr.children.length !== 1 || attr.children[0].type !== "text") {
247528
+ return;
247529
+ }
247530
+ const child = attr.children[0];
247531
+ const value = child.value.trim();
247532
+ if (!value || value.startsWith("$") || !value.includes(".")) {
247533
+ return;
247534
+ }
247535
+ let path;
247536
+ try {
247537
+ path = parseReferencePath(value);
247538
+ } catch {
247539
+ return;
247540
+ }
247541
+ restoreRawPropPositions(node, sourceKey, path);
247542
+ const rewritten = rewritePath(path);
247543
+ if (rewritten === path) {
247544
+ return;
247545
+ }
247546
+ child.value = toXml(rewritten);
247547
+ }
247548
+ function rewritePath(path) {
247549
+ if (path.length < 2) {
247550
+ return path;
247551
+ }
247552
+ const result2 = [path[0]];
247553
+ for (const part of path.slice(1)) {
247554
+ const previous = result2[result2.length - 1];
247555
+ if (!isPropAccess(part)) {
247556
+ result2.push(part);
247557
+ continue;
247558
+ }
247559
+ if (ALL_ITEMS_PROPS.has(part.name)) {
247560
+ previous.index = [...previous.index, ...part.index];
247561
+ continue;
247562
+ }
247563
+ const numbered = NUMBERED_ITEM_PROP.exec(part.name);
247564
+ if (numbered) {
247565
+ previous.index = [
247566
+ ...previous.index,
247567
+ {
247568
+ type: "index",
247569
+ value: [{ type: "text", value: numbered[2] }]
247570
+ },
247571
+ ...part.index
247572
+ ];
247573
+ continue;
247574
+ }
247575
+ result2.push(part);
247576
+ }
247577
+ return result2;
247578
+ }
247579
+ function rewritePropAttribute(node, file) {
247580
+ const propKey = findKey(node, "prop");
247581
+ if (!propKey) {
247582
+ return;
247583
+ }
247584
+ const prop = toXml(node.attributes[propKey].children).trim();
247585
+ const numbered = NUMBERED_ITEM_PROP.exec(prop);
247586
+ if (!ALL_ITEMS_PROPS.has(prop) && !numbered) {
247587
+ return;
247588
+ }
247589
+ const sourceKey = findKey(node, "source");
247590
+ if (!sourceKey) {
247591
+ return;
247592
+ }
247593
+ const sourceAttr = node.attributes[sourceKey];
247594
+ const source = toXml(sourceAttr.children).trim();
247595
+ if (!source) {
247596
+ return;
247597
+ }
247598
+ if (!numbered) {
247599
+ if (node.name.toLowerCase() === "extract") {
247600
+ file.message(
247601
+ `<extract prop="${prop}"> has no v0.7 equivalent and was left as it is; the prop names the whole list, which v0.7 reaches as $${source}.`,
247602
+ {
247603
+ place: node.position,
247604
+ ruleId: "no-v07-equivalent/extract",
247605
+ source: "v06-to-v07"
247606
+ }
247607
+ );
247608
+ return;
247609
+ }
247610
+ delete node.attributes[propKey];
247611
+ return;
247612
+ }
247613
+ const hadDollar = source.startsWith("$");
247614
+ let path;
247615
+ try {
247616
+ path = parseReferencePath(hadDollar ? source.slice(1) : source);
247617
+ } catch (e4) {
247618
+ return;
247619
+ }
247620
+ const last2 = path[path.length - 1];
247621
+ last2.index = [
247622
+ ...last2.index,
247623
+ { type: "index", value: [{ type: "text", value: numbered[2] }] }
247624
+ ];
247625
+ sourceAttr.children = hadDollar ? [{ type: "macro", path, attributes: {} }] : [{ type: "text", value: toXml(path) }];
247626
+ delete node.attributes[propKey];
247627
+ }
247628
+ function findKey(node, attrName) {
247629
+ return Object.keys(node.attributes).find(
247630
+ (key) => key.toLowerCase() === attrName.toLowerCase()
247631
+ );
247632
+ }
247633
+ const upgradeAssignNames = (context) => {
247634
+ return (tree, file) => {
247635
+ visitAll(tree, (node, parents) => {
247636
+ if (!isDastElement(node)) {
247637
+ return;
247638
+ }
247639
+ const spec = lookupComposite(node);
247640
+ if (!spec) {
247641
+ return;
247642
+ }
247643
+ const assignNamesValue = readAssignNames(node);
247644
+ if (assignNamesValue === void 0) {
247645
+ return;
247646
+ }
247647
+ if (spec.noV07Equivalent) {
247648
+ file.message(
247649
+ `<${node.name}> has no v0.7 equivalent and must be rewritten by hand; its references were converted as if it behaved like a v0.6 composite.`,
247650
+ {
247651
+ place: node.position,
247652
+ ruleId: `no-v07-equivalent/${spec.name.toLowerCase()}`,
247653
+ source: "v06-to-v07"
247654
+ }
247655
+ );
247656
+ }
247657
+ if (!assignNamesValue) {
247658
+ deleteAssignNames(node);
247659
+ return;
247660
+ }
247661
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
247662
+ if (parsed.success && firstLeafName(parsed.pieces) === void 0) {
247663
+ deleteAssignNames(node);
247664
+ return;
247665
+ }
247666
+ const onlyPiece = parsed.success && parsed.pieces.length === 1 && typeof parsed.pieces[0] === "string" ? parsed.pieces[0] : void 0;
247667
+ if (onlyPiece !== void 0 && isValidReferenceableName(onlyPiece) && !findAttribute(node, "name") && !context.existingNames.has(onlyPiece) && !context.claimedNames.has(onlyPiece) && producesSingleReplacement(node, spec)) {
247668
+ context.claimedNames.add(onlyPiece);
247669
+ context.registry.register(
247670
+ onlyPiece,
247671
+ void 0,
247672
+ {
247673
+ elementName: node.name,
247674
+ position: node.position,
247675
+ ancestorNames: namespaceChainOf(parents, context),
247676
+ element: node
247677
+ },
247678
+ file
247679
+ );
247680
+ warnIfSelfReferential(node, onlyPiece, file);
247681
+ setCompositeName(node, onlyPiece);
247682
+ return;
247683
+ }
247684
+ const compositeName = registerCompositeAssignNames({
247685
+ node,
247686
+ assignNamesValue,
247687
+ fallbackBase: spec.name,
247688
+ ancestorNames: namespaceChainOf(parents, context),
247689
+ context,
247690
+ file,
247691
+ positionMap: makePositionMap(node, spec, file)
247692
+ });
247693
+ if (compositeName === void 0) {
247694
+ deleteAssignNames(node);
247695
+ return;
247696
+ }
247697
+ warnIfSelfReferential(node, compositeName, file);
247698
+ setCompositeName(node, compositeName);
247699
+ });
247700
+ };
247701
+ };
247702
+ function warnIfSelfReferential(node, compositeName, file) {
247703
+ let referencesSelf = false;
247704
+ for (const attr of Object.values(node.attributes)) {
247705
+ for (const child of attr.children) {
247706
+ visitAllMacros(child, (macro) => {
247707
+ if (macro.path[0]?.name === compositeName) {
247708
+ referencesSelf = true;
247709
+ }
247710
+ });
247711
+ }
247712
+ }
247713
+ if (!referencesSelf) {
247714
+ return;
247715
+ }
247716
+ file.message(
247717
+ `<${node.name}> is being named "${compositeName}", but one of its own attributes already refers to $${compositeName}. That reference resolved to nothing in v0.6; in v0.7 it is a circular reference and the document will not load.`,
247718
+ {
247719
+ place: node.position,
247720
+ ruleId: "assign-names/self-reference",
247721
+ source: "v06-to-v07"
247722
+ }
247723
+ );
247724
+ }
247725
+ const applyAssignNameRenames = (context) => {
247726
+ return (tree, file) => {
247727
+ applyRefRenames(tree, context.registry, file, context);
247728
+ };
247729
+ };
245776
247730
  async function updateSyntaxFromV06toV07_root(dast, options) {
245777
- let processor = unified$1().use(correctElementCapitalization).use(correctAttributeCapitalization).use(correctComponentTypesAttributeCapitalization).use(ensureDollarBeforeNamesOnSpecificAttributes).use(upgradePathSlashesToDots).use(removeNewNamespaceAttribute).use(upgradeRefElement).use(copySourceToExtendOrCopy).use(upgradeCollectElement).use(upgradeMapElement).use(upgradeModuleElement).use(removeConstraintsElement).use(removeDefinitionsElement);
247731
+ const assignNamesContext = createAssignNamesContext(dast);
247732
+ let processor = unified$1().use(correctElementCapitalization).use(correctAttributeCapitalization).use(correctComponentTypesAttributeCapitalization).use(upgradeDeprecatedAttributes).use(ensureDollarBeforeNamesOnSpecificAttributes).use(upgradePathSlashesToDots).use(removeNewNamespaceAttribute).use(upgradeRefElement).use(copySourceToExtendOrCopy, assignNamesContext).use(upgradeCollectElement, assignNamesContext).use(upgradeMapElement, assignNamesContext).use(upgradeAssignNames, assignNamesContext).use(upgradeCopyElements, assignNamesContext).use(applyAssignNameRenames, assignNamesContext).use(upgradeListProps).use(upgradeModuleElement).use(removeConstraintsElement).use(removeDefinitionsElement);
245778
247733
  if (!options.doNotUpgradeAttributeSyntax) {
245779
- processor = processor.use(upgradeAttributeSyntax);
247734
+ processor = processor.use(upgradeAttributeSyntax, assignNamesContext);
245780
247735
  }
245781
247736
  if (!options.doNotUpgradeCopyTags) {
245782
247737
  processor = processor.use(upgradeCopySyntax);
@@ -245817,31 +247772,44 @@ const ensureDollarBeforeNamesOnSpecificAttributes = () => {
245817
247772
  });
245818
247773
  };
245819
247774
  };
245820
- const copySourceToExtendOrCopy = () => {
245821
- return (tree) => {
245822
- visit(tree, (node) => {
247775
+ const copySourceToExtendOrCopy = (context) => {
247776
+ return (tree, file) => {
247777
+ visit(tree, (node, info) => {
245823
247778
  if (!isDastElement(node)) {
245824
247779
  return;
245825
247780
  }
245826
247781
  const copySourceAttr = node.attributes["copySource"];
245827
247782
  const linkAttr = node.attributes["link"];
245828
- const assignNamesAttr = node.attributes["assignNames"];
245829
247783
  const copyPropAttr = node.attributes["copyProp"];
245830
247784
  if (!copySourceAttr) {
245831
247785
  return;
245832
247786
  }
245833
- const targetTag = toXml(linkAttr?.children || []).toLowerCase() === "false" ? "copy" : "extend";
247787
+ const targetTag = linkAttr ? isV06True(linkAttr) ? "extend" : "copy" : isModuleComponentType(node.name) ? "copy" : "extend";
245834
247788
  const baseValue = toXml(copySourceAttr.children).trim();
245835
247789
  let extendValue = baseValue.startsWith("$") ? baseValue : `$${baseValue}`;
245836
247790
  copySourceAttr.name = targetTag;
247791
+ let appendedPropName;
245837
247792
  if (copyPropAttr) {
245838
- extendValue += `.${toXml(copyPropAttr.children).trim()}`;
247793
+ appendedPropName = toXml(copyPropAttr.children).trim();
247794
+ extendValue += `.${appendedPropName}`;
245839
247795
  delete node.attributes["copyProp"];
245840
247796
  }
245841
247797
  copySourceAttr.children = reparseAttribute(extendValue);
245842
- if (assignNamesAttr && toXml(assignNamesAttr.children).trim().indexOf(" ") === -1) {
245843
- assignNamesAttr.name = "name";
247798
+ if (appendedPropName) {
247799
+ const macro = copySourceAttr.children[0];
247800
+ if (macro?.type === "macro") {
247801
+ const last2 = macro.path[macro.path.length - 1];
247802
+ if (last2) {
247803
+ markAsPropAccess(last2);
247804
+ }
247805
+ }
245844
247806
  }
247807
+ convertAssignNames(
247808
+ node,
247809
+ namespaceChainOf(info.parents, context),
247810
+ context,
247811
+ file
247812
+ );
245845
247813
  if (linkAttr) {
245846
247814
  delete node.attributes["link"];
245847
247815
  }
@@ -245876,4 +247844,4 @@ export {
245876
247844
  getDefaultExportFromCjs$1 as g,
245877
247845
  updateSyntaxFromV06toV07 as u
245878
247846
  };
245879
- //# sourceMappingURL=index-Cxf3BQNw.js.map
247847
+ //# sourceMappingURL=index-4M4L_2sg.js.map