links-notation 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,49 @@
1
+ // src/ReferenceLiteral.js
2
+ function hasReferenceLiteralPrefix(text, start = 0) {
3
+ return /^~[0-9]+\{/.test(text.slice(start));
4
+ }
5
+ function encodeReferenceLiteral(text) {
6
+ if (typeof text !== "string" || !text.isWellFormed()) {
7
+ throw new TypeError("Reference must be well-formed Unicode text");
8
+ }
9
+ const hex = Array.from(new TextEncoder().encode(text), (byte) => byte.toString(16).padStart(2, "0")).join("");
10
+ return `~1{${hex}}`;
11
+ }
12
+ function decodeReferenceLiteral(literal) {
13
+ const match = /^~([0-9]+)\{([0-9a-fA-F]*)\}$/.exec(literal);
14
+ if (!match || match[0] !== literal || match[1] !== "1" || match[2].length % 2 !== 0) {
15
+ throw new TypeError("Invalid or unsupported reference literal (expected ~1{UTF-8 hex})");
16
+ }
17
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(match[2].match(/../g) ?? [], (hex) => parseInt(hex, 16)));
18
+ }
19
+ function formatReference(text) {
20
+ if (typeof text !== "string" || !text.isWellFormed()) {
21
+ throw new TypeError("Reference must be well-formed Unicode text");
22
+ }
23
+ if (!text || /[\u0000-\u001f\u007f]/u.test(text)) {
24
+ return encodeReferenceLiteral(text);
25
+ }
26
+ if (!text.startsWith("#") && !/^~[0-9]+\{/.test(text) && !/[\p{White_Space}\ufeff():"'`]/u.test(text)) {
27
+ return text;
28
+ }
29
+ let choice = null;
30
+ for (const quote of ["'", '"', "`"]) {
31
+ if (text.startsWith(quote))
32
+ continue;
33
+ let longest = 0;
34
+ let run = 0;
35
+ for (const character of text) {
36
+ run = character === quote ? run + 1 : 0;
37
+ longest = Math.max(longest, run);
38
+ }
39
+ const count = longest + 1 | 1;
40
+ if (choice === null || count < choice.count)
41
+ choice = { quote, count };
42
+ }
43
+ const delimiter = choice.quote.repeat(choice.count);
44
+ return delimiter + text + delimiter;
45
+ }
46
+
1
47
  // src/Link.js
2
48
  class Link {
3
49
  constructor(id = null, values = null) {
@@ -39,26 +85,7 @@ class Link {
39
85
  if (reference === null || reference === undefined) {
40
86
  return "";
41
87
  }
42
- if (reference === "") {
43
- return '""';
44
- }
45
- const hasSingleQuote = reference.includes("'");
46
- const hasDoubleQuote = reference.includes('"');
47
- const needsQuoting = reference.startsWith("#") || reference.includes(":") || reference.includes("(") || reference.includes(")") || reference.includes(" ") || reference.includes("\t") || reference.includes(`
48
- `) || reference.includes("\r") || hasDoubleQuote || hasSingleQuote;
49
- if (hasSingleQuote && hasDoubleQuote) {
50
- return `'${reference.replace(/'/g, "\\'")}'`;
51
- }
52
- if (hasDoubleQuote) {
53
- return `'${reference}'`;
54
- }
55
- if (hasSingleQuote) {
56
- return `"${reference}"`;
57
- }
58
- if (needsQuoting) {
59
- return `'${reference}'`;
60
- }
61
- return reference;
88
+ return formatReference(reference);
62
89
  }
63
90
  toLinkOrIdString() {
64
91
  if (!this.values || this.values.length === 0) {
@@ -631,14 +658,19 @@ function peg$parse(input, options) {
631
658
  const peg$c0 = "(";
632
659
  const peg$c1 = ")";
633
660
  const peg$c2 = ":";
634
- const peg$c3 = '"';
635
- const peg$c4 = "'";
636
- const peg$c5 = "`";
637
- const peg$c6 = " ";
661
+ const peg$c3 = "~";
662
+ const peg$c4 = "{";
663
+ const peg$c5 = "}";
664
+ const peg$c6 = '"';
665
+ const peg$c7 = "'";
666
+ const peg$c8 = "`";
667
+ const peg$c9 = " ";
638
668
  const peg$r0 = /^[ \t]/;
639
669
  const peg$r1 = /^[\r\n]/;
640
- const peg$r2 = /^[ \t\n\r]/;
641
- const peg$r3 = /^[^ \t\n\r(:)]/;
670
+ const peg$r2 = /^[0-9]/;
671
+ const peg$r3 = /^[^} \t\r\n()]/;
672
+ const peg$r4 = /^[ \t\n\r]/;
673
+ const peg$r5 = /^[^ \t\n\r(:)]/;
642
674
  const peg$e0 = peg$classExpectation([" ", "\t"], false, false, false);
643
675
  const peg$e1 = peg$classExpectation(["\r", `
644
676
  `], false, false, false);
@@ -646,13 +678,19 @@ function peg$parse(input, options) {
646
678
  const peg$e3 = peg$literalExpectation("(", false);
647
679
  const peg$e4 = peg$literalExpectation(")", false);
648
680
  const peg$e5 = peg$literalExpectation(":", false);
649
- const peg$e6 = peg$literalExpectation('"', false);
650
- const peg$e7 = peg$literalExpectation("'", false);
651
- const peg$e8 = peg$literalExpectation("`", false);
652
- const peg$e9 = peg$literalExpectation(" ", false);
653
- const peg$e10 = peg$classExpectation([" ", "\t", `
681
+ const peg$e6 = peg$literalExpectation("~", false);
682
+ const peg$e7 = peg$classExpectation([["0", "9"]], false, false, false);
683
+ const peg$e8 = peg$literalExpectation("{", false);
684
+ const peg$e9 = peg$classExpectation(["}", " ", "\t", "\r", `
685
+ `, "(", ")"], true, false, false);
686
+ const peg$e10 = peg$literalExpectation("}", false);
687
+ const peg$e11 = peg$literalExpectation('"', false);
688
+ const peg$e12 = peg$literalExpectation("'", false);
689
+ const peg$e13 = peg$literalExpectation("`", false);
690
+ const peg$e14 = peg$literalExpectation(" ", false);
691
+ const peg$e15 = peg$classExpectation([" ", "\t", `
654
692
  `, "\r"], false, false, false);
655
- const peg$e11 = peg$classExpectation([" ", "\t", `
693
+ const peg$e16 = peg$classExpectation([" ", "\t", `
656
694
  `, "\r", "(", ":", ")"], true, false, false);
657
695
  function peg$f0() {
658
696
  return resetState();
@@ -749,10 +787,19 @@ function peg$parse(input, options) {
749
787
  function peg$f28(id) {
750
788
  return { id, values: [] };
751
789
  }
752
- function peg$f29(chars) {
790
+ function peg$f29() {
791
+ return hasReferenceLiteralPrefix(input, offset());
792
+ }
793
+ function peg$f30(literal) {
794
+ return decodeReferenceLiteral(literal);
795
+ }
796
+ function peg$f31() {
797
+ return !hasReferenceLiteralPrefix(input, offset());
798
+ }
799
+ function peg$f32(chars) {
753
800
  return chars.join("");
754
801
  }
755
- function peg$f30() {
802
+ function peg$f33() {
756
803
  const pos = offset();
757
804
  const result = parseQuotedStringAt(input, pos, '"');
758
805
  if (result) {
@@ -762,19 +809,19 @@ function peg$parse(input, options) {
762
809
  }
763
810
  return false;
764
811
  }
765
- function peg$f31(chars) {
812
+ function peg$f34(chars) {
766
813
  return parsedValue;
767
814
  }
768
- function peg$f32(c, cs) {
815
+ function peg$f35(c, cs) {
769
816
  return [c].concat(cs).join("");
770
817
  }
771
- function peg$f33() {
818
+ function peg$f36() {
772
819
  return parsedLength > 1 && (parsedLength--, true);
773
820
  }
774
- function peg$f34(c) {
821
+ function peg$f37(c) {
775
822
  return c;
776
823
  }
777
- function peg$f35() {
824
+ function peg$f38() {
778
825
  const pos = offset();
779
826
  const result = parseQuotedStringAt(input, pos, "'");
780
827
  if (result) {
@@ -784,19 +831,19 @@ function peg$parse(input, options) {
784
831
  }
785
832
  return false;
786
833
  }
787
- function peg$f36(chars) {
834
+ function peg$f39(chars) {
788
835
  return parsedValue;
789
836
  }
790
- function peg$f37(c, cs) {
837
+ function peg$f40(c, cs) {
791
838
  return [c].concat(cs).join("");
792
839
  }
793
- function peg$f38() {
840
+ function peg$f41() {
794
841
  return parsedLength > 1 && (parsedLength--, true);
795
842
  }
796
- function peg$f39(c) {
843
+ function peg$f42(c) {
797
844
  return c;
798
845
  }
799
- function peg$f40() {
846
+ function peg$f43() {
800
847
  const pos = offset();
801
848
  const result = parseQuotedStringAt(input, pos, "`");
802
849
  if (result) {
@@ -806,34 +853,34 @@ function peg$parse(input, options) {
806
853
  }
807
854
  return false;
808
855
  }
809
- function peg$f41(chars) {
856
+ function peg$f44(chars) {
810
857
  return parsedValue;
811
858
  }
812
- function peg$f42(c, cs) {
859
+ function peg$f45(c, cs) {
813
860
  return [c].concat(cs).join("");
814
861
  }
815
- function peg$f43() {
862
+ function peg$f46() {
816
863
  return parsedLength > 1 && (parsedLength--, true);
817
864
  }
818
- function peg$f44(c) {
865
+ function peg$f47(c) {
819
866
  return c;
820
867
  }
821
- function peg$f45() {
868
+ function peg$f48() {
822
869
  return indentationStack.slice();
823
870
  }
824
- function peg$f46(spaces) {
871
+ function peg$f49(spaces) {
825
872
  setBaseIndentation(spaces);
826
873
  }
827
- function peg$f47(spaces) {
874
+ function peg$f50(spaces) {
828
875
  return normalizeIndentation(spaces) > getCurrentIndentation();
829
876
  }
830
- function peg$f48(spaces) {
877
+ function peg$f51(spaces) {
831
878
  pushIndentation(spaces);
832
879
  }
833
- function peg$f49(spaces) {
880
+ function peg$f52(spaces) {
834
881
  return checkIndentation(spaces);
835
882
  }
836
- function peg$f50() {
883
+ function peg$f53() {
837
884
  return isInsideNestedContext();
838
885
  }
839
886
  let peg$currPos = options.peg$currPos | 0;
@@ -1680,30 +1727,198 @@ function peg$parse(input, options) {
1680
1727
  }
1681
1728
  function peg$parsereference() {
1682
1729
  let s0;
1683
- s0 = peg$parsequotedReference();
1730
+ s0 = peg$parsereferenceLiteral();
1684
1731
  if (s0 === peg$FAILED) {
1685
- s0 = peg$parsesimpleReference();
1732
+ s0 = peg$parsequotedReference();
1733
+ if (s0 === peg$FAILED) {
1734
+ s0 = peg$parsesimpleReference();
1735
+ }
1686
1736
  }
1687
1737
  return s0;
1688
1738
  }
1689
- function peg$parsesimpleReference() {
1690
- let s0, s1, s2;
1739
+ function peg$parsereferenceLiteral() {
1740
+ let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
1691
1741
  s0 = peg$currPos;
1692
- s1 = [];
1693
- s2 = peg$parsereferenceSymbol();
1742
+ s1 = peg$currPos;
1743
+ peg$silentFails++;
1744
+ if (input.charCodeAt(peg$currPos) === 126) {
1745
+ s2 = peg$c3;
1746
+ peg$currPos++;
1747
+ } else {
1748
+ s2 = peg$FAILED;
1749
+ if (peg$silentFails === 0) {
1750
+ peg$fail(peg$e6);
1751
+ }
1752
+ }
1753
+ peg$silentFails--;
1694
1754
  if (s2 !== peg$FAILED) {
1695
- while (s2 !== peg$FAILED) {
1696
- s1.push(s2);
1697
- s2 = peg$parsereferenceSymbol();
1755
+ peg$currPos = s1;
1756
+ s1 = undefined;
1757
+ } else {
1758
+ s1 = peg$FAILED;
1759
+ }
1760
+ if (s1 !== peg$FAILED) {
1761
+ peg$savedPos = peg$currPos;
1762
+ s2 = peg$f29();
1763
+ if (s2) {
1764
+ s2 = undefined;
1765
+ } else {
1766
+ s2 = peg$FAILED;
1767
+ }
1768
+ if (s2 !== peg$FAILED) {
1769
+ s3 = peg$currPos;
1770
+ s4 = peg$currPos;
1771
+ if (input.charCodeAt(peg$currPos) === 126) {
1772
+ s5 = peg$c3;
1773
+ peg$currPos++;
1774
+ } else {
1775
+ s5 = peg$FAILED;
1776
+ if (peg$silentFails === 0) {
1777
+ peg$fail(peg$e6);
1778
+ }
1779
+ }
1780
+ if (s5 !== peg$FAILED) {
1781
+ s6 = [];
1782
+ s7 = input.charAt(peg$currPos);
1783
+ if (peg$r2.test(s7)) {
1784
+ peg$currPos++;
1785
+ } else {
1786
+ s7 = peg$FAILED;
1787
+ if (peg$silentFails === 0) {
1788
+ peg$fail(peg$e7);
1789
+ }
1790
+ }
1791
+ if (s7 !== peg$FAILED) {
1792
+ while (s7 !== peg$FAILED) {
1793
+ s6.push(s7);
1794
+ s7 = input.charAt(peg$currPos);
1795
+ if (peg$r2.test(s7)) {
1796
+ peg$currPos++;
1797
+ } else {
1798
+ s7 = peg$FAILED;
1799
+ if (peg$silentFails === 0) {
1800
+ peg$fail(peg$e7);
1801
+ }
1802
+ }
1803
+ }
1804
+ } else {
1805
+ s6 = peg$FAILED;
1806
+ }
1807
+ if (s6 !== peg$FAILED) {
1808
+ if (input.charCodeAt(peg$currPos) === 123) {
1809
+ s7 = peg$c4;
1810
+ peg$currPos++;
1811
+ } else {
1812
+ s7 = peg$FAILED;
1813
+ if (peg$silentFails === 0) {
1814
+ peg$fail(peg$e8);
1815
+ }
1816
+ }
1817
+ if (s7 !== peg$FAILED) {
1818
+ s8 = [];
1819
+ s9 = input.charAt(peg$currPos);
1820
+ if (peg$r3.test(s9)) {
1821
+ peg$currPos++;
1822
+ } else {
1823
+ s9 = peg$FAILED;
1824
+ if (peg$silentFails === 0) {
1825
+ peg$fail(peg$e9);
1826
+ }
1827
+ }
1828
+ while (s9 !== peg$FAILED) {
1829
+ s8.push(s9);
1830
+ s9 = input.charAt(peg$currPos);
1831
+ if (peg$r3.test(s9)) {
1832
+ peg$currPos++;
1833
+ } else {
1834
+ s9 = peg$FAILED;
1835
+ if (peg$silentFails === 0) {
1836
+ peg$fail(peg$e9);
1837
+ }
1838
+ }
1839
+ }
1840
+ if (input.charCodeAt(peg$currPos) === 125) {
1841
+ s9 = peg$c5;
1842
+ peg$currPos++;
1843
+ } else {
1844
+ s9 = peg$FAILED;
1845
+ if (peg$silentFails === 0) {
1846
+ peg$fail(peg$e10);
1847
+ }
1848
+ }
1849
+ if (s9 !== peg$FAILED) {
1850
+ s5 = [s5, s6, s7, s8, s9];
1851
+ s4 = s5;
1852
+ } else {
1853
+ peg$currPos = s4;
1854
+ s4 = peg$FAILED;
1855
+ }
1856
+ } else {
1857
+ peg$currPos = s4;
1858
+ s4 = peg$FAILED;
1859
+ }
1860
+ } else {
1861
+ peg$currPos = s4;
1862
+ s4 = peg$FAILED;
1863
+ }
1864
+ } else {
1865
+ peg$currPos = s4;
1866
+ s4 = peg$FAILED;
1867
+ }
1868
+ if (s4 !== peg$FAILED) {
1869
+ s3 = input.substring(s3, peg$currPos);
1870
+ } else {
1871
+ s3 = s4;
1872
+ }
1873
+ if (s3 !== peg$FAILED) {
1874
+ peg$savedPos = s0;
1875
+ s0 = peg$f30(s3);
1876
+ } else {
1877
+ peg$currPos = s0;
1878
+ s0 = peg$FAILED;
1879
+ }
1880
+ } else {
1881
+ peg$currPos = s0;
1882
+ s0 = peg$FAILED;
1698
1883
  }
1884
+ } else {
1885
+ peg$currPos = s0;
1886
+ s0 = peg$FAILED;
1887
+ }
1888
+ return s0;
1889
+ }
1890
+ function peg$parsesimpleReference() {
1891
+ let s0, s1, s2, s3;
1892
+ s0 = peg$currPos;
1893
+ peg$savedPos = peg$currPos;
1894
+ s1 = peg$f31();
1895
+ if (s1) {
1896
+ s1 = undefined;
1699
1897
  } else {
1700
1898
  s1 = peg$FAILED;
1701
1899
  }
1702
1900
  if (s1 !== peg$FAILED) {
1703
- peg$savedPos = s0;
1704
- s1 = peg$f29(s1);
1901
+ s2 = [];
1902
+ s3 = peg$parsereferenceSymbol();
1903
+ if (s3 !== peg$FAILED) {
1904
+ while (s3 !== peg$FAILED) {
1905
+ s2.push(s3);
1906
+ s3 = peg$parsereferenceSymbol();
1907
+ }
1908
+ } else {
1909
+ s2 = peg$FAILED;
1910
+ }
1911
+ if (s2 !== peg$FAILED) {
1912
+ peg$savedPos = s0;
1913
+ s0 = peg$f32(s2);
1914
+ } else {
1915
+ peg$currPos = s0;
1916
+ s0 = peg$FAILED;
1917
+ }
1918
+ } else {
1919
+ peg$currPos = s0;
1920
+ s0 = peg$FAILED;
1705
1921
  }
1706
- s0 = s1;
1707
1922
  return s0;
1708
1923
  }
1709
1924
  function peg$parsequotedReference() {
@@ -1723,12 +1938,12 @@ function peg$parse(input, options) {
1723
1938
  s1 = peg$currPos;
1724
1939
  peg$silentFails++;
1725
1940
  if (input.charCodeAt(peg$currPos) === 34) {
1726
- s2 = peg$c3;
1941
+ s2 = peg$c6;
1727
1942
  peg$currPos++;
1728
1943
  } else {
1729
1944
  s2 = peg$FAILED;
1730
1945
  if (peg$silentFails === 0) {
1731
- peg$fail(peg$e6);
1946
+ peg$fail(peg$e11);
1732
1947
  }
1733
1948
  }
1734
1949
  peg$silentFails--;
@@ -1740,7 +1955,7 @@ function peg$parse(input, options) {
1740
1955
  }
1741
1956
  if (s1 !== peg$FAILED) {
1742
1957
  peg$savedPos = peg$currPos;
1743
- s2 = peg$f30();
1958
+ s2 = peg$f33();
1744
1959
  if (s2) {
1745
1960
  s2 = undefined;
1746
1961
  } else {
@@ -1750,7 +1965,7 @@ function peg$parse(input, options) {
1750
1965
  s3 = peg$parseconsumeDouble();
1751
1966
  if (s3 !== peg$FAILED) {
1752
1967
  peg$savedPos = s0;
1753
- s0 = peg$f31(s3);
1968
+ s0 = peg$f34(s3);
1754
1969
  } else {
1755
1970
  peg$currPos = s0;
1756
1971
  s0 = peg$FAILED;
@@ -1785,7 +2000,7 @@ function peg$parse(input, options) {
1785
2000
  s3 = peg$parseconsumeDoubleMore();
1786
2001
  }
1787
2002
  peg$savedPos = s0;
1788
- s0 = peg$f32(s1, s2);
2003
+ s0 = peg$f35(s1, s2);
1789
2004
  } else {
1790
2005
  peg$currPos = s0;
1791
2006
  s0 = peg$FAILED;
@@ -1796,7 +2011,7 @@ function peg$parse(input, options) {
1796
2011
  let s0, s1, s2;
1797
2012
  s0 = peg$currPos;
1798
2013
  peg$savedPos = peg$currPos;
1799
- s1 = peg$f33();
2014
+ s1 = peg$f36();
1800
2015
  if (s1) {
1801
2016
  s1 = undefined;
1802
2017
  } else {
@@ -1814,7 +2029,7 @@ function peg$parse(input, options) {
1814
2029
  }
1815
2030
  if (s2 !== peg$FAILED) {
1816
2031
  peg$savedPos = s0;
1817
- s0 = peg$f34(s2);
2032
+ s0 = peg$f37(s2);
1818
2033
  } else {
1819
2034
  peg$currPos = s0;
1820
2035
  s0 = peg$FAILED;
@@ -1831,12 +2046,12 @@ function peg$parse(input, options) {
1831
2046
  s1 = peg$currPos;
1832
2047
  peg$silentFails++;
1833
2048
  if (input.charCodeAt(peg$currPos) === 39) {
1834
- s2 = peg$c4;
2049
+ s2 = peg$c7;
1835
2050
  peg$currPos++;
1836
2051
  } else {
1837
2052
  s2 = peg$FAILED;
1838
2053
  if (peg$silentFails === 0) {
1839
- peg$fail(peg$e7);
2054
+ peg$fail(peg$e12);
1840
2055
  }
1841
2056
  }
1842
2057
  peg$silentFails--;
@@ -1848,7 +2063,7 @@ function peg$parse(input, options) {
1848
2063
  }
1849
2064
  if (s1 !== peg$FAILED) {
1850
2065
  peg$savedPos = peg$currPos;
1851
- s2 = peg$f35();
2066
+ s2 = peg$f38();
1852
2067
  if (s2) {
1853
2068
  s2 = undefined;
1854
2069
  } else {
@@ -1858,7 +2073,7 @@ function peg$parse(input, options) {
1858
2073
  s3 = peg$parseconsumeSingle();
1859
2074
  if (s3 !== peg$FAILED) {
1860
2075
  peg$savedPos = s0;
1861
- s0 = peg$f36(s3);
2076
+ s0 = peg$f39(s3);
1862
2077
  } else {
1863
2078
  peg$currPos = s0;
1864
2079
  s0 = peg$FAILED;
@@ -1893,7 +2108,7 @@ function peg$parse(input, options) {
1893
2108
  s3 = peg$parseconsumeSingleMore();
1894
2109
  }
1895
2110
  peg$savedPos = s0;
1896
- s0 = peg$f37(s1, s2);
2111
+ s0 = peg$f40(s1, s2);
1897
2112
  } else {
1898
2113
  peg$currPos = s0;
1899
2114
  s0 = peg$FAILED;
@@ -1904,7 +2119,7 @@ function peg$parse(input, options) {
1904
2119
  let s0, s1, s2;
1905
2120
  s0 = peg$currPos;
1906
2121
  peg$savedPos = peg$currPos;
1907
- s1 = peg$f38();
2122
+ s1 = peg$f41();
1908
2123
  if (s1) {
1909
2124
  s1 = undefined;
1910
2125
  } else {
@@ -1922,7 +2137,7 @@ function peg$parse(input, options) {
1922
2137
  }
1923
2138
  if (s2 !== peg$FAILED) {
1924
2139
  peg$savedPos = s0;
1925
- s0 = peg$f39(s2);
2140
+ s0 = peg$f42(s2);
1926
2141
  } else {
1927
2142
  peg$currPos = s0;
1928
2143
  s0 = peg$FAILED;
@@ -1939,12 +2154,12 @@ function peg$parse(input, options) {
1939
2154
  s1 = peg$currPos;
1940
2155
  peg$silentFails++;
1941
2156
  if (input.charCodeAt(peg$currPos) === 96) {
1942
- s2 = peg$c5;
2157
+ s2 = peg$c8;
1943
2158
  peg$currPos++;
1944
2159
  } else {
1945
2160
  s2 = peg$FAILED;
1946
2161
  if (peg$silentFails === 0) {
1947
- peg$fail(peg$e8);
2162
+ peg$fail(peg$e13);
1948
2163
  }
1949
2164
  }
1950
2165
  peg$silentFails--;
@@ -1956,7 +2171,7 @@ function peg$parse(input, options) {
1956
2171
  }
1957
2172
  if (s1 !== peg$FAILED) {
1958
2173
  peg$savedPos = peg$currPos;
1959
- s2 = peg$f40();
2174
+ s2 = peg$f43();
1960
2175
  if (s2) {
1961
2176
  s2 = undefined;
1962
2177
  } else {
@@ -1966,7 +2181,7 @@ function peg$parse(input, options) {
1966
2181
  s3 = peg$parseconsumeBacktick();
1967
2182
  if (s3 !== peg$FAILED) {
1968
2183
  peg$savedPos = s0;
1969
- s0 = peg$f41(s3);
2184
+ s0 = peg$f44(s3);
1970
2185
  } else {
1971
2186
  peg$currPos = s0;
1972
2187
  s0 = peg$FAILED;
@@ -2001,7 +2216,7 @@ function peg$parse(input, options) {
2001
2216
  s3 = peg$parseconsumeBacktickMore();
2002
2217
  }
2003
2218
  peg$savedPos = s0;
2004
- s0 = peg$f42(s1, s2);
2219
+ s0 = peg$f45(s1, s2);
2005
2220
  } else {
2006
2221
  peg$currPos = s0;
2007
2222
  s0 = peg$FAILED;
@@ -2012,7 +2227,7 @@ function peg$parse(input, options) {
2012
2227
  let s0, s1, s2;
2013
2228
  s0 = peg$currPos;
2014
2229
  peg$savedPos = peg$currPos;
2015
- s1 = peg$f43();
2230
+ s1 = peg$f46();
2016
2231
  if (s1) {
2017
2232
  s1 = undefined;
2018
2233
  } else {
@@ -2030,7 +2245,7 @@ function peg$parse(input, options) {
2030
2245
  }
2031
2246
  if (s2 !== peg$FAILED) {
2032
2247
  peg$savedPos = s0;
2033
- s0 = peg$f44(s2);
2248
+ s0 = peg$f47(s2);
2034
2249
  } else {
2035
2250
  peg$currPos = s0;
2036
2251
  s0 = peg$FAILED;
@@ -2046,7 +2261,7 @@ function peg$parse(input, options) {
2046
2261
  s0 = peg$currPos;
2047
2262
  s1 = "";
2048
2263
  peg$savedPos = s0;
2049
- s1 = peg$f45();
2264
+ s1 = peg$f48();
2050
2265
  s0 = s1;
2051
2266
  return s0;
2052
2267
  }
@@ -2055,28 +2270,28 @@ function peg$parse(input, options) {
2055
2270
  s0 = peg$currPos;
2056
2271
  s1 = [];
2057
2272
  if (input.charCodeAt(peg$currPos) === 32) {
2058
- s2 = peg$c6;
2273
+ s2 = peg$c9;
2059
2274
  peg$currPos++;
2060
2275
  } else {
2061
2276
  s2 = peg$FAILED;
2062
2277
  if (peg$silentFails === 0) {
2063
- peg$fail(peg$e9);
2278
+ peg$fail(peg$e14);
2064
2279
  }
2065
2280
  }
2066
2281
  while (s2 !== peg$FAILED) {
2067
2282
  s1.push(s2);
2068
2283
  if (input.charCodeAt(peg$currPos) === 32) {
2069
- s2 = peg$c6;
2284
+ s2 = peg$c9;
2070
2285
  peg$currPos++;
2071
2286
  } else {
2072
2287
  s2 = peg$FAILED;
2073
2288
  if (peg$silentFails === 0) {
2074
- peg$fail(peg$e9);
2289
+ peg$fail(peg$e14);
2075
2290
  }
2076
2291
  }
2077
2292
  }
2078
2293
  peg$savedPos = s0;
2079
- s1 = peg$f46(s1);
2294
+ s1 = peg$f49(s1);
2080
2295
  s0 = s1;
2081
2296
  return s0;
2082
2297
  }
@@ -2085,28 +2300,28 @@ function peg$parse(input, options) {
2085
2300
  s0 = peg$currPos;
2086
2301
  s1 = [];
2087
2302
  if (input.charCodeAt(peg$currPos) === 32) {
2088
- s2 = peg$c6;
2303
+ s2 = peg$c9;
2089
2304
  peg$currPos++;
2090
2305
  } else {
2091
2306
  s2 = peg$FAILED;
2092
2307
  if (peg$silentFails === 0) {
2093
- peg$fail(peg$e9);
2308
+ peg$fail(peg$e14);
2094
2309
  }
2095
2310
  }
2096
2311
  while (s2 !== peg$FAILED) {
2097
2312
  s1.push(s2);
2098
2313
  if (input.charCodeAt(peg$currPos) === 32) {
2099
- s2 = peg$c6;
2314
+ s2 = peg$c9;
2100
2315
  peg$currPos++;
2101
2316
  } else {
2102
2317
  s2 = peg$FAILED;
2103
2318
  if (peg$silentFails === 0) {
2104
- peg$fail(peg$e9);
2319
+ peg$fail(peg$e14);
2105
2320
  }
2106
2321
  }
2107
2322
  }
2108
2323
  peg$savedPos = peg$currPos;
2109
- s2 = peg$f47(s1);
2324
+ s2 = peg$f50(s1);
2110
2325
  if (s2) {
2111
2326
  s2 = undefined;
2112
2327
  } else {
@@ -2114,7 +2329,7 @@ function peg$parse(input, options) {
2114
2329
  }
2115
2330
  if (s2 !== peg$FAILED) {
2116
2331
  peg$savedPos = s0;
2117
- s0 = peg$f48(s1);
2332
+ s0 = peg$f51(s1);
2118
2333
  } else {
2119
2334
  peg$currPos = s0;
2120
2335
  s0 = peg$FAILED;
@@ -2126,28 +2341,28 @@ function peg$parse(input, options) {
2126
2341
  s0 = peg$currPos;
2127
2342
  s1 = [];
2128
2343
  if (input.charCodeAt(peg$currPos) === 32) {
2129
- s2 = peg$c6;
2344
+ s2 = peg$c9;
2130
2345
  peg$currPos++;
2131
2346
  } else {
2132
2347
  s2 = peg$FAILED;
2133
2348
  if (peg$silentFails === 0) {
2134
- peg$fail(peg$e9);
2349
+ peg$fail(peg$e14);
2135
2350
  }
2136
2351
  }
2137
2352
  while (s2 !== peg$FAILED) {
2138
2353
  s1.push(s2);
2139
2354
  if (input.charCodeAt(peg$currPos) === 32) {
2140
- s2 = peg$c6;
2355
+ s2 = peg$c9;
2141
2356
  peg$currPos++;
2142
2357
  } else {
2143
2358
  s2 = peg$FAILED;
2144
2359
  if (peg$silentFails === 0) {
2145
- peg$fail(peg$e9);
2360
+ peg$fail(peg$e14);
2146
2361
  }
2147
2362
  }
2148
2363
  }
2149
2364
  peg$savedPos = peg$currPos;
2150
- s2 = peg$f49(s1);
2365
+ s2 = peg$f52(s1);
2151
2366
  if (s2) {
2152
2367
  s2 = undefined;
2153
2368
  } else {
@@ -2358,7 +2573,7 @@ function peg$parse(input, options) {
2358
2573
  let s0, s1, s2, s3;
2359
2574
  s0 = peg$currPos;
2360
2575
  peg$savedPos = peg$currPos;
2361
- s1 = peg$f50();
2576
+ s1 = peg$f53();
2362
2577
  if (s1) {
2363
2578
  s1 = undefined;
2364
2579
  } else {
@@ -2457,12 +2672,12 @@ function peg$parse(input, options) {
2457
2672
  function peg$parsewhiteSpaceSymbol() {
2458
2673
  let s0;
2459
2674
  s0 = input.charAt(peg$currPos);
2460
- if (peg$r2.test(s0)) {
2675
+ if (peg$r4.test(s0)) {
2461
2676
  peg$currPos++;
2462
2677
  } else {
2463
2678
  s0 = peg$FAILED;
2464
2679
  if (peg$silentFails === 0) {
2465
- peg$fail(peg$e10);
2680
+ peg$fail(peg$e15);
2466
2681
  }
2467
2682
  }
2468
2683
  return s0;
@@ -2470,12 +2685,12 @@ function peg$parse(input, options) {
2470
2685
  function peg$parsereferenceSymbol() {
2471
2686
  let s0;
2472
2687
  s0 = input.charAt(peg$currPos);
2473
- if (peg$r3.test(s0)) {
2688
+ if (peg$r5.test(s0)) {
2474
2689
  peg$currPos++;
2475
2690
  } else {
2476
2691
  s0 = peg$FAILED;
2477
2692
  if (peg$silentFails === 0) {
2478
- peg$fail(peg$e11);
2693
+ peg$fail(peg$e16);
2479
2694
  }
2480
2695
  }
2481
2696
  return s0;
@@ -2980,16 +3195,596 @@ class FormatOptions {
2980
3195
  // src/FormatConfig.js
2981
3196
  class FormatConfig extends FormatOptions {
2982
3197
  }
3198
+ // src/Binary.js
3199
+ var U64 = (1n << 64n) - 1n;
3200
+ var WIDTHS = [1, 2, 4, 8];
3201
+ function requireValue(condition, message) {
3202
+ if (!condition)
3203
+ throw new RangeError(message);
3204
+ }
3205
+ function uint64(value) {
3206
+ requireValue(typeof value === "bigint" || Number.isSafeInteger(value) && value >= 0, "expected uint64");
3207
+ const result = BigInt(value);
3208
+ requireValue(result >= 0n && result <= U64, "uint64 overflow");
3209
+ return result;
3210
+ }
3211
+
3212
+ class External {
3213
+ constructor(value) {
3214
+ this.value = uint64(value);
3215
+ }
3216
+ }
3217
+
3218
+ class ArityRange {
3219
+ constructor(min = 2, max = 2) {
3220
+ this.min = uint64(min);
3221
+ this.max = max === null ? null : uint64(max);
3222
+ requireValue(this.min > 0n && this.min <= U64 >> 4n && (this.max === null || this.max >= this.min), "invalid arity");
3223
+ }
3224
+ contains(length) {
3225
+ return BigInt(length) >= this.min && (this.max === null || BigInt(length) <= this.max);
3226
+ }
3227
+ get fixed() {
3228
+ return this.min === this.max;
3229
+ }
3230
+ static parse(text) {
3231
+ requireValue(/^[0-9]+(?:\.\.[0-9]*)?$/.test(text), "invalid arity");
3232
+ const parts = text.split("..");
3233
+ return new ArityRange(BigInt(parts[0]), parts.at(-1) === "" ? null : BigInt(parts.at(-1)));
3234
+ }
3235
+ }
3236
+
3237
+ class DecodeLimits {
3238
+ constructor(values = {}) {
3239
+ Object.assign(this, {
3240
+ maxLinks: 2 ** 22,
3241
+ maxReferences: 2 ** 24,
3242
+ maxNodes: 2 ** 22,
3243
+ maxStringBytes: 64 * 2 ** 20,
3244
+ maxDepth: 64
3245
+ }, values);
3246
+ for (const key of Object.keys(this)) {
3247
+ requireValue([
3248
+ "maxLinks",
3249
+ "maxReferences",
3250
+ "maxNodes",
3251
+ "maxStringBytes",
3252
+ "maxDepth"
3253
+ ].includes(key), "unknown limit");
3254
+ requireValue(Number.isSafeInteger(this[key]) && this[key] >= 0, "invalid limit");
3255
+ }
3256
+ }
3257
+ static unlimited() {
3258
+ return new DecodeLimits({
3259
+ maxLinks: Number.MAX_SAFE_INTEGER,
3260
+ maxReferences: Number.MAX_SAFE_INTEGER,
3261
+ maxNodes: Number.MAX_SAFE_INTEGER,
3262
+ maxStringBytes: Number.MAX_SAFE_INTEGER,
3263
+ maxDepth: Number.MAX_SAFE_INTEGER
3264
+ });
3265
+ }
3266
+ }
3267
+
3268
+ class BinaryLinoOptions {
3269
+ constructor(externalReferences = false, arity = new ArityRange, packedWidths = false) {
3270
+ Object.assign(this, { externalReferences, arity, packedWidths });
3271
+ }
3272
+ static ofPacket(packet) {
3273
+ let min = 2, max = 2;
3274
+ for (const [, link] of packet.links()) {
3275
+ min = Math.min(min, link.length);
3276
+ max = Math.max(max, link.length);
3277
+ }
3278
+ return new BinaryLinoOptions(packet.externalReferences, new ArityRange(min, max), new Set(packet.sections.map((s) => s.width)).size > 1);
3279
+ }
3280
+ }
3281
+
3282
+ class Section {
3283
+ constructor(gap, arity, width, links) {
3284
+ Object.assign(this, { gap: uint64(gap), arity, width, links });
3285
+ }
3286
+ }
3287
+ function referenceWidth(reference, external) {
3288
+ const value = reference instanceof External ? reference.value : uint64(reference);
3289
+ requireValue(!(reference instanceof External) || external, "external references disabled");
3290
+ for (const width of WIDTHS)
3291
+ if (value < 1n << BigInt(width * 8 - Number(external)))
3292
+ return width;
3293
+ throw new RangeError("reference exceeds capacity");
3294
+ }
3295
+ function leb(out, input) {
3296
+ let value = uint64(input);
3297
+ while (value >= 128n) {
3298
+ out.push(Number(value & 127n) | 128);
3299
+ value >>= 7n;
3300
+ }
3301
+ out.push(Number(value));
3302
+ }
3303
+
3304
+ class PacketReader {
3305
+ constructor(bytes, offset = 0) {
3306
+ requireValue(bytes instanceof Uint8Array && Number.isSafeInteger(offset) && offset >= 0 && offset <= bytes.length, "invalid byte cursor");
3307
+ this.bytes = bytes;
3308
+ this.offset = offset;
3309
+ }
3310
+ raw(width) {
3311
+ requireValue(width <= this.bytes.length - this.offset, "unexpected end of packet");
3312
+ let result = 0n;
3313
+ for (let i = 0;i < width; i++)
3314
+ result |= BigInt(this.bytes[this.offset++]) << BigInt(i * 8);
3315
+ return result;
3316
+ }
3317
+ leb() {
3318
+ let value = 0n;
3319
+ for (let shift = 0n;shift < 64n; shift += 7n) {
3320
+ const byte = this.raw(1);
3321
+ requireValue(shift !== 63n || (byte & 127n) <= 1n, "LEB128 overflow");
3322
+ value |= (byte & 127n) << shift;
3323
+ if (byte < 128n)
3324
+ return value;
3325
+ }
3326
+ throw new RangeError("LEB128 overflow");
3327
+ }
3328
+ read(limits = new DecodeLimits) {
3329
+ if (this.offset === this.bytes.length)
3330
+ return null;
3331
+ const header = Number(this.raw(1));
3332
+ requireValue((header & 240) === 16, "unsupported binary version");
3333
+ const sections = [], counts = [];
3334
+ if (header & 2) {
3335
+ requireValue((header & 12) === 0, "explicit header width bits set");
3336
+ const sectionCount = this.leb();
3337
+ requireValue(sectionCount <= BigInt(limits.maxLinks), "too many sections");
3338
+ let address = 1n, total = 0n;
3339
+ for (let i = 0n;i < sectionCount; i++) {
3340
+ const shape = this.leb(), gap = shape & 4n ? this.leb() : 0n;
3341
+ const min = shape >> 4n, extra = shape & 8n ? this.leb() : null;
3342
+ const arity = new ArityRange(min, extra === null ? min : extra === 0n ? null : uint64(min + extra));
3343
+ const count = this.leb();
3344
+ address = uint64(address + gap + count);
3345
+ total += count;
3346
+ requireValue(total <= BigInt(limits.maxLinks), "too many links");
3347
+ sections.push(new Section(gap, arity, WIDTHS[Number(shape & 3n)], []));
3348
+ counts.push(Number(count));
3349
+ }
3350
+ } else {
3351
+ const count = this.leb();
3352
+ uint64(6n + count);
3353
+ requireValue(count <= BigInt(limits.maxLinks), "too many links");
3354
+ if (count) {
3355
+ sections.push(new Section(5, new ArityRange, WIDTHS[header >> 2 & 3], []));
3356
+ counts.push(Number(count));
3357
+ }
3358
+ }
3359
+ let references = 0n;
3360
+ for (let i = 0;i < sections.length; i++) {
3361
+ const section = sections[i];
3362
+ for (let j = 0;j < counts[i]; j++) {
3363
+ const length = uint64(section.arity.min + (section.arity.fixed ? 0n : this.leb()));
3364
+ requireValue(section.arity.contains(length), "link outside arity");
3365
+ references += length;
3366
+ requireValue(references <= BigInt(limits.maxReferences), "too many references");
3367
+ const link = [], top = 1n << BigInt(section.width * 8 - 1);
3368
+ for (let k = 0n;k < length; k++) {
3369
+ const raw = this.raw(section.width);
3370
+ link.push(header & 1 && raw >= top ? new External(raw === top ? 0n : (top << 1n) - raw) : raw);
3371
+ }
3372
+ section.links.push(link);
3373
+ }
3374
+ }
3375
+ return new LinksPacket(Boolean(header & 1), sections);
3376
+ }
3377
+ }
3378
+
3379
+ class LinksPacket {
3380
+ constructor(externalReferences = false, sections = []) {
3381
+ Object.assign(this, { externalReferences, sections });
3382
+ }
3383
+ links() {
3384
+ const result = [];
3385
+ let address = 1n;
3386
+ for (const section of this.sections) {
3387
+ address = uint64(address + uint64(section.gap));
3388
+ for (const link of section.links) {
3389
+ result.push([
3390
+ address,
3391
+ link.map((r) => r instanceof External ? r : uint64(r))
3392
+ ]);
3393
+ address = uint64(address + 1n);
3394
+ }
3395
+ }
3396
+ return result;
3397
+ }
3398
+ validate(limits = new DecodeLimits) {
3399
+ requireValue(this.sections.length <= limits.maxLinks && this.links().length <= limits.maxLinks, "too many links or sections");
3400
+ let references = 0;
3401
+ for (const s of this.sections) {
3402
+ requireValue(WIDTHS.includes(s.width), "invalid width");
3403
+ new ArityRange(s.arity.min, s.arity.max);
3404
+ for (const link of s.links) {
3405
+ requireValue(s.arity.contains(link.length), "link outside arity");
3406
+ references += link.length;
3407
+ requireValue(references <= limits.maxReferences, "too many references");
3408
+ for (const r of link)
3409
+ requireValue(referenceWidth(r, this.externalReferences) <= s.width, "reference outside width");
3410
+ }
3411
+ }
3412
+ return this;
3413
+ }
3414
+ toBytes(limits = new DecodeLimits) {
3415
+ this.validate(limits);
3416
+ const s = this.sections[0];
3417
+ const compact = !s || this.sections.length === 1 && s.gap === 5n && s.arity.min === 2n && s.arity.max === 2n && s.links.length > 0;
3418
+ const out = [16 | Number(this.externalReferences)];
3419
+ if (compact) {
3420
+ out[0] |= WIDTHS.indexOf(s?.width ?? 1) << 2;
3421
+ leb(out, s?.links.length ?? 0);
3422
+ } else {
3423
+ out[0] |= 2;
3424
+ leb(out, this.sections.length);
3425
+ for (const s of this.sections) {
3426
+ leb(out, s.arity.min << 4n | BigInt(WIDTHS.indexOf(s.width) | (s.gap ? 4 : 0) | (s.arity.fixed ? 0 : 8)));
3427
+ if (s.gap)
3428
+ leb(out, s.gap);
3429
+ if (!s.arity.fixed)
3430
+ leb(out, s.arity.max === null ? 0n : s.arity.max - s.arity.min);
3431
+ leb(out, s.links.length);
3432
+ }
3433
+ }
3434
+ for (const s of this.sections)
3435
+ for (const link of s.links) {
3436
+ if (!s.arity.fixed)
3437
+ leb(out, BigInt(link.length) - s.arity.min);
3438
+ for (const r of link) {
3439
+ const bits = BigInt(s.width * 8);
3440
+ let raw = r instanceof External ? r.value === 0n ? 1n << bits - 1n : (1n << bits) - r.value : uint64(r);
3441
+ for (let i = 0;i < s.width; i++) {
3442
+ out.push(Number(raw & 255n));
3443
+ raw >>= 8n;
3444
+ }
3445
+ }
3446
+ }
3447
+ return Uint8Array.from(out);
3448
+ }
3449
+ static fromBytes(bytes, limits = new DecodeLimits) {
3450
+ const reader = new PacketReader(bytes), packet = reader.read(limits);
3451
+ requireValue(packet !== null, "empty input");
3452
+ requireValue(reader.offset === bytes.length, "trailing bytes");
3453
+ return packet;
3454
+ }
3455
+ static parseLinks(text) {
3456
+ return text.split(";").filter((s) => s.trim()).map((entry) => {
3457
+ const [a, refs] = entry.split(":");
3458
+ return [
3459
+ uint64(BigInt(a.trim())),
3460
+ refs.trim().split(/\s+/).filter(Boolean).map((r) => r.startsWith("#") ? new External(BigInt(r.slice(1))) : uint64(BigInt(r)))
3461
+ ];
3462
+ });
3463
+ }
3464
+ static pack(externalReferences, input, packedWidths = false) {
3465
+ const links = input.map(([a, r]) => [uint64(a), r]);
3466
+ let previous = 0n;
3467
+ const needs = links.map(([a, refs]) => {
3468
+ requireValue(a > previous && a < U64 && refs.length > 0, "invalid address order or empty link");
3469
+ previous = a;
3470
+ return refs.reduce((need, r) => Math.max(need, referenceWidth(r, externalReferences)), 1);
3471
+ });
3472
+ function layout(packed) {
3473
+ if (!links.length)
3474
+ return [];
3475
+ const widest = needs.reduce((a, b) => Math.max(a, b), 1), opens = [], bests = [];
3476
+ let costs = Array(8).fill(Infinity);
3477
+ const cheapest = (c) => c.reduce((best, v, s) => v < c[best] ? s : best, 0);
3478
+ for (let i = 0;i < links.length; i++) {
3479
+ const best = cheapest(costs), before = i ? costs[best] : 0, next = Array(8).fill(Infinity);
3480
+ let mask = 0;
3481
+ bests.push(best);
3482
+ for (let state = 0;state < 8; state++) {
3483
+ const width = WIDTHS[state >> 1], variable = state & 1;
3484
+ if (!packed && width !== widest || width < needs[i])
3485
+ continue;
3486
+ const opening = before + 2 + variable;
3487
+ const continuing = i && links[i - 1][0] + 1n === links[i][0] && (variable || links[i - 1][1].length === links[i][1].length) ? costs[state] : Infinity;
3488
+ if (continuing <= opening)
3489
+ next[state] = continuing + links[i][1].length * width + variable;
3490
+ else {
3491
+ next[state] = opening + links[i][1].length * width + variable;
3492
+ mask |= 1 << state;
3493
+ }
3494
+ }
3495
+ opens.push(mask);
3496
+ costs = next;
3497
+ }
3498
+ const result = [];
3499
+ let end = links.length, state = cheapest(costs);
3500
+ for (let i = links.length - 1;i >= 0; i--)
3501
+ if (opens[i] & 1 << state) {
3502
+ result.push([end - i, WIDTHS[state >> 1]]);
3503
+ end = i;
3504
+ state = bests[i];
3505
+ }
3506
+ return result.reverse();
3507
+ }
3508
+ function packet(plan) {
3509
+ const sections = [];
3510
+ let index = 0, address = 1n;
3511
+ for (const [count, width] of plan) {
3512
+ const members = links.slice(index, index + count), start = members[0][0];
3513
+ let min = Infinity, max = 0;
3514
+ for (const [, r] of members) {
3515
+ min = Math.min(min, r.length);
3516
+ max = Math.max(max, r.length);
3517
+ }
3518
+ sections.push(new Section(start - address, new ArityRange(min, max), width, members.map(([, r]) => r)));
3519
+ index += count;
3520
+ address = start + BigInt(count);
3521
+ }
3522
+ return new LinksPacket(externalReferences, sections);
3523
+ }
3524
+ const uniform = packet(layout(false));
3525
+ if (!packedWidths)
3526
+ return uniform;
3527
+ const packed = packet(layout(true));
3528
+ return packed.toBytes(DecodeLimits.unlimited()).length < uniform.toBytes(DecodeLimits.unlimited()).length ? packed : uniform;
3529
+ }
3530
+ }
3531
+
3532
+ class Encoder {
3533
+ constructor(options) {
3534
+ this.options = options;
3535
+ this.doublets = [];
3536
+ this.tuples = [];
3537
+ this.created = new Map;
3538
+ this.powers = [["i", 1n]];
3539
+ }
3540
+ link(items) {
3541
+ const key = items.map(([k, v]) => `${k}${v}`).join(",");
3542
+ if (!this.created.has(key)) {
3543
+ const doublet = items.length === 2 && items.every(([k]) => k !== "t"), target = doublet ? this.doublets : this.tuples;
3544
+ const node = [doublet ? "d" : "t", BigInt(target.length)];
3545
+ target.push(items);
3546
+ this.created.set(key, node);
3547
+ }
3548
+ return this.created.get(key);
3549
+ }
3550
+ chain(items) {
3551
+ let tail = ["i", 0n];
3552
+ for (let i = items.length - 1;i >= 0; i--)
3553
+ tail = this.link([items[i], tail]);
3554
+ return tail;
3555
+ }
3556
+ typed(marker, elements) {
3557
+ const items = [["i", BigInt(marker)], ...elements];
3558
+ return items.length !== 2 && this.options.arity.contains(items.length) ? this.link(items) : this.link([items[0], this.chain(elements)]);
3559
+ }
3560
+ list(elements) {
3561
+ if (!elements.length)
3562
+ return ["i", 0n];
3563
+ return elements.length === 2 || this.options.arity.contains(elements.length) ? this.link(elements) : this.typed(4, elements);
3564
+ }
3565
+ unary(value) {
3566
+ const powers = [];
3567
+ for (let bit = 63;bit >= 0; bit--)
3568
+ if (value & 1n << BigInt(bit)) {
3569
+ while (this.powers.length <= bit) {
3570
+ const p = this.powers.at(-1);
3571
+ this.powers.push(this.link([p, p]));
3572
+ }
3573
+ powers.push(this.powers[bit]);
3574
+ }
3575
+ let sum = powers.pop() ?? ["i", 0n];
3576
+ while (powers.length)
3577
+ sum = this.link([powers.pop(), sum]);
3578
+ return sum;
3579
+ }
3580
+ scalar(value) {
3581
+ return this.options.externalReferences && value < 1n << 63n ? ["e", value] : this.unary(value);
3582
+ }
3583
+ reference(text) {
3584
+ if (/^(0|[1-9][0-9]*)$/.test(text) && text.length <= 20 && BigInt(text) <= U64) {
3585
+ const value = BigInt(text);
3586
+ return this.options.externalReferences && value < 1n << 63n ? ["e", value] : this.link([["i", 2n], this.unary(value)]);
3587
+ }
3588
+ return this.typed(3, Array.from(text, (c) => this.scalar(BigInt(c.codePointAt(0)))));
3589
+ }
3590
+ encode(node) {
3591
+ if (node.id !== null && !node.values.length)
3592
+ return this.reference(node.id);
3593
+ if (node.id !== null) {
3594
+ const id = this.reference(node.id);
3595
+ return this.typed(5, [id, ...node.values.map((v) => this.encode(v))]);
3596
+ }
3597
+ return this.list(node.values.map((v) => this.encode(v)));
3598
+ }
3599
+ finish() {
3600
+ const resolve = ([k, v]) => k === "e" ? new External(v) : k === "i" ? v : 6n + v + (k === "t" ? BigInt(this.doublets.length) : 0n);
3601
+ return LinksPacket.pack(this.options.externalReferences, this.doublets.concat(this.tuples).map((items, i) => [6n + BigInt(i), items.map(resolve)]), this.options.packedWidths);
3602
+ }
3603
+ }
3604
+
3605
+ class Decoder {
3606
+ constructor(packet, limits) {
3607
+ packet.validate(limits);
3608
+ this.limits = limits;
3609
+ this.links = [];
3610
+ this.unary = [];
3611
+ this.nodes = limits.maxNodes;
3612
+ this.strings = limits.maxStringBytes;
3613
+ for (const [address, refs] of packet.links()) {
3614
+ requireValue(address === 6n + BigInt(this.links.length) && refs.every((r) => r instanceof External || r < address), "document addresses must be contiguous and references backward");
3615
+ const value = (r) => r instanceof External ? null : r <= 1n ? r : r >= 6n ? this.unary[Number(r - 6n)] : null;
3616
+ const a = refs.length === 2 ? value(refs[0]) : null, b = refs.length === 2 ? value(refs[1]) : null;
3617
+ this.unary.push(a !== null && b !== null && a + b <= U64 ? a + b : null);
3618
+ this.links.push(refs);
3619
+ }
3620
+ }
3621
+ chain(tail) {
3622
+ const elements = [];
3623
+ while (tail !== 0n) {
3624
+ requireValue(typeof tail === "bigint" && tail >= 6n, "broken chain");
3625
+ const items = this.links[Number(tail - 6n)];
3626
+ requireValue(items.length === 2 && elements.length < this.limits.maxNodes, "broken or excessive chain");
3627
+ elements.push(items[0]);
3628
+ tail = items[1];
3629
+ }
3630
+ return elements;
3631
+ }
3632
+ number(r) {
3633
+ const value = r instanceof External ? r.value : r <= 1n ? r : r >= 6n ? this.unary[Number(r - 6n)] : null;
3634
+ requireValue(value !== null, "expected unary number");
3635
+ return value;
3636
+ }
3637
+ text(text) {
3638
+ this.strings -= new globalThis.TextEncoder().encode(text).length;
3639
+ requireValue(this.strings >= 0, "string budget exceeded");
3640
+ return new Link(text);
3641
+ }
3642
+ decode(r, depth) {
3643
+ requireValue(depth < this.limits.maxDepth && --this.nodes >= 0, "node or depth budget exceeded");
3644
+ if (r instanceof External)
3645
+ return this.text(String(r.value));
3646
+ if (r === 0n)
3647
+ return new Link;
3648
+ requireValue(r >= 6n, "standalone marker");
3649
+ const items = this.links[Number(r - 6n)];
3650
+ let elements;
3651
+ if (typeof items[0] === "bigint" && items[0] >= 1n && items[0] <= 5n) {
3652
+ const marker = Number(items[0]);
3653
+ elements = items.length !== 2 || marker === 2 ? items.slice(1) : this.chain(items[1]);
3654
+ if (marker === 2) {
3655
+ requireValue(elements.length === 1, "number needs one value");
3656
+ return this.text(String(this.number(elements[0])));
3657
+ }
3658
+ if (marker === 3) {
3659
+ const chars = [];
3660
+ let byteCount = 0;
3661
+ for (const e of elements) {
3662
+ const p = this.number(e);
3663
+ requireValue(p <= 0x10ffffn && !(p >= 0xd800n && p <= 0xdfffn), "invalid Unicode scalar");
3664
+ const size = p <= 0x7fn ? 1 : p <= 0x7ffn ? 2 : p <= 0xffffn ? 3 : 4;
3665
+ requireValue(size <= this.strings - byteCount, "string budget exceeded");
3666
+ byteCount += size;
3667
+ chars.push(String.fromCodePoint(Number(p)));
3668
+ }
3669
+ return this.text(chars.join(""));
3670
+ }
3671
+ if (marker === 5) {
3672
+ requireValue(elements.length > 0, "identified needs id");
3673
+ const id = this.decode(elements[0], depth);
3674
+ requireValue(id.id !== null && !id.values.length, "id must be reference");
3675
+ return new Link(id.id, elements.slice(1).map((e) => this.decode(e, depth + 1)));
3676
+ }
3677
+ requireValue(marker === 4, "invalid typed marker");
3678
+ } else
3679
+ elements = items;
3680
+ return new Link(null, elements.map((e) => this.decode(e, depth + 1)));
3681
+ }
3682
+ document() {
3683
+ if (!this.links.length)
3684
+ return [];
3685
+ const root = this.links.at(-1);
3686
+ let elements;
3687
+ if (root.length === 2 && root[0] === 4n)
3688
+ elements = this.chain(root[1]);
3689
+ else {
3690
+ requireValue(!(typeof root[0] === "bigint" && root[0] >= 1n && root[0] <= 5n), "root must be list");
3691
+ elements = root;
3692
+ }
3693
+ return elements.map((e) => this.decode(e, 0));
3694
+ }
3695
+ }
3696
+ function canonical(node) {
3697
+ if (node.id === null && node.values.length === 1 && node.values[0].id !== null && !node.values[0].values.length)
3698
+ return node.values[0];
3699
+ return new Link(node.id, node.values.map(canonical));
3700
+ }
3701
+ function formatBinaryReference(text) {
3702
+ return formatReference(text);
3703
+ }
3704
+ function formatBinaryDocument(document) {
3705
+ function nested(node, top = false) {
3706
+ if (node.id !== null && !node.values.length)
3707
+ return formatBinaryReference(node.id);
3708
+ const values = node.values.map((v) => nested(v)).join(" ");
3709
+ if (node.id !== null)
3710
+ return `(${formatBinaryReference(node.id)}: ${values})`;
3711
+ if (node.values.length === 1 && node.values[0].id !== null && !node.values[0].values.length)
3712
+ return `((${values}))`;
3713
+ return top && node.values.length >= 2 ? values : `(${values})`;
3714
+ }
3715
+ return document.map((n) => nested(n, true)).join(`
3716
+ `);
3717
+ }
3718
+
3719
+ class BinaryLinoCodec {
3720
+ constructor(options = new BinaryLinoOptions, limits = new DecodeLimits) {
3721
+ Object.assign(this, { options, limits });
3722
+ }
3723
+ encodePacket(document) {
3724
+ requireValue(this.options.arity.contains(2), "arity must contain 2");
3725
+ const pending = document.map((n) => [n, 0]);
3726
+ let nodes = 0, strings = 0;
3727
+ while (pending.length) {
3728
+ const [n, depth] = pending.pop();
3729
+ requireValue(n instanceof Link && depth < this.limits.maxDepth, "invalid model or excessive depth");
3730
+ nodes += 1 + Number(n.id !== null && n.values.length > 0);
3731
+ if (n.id !== null) {
3732
+ requireValue(typeof n.id === "string" && n.id.isWellFormed(), "invalid Unicode string");
3733
+ strings += new globalThis.TextEncoder().encode(n.id).length;
3734
+ }
3735
+ requireValue(nodes <= this.limits.maxNodes && strings <= this.limits.maxStringBytes, "model budget exceeded");
3736
+ for (const v of n.values)
3737
+ pending.push([v, depth + 1]);
3738
+ }
3739
+ const encoder = new Encoder(this.options);
3740
+ if (document.length)
3741
+ encoder.list(document.map((n) => encoder.encode(n)));
3742
+ return encoder.finish().validate(this.limits);
3743
+ }
3744
+ encode(document) {
3745
+ return this.encodePacket(document).toBytes(this.limits);
3746
+ }
3747
+ decodePacket(packet) {
3748
+ return new Decoder(packet, this.limits).document();
3749
+ }
3750
+ decode(bytes) {
3751
+ return this.decodePacket(LinksPacket.fromBytes(bytes, this.limits));
3752
+ }
3753
+ parseDocument(text, parser = new Parser) {
3754
+ return parser.parse(text).map(canonical);
3755
+ }
3756
+ formatDocument(document) {
3757
+ return formatBinaryDocument(document);
3758
+ }
3759
+ encodeText(text, parser) {
3760
+ return this.encode(this.parseDocument(text, parser));
3761
+ }
3762
+ decodeText(bytes) {
3763
+ return this.formatDocument(this.decode(bytes));
3764
+ }
3765
+ }
2983
3766
  export {
3767
+ ArityRange,
3768
+ BinaryLinoCodec,
3769
+ BinaryLinoOptions,
2984
3770
  DEFAULT_MAX_DEPTH,
3771
+ DecodeLimits,
3772
+ External,
2985
3773
  FormatConfig,
2986
3774
  FormatOptions,
2987
3775
  Link,
2988
3776
  LinksGroup,
3777
+ LinksPacket,
3778
+ PacketReader,
2989
3779
  ParseError,
2990
3780
  Parser,
3781
+ Section,
2991
3782
  StreamParseError,
2992
3783
  StreamParser,
3784
+ decodeReferenceLiteral,
3785
+ encodeReferenceLiteral,
3786
+ formatBinaryDocument,
3787
+ formatBinaryReference,
2993
3788
  formatLinks,
2994
3789
  stripComments
2995
3790
  };