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

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-D-2i13ZI.js} +2185 -317
  26. package/{index-Cxf3BQNw.js.map → index-D-2i13ZI.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-hQwEEL17-Br5jiMaf.js} +2 -2
  32. package/{sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js.map → sha256-8sXzDnE0-hQwEEL17-Br5jiMaf.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-hQwEEL17-Br5jiMaf.js").then((n2) => n2.s)).default;
47328
47360
  digest = (data2) => sha256(data2, {
47329
47361
  asBytes: true
47330
47362
  });
@@ -244029,6 +244061,17 @@ const correctAttributeCapitalization = () => {
244029
244061
  });
244030
244062
  };
244031
244063
  };
244064
+ const LEGACY_V06_ELEMENT_NAMES = [
244065
+ "copy",
244066
+ "map",
244067
+ "template",
244068
+ "sources",
244069
+ "extract",
244070
+ "customAttribute",
244071
+ "constraints",
244072
+ "styleDefinitions",
244073
+ "feedbackDefinitions"
244074
+ ];
244032
244075
  const correctElementCapitalization = () => {
244033
244076
  const componentInfoObjects2 = createComponentInfoObjects();
244034
244077
  const correctCapitalization = Object.keys(
@@ -244037,6 +244080,9 @@ const correctElementCapitalization = () => {
244037
244080
  const correctCapitalizationMap = Object.fromEntries(
244038
244081
  correctCapitalization.map((name2) => [name2.toLowerCase(), name2])
244039
244082
  );
244083
+ for (const name2 of LEGACY_V06_ELEMENT_NAMES) {
244084
+ correctCapitalizationMap[name2.toLowerCase()] ??= name2;
244085
+ }
244040
244086
  return (tree) => {
244041
244087
  visit(tree, (node) => {
244042
244088
  if (!isDastElement(node)) {
@@ -244097,34 +244143,6 @@ function renameAttrInPlace(elm, oldName, newName) {
244097
244143
  );
244098
244144
  elm.attributes = newAttrs;
244099
244145
  }
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
244146
  const componentInfoObjects = createComponentInfoObjects();
244129
244147
  function determinePropType(componentType, propName, nIndices = 0) {
244130
244148
  const publicStateVariableInfo = componentInfoObjects.publicStateVariableInfo[componentType];
@@ -244207,10 +244225,889 @@ function componentTypeFromWrapping(wrappingComponents, nDimensions, nIndices) {
244207
244225
  }
244208
244226
  return { foundComponentType: false };
244209
244227
  }
244210
- const upgradeCollectElement = () => {
244228
+ function isModuleComponentType(componentType) {
244229
+ return componentInfoObjects.isInheritedComponentType({
244230
+ inheritedComponentType: componentType,
244231
+ baseComponentType: "module"
244232
+ });
244233
+ }
244234
+ function breakStringInPiecesBySpacesOrParens(string) {
244235
+ if (typeof string !== "string") {
244236
+ return { success: false };
244237
+ }
244238
+ let numParens = 0;
244239
+ const pieces = [];
244240
+ string = string.trim();
244241
+ let beginInd = 0;
244242
+ for (let ind = 0; ind < string.length; ind++) {
244243
+ const char = string[ind];
244244
+ if (char === "(") {
244245
+ if (numParens === 0) {
244246
+ const newPiece2 = string.substring(beginInd, ind).trim();
244247
+ if (newPiece2.length > 0) {
244248
+ pieces.push(newPiece2);
244249
+ }
244250
+ beginInd = ind;
244251
+ }
244252
+ numParens++;
244253
+ } else if (char === ")") {
244254
+ if (numParens === 0) {
244255
+ return { success: false };
244256
+ }
244257
+ if (numParens === 1) {
244258
+ const newPiece2 = string.substring(beginInd + 1, ind).trim();
244259
+ if (newPiece2.length > 0) {
244260
+ const result2 = breakStringInPiecesBySpacesOrParens(newPiece2);
244261
+ if (result2.success === true) {
244262
+ pieces.push(result2.pieces);
244263
+ } else {
244264
+ pieces.push(newPiece2);
244265
+ }
244266
+ }
244267
+ beginInd = ind + 1;
244268
+ }
244269
+ numParens--;
244270
+ } else if (numParens === 0 && char.match(/\s/)) {
244271
+ const newPiece2 = string.substring(beginInd, ind).trim();
244272
+ if (newPiece2.length > 0) {
244273
+ pieces.push(newPiece2);
244274
+ }
244275
+ beginInd = ind;
244276
+ }
244277
+ }
244278
+ if (numParens !== 0) {
244279
+ return { success: false };
244280
+ }
244281
+ const newPiece = string.substring(beginInd, string.length).trim();
244282
+ if (newPiece.length > 0) {
244283
+ pieces.push(newPiece);
244284
+ }
244285
+ return { success: true, pieces };
244286
+ }
244287
+ function firstLeafName(pieces) {
244288
+ for (const piece of pieces) {
244289
+ if (typeof piece === "string") {
244290
+ return piece;
244291
+ }
244292
+ const nested = firstLeafName(piece);
244293
+ if (nested !== void 0) {
244294
+ return nested;
244295
+ }
244296
+ }
244297
+ return void 0;
244298
+ }
244299
+ const VALID_REFERENCEABLE_NAME = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
244300
+ function isValidReferenceableName(name2) {
244301
+ return VALID_REFERENCEABLE_NAME.test(name2);
244302
+ }
244303
+ function makeIndexedPathPart(name2, indices) {
244304
+ return {
244305
+ type: "pathPart",
244306
+ name: name2,
244307
+ index: indices.map((i2) => ({
244308
+ type: "index",
244309
+ value: [{ type: "text", value: `${i2}` }]
244310
+ }))
244311
+ };
244312
+ }
244313
+ class RenameRegistry {
244314
+ constructor(existingNames = /* @__PURE__ */ new Set()) {
244315
+ this._renames = /* @__PURE__ */ new Map();
244316
+ this._matched = /* @__PURE__ */ new Set();
244317
+ this._existingNames = existingNames;
244318
+ }
244319
+ /**
244320
+ * Register that `oldName` should be replaced by `replacement` wherever it appears in
244321
+ * a macro path. The first registration of a name wins; a later one warns.
244322
+ *
244323
+ * Pass `undefined` for `replacement` to claim the name without rewriting anything,
244324
+ * which is what a composite that simply took the assigned name as its own `name`
244325
+ * needs: references already resolve, but a later composite assigning the same name
244326
+ * must not silently redirect them.
244327
+ */
244328
+ register(oldName, replacement, origin, file) {
244329
+ if (!oldName) {
244330
+ return;
244331
+ }
244332
+ const existing = this._renames.get(oldName) ?? [];
244333
+ const scope = origin.ancestorNames ?? [];
244334
+ const sameScope = existing.find(
244335
+ (target) => sameScopeAs(target.origin.ancestorNames ?? [], scope)
244336
+ );
244337
+ if (sameScope) {
244338
+ file.message(
244339
+ `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.`,
244340
+ {
244341
+ place: origin.position,
244342
+ ruleId: "assign-names/duplicate-name",
244343
+ source: "v06-to-v07"
244344
+ }
244345
+ );
244346
+ return;
244347
+ }
244348
+ if (existing.length === 0 && this._existingNames.has(oldName)) {
244349
+ file.message(
244350
+ `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.`,
244351
+ {
244352
+ place: origin.position,
244353
+ ruleId: "assign-names/shadows-existing-name",
244354
+ source: "v06-to-v07"
244355
+ }
244356
+ );
244357
+ }
244358
+ existing.push({ replacement, origin });
244359
+ this._renames.set(oldName, existing);
244360
+ }
244361
+ /**
244362
+ * The rename for `name`, chosen by which of them the reference is reaching into.
244363
+ *
244364
+ * `precedingNames` are the path parts written before it, so `$g2.a` looks up `a` with
244365
+ * `["g2"]`. The registration whose enclosing names are the longest match at the end of
244366
+ * that wins; one recorded with no enclosing names matches anything, which is what
244367
+ * keeps an unscoped document behaving exactly as before.
244368
+ */
244369
+ get(name2, precedingNames = [], writtenOn) {
244370
+ const targets = this._renames.get(name2);
244371
+ if (!targets || targets.length === 0) {
244372
+ return void 0;
244373
+ }
244374
+ let best;
244375
+ let bestScore = -1;
244376
+ for (const target of targets) {
244377
+ if (writtenOn && target.origin.element === writtenOn) {
244378
+ continue;
244379
+ }
244380
+ const scope = target.origin.ancestorNames ?? [];
244381
+ if (!isSuffixOf(scope, precedingNames)) {
244382
+ continue;
244383
+ }
244384
+ if (scope.length > bestScore) {
244385
+ best = target;
244386
+ bestScore = scope.length;
244387
+ }
244388
+ }
244389
+ if (best) {
244390
+ this._matched.add(name2);
244391
+ }
244392
+ return best;
244393
+ }
244394
+ /** Whether `name` is registered *and* some registration rewrites references to it. */
244395
+ hasReplacement(name2) {
244396
+ return (this._renames.get(name2) ?? []).some(
244397
+ (target) => target.replacement !== void 0
244398
+ );
244399
+ }
244400
+ get size() {
244401
+ return this._renames.size;
244402
+ }
244403
+ /** Registered names that were never referenced anywhere in the document. */
244404
+ unused() {
244405
+ return [...this._renames.keys()].filter((n2) => !this._matched.has(n2));
244406
+ }
244407
+ }
244408
+ function sameScopeAs(a2, b2) {
244409
+ return a2.length === b2.length && a2.every((name2, i2) => name2 === b2[i2]);
244410
+ }
244411
+ function isSuffixOf(scope, path) {
244412
+ if (scope.length > path.length) {
244413
+ return false;
244414
+ }
244415
+ const offset = path.length - scope.length;
244416
+ return scope.every((name2, i2) => name2 === path[offset + i2]);
244417
+ }
244418
+ function collectExistingNames(tree) {
244419
+ const names = /* @__PURE__ */ new Set();
244420
+ visit(tree, (node) => {
244421
+ if (!isDastElement(node)) {
244422
+ return;
244423
+ }
244424
+ const nameAttr = Object.entries(node.attributes).find(
244425
+ ([name2]) => name2.toLowerCase() === "name"
244426
+ )?.[1];
244427
+ if (nameAttr) {
244428
+ const name2 = toXml(nameAttr.children).trim();
244429
+ if (name2) {
244430
+ names.add(name2);
244431
+ }
244432
+ }
244433
+ });
244434
+ return names;
244435
+ }
244436
+ function collectAllNames(tree) {
244437
+ const names = collectExistingNames(tree);
244438
+ visit(tree, (node) => {
244439
+ if (!isDastElement(node)) {
244440
+ return;
244441
+ }
244442
+ const assignNamesAttr = Object.entries(node.attributes).find(
244443
+ ([name2]) => name2.toLowerCase() === "assignnames"
244444
+ )?.[1];
244445
+ if (!assignNamesAttr) {
244446
+ return;
244447
+ }
244448
+ const assignNames = toXml(assignNamesAttr.children).trim();
244449
+ for (const name2 of assignNames.split(/[\s()]+/)) {
244450
+ if (name2) {
244451
+ names.add(name2);
244452
+ }
244453
+ }
244454
+ });
244455
+ return names;
244456
+ }
244457
+ function createUniqueNameFactory(tree) {
244458
+ const used = collectAllNames(tree);
244459
+ return (baseName) => {
244460
+ let name2 = baseName;
244461
+ let i2 = 1;
244462
+ while (used.has(name2)) {
244463
+ name2 = `${baseName}${i2}`;
244464
+ i2++;
244465
+ }
244466
+ used.add(name2);
244467
+ return name2;
244468
+ };
244469
+ }
244470
+ function isV06True(attr) {
244471
+ if (!attr) {
244472
+ return false;
244473
+ }
244474
+ const value = toXml(attr.children).trim().toLowerCase();
244475
+ return value === "" || value === "true";
244476
+ }
244477
+ const COMPOSITES = {
244478
+ select: {
244479
+ name: "select",
244480
+ count: { kind: "attr", attr: "numToSelect" },
244481
+ grouping: { childName: "option" }
244482
+ },
244483
+ selectfromsequence: {
244484
+ name: "selectFromSequence",
244485
+ count: { kind: "attr", attr: "numToSelect" }
244486
+ },
244487
+ selectrandomnumbers: {
244488
+ name: "selectRandomNumbers",
244489
+ count: { kind: "attr", attr: "numToSelect" }
244490
+ },
244491
+ samplerandomnumbers: {
244492
+ name: "sampleRandomNumbers",
244493
+ count: { kind: "attr", attr: "numSamples" }
244494
+ },
244495
+ selectprimenumbers: {
244496
+ name: "selectPrimeNumbers",
244497
+ count: { kind: "attr", attr: "numToSelect" }
244498
+ },
244499
+ sampleprimenumbers: {
244500
+ name: "samplePrimeNumbers",
244501
+ count: { kind: "attr", attr: "numSamples" }
244502
+ },
244503
+ conditionalcontent: {
244504
+ name: "conditionalContent",
244505
+ count: { kind: "always-one" },
244506
+ grouping: { childName: "case", alsoMatch: ["else"] }
244507
+ },
244508
+ lorem: { name: "lorem", count: { kind: "unknown" } },
244509
+ sort: { name: "sort", count: { kind: "unknown" } },
244510
+ shuffle: { name: "shuffle", count: { kind: "unknown" } },
244511
+ group: { name: "group", count: { kind: "unknown" } },
244512
+ sequence: { name: "sequence", count: { kind: "unknown" } },
244513
+ substitute: { name: "substitute", count: { kind: "unknown" } },
244514
+ split: { name: "split", count: { kind: "unknown" } },
244515
+ intersection: { name: "intersection", count: { kind: "unknown" } },
244516
+ extract: {
244517
+ name: "extract",
244518
+ count: { kind: "unknown" },
244519
+ noV07Equivalent: true
244520
+ }
244521
+ };
244522
+ function lookupComposite(node) {
244523
+ return COMPOSITES[node.name.toLowerCase()];
244524
+ }
244525
+ function producesSingleReplacement(node, spec) {
244526
+ if (spec.count.kind === "always-one") {
244527
+ return true;
244528
+ }
244529
+ if (spec.count.kind === "unknown") {
244530
+ return false;
244531
+ }
244532
+ const attr = findAttribute(node, spec.count.attr);
244533
+ if (!attr) {
244534
+ return true;
244535
+ }
244536
+ const raw = toXml(attr.children).trim();
244537
+ return raw === "" || raw === "1";
244538
+ }
244539
+ function findAttribute(node, attrName) {
244540
+ return Object.entries(node.attributes).find(
244541
+ ([name2]) => name2.toLowerCase() === attrName.toLowerCase()
244542
+ )?.[1];
244543
+ }
244544
+ function makePositionMap(node, spec, file) {
244545
+ if (!spec.grouping) {
244546
+ return void 0;
244547
+ }
244548
+ const names = [
244549
+ spec.grouping.childName,
244550
+ ...spec.grouping.alsoMatch || []
244551
+ ].map((n2) => n2.toLowerCase());
244552
+ const branches = node.children.filter(
244553
+ (child) => isDastElement(child) && names.includes(child.name.toLowerCase())
244554
+ );
244555
+ if (branches.length === 0) {
244556
+ return void 0;
244557
+ }
244558
+ return positionMapForBranches(
244559
+ branches.map((branch) => branch.children),
244560
+ node,
244561
+ file
244562
+ );
244563
+ }
244564
+ function makeTemplatePositionMap(template2, node, file) {
244565
+ return positionMapForBranches([template2.children], node, file);
244566
+ }
244567
+ function positionMapForBranches(branches, node, file) {
244568
+ const maps = branches.map((children) => branchPositionMap(children));
244569
+ const first2 = maps[0];
244570
+ if (maps.every((m2) => isIdentity(m2))) {
244571
+ return void 0;
244572
+ }
244573
+ if (!maps.every((m2) => sameMap(m2, first2))) {
244574
+ file.message(
244575
+ `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.`,
244576
+ {
244577
+ place: node.position,
244578
+ ruleId: "assign-names/branch-index-skew",
244579
+ source: "v06-to-v07"
244580
+ }
244581
+ );
244582
+ }
244583
+ file.message(
244584
+ `<${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.`,
244585
+ {
244586
+ place: node.position,
244587
+ ruleId: "assign-names/primitive-skew",
244588
+ source: "v06-to-v07"
244589
+ }
244590
+ );
244591
+ const insideGroupingDepth = 2;
244592
+ return (depth, ordinal) => {
244593
+ if (depth !== insideGroupingDepth) {
244594
+ return ordinal;
244595
+ }
244596
+ return first2[ordinal - 1];
244597
+ };
244598
+ }
244599
+ function branchPositionMap(children) {
244600
+ const result2 = [];
244601
+ let position2 = 0;
244602
+ for (const child of children) {
244603
+ if (child.type === "text") {
244604
+ if (child.value.trim() === "") {
244605
+ continue;
244606
+ }
244607
+ position2++;
244608
+ continue;
244609
+ }
244610
+ if (child.type === "comment" || child.type === "instruction") {
244611
+ continue;
244612
+ }
244613
+ position2++;
244614
+ result2.push(position2);
244615
+ }
244616
+ return result2;
244617
+ }
244618
+ function isIdentity(map2) {
244619
+ return map2.every((v2, i2) => v2 === i2 + 1);
244620
+ }
244621
+ function sameMap(a2, b2) {
244622
+ return a2.length === b2.length && a2.every((v2, i2) => v2 === b2[i2]);
244623
+ }
244624
+ function createAssignNamesContext(tree) {
244625
+ const existingNames = collectExistingNames(tree);
244626
+ const namespaceElements = /* @__PURE__ */ new WeakMap();
244627
+ let unnamedCount = 0;
244628
+ visit(tree, (node) => {
244629
+ if (!isDastElement(node)) {
244630
+ return;
244631
+ }
244632
+ const newNamespaceKey = Object.keys(node.attributes).find(
244633
+ (key) => key.toLowerCase() === "newnamespace"
244634
+ );
244635
+ if (newNamespaceKey === void 0) {
244636
+ return;
244637
+ }
244638
+ const newNamespaceValue = toXml(
244639
+ node.attributes[newNamespaceKey].children
244640
+ ).trim().toLowerCase();
244641
+ if (newNamespaceValue !== "" && newNamespaceValue !== "true") {
244642
+ return;
244643
+ }
244644
+ const nameAttr = findAttribute(node, "name");
244645
+ const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
244646
+ namespaceElements.set(node, name2 || `\0ns${++unnamedCount}`);
244647
+ });
244648
+ const context = {
244649
+ registry: new RenameRegistry(existingNames),
244650
+ uniqueName: createUniqueNameFactory(tree),
244651
+ existingNames,
244652
+ claimedNames: /* @__PURE__ */ new Set(),
244653
+ namespaceElements,
244654
+ existingNameScopes: /* @__PURE__ */ new Map()
244655
+ };
244656
+ visit(tree, (node, info) => {
244657
+ if (!isDastElement(node)) {
244658
+ return;
244659
+ }
244660
+ const nameAttr = findAttribute(node, "name");
244661
+ const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
244662
+ if (!name2) {
244663
+ return;
244664
+ }
244665
+ const scopes = context.existingNameScopes.get(name2) ?? [];
244666
+ scopes.push(namespaceChainOf(info.parents, context));
244667
+ context.existingNameScopes.set(name2, scopes);
244668
+ });
244669
+ return context;
244670
+ }
244671
+ function nameTakenInScope(context, name2, ancestorNames) {
244672
+ const scopes = context.existingNameScopes.get(name2);
244673
+ if (!scopes) {
244674
+ return false;
244675
+ }
244676
+ const here = ancestorNames ?? [];
244677
+ return scopes.some(
244678
+ (scope) => scope.length === here.length && scope.every((segment, i2) => segment === here[i2])
244679
+ );
244680
+ }
244681
+ function chooseCompositeName(node, pieces, fallbackBase, context, file) {
244682
+ const nameAttr = findAttribute(node, "name");
244683
+ const existingName = nameAttr ? toXml(nameAttr.children).trim() : "";
244684
+ if (existingName && isValidReferenceableName(existingName)) {
244685
+ return existingName;
244686
+ }
244687
+ if (existingName) {
244688
+ file?.message(
244689
+ `<${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.`,
244690
+ {
244691
+ place: node.position,
244692
+ ruleId: "assign-names/invalid-name",
244693
+ source: "v06-to-v07"
244694
+ }
244695
+ );
244696
+ }
244697
+ const firstName = firstLeafName(pieces);
244698
+ if (firstName && isValidReferenceableName(firstName) && !context.existingNames.has(firstName) && !context.claimedNames.has(firstName)) {
244699
+ context.claimedNames.add(firstName);
244700
+ return firstName;
244701
+ }
244702
+ return context.uniqueName(fallbackBase);
244703
+ }
244704
+ function setCompositeName(node, name2) {
244705
+ const nameAttr = findAttribute(node, "name");
244706
+ const oldKey = assignNamesKey(node);
244707
+ if (nameAttr) {
244708
+ if (toXml(nameAttr.children) !== name2) {
244709
+ nameAttr.children = [{ type: "text", value: name2 }];
244710
+ }
244711
+ deleteAssignNames(node);
244712
+ return;
244713
+ }
244714
+ if (oldKey !== void 0) {
244715
+ renameAttrInPlace(node, oldKey, "name");
244716
+ node.attributes["name"].children = [{ type: "text", value: name2 }];
244717
+ return;
244718
+ }
244719
+ node.attributes["name"] = {
244720
+ type: "attribute",
244721
+ name: "name",
244722
+ children: [{ type: "text", value: name2 }]
244723
+ };
244724
+ }
244725
+ function readAssignNames(node) {
244726
+ const key = assignNamesKey(node);
244727
+ if (key === void 0) {
244728
+ return void 0;
244729
+ }
244730
+ return toXml(node.attributes[key].children).trim();
244731
+ }
244732
+ function deleteAssignNames(node) {
244733
+ const key = assignNamesKey(node);
244734
+ if (key !== void 0) {
244735
+ delete node.attributes[key];
244736
+ }
244737
+ }
244738
+ function assignNamesKey(node) {
244739
+ return Object.keys(node.attributes).find(
244740
+ (k2) => k2.toLowerCase() === "assignnames"
244741
+ );
244742
+ }
244743
+ function namespaceChainOf(parents, context) {
244744
+ const chain2 = [];
244745
+ for (const parent of parents) {
244746
+ const segment = context.namespaceElements.get(parent);
244747
+ if (segment !== void 0) {
244748
+ chain2.push(segment);
244749
+ }
244750
+ }
244751
+ return chain2.reverse();
244752
+ }
244753
+ function inheritNamespace(from, to2, context) {
244754
+ const segment = context.namespaceElements.get(from);
244755
+ if (segment !== void 0) {
244756
+ context.namespaceElements.set(to2, segment);
244757
+ }
244758
+ }
244759
+ const identityPositionMap = (_depth, ordinal) => ordinal;
244760
+ function registerAssignNames({
244761
+ assignNamesValue,
244762
+ compositeName,
244763
+ registry,
244764
+ origin,
244765
+ file,
244766
+ positionMap = identityPositionMap
244767
+ }) {
244768
+ const result2 = breakStringInPiecesBySpacesOrParens(assignNamesValue);
244769
+ if (!result2.success) {
244770
+ file.message(
244771
+ `Could not parse assignNames="${assignNamesValue}" on <${origin.elementName}> because its parentheses are unbalanced; references to those names were not converted.`,
244772
+ {
244773
+ place: origin.position,
244774
+ ruleId: "assign-names/unbalanced-parens",
244775
+ source: "v06-to-v07"
244776
+ }
244777
+ );
244778
+ return false;
244779
+ }
244780
+ registerPieces(result2.pieces, []);
244781
+ return true;
244782
+ function registerPieces(pieces, indexPath) {
244783
+ pieces.forEach((piece, i2) => {
244784
+ const depth = indexPath.length + 1;
244785
+ const position2 = positionMap(depth, i2 + 1);
244786
+ if (position2 === void 0) {
244787
+ reportNamesNothing(piece);
244788
+ return;
244789
+ }
244790
+ const indices = [...indexPath, position2];
244791
+ if (typeof piece === "string") {
244792
+ if (!isValidReferenceableName(piece)) {
244793
+ file.message(
244794
+ `The assignNames token "${piece}" on <${origin.elementName}> is not a valid v0.7 name, so references to it were not converted.`,
244795
+ {
244796
+ place: origin.position,
244797
+ ruleId: "assign-names/invalid-name",
244798
+ source: "v06-to-v07"
244799
+ }
244800
+ );
244801
+ return;
244802
+ }
244803
+ registry.register(
244804
+ piece,
244805
+ [makeIndexedPathPart(compositeName, indices)],
244806
+ origin,
244807
+ file
244808
+ );
244809
+ } else {
244810
+ registerPieces(piece, indices);
244811
+ }
244812
+ });
244813
+ }
244814
+ function reportNamesNothing(piece) {
244815
+ if (typeof piece !== "string") {
244816
+ piece.forEach(reportNamesNothing);
244817
+ return;
244818
+ }
244819
+ file.message(
244820
+ `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.`,
244821
+ {
244822
+ place: origin.position,
244823
+ ruleId: "assign-names/names-nothing",
244824
+ source: "v06-to-v07"
244825
+ }
244826
+ );
244827
+ }
244828
+ }
244829
+ function registerCompositeAssignNames({
244830
+ node,
244831
+ assignNamesValue,
244832
+ fallbackBase,
244833
+ ancestorNames,
244834
+ context,
244835
+ file,
244836
+ positionMap
244837
+ }) {
244838
+ const origin = {
244839
+ elementName: node.name,
244840
+ position: node.position,
244841
+ ancestorNames,
244842
+ element: node
244843
+ };
244844
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
244845
+ if (!parsed.success) {
244846
+ registerAssignNames({
244847
+ assignNamesValue,
244848
+ compositeName: "",
244849
+ registry: context.registry,
244850
+ origin,
244851
+ file
244852
+ });
244853
+ return void 0;
244854
+ }
244855
+ if (firstLeafName(parsed.pieces) === void 0) {
244856
+ return void 0;
244857
+ }
244858
+ const compositeName = chooseCompositeName(
244859
+ node,
244860
+ parsed.pieces,
244861
+ fallbackBase,
244862
+ context,
244863
+ file
244864
+ );
244865
+ registerAssignNames({
244866
+ assignNamesValue,
244867
+ compositeName,
244868
+ registry: context.registry,
244869
+ origin,
244870
+ file,
244871
+ positionMap
244872
+ });
244873
+ return compositeName;
244874
+ }
244875
+ function visitAll(tree, visitor) {
244876
+ walk(tree, [], void 0);
244877
+ function walk(node, parents, attributeOwner) {
244878
+ const isMacro = node.type === "macro" || node.type === "function";
244879
+ if (!isMacro) {
244880
+ visitor(node, parents, attributeOwner);
244881
+ }
244882
+ const innerParents = isDastElement(node) ? [node, ...parents] : parents;
244883
+ if (isDastElement(node)) {
244884
+ for (const attr of Object.values(node.attributes)) {
244885
+ walkArray(attr.children, innerParents, node);
244886
+ }
244887
+ }
244888
+ if (node.type === "macro") {
244889
+ walkMacroAttributes(node, innerParents, attributeOwner);
244890
+ walkMacroPath(node, innerParents, attributeOwner);
244891
+ const accessedProp = node.accessedProp;
244892
+ if (accessedProp) {
244893
+ walk(accessedProp, innerParents, attributeOwner);
244894
+ }
244895
+ }
244896
+ if (node.type === "function") {
244897
+ const inner = node.macro;
244898
+ if (inner) {
244899
+ walk(inner, innerParents, attributeOwner);
244900
+ }
244901
+ walkMacroPath(node, innerParents, attributeOwner);
244902
+ for (const inputPart of node.input || []) {
244903
+ walkArray(
244904
+ inputPart,
244905
+ innerParents,
244906
+ attributeOwner
244907
+ );
244908
+ }
244909
+ }
244910
+ if ("children" in node && Array.isArray(node.children)) {
244911
+ walkArray(
244912
+ node.children,
244913
+ innerParents,
244914
+ isDastElement(node) ? void 0 : attributeOwner
244915
+ );
244916
+ }
244917
+ if (isMacro) {
244918
+ visitor(node, parents, attributeOwner);
244919
+ }
244920
+ }
244921
+ function walkMacroAttributes(node, parents, attributeOwner) {
244922
+ const attrs = Array.isArray(node.attributes) ? node.attributes : Object.values(node.attributes);
244923
+ for (const attr of attrs) {
244924
+ walkArray(attr.children, parents, attributeOwner);
244925
+ }
244926
+ }
244927
+ function walkMacroPath(node, parents, attributeOwner) {
244928
+ for (const part of node.path || []) {
244929
+ for (const index2 of part.index) {
244930
+ walkArray(index2.value, parents, attributeOwner);
244931
+ }
244932
+ }
244933
+ }
244934
+ function walkArray(nodes, parents, attributeOwner) {
244935
+ for (let i2 = 0; i2 < nodes.length; i2++) {
244936
+ walk(nodes[i2], parents, attributeOwner);
244937
+ }
244938
+ }
244939
+ }
244940
+ function visitAllMacros(tree, visitor) {
244941
+ visitAll(tree, (node, parents, attributeOwner) => {
244942
+ if (node.type !== "macro" && node.type !== "function") {
244943
+ return;
244944
+ }
244945
+ if (!Array.isArray(node.path)) {
244946
+ return;
244947
+ }
244948
+ visitor(node, parents, attributeOwner);
244949
+ });
244950
+ }
244951
+ const propAccessParts = /* @__PURE__ */ new WeakSet();
244952
+ function markAsPropAccess(part) {
244953
+ propAccessParts.add(part);
244954
+ }
244955
+ function isPropAccess(part) {
244956
+ return propAccessParts.has(part);
244957
+ }
244958
+ const rawPropPositions = /* @__PURE__ */ new WeakMap();
244959
+ function markRawPropPositions(node, attrName, positions) {
244960
+ let byAttr = rawPropPositions.get(node);
244961
+ if (!byAttr) {
244962
+ byAttr = /* @__PURE__ */ new Map();
244963
+ rawPropPositions.set(node, byAttr);
244964
+ }
244965
+ byAttr.set(attrName.toLowerCase(), positions);
244966
+ }
244967
+ function restoreRawPropPositions(node, attrName, path) {
244968
+ const positions = rawPropPositions.get(node)?.get(attrName.toLowerCase());
244969
+ if (!positions) {
244970
+ return;
244971
+ }
244972
+ for (const position2 of positions) {
244973
+ const part = path[position2];
244974
+ if (part) {
244975
+ markAsPropAccess(part);
244976
+ }
244977
+ }
244978
+ }
244979
+ const RAW_REFERENCE_ATTRS = {
244980
+ copy: ["source"],
244981
+ extract: ["source"]
244982
+ };
244983
+ function applyRefRenames(tree, registry, file, context) {
244984
+ if (registry.size === 0) {
244985
+ return;
244986
+ }
244987
+ visitAllMacros(tree, (node, parents, attributeOwner) => {
244988
+ node.path = renamePath(
244989
+ node.path,
244990
+ registry,
244991
+ file,
244992
+ node.position,
244993
+ namespaceChainOf(parents, context),
244994
+ // A reference written on an element cannot mean the name that element is
244995
+ // about to take: `<copy source="$x0" assignNames="x0">` reaches elsewhere
244996
+ // for the thing it copies. References among its *children* are a different
244997
+ // matter and keep their ownership clear, so `visitAll` reports none for them.
244998
+ attributeOwner
244999
+ );
245000
+ });
245001
+ visitAll(tree, (node, parents) => {
245002
+ if (!isDastElement(node)) {
245003
+ return;
245004
+ }
245005
+ const attrNames = RAW_REFERENCE_ATTRS[node.name.toLowerCase()];
245006
+ if (!attrNames) {
245007
+ return;
245008
+ }
245009
+ const enclosing = namespaceChainOf(parents, context);
245010
+ for (const attrName of attrNames) {
245011
+ renameRawReferenceAttribute(
245012
+ node,
245013
+ attrName,
245014
+ registry,
245015
+ file,
245016
+ enclosing
245017
+ );
245018
+ }
245019
+ });
245020
+ }
245021
+ function renameRawReferenceAttribute(node, attrName, registry, file, enclosingNames) {
245022
+ const attr = Object.entries(node.attributes).find(
245023
+ ([name2]) => name2.toLowerCase() === attrName.toLowerCase()
245024
+ )?.[1];
245025
+ if (!attr || attr.children.length !== 1) {
245026
+ return;
245027
+ }
245028
+ const child = attr.children[0];
245029
+ if (child.type !== "text") {
245030
+ return;
245031
+ }
245032
+ const value = child.value.trim();
245033
+ if (!value) {
245034
+ return;
245035
+ }
245036
+ if (!value.split(/[^A-Za-z0-9_-]+/).some((piece) => registry.hasReplacement(piece))) {
245037
+ return;
245038
+ }
245039
+ let path;
245040
+ try {
245041
+ path = parseReferencePath(value);
245042
+ } catch (e4) {
245043
+ file.message(
245044
+ `Could not convert a reference to an assignNames name in ${attrName}="${value}".`,
245045
+ {
245046
+ place: node.position,
245047
+ ruleId: "assign-names/unparsable-reference-attribute",
245048
+ source: "v06-to-v07"
245049
+ }
245050
+ );
245051
+ return;
245052
+ }
245053
+ restoreRawPropPositions(node, attrName, path);
245054
+ const asMacro = { type: "macro", path, attributes: {} };
245055
+ visitAllMacros(asMacro, (macro) => {
245056
+ macro.path = renamePath(
245057
+ macro.path,
245058
+ registry,
245059
+ file,
245060
+ node.position,
245061
+ enclosingNames,
245062
+ // A copy's `source` says what it copies, which is never the copy itself:
245063
+ // `<copy source="../x0" assignNames="x0">` names its result `x0` while
245064
+ // reaching out of the namespace for the `x0` it copies.
245065
+ node
245066
+ );
245067
+ });
245068
+ child.value = toXml(asMacro.path);
245069
+ }
245070
+ function renamePath(path, registry, file, place, enclosingNames = [], writtenOn) {
245071
+ if (!path.some((part) => registry.hasReplacement(part.name))) {
245072
+ return path;
245073
+ }
245074
+ return path.flatMap((part, partIndex) => {
245075
+ const target = registry.get(
245076
+ part.name,
245077
+ [...enclosingNames, ...path.slice(0, partIndex).map((p2) => p2.name)],
245078
+ writtenOn
245079
+ );
245080
+ if (!target?.replacement) {
245081
+ return [part];
245082
+ }
245083
+ if (partIndex > 0 && isPropAccess(part)) {
245084
+ return [part];
245085
+ }
245086
+ const replacement = structuredClone(
245087
+ target.replacement
245088
+ );
245089
+ const last2 = replacement[replacement.length - 1];
245090
+ last2.index = [...last2.index, ...part.index];
245091
+ return replacement;
245092
+ });
245093
+ }
245094
+ function parseReferencePath(value) {
245095
+ for (const candidate of [`$${value}`, `$(${value})`]) {
245096
+ let reparsed;
245097
+ try {
245098
+ reparsed = reparseAttribute(candidate);
245099
+ } catch (e4) {
245100
+ continue;
245101
+ }
245102
+ if (reparsed.length === 1 && reparsed[0].type === "macro") {
245103
+ return reparsed[0].path;
245104
+ }
245105
+ }
245106
+ throw new Error(`Could not parse "${value}" as a reference`);
245107
+ }
245108
+ const upgradeCollectElement = (context) => {
244211
245109
  return (tree, file) => {
244212
- const refsToRename = {};
244213
- visit(tree, (node) => {
245110
+ visit(tree, (node, info) => {
244214
245111
  if (!isDastElement(node)) {
244215
245112
  return;
244216
245113
  }
@@ -244220,50 +245117,45 @@ const upgradeCollectElement = () => {
244220
245117
  if (node.attributes["componentTypes"]) {
244221
245118
  renameAttrInPlace(node, "componentTypes", "componentType");
244222
245119
  }
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
- );
245120
+ for (const oldKey of ["source", "target"]) {
245121
+ if (!node.attributes[oldKey]) {
245122
+ continue;
244238
245123
  }
245124
+ renameAttrInPlace(node, oldKey, "from");
245125
+ makeFromAReference(node, file);
245126
+ break;
244239
245127
  }
244240
- const assignNames = node.attributes["assignNames"];
244241
- if (!assignNames) {
245128
+ const assignNamesValue = readAssignNames(node);
245129
+ if (!assignNamesValue) {
245130
+ deleteAssignNames(node);
244242
245131
  return;
244243
245132
  }
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;
245133
+ const compositeName = registerCompositeAssignNames({
245134
+ node,
245135
+ assignNamesValue,
245136
+ fallbackBase: "collect",
245137
+ ancestorNames: namespaceChainOf(info.parents, context),
245138
+ context,
245139
+ file
244255
245140
  });
245141
+ if (compositeName === void 0) {
245142
+ deleteAssignNames(node);
245143
+ return;
245144
+ }
245145
+ setCompositeName(node, compositeName);
244256
245146
  });
244257
245147
  replaceNode(tree, (node) => {
244258
245148
  if (!isDastElement(node) || node.name !== "collect") {
244259
245149
  return;
244260
245150
  }
244261
- const propAttr = node.attributes["prop"];
244262
- const propName = toXml(propAttr?.children).trim();
245151
+ const propKey = Object.keys(node.attributes).find(
245152
+ (key) => key.toLowerCase() === "prop"
245153
+ );
245154
+ const propName = propKey ? toXml(node.attributes[propKey].children).trim() : "";
244263
245155
  if (!propName) {
244264
245156
  return;
244265
245157
  }
244266
- delete node.attributes["prop"];
245158
+ delete node.attributes[propKey];
244267
245159
  const setup = {
244268
245160
  type: "element",
244269
245161
  name: "setup",
@@ -244273,8 +245165,9 @@ const upgradeCollectElement = () => {
244273
245165
  const componentType = toXml(
244274
245166
  node.attributes["componentType"]?.children
244275
245167
  ).trim();
244276
- const listName = node.attributes["name"] ? toXml(node.attributes["name"].children) : getUniqueName(tree, "list");
244277
- const collectName = getUniqueName(tree, `collect_${listName}`);
245168
+ const authoredListName = node.attributes["name"] ? toXml(node.attributes["name"].children).trim() : "";
245169
+ const listName = authoredListName && isValidReferenceableName(authoredListName) ? authoredListName : context.uniqueName("list");
245170
+ const collectName = context.uniqueName(`collect_${listName}`);
244278
245171
  node.attributes["name"] = {
244279
245172
  type: "attribute",
244280
245173
  name: "name",
@@ -244284,7 +245177,11 @@ const upgradeCollectElement = () => {
244284
245177
  if (!listType) {
244285
245178
  file.message(
244286
245179
  `Could not determine type for prop "${propName}" of component type "${componentType}". Using "math" as default.`,
244287
- { place: node.position }
245180
+ {
245181
+ place: node.position,
245182
+ ruleId: "collect/unknown-prop-type",
245183
+ source: "v06-to-v07"
245184
+ }
244288
245185
  );
244289
245186
  listType = "math";
244290
245187
  }
@@ -244302,30 +245199,81 @@ const upgradeCollectElement = () => {
244302
245199
  extend: {
244303
245200
  type: "attribute",
244304
245201
  name: "extend",
244305
- children: reparseAttribute(
244306
- `$${collectName}.${propName}`
244307
- )
245202
+ children: [
245203
+ {
245204
+ type: "macro",
245205
+ path: [
245206
+ ...parseReferencePath(collectName),
245207
+ ...propPathParts(propName, node, file)
245208
+ ],
245209
+ attributes: {}
245210
+ }
245211
+ ]
244308
245212
  }
244309
245213
  },
244310
245214
  children: []
244311
245215
  };
244312
245216
  return [setup, list];
244313
245217
  });
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
245218
  };
244326
245219
  };
245220
+ function makeFromAReference(node, file) {
245221
+ const attr = node.attributes["from"];
245222
+ const value = toXml(attr.children).trim();
245223
+ if (!value || value.startsWith("$")) {
245224
+ return;
245225
+ }
245226
+ try {
245227
+ attr.children = [
245228
+ {
245229
+ type: "macro",
245230
+ path: parseReferencePath(value),
245231
+ attributes: {}
245232
+ }
245233
+ ];
245234
+ } catch {
245235
+ file.message(
245236
+ `Could not read "${value}" as the name of what <collect> collects from.`,
245237
+ {
245238
+ place: node.position,
245239
+ ruleId: "collect/unparsable-from",
245240
+ source: "v06-to-v07"
245241
+ }
245242
+ );
245243
+ }
245244
+ }
245245
+ function propPathParts(propName, node, file) {
245246
+ let parts;
245247
+ try {
245248
+ parts = parseReferencePath(propName);
245249
+ } catch {
245250
+ file.message(
245251
+ `<collect prop="${propName}"> could not be turned into a reference, so the generated list extends a path that needs fixing by hand.`,
245252
+ {
245253
+ place: node.position,
245254
+ ruleId: "collect/unparsable-prop",
245255
+ source: "v06-to-v07"
245256
+ }
245257
+ );
245258
+ return [{ type: "pathPart", name: propName, index: [] }];
245259
+ }
245260
+ parts.forEach(markAsPropAccess);
245261
+ return parts;
245262
+ }
244327
245263
  const upgradePathSlashesToDots = () => {
244328
245264
  return (tree, file) => {
245265
+ const warnParentPath = (original) => {
245266
+ file.message(
245267
+ `There is no equivalent to the $(../x) syntax; a best-guess was made when converting ${macroToString(
245268
+ original
245269
+ )}`,
245270
+ {
245271
+ place: original.position,
245272
+ ruleId: "no-v07-equivalent/parent-path",
245273
+ source: "v06-to-v07"
245274
+ }
245275
+ );
245276
+ };
244329
245277
  visit(
244330
245278
  tree,
244331
245279
  // @ts-ignore
@@ -244336,44 +245284,17 @@ const upgradePathSlashesToDots = () => {
244336
245284
  }
244337
245285
  if (isDastElement(node)) {
244338
245286
  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
- }
245287
+ collectV06Macros(attr.children, macros);
244344
245288
  }
244345
245289
  }
244346
245290
  for (const node2 of macros) {
244347
- const macro = node2.type === "macro" ? v06MacroToV07Macro(node2) : v06FunctionMacroToV07FunctionMacro(node2);
245291
+ const macro = node2.type === "macro" ? v06MacroToV07Macro(node2, warnParentPath) : v06FunctionMacroToV07FunctionMacro(
245292
+ node2,
245293
+ warnParentPath
245294
+ );
244348
245295
  Object.keys(node2).forEach((key) => {
244349
245296
  delete node2[key];
244350
245297
  });
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
245298
  Object.assign(node2, macro);
244378
245299
  }
244379
245300
  }
@@ -244382,24 +245303,54 @@ const upgradePathSlashesToDots = () => {
244382
245303
  if (!isDastElement(node)) {
244383
245304
  return;
244384
245305
  }
245306
+ if (!ELEMENTS_WITH_REFERENCE_SOURCE.has(node.name.toLowerCase())) {
245307
+ return;
245308
+ }
244385
245309
  const sourceAttr = node.attributes["source"];
244386
245310
  if (!sourceAttr) {
244387
245311
  return;
244388
245312
  }
244389
245313
  const sourceName = toXml(sourceAttr.children).trim();
244390
- if (!sourceName.includes("/")) {
245314
+ const hasSlash = sourceName.includes("/");
245315
+ if (!hasSlash && !sourceName.includes(".")) {
244391
245316
  return;
244392
245317
  }
244393
245318
  const reparsedSource = parseMacrosV06(`$(${sourceName})`);
244394
245319
  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
- );
245320
+ if (hasSlash) {
245321
+ file.message(
245322
+ `Could not reparse "source" attribute that contains a slash: "${sourceName}".`,
245323
+ {
245324
+ place: node.position,
245325
+ ruleId: "copy/unparsable-source",
245326
+ source: "v06-to-v07"
245327
+ }
245328
+ );
245329
+ }
244399
245330
  return;
244400
245331
  }
244401
- const upgradedSource = v06MacroToV07Macro(reparsedSource[0]);
245332
+ const upgradedSource = v06MacroToV07Macro(
245333
+ reparsedSource[0],
245334
+ () => file.message(
245335
+ `There is no equivalent to the ../x syntax; a best-guess was made when converting source="${sourceName}"`,
245336
+ {
245337
+ place: node.position,
245338
+ ruleId: "no-v07-equivalent/parent-path",
245339
+ source: "v06-to-v07"
245340
+ }
245341
+ )
245342
+ );
245343
+ markRawPropPositions(
245344
+ node,
245345
+ "source",
245346
+ upgradedSource.path.flatMap(
245347
+ (part, index2) => isPropAccess(part) ? [index2] : []
245348
+ )
245349
+ );
244402
245350
  const newSourceName = toXml(upgradedSource.path);
245351
+ if (newSourceName === sourceName) {
245352
+ return;
245353
+ }
244403
245354
  sourceAttr.children = [
244404
245355
  {
244405
245356
  type: "text",
@@ -244410,12 +245361,44 @@ const upgradePathSlashesToDots = () => {
244410
245361
  });
244411
245362
  };
244412
245363
  };
244413
- function v06MacroToV07Macro(macro) {
244414
- const path = flattenedAccessedProps(macro);
245364
+ function collectV06Macros(nodes, macros) {
245365
+ for (const node of nodes) {
245366
+ if (isV06MacroOrFunctionMacro(node)) {
245367
+ macros.push(node);
245368
+ }
245369
+ }
245370
+ }
245371
+ const ELEMENTS_WITH_REFERENCE_SOURCE = /* @__PURE__ */ new Set(["copy", "collect", "extract"]);
245372
+ function collapseParentPathParts(path, warn) {
245373
+ if (!path.some((part) => part.name === "..")) {
245374
+ return path;
245375
+ }
245376
+ const newPath = [];
245377
+ let warned = false;
245378
+ for (const part of path) {
245379
+ if (part.name === "..") {
245380
+ if (newPath.length > 0) {
245381
+ newPath.pop();
245382
+ }
245383
+ if (!warned) {
245384
+ warned = true;
245385
+ warn();
245386
+ }
245387
+ continue;
245388
+ }
245389
+ newPath.push(part);
245390
+ }
245391
+ return newPath;
245392
+ }
245393
+ function v06MacroToV07Macro(macro, warn, reportAs = macro) {
245394
+ const path = collapseParentPathParts(
245395
+ flattenedAccessedProps(macro, warn),
245396
+ () => warn(reportAs)
245397
+ );
244415
245398
  const { accessedProp, version: version2, attributes, ...rest2 } = macro;
244416
245399
  return {
244417
245400
  ...rest2,
244418
- attributes: v06AttributeToV07Attribute(mergeAttributes(macro)),
245401
+ attributes: v06AttributeToV07Attribute(mergeAttributes(macro), warn),
244419
245402
  path
244420
245403
  };
244421
245404
  }
@@ -244433,35 +245416,56 @@ function mergeAttributes(macro) {
244433
245416
  }
244434
245417
  return ret;
244435
245418
  }
244436
- function v06FunctionMacroToV07FunctionMacro(funcMacro) {
244437
- const macro = v06MacroToV07Macro(funcMacro.macro);
245419
+ function v06FunctionMacroToV07FunctionMacro(funcMacro, warn) {
245420
+ const macro = v06MacroToV07Macro(funcMacro.macro, warn, funcMacro);
244438
245421
  return {
244439
245422
  type: "function",
244440
245423
  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,
245424
+ input: convertArguments(funcMacro.input, warn),
244444
245425
  position: funcMacro.position
244445
245426
  };
244446
245427
  }
244447
- function v06IndexToV07Index(index2) {
245428
+ function convertArguments(input, warn) {
245429
+ if (!input) {
245430
+ return null;
245431
+ }
245432
+ return input.map(
245433
+ (argument) => argument.map((node) => {
245434
+ if (isV06MacroOrFunctionMacro(node)) {
245435
+ return node.type === "macro" ? v06MacroToV07Macro(node, warn) : v06FunctionMacroToV07FunctionMacro(node, warn);
245436
+ }
245437
+ return node;
245438
+ })
245439
+ );
245440
+ }
245441
+ function v06IndexToV07Index(index2, warn) {
244448
245442
  return index2.map((ind) => ({
244449
245443
  ...ind,
244450
- value: ind.value.map(
244451
- (v2) => v2.type === "macro" ? v06MacroToV07Macro(v2) : v2
244452
- )
245444
+ // @ts-ignore -- see the note on `value` below
245445
+ // The DAST types say an index holds only text and plain macros, but the v0.6
245446
+ // parser does put a function macro in one (`$list[$$(g/h)(2)]`), so both have
245447
+ // to be converted here — this is the only pass that reaches them.
245448
+ value: ind.value.map((v2) => {
245449
+ if (v2.type === "macro") {
245450
+ return v06MacroToV07Macro(v2, warn);
245451
+ }
245452
+ if (v2.type === "function") {
245453
+ return v06FunctionMacroToV07FunctionMacro(v2, warn);
245454
+ }
245455
+ return v2;
245456
+ })
244453
245457
  }));
244454
245458
  }
244455
- function v06AttributeToV07Attribute(attrs) {
245459
+ function v06AttributeToV07Attribute(attrs, warn) {
244456
245460
  const ret = {};
244457
245461
  attrs = Array.isArray(attrs) ? attrs : Object.values(attrs);
244458
245462
  for (const attr of attrs) {
244459
245463
  const children = attr.children.map((c2) => {
244460
245464
  if (c2.type === "macro") {
244461
- return v06MacroToV07Macro(c2);
245465
+ return v06MacroToV07Macro(c2, warn);
244462
245466
  }
244463
245467
  if (c2.type === "function") {
244464
- return v06FunctionMacroToV07FunctionMacro(c2);
245468
+ return v06FunctionMacroToV07FunctionMacro(c2, warn);
244465
245469
  }
244466
245470
  return c2;
244467
245471
  });
@@ -244472,15 +245476,17 @@ function v06AttributeToV07Attribute(attrs) {
244472
245476
  }
244473
245477
  return ret;
244474
245478
  }
244475
- function flattenedAccessedProps(macro) {
245479
+ function flattenedAccessedProps(macro, warn) {
244476
245480
  const path = macro.path.map((p2) => {
244477
245481
  return {
244478
245482
  ...p2,
244479
- index: v06IndexToV07Index(p2.index)
245483
+ index: v06IndexToV07Index(p2.index, warn)
244480
245484
  };
244481
245485
  });
244482
245486
  if (macro.accessedProp) {
244483
- return [...path, ...flattenedAccessedProps(macro.accessedProp)];
245487
+ const propParts = flattenedAccessedProps(macro.accessedProp, warn);
245488
+ propParts.forEach(markAsPropAccess);
245489
+ return [...path, ...propParts];
244484
245490
  }
244485
245491
  return path;
244486
245492
  }
@@ -245235,9 +246241,26 @@ async function createCoreForLookup({ dast }) {
245235
246241
  const wasmBuffer = (await import("./lib_doenetml_worker_bg-BJtDoC-f.js")).default;
245236
246242
  await __wbg_init({ module_or_path: wasmBuffer });
245237
246243
  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();
246244
+ let core2;
246245
+ async function releaseCores() {
246246
+ try {
246247
+ await core2?.terminate();
246248
+ } catch (e4) {
246249
+ }
246250
+ try {
246251
+ rustCore.free();
246252
+ } catch (e4) {
246253
+ }
246254
+ }
246255
+ let normalizedRoot;
246256
+ try {
246257
+ dast = normalizeDocumentDast(structuredClone(dast), true);
246258
+ rustCore.set_source(dast, toXml(dast));
246259
+ normalizedRoot = rustCore.return_normalized_dast_root();
246260
+ } catch (e4) {
246261
+ await releaseCores();
246262
+ throw e4;
246263
+ }
245241
246264
  function resolvePath(path, origin, skip_parent_search) {
245242
246265
  return rustCore.resolve_path(path, origin, skip_parent_search);
245243
246266
  }
@@ -245248,44 +246271,62 @@ async function createCoreForLookup({ dast }) {
245248
246271
  rustCore.delete_nodes_from_resolver(node_list);
245249
246272
  }
245250
246273
  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);
246274
+ try {
246275
+ core2 = new PublicDoenetMLCore$1();
246276
+ core2.setSource(toXml(dast));
246277
+ core2.setFlags(flags);
246278
+ await core2.initializeWorker({
246279
+ activityId: "",
246280
+ docId: "1",
246281
+ requestedVariantIndex: 1,
246282
+ attemptNumber: 1,
246283
+ normalizedRoot,
246284
+ addNodesToResolver,
246285
+ deleteNodesFromResolver,
246286
+ resolvePath
246287
+ });
246288
+ const dastResult = await core2.createCoreGenerateDast(
246289
+ {
246290
+ coreId: "",
246291
+ cid: "",
246292
+ initializeCounters: {},
246293
+ theme: "light"
246294
+ },
246295
+ () => null,
246296
+ () => null,
246297
+ () => null,
246298
+ () => null,
246299
+ () => null,
246300
+ () => null,
246301
+ async () => ({ allowView: true })
246302
+ );
246303
+ if (!dastResult.success) {
246304
+ throw Error(dastResult.errMsg);
246305
+ }
246306
+ } catch (e4) {
246307
+ await releaseCores();
246308
+ throw e4;
246309
+ }
246310
+ const readyCore = core2;
246311
+ if (!readyCore) {
246312
+ await releaseCores();
246313
+ throw Error("The DoenetML core was not initialized.");
245281
246314
  }
245282
246315
  function resolvePathToNodeIdx(name2, origin = 0) {
245283
246316
  if (name2.startsWith("$")) {
245284
246317
  name2 = name2.slice(1);
245285
246318
  }
245286
- return resolvePathImmediatelyToNodeIdx(name2, rustCore, core2, origin);
246319
+ return resolvePathImmediatelyToNodeIdx(
246320
+ name2,
246321
+ rustCore,
246322
+ readyCore,
246323
+ origin
246324
+ );
245287
246325
  }
245288
- return { core: core2, rustCore, resolvePathToNodeIdx };
246326
+ async function dispose() {
246327
+ await releaseCores();
246328
+ }
246329
+ return { core: readyCore, rustCore, resolvePathToNodeIdx, dispose };
245289
246330
  }
245290
246331
  const upgradeCopySyntax = () => {
245291
246332
  return async (tree, file) => {
@@ -245302,91 +246343,128 @@ const upgradeCopySyntax = () => {
245302
246343
  if (skip) {
245303
246344
  return;
245304
246345
  }
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"];
246346
+ let core2;
246347
+ try {
246348
+ core2 = await createCoreForLookup({ dast: tree });
246349
+ } catch (e4) {
246350
+ file.message(
246351
+ `Could not load the document to work out what the <copy> tags refer to, so they were left as they are: ${e4}`,
246352
+ {
246353
+ ruleId: "copy/could-not-load-document",
246354
+ source: "v06-to-v07"
245329
246355
  }
245330
- renameAttrInPlace(node, "assignNames", "name");
246356
+ );
246357
+ return;
246358
+ }
246359
+ try {
246360
+ await resolveCopyTags(core2, tree, file);
246361
+ } finally {
246362
+ await core2.dispose();
246363
+ }
246364
+ };
246365
+ };
246366
+ async function resolveCopyTags(core2, tree, file) {
246367
+ const referenced = [];
246368
+ visit(tree, (node) => {
246369
+ if (!isDastElement(node) || node.name !== "copy") {
246370
+ return;
246371
+ }
246372
+ if (Object.keys(node.attributes).some(
246373
+ (key) => key.toLowerCase() === "uri"
246374
+ )) {
246375
+ return;
246376
+ }
246377
+ let referentName = toXml(node.attributes["source"]?.children).trim();
246378
+ if (!referentName) {
246379
+ return;
246380
+ }
246381
+ const propKey = Object.keys(node.attributes).find(
246382
+ (key) => key.toLowerCase() === "prop"
246383
+ );
246384
+ if (propKey) {
246385
+ const propName = toXml(node.attributes[propKey].children).trim();
246386
+ if (propName) {
246387
+ referentName += `.${propName}`;
245331
246388
  }
245332
- referenced.push({
245333
- node,
245334
- referentType: findReferentType(core2, referentName),
245335
- referentName
245336
- });
245337
- });
245338
- for (let {
246389
+ }
246390
+ referenced.push({
245339
246391
  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;
246392
+ referentType: findReferentType(core2, referentName),
246393
+ referentName,
246394
+ propKey
246395
+ });
246396
+ });
246397
+ for (let {
246398
+ node,
246399
+ referentType: referentPromise,
246400
+ referentName,
246401
+ propKey
246402
+ } of referenced) {
246403
+ try {
246404
+ const referentType = await referentPromise;
246405
+ if (propKey) {
246406
+ delete node.attributes[propKey];
246407
+ }
246408
+ const linkKey = Object.keys(node.attributes).find(
246409
+ (key) => key.toLowerCase() === "link"
246410
+ );
246411
+ const targetTag = linkKey ? isV06True(node.attributes[linkKey]) ? "extend" : "copy" : isModuleComponentType(referentType) ? "copy" : "extend";
246412
+ if (linkKey) {
246413
+ delete node.attributes[linkKey];
245363
246414
  }
246415
+ renameAttrInPlace(node, "source", targetTag);
246416
+ const bareName = referentName.startsWith("$") ? referentName.slice(1) : referentName;
246417
+ node.attributes[targetTag].children = [
246418
+ {
246419
+ type: "macro",
246420
+ path: parseReferencePath(bareName),
246421
+ attributes: {}
246422
+ }
246423
+ ];
246424
+ node.name = referentType;
246425
+ } catch (e4) {
246426
+ file.message(
246427
+ `Could not resolve referent type for <copy> tag with source="${referentName}": ${e4}`,
246428
+ {
246429
+ place: node.position,
246430
+ ruleId: "copy/unresolved-referent",
246431
+ source: "v06-to-v07"
246432
+ }
246433
+ );
246434
+ continue;
245364
246435
  }
245365
- };
245366
- };
245367
- async function findReferentType(core2, referentName) {
245368
- if (!referentName.startsWith("$")) {
245369
- referentName = `$${referentName}`;
245370
246436
  }
245371
- const reparsed = reparseAttribute(referentName);
245372
- const path = reparsed[0]?.type === "macro" ? reparsed[0].path : null;
245373
- if (!path) {
246437
+ }
246438
+ async function findReferentType(core2, referentName) {
246439
+ const bare = referentName.startsWith("$") ? referentName.slice(1) : referentName;
246440
+ let path;
246441
+ try {
246442
+ path = parseReferencePath(bare);
246443
+ } catch (e4) {
245374
246444
  throw new Error(`Could not parse referent name "${referentName}"`);
245375
246445
  }
245376
246446
  let unresolvedIndex = [];
245377
246447
  let unresolvedProps = [];
245378
246448
  let referentType = void 0;
245379
- for (let i2 = path.length; i2 > 0; i2--) {
246449
+ search: for (let i2 = path.length; i2 > 0; i2--) {
245380
246450
  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;
246451
+ for (const keepIndices of [true, false]) {
246452
+ if (keepIndices && !hasOnlyLiteralIndices(pathParts)) {
246453
+ continue;
246454
+ }
246455
+ const pathStr = keepIndices ? printPath(pathParts) : printPathWithoutIndices(pathParts);
246456
+ const referentIdx = await core2.resolvePathToNodeIdx(pathStr);
246457
+ if (referentIdx === -1) {
246458
+ continue;
245389
246459
  }
246460
+ const foundType = core2.core.core?.components?.[referentIdx]?.componentType;
246461
+ if (!foundType || foundType.startsWith("_")) {
246462
+ continue;
246463
+ }
246464
+ referentType = foundType;
246465
+ unresolvedIndex = keepIndices ? [] : pathParts.flatMap((part) => part.index);
246466
+ unresolvedProps = path.slice(i2);
246467
+ break search;
245390
246468
  }
245391
246469
  }
245392
246470
  if (unresolvedIndex.length !== 0) {
@@ -245408,14 +246486,287 @@ async function findReferentType(core2, referentName) {
245408
246486
  }
245409
246487
  throw new Error(`Could not find referent type for "${referentName}"`);
245410
246488
  }
246489
+ function hasOnlyLiteralIndices(pathParts) {
246490
+ return pathParts.every(
246491
+ (part) => part.index.every(
246492
+ (index2) => index2.value.length === 1 && index2.value[0].type === "text" && /^\d+$/.test(index2.value[0].value.trim())
246493
+ )
246494
+ );
246495
+ }
246496
+ function printPath(pathParts) {
246497
+ return pathParts.map(
246498
+ (part) => part.name + part.index.map((index2) => `[${toXml(index2.value).trim()}]`).join("")
246499
+ ).join(".");
246500
+ }
245411
246501
  function printPathWithoutIndices(pathParts) {
245412
246502
  return pathParts.map((part) => {
245413
246503
  return part.name;
245414
246504
  }).join(".");
245415
246505
  }
245416
- const upgradeAttributeSyntax = () => {
246506
+ const upgradeCopyElements = (context) => {
246507
+ return (tree, file) => {
246508
+ visit(tree, (node, info) => {
246509
+ if (!isDastElement(node)) {
246510
+ return;
246511
+ }
246512
+ if (node.name.toLowerCase() === "ref") {
246513
+ warnAboutExternalRef(node, file);
246514
+ return;
246515
+ }
246516
+ if (node.name.toLowerCase() !== "copy") {
246517
+ return;
246518
+ }
246519
+ convertAssignNames(
246520
+ node,
246521
+ namespaceChainOf(info.parents, context),
246522
+ context,
246523
+ file
246524
+ );
246525
+ const uriKey = findKey$1(node, "uri");
246526
+ if (!uriKey) {
246527
+ return;
246528
+ }
246529
+ const uri = toXml(node.attributes[uriKey].children).trim();
246530
+ if (!uri.toLowerCase().startsWith("doenet:")) {
246531
+ return;
246532
+ }
246533
+ const passedAttributes = Object.keys(node.attributes).filter(
246534
+ (key) => !COPY_OWN_ATTRIBUTES.has(key.toLowerCase())
246535
+ );
246536
+ if (passedAttributes.length === 0) {
246537
+ file.message(
246538
+ `<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.`,
246539
+ {
246540
+ place: node.position,
246541
+ ruleId: "external-copy/unknown-component-type",
246542
+ source: "v06-to-v07"
246543
+ }
246544
+ );
246545
+ return;
246546
+ }
246547
+ const narrowing = Object.keys(node.attributes).filter(
246548
+ (key) => COPY_NARROWING_ATTRIBUTES.has(key.toLowerCase())
246549
+ );
246550
+ if (narrowing.length > 0) {
246551
+ file.message(
246552
+ `<copy uri="${uri}"> could not be converted because it also sets ${narrowing.join(
246553
+ ", "
246554
+ )}, 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.`,
246555
+ {
246556
+ place: node.position,
246557
+ ruleId: "external-copy/narrowed",
246558
+ source: "v06-to-v07"
246559
+ }
246560
+ );
246561
+ return;
246562
+ }
246563
+ const dropped = Object.keys(node.attributes).filter(
246564
+ (key) => COPY_CONTROL_ATTRIBUTES.has(key.toLowerCase())
246565
+ );
246566
+ for (const key of dropped) {
246567
+ delete node.attributes[key];
246568
+ }
246569
+ const linkKey = findKey$1(node, "link");
246570
+ const targetTag = linkKey && isV06True(node.attributes[linkKey]) ? "extend" : "copy";
246571
+ if (linkKey) {
246572
+ delete node.attributes[linkKey];
246573
+ }
246574
+ node.name = "module";
246575
+ renameAttrInPlace(node, uriKey, targetTag);
246576
+ if (dropped.length > 0) {
246577
+ file.message(
246578
+ `Dropped ${dropped.join(
246579
+ ", "
246580
+ )} from <copy uri="${uri}">: they controlled how v0.6 copied, and a <module ${targetTag}="doenet:..."> has no equivalent.`,
246581
+ {
246582
+ place: node.position,
246583
+ ruleId: "external-copy/dropped-copy-controls",
246584
+ source: "v06-to-v07"
246585
+ }
246586
+ );
246587
+ }
246588
+ file.message(
246589
+ `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>.`,
246590
+ {
246591
+ place: node.position,
246592
+ ruleId: "external-copy/needs-new-content-id",
246593
+ source: "v06-to-v07"
246594
+ }
246595
+ );
246596
+ });
246597
+ };
246598
+ };
246599
+ const COPY_NARROWING_ATTRIBUTES = /* @__PURE__ */ new Set([
246600
+ "componentindex",
246601
+ "createcomponentoftype",
246602
+ "numcomponents",
246603
+ "obtainpropfromcomposite",
246604
+ "prop",
246605
+ "propindex",
246606
+ "removeemptyarrayentries",
246607
+ "source",
246608
+ "sourceindex",
246609
+ "sourcesubnames",
246610
+ "sourcesubnamescomponentindex",
246611
+ "target",
246612
+ "tname"
246613
+ ]);
246614
+ const COPY_CONTROL_ATTRIBUTES = /* @__PURE__ */ new Set([
246615
+ "assignnamesskip",
246616
+ "assignnewnamespaces",
246617
+ "sourceattributestoignore"
246618
+ ]);
246619
+ const COPY_OWN_ATTRIBUTES = /* @__PURE__ */ new Set([
246620
+ "assignnames",
246621
+ "assignnamesskip",
246622
+ "assignnewnamespaces",
246623
+ "componentindex",
246624
+ "createcomponentoftype",
246625
+ "link",
246626
+ "name",
246627
+ "newnamespace",
246628
+ "numcomponents",
246629
+ "obtainpropfromcomposite",
246630
+ "prop",
246631
+ "propindex",
246632
+ "removeemptyarrayentries",
246633
+ "source",
246634
+ "sourceattributestoignore",
246635
+ "sourceindex",
246636
+ "sourcesubnames",
246637
+ "sourcesubnamescomponentindex",
246638
+ "target",
246639
+ "tname",
246640
+ "uri"
246641
+ ]);
246642
+ function convertAssignNames(node, ancestorNames, context, file) {
246643
+ const assignNamesValue = readAssignNames(node);
246644
+ if (!assignNamesValue) {
246645
+ deleteAssignNames(node);
246646
+ return;
246647
+ }
246648
+ const origin = {
246649
+ elementName: node.name,
246650
+ position: node.position,
246651
+ ancestorNames,
246652
+ element: node
246653
+ };
246654
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
246655
+ const names = parsed.success && parsed.pieces.every((p2) => typeof p2 === "string") ? parsed.pieces : void 0;
246656
+ if (!names || names.length !== 1) {
246657
+ file.message(
246658
+ `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.`,
246659
+ {
246660
+ place: node.position,
246661
+ ruleId: "copy/unmapped-assign-names",
246662
+ source: "v06-to-v07"
246663
+ }
246664
+ );
246665
+ deleteAssignNames(node);
246666
+ return;
246667
+ }
246668
+ const [assignedName] = names;
246669
+ const existingName = toXml(
246670
+ node.attributes[findKey$1(node, "name") ?? ""]?.children ?? []
246671
+ ).trim();
246672
+ const nameIsUnusable = !isValidReferenceableName(assignedName);
246673
+ const nameBelongsToAnother = nameIsUnusable || nameTakenInScope(context, assignedName, ancestorNames);
246674
+ const nameIsTaken = nameBelongsToAnother || context.existingNames.has(assignedName) || context.claimedNames.has(assignedName);
246675
+ if (existingName && !isValidReferenceableName(existingName)) {
246676
+ file.message(
246677
+ `<${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.`,
246678
+ {
246679
+ place: node.position,
246680
+ ruleId: "assign-names/invalid-name",
246681
+ source: "v06-to-v07"
246682
+ }
246683
+ );
246684
+ deleteAssignNames(node);
246685
+ setCompositeName(node, context.uniqueName("copy"));
246686
+ return;
246687
+ }
246688
+ if (existingName) {
246689
+ if (existingName !== assignedName && !nameBelongsToAnother) {
246690
+ context.registry.register(
246691
+ assignedName,
246692
+ [makeIndexedPathPart(existingName, [])],
246693
+ origin,
246694
+ file
246695
+ );
246696
+ } else if (existingName !== assignedName) {
246697
+ reportUnusableName(node, assignedName, nameIsUnusable, file);
246698
+ }
246699
+ deleteAssignNames(node);
246700
+ setCompositeName(node, existingName);
246701
+ return;
246702
+ }
246703
+ if (nameIsTaken) {
246704
+ const generated = context.uniqueName("copy");
246705
+ if (nameBelongsToAnother) {
246706
+ reportUnusableName(node, assignedName, nameIsUnusable, file);
246707
+ } else {
246708
+ context.registry.register(
246709
+ assignedName,
246710
+ [makeIndexedPathPart(generated, [])],
246711
+ origin,
246712
+ file
246713
+ );
246714
+ }
246715
+ deleteAssignNames(node);
246716
+ setCompositeName(node, generated);
246717
+ return;
246718
+ }
246719
+ context.claimedNames.add(assignedName);
246720
+ context.registry.register(assignedName, void 0, origin, file);
246721
+ setCompositeName(node, assignedName);
246722
+ }
246723
+ function warnAboutExternalRef(node, file) {
246724
+ const toKey = findKey$1(node, "to");
246725
+ if (!toKey) {
246726
+ return;
246727
+ }
246728
+ const target = toXml(node.attributes[toKey].children).trim();
246729
+ if (!/^doenet:.*(activityId|doenetId|cid|pageId)=/i.test(target)) {
246730
+ return;
246731
+ }
246732
+ file.message(
246733
+ `<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.`,
246734
+ {
246735
+ place: node.position,
246736
+ ruleId: "external-ref/needs-new-content-id",
246737
+ source: "v06-to-v07"
246738
+ }
246739
+ );
246740
+ }
246741
+ function reportUnusableName(node, assignedName, nameIsUnusable, file) {
246742
+ if (nameIsUnusable) {
246743
+ file.message(
246744
+ `<${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.`,
246745
+ {
246746
+ place: node.position,
246747
+ ruleId: "assign-names/invalid-name",
246748
+ source: "v06-to-v07"
246749
+ }
246750
+ );
246751
+ return;
246752
+ }
246753
+ file.message(
246754
+ `<${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.`,
246755
+ {
246756
+ place: node.position,
246757
+ ruleId: "copy/name-already-taken",
246758
+ source: "v06-to-v07"
246759
+ }
246760
+ );
246761
+ }
246762
+ function findKey$1(node, attrName) {
246763
+ return Object.keys(node.attributes).find(
246764
+ (key) => key.toLowerCase() === attrName.toLowerCase()
246765
+ );
246766
+ }
246767
+ const upgradeAttributeSyntax = (context) => {
245417
246768
  return async (tree, file) => {
245418
- visit(tree, (node) => {
246769
+ visit(tree, (node, info) => {
245419
246770
  if (node.type !== "macro") {
245420
246771
  return;
245421
246772
  }
@@ -245441,6 +246792,18 @@ const upgradeAttributeSyntax = () => {
245441
246792
  }
245442
246793
  });
245443
246794
  Object.assign(node, copy2);
246795
+ const assigned = readAssignNames(node);
246796
+ convertAssignNames(
246797
+ node,
246798
+ namespaceChainOf(info.parents, context),
246799
+ context,
246800
+ file
246801
+ );
246802
+ warnIfNameCouldNotBeKept(
246803
+ node,
246804
+ assigned,
246805
+ file
246806
+ );
245444
246807
  });
245445
246808
  const macrosInAttributes = [];
245446
246809
  visit(tree, (node, info) => {
@@ -245534,39 +246897,34 @@ const upgradeAttributeSyntax = () => {
245534
246897
  documentElement.children.unshift(setupTag);
245535
246898
  };
245536
246899
  };
245537
- const upgradeMapElement = () => {
246900
+ function warnIfNameCouldNotBeKept(node, assigned, file) {
246901
+ if (!assigned) {
246902
+ return;
246903
+ }
246904
+ const name2 = toXml(node.attributes["name"]?.children ?? []).trim();
246905
+ if (name2 === assigned.trim()) {
246906
+ return;
246907
+ }
246908
+ file.message(
246909
+ `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.`,
246910
+ {
246911
+ place: node.position,
246912
+ ruleId: "assign-names/late-attribute-assignment",
246913
+ source: "v06-to-v07"
246914
+ }
246915
+ );
246916
+ }
246917
+ const upgradeMapElement = (context) => {
245538
246918
  return (tree, file) => {
245539
- const refsToRename = {};
245540
- replaceNode(tree, (node) => {
246919
+ replaceNode(tree, (node, info) => {
245541
246920
  if (!isDastElement(node)) {
245542
246921
  return;
245543
246922
  }
245544
- if (node.name !== "map") {
246923
+ if (node.name.toLowerCase() !== "map") {
245545
246924
  return;
245546
246925
  }
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
- }
246926
+ let name2 = toXml(node.attributes["name"]?.children).trim();
246927
+ const assignNamesValue = readAssignNames(node);
245570
246928
  const templateNode = node.children.find(
245571
246929
  (child) => isDastElement(child) && child.name === "template"
245572
246930
  );
@@ -245576,10 +246934,32 @@ const upgradeMapElement = () => {
245576
246934
  if (!templateNode || !isDastElement(templateNode) || !sourcesNode || !isDastElement(sourcesNode)) {
245577
246935
  file.message(
245578
246936
  `Map element must have both a template and sources children to be converted`,
245579
- { place: node.position }
246937
+ {
246938
+ place: node.position,
246939
+ ruleId: "map/missing-template-or-sources",
246940
+ source: "v06-to-v07"
246941
+ }
245580
246942
  );
245581
246943
  return;
245582
246944
  }
246945
+ if (assignNamesValue) {
246946
+ name2 = registerCompositeAssignNames({
246947
+ node,
246948
+ assignNamesValue,
246949
+ fallbackBase: "repeat",
246950
+ ancestorNames: namespaceChainOf(info.parents, context),
246951
+ context,
246952
+ file,
246953
+ // A nested name such as `assignNames="(a b)"` counts positions
246954
+ // inside one iteration, which are the template's children — and
246955
+ // v0.6 skipped bare text there while v0.7 counts it.
246956
+ positionMap: makeTemplatePositionMap(
246957
+ templateNode,
246958
+ node,
246959
+ file
246960
+ )
246961
+ }) ?? name2;
246962
+ }
245583
246963
  const valueName = toXml(
245584
246964
  sourcesNode.attributes["alias"]?.children
245585
246965
  ).trim();
@@ -245591,6 +246971,7 @@ const upgradeMapElement = () => {
245591
246971
  (child) => isDastElement(child) && child.name === "sequence"
245592
246972
  )) {
245593
246973
  if (name2) {
246974
+ warnIfNameLost(sequenceNode, name2, file);
245594
246975
  sequenceNode.attributes["name"] = {
245595
246976
  type: "attribute",
245596
246977
  name: "name",
@@ -245598,6 +246979,7 @@ const upgradeMapElement = () => {
245598
246979
  };
245599
246980
  }
245600
246981
  sequenceNode.name = "repeatForSequence";
246982
+ inheritNamespace(templateNode, sequenceNode, context);
245601
246983
  if (valueName) {
245602
246984
  sequenceNode.attributes["valueName"] = {
245603
246985
  type: "attribute",
@@ -245627,12 +247009,15 @@ const upgradeMapElement = () => {
245627
247009
  attributes: {},
245628
247010
  children: [groupTag]
245629
247011
  };
245630
- const groupName = getUniqueName(tree, "group");
247012
+ const groupName = context.uniqueName("group");
245631
247013
  groupTag.attributes["name"] = {
245632
247014
  type: "attribute",
245633
247015
  name: "name",
245634
247016
  children: reparseAttribute(groupName)
245635
247017
  };
247018
+ if (name2) {
247019
+ warnIfNameLost(templateNode, name2, file);
247020
+ }
245636
247021
  templateNode.name = "repeat";
245637
247022
  templateNode.attributes["for"] = {
245638
247023
  type: "attribute",
@@ -245663,19 +247048,22 @@ const upgradeMapElement = () => {
245663
247048
  return [setupTag, templateNode];
245664
247049
  }
245665
247050
  });
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
247051
  };
245678
247052
  };
247053
+ function warnIfNameLost(node, newName, file) {
247054
+ const existing = toXml(node.attributes["name"]?.children).trim();
247055
+ if (!existing || existing === newName) {
247056
+ return;
247057
+ }
247058
+ file.message(
247059
+ `<${node.name} name="${existing}"> becomes the <repeat> that takes the name "${newName}", so "${existing}" is gone; references to it need fixing by hand.`,
247060
+ {
247061
+ place: node.position,
247062
+ ruleId: "map/name-overwritten",
247063
+ source: "v06-to-v07"
247064
+ }
247065
+ );
247066
+ }
245679
247067
  const upgradeModuleElement = () => {
245680
247068
  return (tree, file) => {
245681
247069
  visit(tree, (node) => {
@@ -245691,14 +247079,30 @@ const upgradeModuleElement = () => {
245691
247079
  if (!setupNode) {
245692
247080
  return;
245693
247081
  }
245694
- node.children.filter(
245695
- (child) => !isDastElement(child) || child.name !== "setup"
245696
- );
247082
+ const isCustomAttribute = (child) => isDastElement(child) && child.name === "customAttribute";
245697
247083
  const customAttributeNodes = setupNode.children.filter(
245698
- (child) => isDastElement(child) && child.name === "customAttribute"
247084
+ (child) => isCustomAttribute(child)
247085
+ );
247086
+ const otherSetupChildren = setupNode.children.filter(
247087
+ (child) => !isCustomAttribute(child)
245699
247088
  );
245700
247089
  setupNode.children = [];
245701
247090
  setupNode.name = "moduleAttributes";
247091
+ if (otherSetupChildren.some(
247092
+ (child) => child.type !== "text" || child.value.trim() !== ""
247093
+ )) {
247094
+ const newSetup = {
247095
+ type: "element",
247096
+ name: "setup",
247097
+ attributes: {},
247098
+ children: otherSetupChildren
247099
+ };
247100
+ node.children.splice(
247101
+ node.children.indexOf(setupNode) + 1,
247102
+ 0,
247103
+ newSetup
247104
+ );
247105
+ }
245702
247106
  for (const customAttributeNode of customAttributeNodes) {
245703
247107
  const name2 = toXml(
245704
247108
  customAttributeNode.attributes["assignNames"]?.children
@@ -245710,7 +247114,9 @@ const upgradeModuleElement = () => {
245710
247114
  file.message(
245711
247115
  `Module "customAttribute" is missing a "componentType"; the syntax cannot be upgraded with a "componentType".`,
245712
247116
  {
245713
- place: customAttributeNode.position
247117
+ place: customAttributeNode.position,
247118
+ ruleId: "module/custom-attribute-without-type",
247119
+ source: "v06-to-v07"
245714
247120
  }
245715
247121
  );
245716
247122
  continue;
@@ -245773,10 +247179,459 @@ const removeDefinitionsElement = () => {
245773
247179
  });
245774
247180
  };
245775
247181
  };
247182
+ const GLOBAL_RULES = {
247183
+ // v0.6 renamed `targets*` to `sources*`; v0.7 renamed them again to `references*`.
247184
+ sourcesareresponses: {
247185
+ kind: "renameToReferenceList",
247186
+ to: "referencesAreResponses"
247187
+ },
247188
+ targetsareresponses: {
247189
+ kind: "renameToReferenceList",
247190
+ to: "referencesAreResponses"
247191
+ },
247192
+ sourcesarefunctionsymbols: {
247193
+ kind: "renameToReferenceList",
247194
+ to: "referencesAreFunctionSymbols"
247195
+ },
247196
+ targetsarefunctionsymbols: {
247197
+ kind: "renameToReferenceList",
247198
+ to: "referencesAreFunctionSymbols"
247199
+ },
247200
+ triggerwithtargets: { kind: "renameToReferenceList", to: "triggerWith" },
247201
+ triggerwithtnames: { kind: "renameToReferenceList", to: "triggerWith" },
247202
+ updatewithtname: { kind: "rename", to: "updateWith" },
247203
+ updatewithtarget: { kind: "rename", to: "updateWith" },
247204
+ // `tname` was the pre-v0.6 spelling of the attribute naming what to act on. On
247205
+ // components that *copy*, it became `source`; everywhere else it became `target`.
247206
+ // The element-specific tables below override this for the copying components.
247207
+ tname: { kind: "rename", to: "target" }
247208
+ };
247209
+ const ELEMENT_RULES = {
247210
+ copy: { tname: { kind: "rename", to: "source" } },
247211
+ collect: {
247212
+ tname: { kind: "rename", to: "source" },
247213
+ draggable: {
247214
+ kind: "remove",
247215
+ because: "<collect> does not take `draggable` in v0.7"
247216
+ }
247217
+ },
247218
+ extract: { tname: { kind: "rename", to: "source" } },
247219
+ updatevalue: {
247220
+ // `<updateValue target="x" prop="y">` is a single path in v0.7.
247221
+ prop: { kind: "mergeInto", target: "target" }
247222
+ },
247223
+ animatefromsequence: { prop: { kind: "mergeInto", target: "target" } },
247224
+ ref: {
247225
+ page: {
247226
+ kind: "remove",
247227
+ because: "v0.7 documents are not paginated, so <ref> has no `page`; link to the individual document instead",
247228
+ ruleId: "deprecated/ref-page"
247229
+ }
247230
+ },
247231
+ variantcontrol: { nvariants: { kind: "rename", to: "numVariants" } },
247232
+ option: {
247233
+ selectforvariantnames: { kind: "rename", to: "selectForVariants" }
247234
+ },
247235
+ graph: {
247236
+ xlabel: { kind: "toChildElement", elementName: "xLabel" },
247237
+ ylabel: { kind: "toChildElement", elementName: "yLabel" },
247238
+ height: {
247239
+ kind: "remove",
247240
+ because: "v0.7 graphs are sized with `size`, `width` and `aspectRatio`"
247241
+ }
247242
+ },
247243
+ image: {
247244
+ // v0.6 rendered `description` as the image's `alt` text. v0.7 carries that in a
247245
+ // `<shortDescription>` child, which the reference pages describe as required for
247246
+ // accessibility, so this must be converted rather than dropped.
247247
+ description: {
247248
+ kind: "toChildElement",
247249
+ elementName: "shortDescription"
247250
+ }
247251
+ },
247252
+ conditionalcontent: {
247253
+ maximumnumbertoshow: {
247254
+ kind: "remove",
247255
+ because: "v0.7 <conditionalContent> always shows one case"
247256
+ }
247257
+ },
247258
+ embed: {
247259
+ encodedgeogebracontent: {
247260
+ kind: "unsupported",
247261
+ because: "v0.7 has no <embed> element and no GeoGebra support; this content must be replaced by hand",
247262
+ ruleId: "no-v07-equivalent/embed-geogebra"
247263
+ }
247264
+ },
247265
+ point: {
247266
+ link: {
247267
+ kind: "remove",
247268
+ because: "`link` only means something alongside `copySource`",
247269
+ // `copySourceToExtendOrCopy` needs `link` when there is a `copySource`.
247270
+ when: (_value, node) => !findAttrKey(node, "copySource") && !findAttrKey(node, "source")
247271
+ }
247272
+ },
247273
+ tabular: removeSides(),
247274
+ row: removeSides(),
247275
+ cell: removeSides()
247276
+ };
247277
+ function removeSides() {
247278
+ const rule = {
247279
+ kind: "remove",
247280
+ because: "v0.7 tables do not take per-side border attributes"
247281
+ };
247282
+ return { top: rule, bottom: rule, left: rule, right: rule };
247283
+ }
247284
+ const upgradeDeprecatedAttributes = () => {
247285
+ return (tree, file) => {
247286
+ visit(tree, (node) => {
247287
+ if (!isDastElement(node)) {
247288
+ return;
247289
+ }
247290
+ const elm = node;
247291
+ const rules = {
247292
+ ...GLOBAL_RULES,
247293
+ ...ELEMENT_RULES[elm.name.toLowerCase()] || {}
247294
+ };
247295
+ const keys2 = Object.keys(elm.attributes);
247296
+ const isMerge = (key) => rules[key.toLowerCase()]?.kind === "mergeInto";
247297
+ for (const key of [
247298
+ ...keys2.filter((k2) => !isMerge(k2)),
247299
+ ...keys2.filter(isMerge)
247300
+ ]) {
247301
+ const rule = rules[key.toLowerCase()];
247302
+ if (!rule) {
247303
+ continue;
247304
+ }
247305
+ const attr = elm.attributes[key];
247306
+ if (!attr) {
247307
+ continue;
247308
+ }
247309
+ const value = toXml(attr.children).trim();
247310
+ if (rule.when && !rule.when(value, elm)) {
247311
+ continue;
247312
+ }
247313
+ applyRule(elm, key, attr, value, rule, file);
247314
+ }
247315
+ });
247316
+ };
247317
+ };
247318
+ const prependedChildCount = /* @__PURE__ */ new WeakMap();
247319
+ function applyRule(elm, key, attr, value, rule, file) {
247320
+ switch (rule.kind) {
247321
+ case "rename": {
247322
+ renameAttrInPlace(elm, key, rule.to);
247323
+ return;
247324
+ }
247325
+ case "renameToReferenceList": {
247326
+ renameAttrInPlace(elm, key, rule.to);
247327
+ const dollared = value.split(/\s+/).filter((t4) => t4).map(referenceTo).join(" ");
247328
+ elm.attributes[rule.to].children = reparseAttributeV6(dollared);
247329
+ return;
247330
+ }
247331
+ case "mergeInto": {
247332
+ const targetKey = findAttrKey(elm, rule.target);
247333
+ if (!targetKey || !value) {
247334
+ return;
247335
+ }
247336
+ const targetValue = toXml(
247337
+ elm.attributes[targetKey].children
247338
+ ).trim();
247339
+ elm.attributes[targetKey].children = reparseAttributeV6(
247340
+ `${targetValue}.${value}`
247341
+ );
247342
+ delete elm.attributes[key];
247343
+ return;
247344
+ }
247345
+ case "toChildElement": {
247346
+ if (!value) {
247347
+ delete elm.attributes[key];
247348
+ return;
247349
+ }
247350
+ const child = {
247351
+ type: "element",
247352
+ name: rule.elementName,
247353
+ attributes: {},
247354
+ children: attr.children,
247355
+ position: attr.position
247356
+ };
247357
+ const alreadyPrepended = prependedChildCount.get(elm) || 0;
247358
+ elm.children.splice(alreadyPrepended, 0, child);
247359
+ prependedChildCount.set(elm, alreadyPrepended + 1);
247360
+ delete elm.attributes[key];
247361
+ return;
247362
+ }
247363
+ case "remove": {
247364
+ delete elm.attributes[key];
247365
+ file.message(
247366
+ `Removed ${key}="${value}" from <${elm.name}>: ${rule.because}.`,
247367
+ {
247368
+ place: elm.position,
247369
+ ruleId: rule.ruleId || `deprecated/${key.toLowerCase()}`,
247370
+ source: "v06-to-v07"
247371
+ }
247372
+ );
247373
+ return;
247374
+ }
247375
+ case "unsupported": {
247376
+ file.message(
247377
+ `<${elm.name} ${key}="..."> was left unchanged: ${rule.because}.`,
247378
+ {
247379
+ place: elm.position,
247380
+ ruleId: rule.ruleId || `no-v07-equivalent/${key.toLowerCase()}`,
247381
+ source: "v06-to-v07"
247382
+ }
247383
+ );
247384
+ return;
247385
+ }
247386
+ }
247387
+ }
247388
+ function findAttrKey(elm, attrName) {
247389
+ return Object.keys(elm.attributes).find(
247390
+ (key) => key.toLowerCase() === attrName.toLowerCase()
247391
+ );
247392
+ }
247393
+ function referenceTo(token) {
247394
+ if (token.startsWith("$(")) {
247395
+ return token;
247396
+ }
247397
+ const name2 = token.startsWith("$") ? token.slice(1) : token;
247398
+ return /^[a-zA-Z0-9_]+$/.test(name2) ? `$${name2}` : `$(${name2})`;
247399
+ }
247400
+ const ALL_ITEMS_PROPS = /* @__PURE__ */ new Set(["maths", "texts", "numbers", "booleans"]);
247401
+ const NUMBERED_ITEM_PROP = /^(math|text|number|boolean)(\d+)$/;
247402
+ const ELEMENTS_WITH_PROP = /* @__PURE__ */ new Set(["copy", "extract"]);
247403
+ const upgradeListProps = () => {
247404
+ return (tree, file) => {
247405
+ visitAllMacros(tree, (node) => {
247406
+ node.path = rewritePath(node.path);
247407
+ });
247408
+ visitAll(tree, (node) => {
247409
+ if (!isDastElement(node) || !ELEMENTS_WITH_PROP.has(node.name.toLowerCase())) {
247410
+ return;
247411
+ }
247412
+ rewritePropAttribute(node, file);
247413
+ rewriteRawSourceAttribute(node);
247414
+ });
247415
+ };
247416
+ };
247417
+ const ELEMENTS_WITH_RAW_SOURCE = /* @__PURE__ */ new Set(["copy", "extract"]);
247418
+ function rewriteRawSourceAttribute(node) {
247419
+ if (!ELEMENTS_WITH_RAW_SOURCE.has(node.name.toLowerCase())) {
247420
+ return;
247421
+ }
247422
+ const sourceKey = findKey(node, "source");
247423
+ if (!sourceKey) {
247424
+ return;
247425
+ }
247426
+ const attr = node.attributes[sourceKey];
247427
+ if (attr.children.length !== 1 || attr.children[0].type !== "text") {
247428
+ return;
247429
+ }
247430
+ const child = attr.children[0];
247431
+ const value = child.value.trim();
247432
+ if (!value || value.startsWith("$") || !value.includes(".")) {
247433
+ return;
247434
+ }
247435
+ let path;
247436
+ try {
247437
+ path = parseReferencePath(value);
247438
+ } catch {
247439
+ return;
247440
+ }
247441
+ restoreRawPropPositions(node, sourceKey, path);
247442
+ const rewritten = rewritePath(path);
247443
+ if (rewritten === path) {
247444
+ return;
247445
+ }
247446
+ child.value = toXml(rewritten);
247447
+ }
247448
+ function rewritePath(path) {
247449
+ if (path.length < 2) {
247450
+ return path;
247451
+ }
247452
+ const result2 = [path[0]];
247453
+ for (const part of path.slice(1)) {
247454
+ const previous = result2[result2.length - 1];
247455
+ if (!isPropAccess(part)) {
247456
+ result2.push(part);
247457
+ continue;
247458
+ }
247459
+ if (ALL_ITEMS_PROPS.has(part.name)) {
247460
+ previous.index = [...previous.index, ...part.index];
247461
+ continue;
247462
+ }
247463
+ const numbered = NUMBERED_ITEM_PROP.exec(part.name);
247464
+ if (numbered) {
247465
+ previous.index = [
247466
+ ...previous.index,
247467
+ {
247468
+ type: "index",
247469
+ value: [{ type: "text", value: numbered[2] }]
247470
+ },
247471
+ ...part.index
247472
+ ];
247473
+ continue;
247474
+ }
247475
+ result2.push(part);
247476
+ }
247477
+ return result2;
247478
+ }
247479
+ function rewritePropAttribute(node, file) {
247480
+ const propKey = findKey(node, "prop");
247481
+ if (!propKey) {
247482
+ return;
247483
+ }
247484
+ const prop = toXml(node.attributes[propKey].children).trim();
247485
+ const numbered = NUMBERED_ITEM_PROP.exec(prop);
247486
+ if (!ALL_ITEMS_PROPS.has(prop) && !numbered) {
247487
+ return;
247488
+ }
247489
+ const sourceKey = findKey(node, "source");
247490
+ if (!sourceKey) {
247491
+ return;
247492
+ }
247493
+ const sourceAttr = node.attributes[sourceKey];
247494
+ const source = toXml(sourceAttr.children).trim();
247495
+ if (!source) {
247496
+ return;
247497
+ }
247498
+ if (!numbered) {
247499
+ if (node.name.toLowerCase() === "extract") {
247500
+ file.message(
247501
+ `<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}.`,
247502
+ {
247503
+ place: node.position,
247504
+ ruleId: "no-v07-equivalent/extract",
247505
+ source: "v06-to-v07"
247506
+ }
247507
+ );
247508
+ return;
247509
+ }
247510
+ delete node.attributes[propKey];
247511
+ return;
247512
+ }
247513
+ const hadDollar = source.startsWith("$");
247514
+ let path;
247515
+ try {
247516
+ path = parseReferencePath(hadDollar ? source.slice(1) : source);
247517
+ } catch (e4) {
247518
+ return;
247519
+ }
247520
+ const last2 = path[path.length - 1];
247521
+ last2.index = [
247522
+ ...last2.index,
247523
+ { type: "index", value: [{ type: "text", value: numbered[2] }] }
247524
+ ];
247525
+ sourceAttr.children = hadDollar ? [{ type: "macro", path, attributes: {} }] : [{ type: "text", value: toXml(path) }];
247526
+ delete node.attributes[propKey];
247527
+ }
247528
+ function findKey(node, attrName) {
247529
+ return Object.keys(node.attributes).find(
247530
+ (key) => key.toLowerCase() === attrName.toLowerCase()
247531
+ );
247532
+ }
247533
+ const upgradeAssignNames = (context) => {
247534
+ return (tree, file) => {
247535
+ visitAll(tree, (node, parents) => {
247536
+ if (!isDastElement(node)) {
247537
+ return;
247538
+ }
247539
+ const spec = lookupComposite(node);
247540
+ if (!spec) {
247541
+ return;
247542
+ }
247543
+ const assignNamesValue = readAssignNames(node);
247544
+ if (assignNamesValue === void 0) {
247545
+ return;
247546
+ }
247547
+ if (spec.noV07Equivalent) {
247548
+ file.message(
247549
+ `<${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.`,
247550
+ {
247551
+ place: node.position,
247552
+ ruleId: `no-v07-equivalent/${spec.name.toLowerCase()}`,
247553
+ source: "v06-to-v07"
247554
+ }
247555
+ );
247556
+ }
247557
+ if (!assignNamesValue) {
247558
+ deleteAssignNames(node);
247559
+ return;
247560
+ }
247561
+ const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
247562
+ if (parsed.success && firstLeafName(parsed.pieces) === void 0) {
247563
+ deleteAssignNames(node);
247564
+ return;
247565
+ }
247566
+ const onlyPiece = parsed.success && parsed.pieces.length === 1 && typeof parsed.pieces[0] === "string" ? parsed.pieces[0] : void 0;
247567
+ if (onlyPiece !== void 0 && isValidReferenceableName(onlyPiece) && !findAttribute(node, "name") && !context.existingNames.has(onlyPiece) && !context.claimedNames.has(onlyPiece) && producesSingleReplacement(node, spec)) {
247568
+ context.claimedNames.add(onlyPiece);
247569
+ context.registry.register(
247570
+ onlyPiece,
247571
+ void 0,
247572
+ {
247573
+ elementName: node.name,
247574
+ position: node.position,
247575
+ ancestorNames: namespaceChainOf(parents, context),
247576
+ element: node
247577
+ },
247578
+ file
247579
+ );
247580
+ warnIfSelfReferential(node, onlyPiece, file);
247581
+ setCompositeName(node, onlyPiece);
247582
+ return;
247583
+ }
247584
+ const compositeName = registerCompositeAssignNames({
247585
+ node,
247586
+ assignNamesValue,
247587
+ fallbackBase: spec.name,
247588
+ ancestorNames: namespaceChainOf(parents, context),
247589
+ context,
247590
+ file,
247591
+ positionMap: makePositionMap(node, spec, file)
247592
+ });
247593
+ if (compositeName === void 0) {
247594
+ deleteAssignNames(node);
247595
+ return;
247596
+ }
247597
+ warnIfSelfReferential(node, compositeName, file);
247598
+ setCompositeName(node, compositeName);
247599
+ });
247600
+ };
247601
+ };
247602
+ function warnIfSelfReferential(node, compositeName, file) {
247603
+ let referencesSelf = false;
247604
+ for (const attr of Object.values(node.attributes)) {
247605
+ for (const child of attr.children) {
247606
+ visitAllMacros(child, (macro) => {
247607
+ if (macro.path[0]?.name === compositeName) {
247608
+ referencesSelf = true;
247609
+ }
247610
+ });
247611
+ }
247612
+ }
247613
+ if (!referencesSelf) {
247614
+ return;
247615
+ }
247616
+ file.message(
247617
+ `<${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.`,
247618
+ {
247619
+ place: node.position,
247620
+ ruleId: "assign-names/self-reference",
247621
+ source: "v06-to-v07"
247622
+ }
247623
+ );
247624
+ }
247625
+ const applyAssignNameRenames = (context) => {
247626
+ return (tree, file) => {
247627
+ applyRefRenames(tree, context.registry, file, context);
247628
+ };
247629
+ };
245776
247630
  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);
247631
+ const assignNamesContext = createAssignNamesContext(dast);
247632
+ 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
247633
  if (!options.doNotUpgradeAttributeSyntax) {
245779
- processor = processor.use(upgradeAttributeSyntax);
247634
+ processor = processor.use(upgradeAttributeSyntax, assignNamesContext);
245780
247635
  }
245781
247636
  if (!options.doNotUpgradeCopyTags) {
245782
247637
  processor = processor.use(upgradeCopySyntax);
@@ -245817,31 +247672,44 @@ const ensureDollarBeforeNamesOnSpecificAttributes = () => {
245817
247672
  });
245818
247673
  };
245819
247674
  };
245820
- const copySourceToExtendOrCopy = () => {
245821
- return (tree) => {
245822
- visit(tree, (node) => {
247675
+ const copySourceToExtendOrCopy = (context) => {
247676
+ return (tree, file) => {
247677
+ visit(tree, (node, info) => {
245823
247678
  if (!isDastElement(node)) {
245824
247679
  return;
245825
247680
  }
245826
247681
  const copySourceAttr = node.attributes["copySource"];
245827
247682
  const linkAttr = node.attributes["link"];
245828
- const assignNamesAttr = node.attributes["assignNames"];
245829
247683
  const copyPropAttr = node.attributes["copyProp"];
245830
247684
  if (!copySourceAttr) {
245831
247685
  return;
245832
247686
  }
245833
- const targetTag = toXml(linkAttr?.children || []).toLowerCase() === "false" ? "copy" : "extend";
247687
+ const targetTag = linkAttr ? isV06True(linkAttr) ? "extend" : "copy" : isModuleComponentType(node.name) ? "copy" : "extend";
245834
247688
  const baseValue = toXml(copySourceAttr.children).trim();
245835
247689
  let extendValue = baseValue.startsWith("$") ? baseValue : `$${baseValue}`;
245836
247690
  copySourceAttr.name = targetTag;
247691
+ let appendedPropName;
245837
247692
  if (copyPropAttr) {
245838
- extendValue += `.${toXml(copyPropAttr.children).trim()}`;
247693
+ appendedPropName = toXml(copyPropAttr.children).trim();
247694
+ extendValue += `.${appendedPropName}`;
245839
247695
  delete node.attributes["copyProp"];
245840
247696
  }
245841
247697
  copySourceAttr.children = reparseAttribute(extendValue);
245842
- if (assignNamesAttr && toXml(assignNamesAttr.children).trim().indexOf(" ") === -1) {
245843
- assignNamesAttr.name = "name";
247698
+ if (appendedPropName) {
247699
+ const macro = copySourceAttr.children[0];
247700
+ if (macro?.type === "macro") {
247701
+ const last2 = macro.path[macro.path.length - 1];
247702
+ if (last2) {
247703
+ markAsPropAccess(last2);
247704
+ }
247705
+ }
245844
247706
  }
247707
+ convertAssignNames(
247708
+ node,
247709
+ namespaceChainOf(info.parents, context),
247710
+ context,
247711
+ file
247712
+ );
245845
247713
  if (linkAttr) {
245846
247714
  delete node.attributes["link"];
245847
247715
  }
@@ -245876,4 +247744,4 @@ export {
245876
247744
  getDefaultExportFromCjs$1 as g,
245877
247745
  updateSyntaxFromV06toV07 as u
245878
247746
  };
245879
- //# sourceMappingURL=index-Cxf3BQNw.js.map
247747
+ //# sourceMappingURL=index-D-2i13ZI.js.map