@marko/runtime-tags 6.0.112 → 6.0.114
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/README.md +1 -1
- package/dist/common/accessor.d.ts +2 -2
- package/dist/common/accessor.debug.d.ts +2 -2
- package/dist/common/types.d.ts +6 -1
- package/dist/debug/dom.js +140 -90
- package/dist/debug/dom.mjs +140 -90
- package/dist/debug/html.js +34 -24
- package/dist/debug/html.mjs +34 -24
- package/dist/dom/control-flow.d.ts +2 -1
- package/dist/dom/queue.d.ts +1 -1
- package/dist/dom/resume.d.ts +21 -1
- package/dist/dom.d.ts +1 -1
- package/dist/dom.js +120 -95
- package/dist/dom.mjs +120 -95
- package/dist/html/writer.d.ts +2 -0
- package/dist/html.js +28 -24
- package/dist/html.mjs +28 -24
- package/dist/translator/index.js +35 -13
- package/dist/translator/util/sections.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
# [<img alt="Marko" src="https://raw.githubusercontent.com/marko-js/website
|
|
3
|
+
# [<img alt="Marko" src="https://raw.githubusercontent.com/marko-js/website/refs/heads/main/public/assets/logo.svg" width="250">](https://markojs.com/)
|
|
4
4
|
|
|
5
5
|
**A declarative, HTML-based language that makes building web apps fun 🔥**
|
|
6
6
|
|
|
@@ -18,6 +18,7 @@ export declare enum AccessorProp {
|
|
|
18
18
|
Owner = "_",
|
|
19
19
|
AbortControllers = "A",
|
|
20
20
|
AbortScopes = "B",
|
|
21
|
+
AwaitCounter = "O",
|
|
21
22
|
BranchAccessor = "C",
|
|
22
23
|
BranchScopes = "D",
|
|
23
24
|
CatchContent = "E",
|
|
@@ -25,12 +26,11 @@ export declare enum AccessorProp {
|
|
|
25
26
|
ClosestBranchId = "G",
|
|
26
27
|
Creating = "H",
|
|
27
28
|
Destroyed = "I",
|
|
28
|
-
PendingEffects = "J",
|
|
29
29
|
EndNode = "K",
|
|
30
30
|
Id = "L",
|
|
31
31
|
LoopKey = "M",
|
|
32
32
|
ParentBranch = "N",
|
|
33
|
-
|
|
33
|
+
PendingEffects = "J",
|
|
34
34
|
PlaceholderBranch = "P",
|
|
35
35
|
PlaceholderContent = "Q",
|
|
36
36
|
Renderer = "R",
|
|
@@ -18,6 +18,7 @@ export declare enum AccessorProp {
|
|
|
18
18
|
Owner = "_",
|
|
19
19
|
AbortControllers = "#AbortControllers",
|
|
20
20
|
AbortScopes = "#AbortScopes",
|
|
21
|
+
AwaitCounter = "#AwaitCounter",
|
|
21
22
|
BranchAccessor = "#BranchAccessor",
|
|
22
23
|
BranchScopes = "#BranchScopes",
|
|
23
24
|
CatchContent = "#CatchContent",
|
|
@@ -25,12 +26,11 @@ export declare enum AccessorProp {
|
|
|
25
26
|
ClosestBranchId = "#ClosestBranchId",
|
|
26
27
|
Creating = "#Creating",
|
|
27
28
|
Destroyed = "#Destroyed",
|
|
28
|
-
PendingEffects = "#PendingEffects",
|
|
29
29
|
EndNode = "#EndNode",
|
|
30
30
|
Id = "#Id",
|
|
31
31
|
LoopKey = "#LoopKey",
|
|
32
32
|
ParentBranch = "#ParentBranch",
|
|
33
|
-
|
|
33
|
+
PendingEffects = "#PendingEffects",
|
|
34
34
|
PlaceholderBranch = "#PlaceholderBranch",
|
|
35
35
|
PlaceholderContent = "#PlaceholderContent",
|
|
36
36
|
Renderer = "#Renderer",
|
package/dist/common/types.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface BranchScope extends Scope {
|
|
|
10
10
|
[AccessorProp.AbortScopes]: Set<Scope> | undefined;
|
|
11
11
|
[AccessorProp.BranchScopes]: Set<BranchScope> | undefined;
|
|
12
12
|
[AccessorProp.Renderer]: ClientRenderer | string;
|
|
13
|
-
[AccessorProp.
|
|
13
|
+
[AccessorProp.AwaitCounter]: AwaitCounter | undefined;
|
|
14
14
|
[AccessorProp.PendingEffects]: unknown[] | undefined;
|
|
15
15
|
}
|
|
16
16
|
export interface Scope {
|
|
@@ -33,6 +33,11 @@ export declare enum ResumeSymbol {
|
|
|
33
33
|
BranchEndOnlyChildInParent = ")",
|
|
34
34
|
BranchEndSingleNodeOnlyChildInParent = "}"
|
|
35
35
|
}
|
|
36
|
+
export interface AwaitCounter {
|
|
37
|
+
d?: 1;
|
|
38
|
+
i: number;
|
|
39
|
+
c: () => void;
|
|
40
|
+
}
|
|
36
41
|
export { AccessorPrefix, AccessorProp } from "./accessor.debug";
|
|
37
42
|
export declare enum NodeType {
|
|
38
43
|
Element = 1,
|
package/dist/debug/dom.js
CHANGED
|
@@ -50,7 +50,8 @@ __export(dom_exports, {
|
|
|
50
50
|
_attrs_partial: () => _attrs_partial,
|
|
51
51
|
_attrs_partial_content: () => _attrs_partial_content,
|
|
52
52
|
_attrs_script: () => _attrs_script,
|
|
53
|
-
|
|
53
|
+
_await_content: () => _await_content,
|
|
54
|
+
_await_promise: () => _await_promise,
|
|
54
55
|
_call: () => _call,
|
|
55
56
|
_child_setup: () => _child_setup,
|
|
56
57
|
_closure: () => _closure,
|
|
@@ -615,60 +616,64 @@ function init(runtimeId = DEFAULT_RUNTIME_ID) {
|
|
|
615
616
|
let lastScopeId = 0;
|
|
616
617
|
const nextToken = () => lastToken = visitText.slice(
|
|
617
618
|
lastTokenIndex,
|
|
618
|
-
|
|
619
|
-
(lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1) ? lastTokenIndex - 1 : visitText.length
|
|
619
|
+
(lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1
|
|
620
620
|
);
|
|
621
|
-
render.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
[
|
|
633
|
-
|
|
634
|
-
);
|
|
635
|
-
} else {
|
|
636
|
-
for (const scope of serialized(serializeContext)) {
|
|
637
|
-
if (!$global) {
|
|
638
|
-
$global = scope || {};
|
|
639
|
-
$global.runtimeId = runtimeId;
|
|
640
|
-
$global.renderId = renderId;
|
|
641
|
-
} else if (typeof scope === "number") {
|
|
642
|
-
lastScopeId += scope;
|
|
643
|
-
} else {
|
|
644
|
-
scopeLookup[scope["#Id" /* Id */] = ++lastScopeId] = scope;
|
|
645
|
-
scope["$global" /* Global */] = $global;
|
|
646
|
-
if (branchesEnabled) {
|
|
647
|
-
scope["#ClosestBranch" /* ClosestBranch */] = scopeLookup[scope["#ClosestBranchId" /* ClosestBranchId */]];
|
|
621
|
+
render.m = (effects = []) => {
|
|
622
|
+
for (const serialized of resumes = render.r || []) {
|
|
623
|
+
if (typeof serialized === "string") {
|
|
624
|
+
lastTokenIndex = 0;
|
|
625
|
+
visitText = serialized;
|
|
626
|
+
while (nextToken()) {
|
|
627
|
+
if (/\D/.test(lastToken)) {
|
|
628
|
+
lastEffect = registeredValues[lastToken];
|
|
629
|
+
} else {
|
|
630
|
+
effects.push(
|
|
631
|
+
lastEffect,
|
|
632
|
+
scopeLookup[lastToken] ||= {
|
|
633
|
+
["#Id" /* Id */]: +lastToken
|
|
648
634
|
}
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
} else {
|
|
639
|
+
for (const scope of serialized(serializeContext)) {
|
|
640
|
+
if (!$global) {
|
|
641
|
+
$global = scope || {};
|
|
642
|
+
$global.runtimeId = runtimeId;
|
|
643
|
+
$global.renderId = renderId;
|
|
644
|
+
} else if (typeof scope === "number") {
|
|
645
|
+
lastScopeId += scope;
|
|
646
|
+
} else {
|
|
647
|
+
scopeLookup[scope["#Id" /* Id */] = ++lastScopeId] = scope;
|
|
648
|
+
scope["$global" /* Global */] = $global;
|
|
649
|
+
if (branchesEnabled) {
|
|
650
|
+
scope["#ClosestBranch" /* ClosestBranch */] = scopeLookup[scope["#ClosestBranchId" /* ClosestBranchId */]];
|
|
649
651
|
}
|
|
650
652
|
}
|
|
651
653
|
}
|
|
652
654
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
655
|
+
}
|
|
656
|
+
for (visit of visits = render.v) {
|
|
657
|
+
lastTokenIndex = render.i.length;
|
|
658
|
+
visitText = visit.data;
|
|
659
|
+
visitType = visitText[lastTokenIndex++];
|
|
660
|
+
visitScope = scopeLookup[+nextToken(
|
|
661
|
+
/* read scope id */
|
|
662
|
+
)] ||= {
|
|
663
|
+
["#Id" /* Id */]: +lastToken
|
|
664
|
+
};
|
|
665
|
+
if (visitType === "*" /* Node */) {
|
|
666
|
+
visitScope["Getter:" /* Getter */ + nextToken()] = /* @__PURE__ */ ((node) => () => node)(visitScope[lastToken] = visit.previousSibling);
|
|
667
|
+
} else if (branchesEnabled) {
|
|
668
|
+
visitBranches();
|
|
667
669
|
}
|
|
668
|
-
runEffects(effects);
|
|
669
|
-
} finally {
|
|
670
|
-
isResuming = visits.length = resumes.length = 0;
|
|
671
670
|
}
|
|
671
|
+
visits.length = resumes.length = 0;
|
|
672
|
+
return effects;
|
|
673
|
+
};
|
|
674
|
+
render.w = () => {
|
|
675
|
+
walk2();
|
|
676
|
+
runResumeEffects(render);
|
|
672
677
|
};
|
|
673
678
|
return render;
|
|
674
679
|
})
|
|
@@ -677,7 +682,7 @@ function init(runtimeId = DEFAULT_RUNTIME_ID) {
|
|
|
677
682
|
if (renders) {
|
|
678
683
|
initRuntime(renders);
|
|
679
684
|
for (const renderId in renders) {
|
|
680
|
-
resumeRender(renderId)
|
|
685
|
+
runResumeEffects(resumeRender(renderId));
|
|
681
686
|
}
|
|
682
687
|
} else {
|
|
683
688
|
defineRuntime({
|
|
@@ -687,6 +692,14 @@ function init(runtimeId = DEFAULT_RUNTIME_ID) {
|
|
|
687
692
|
}
|
|
688
693
|
}
|
|
689
694
|
var isResuming;
|
|
695
|
+
function runResumeEffects(render) {
|
|
696
|
+
try {
|
|
697
|
+
isResuming = 1;
|
|
698
|
+
runEffects(render.m(), 1);
|
|
699
|
+
} finally {
|
|
700
|
+
isResuming = 0;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
690
703
|
function getRegisteredWithScope(id, scope) {
|
|
691
704
|
const val = registeredValues[id];
|
|
692
705
|
return scope ? val(scope) : val;
|
|
@@ -1773,24 +1786,52 @@ function longestIncreasingSubsequence(a) {
|
|
|
1773
1786
|
}
|
|
1774
1787
|
|
|
1775
1788
|
// src/dom/control-flow.ts
|
|
1776
|
-
function
|
|
1789
|
+
function _await_promise(nodeAccessor, params) {
|
|
1777
1790
|
if (false) nodeAccessor = decodeAccessor4(nodeAccessor);
|
|
1778
1791
|
const promiseAccessor = "Promise:" /* Promise */ + nodeAccessor;
|
|
1779
1792
|
const branchAccessor = "BranchScopes:" /* BranchScopes */ + nodeAccessor;
|
|
1780
|
-
const
|
|
1781
|
-
|
|
1793
|
+
const rendererAccessor = "ConditionalRenderer:" /* ConditionalRenderer */ + nodeAccessor;
|
|
1794
|
+
_enable_catch();
|
|
1782
1795
|
return (scope, promise) => {
|
|
1783
|
-
|
|
1796
|
+
let awaitCounter;
|
|
1797
|
+
let renderData;
|
|
1784
1798
|
const tryWithPlaceholder = findBranchWithKey(
|
|
1785
1799
|
scope,
|
|
1786
1800
|
"#PlaceholderContent" /* PlaceholderContent */
|
|
1787
1801
|
);
|
|
1788
|
-
let awaitBranch = scope[branchAccessor];
|
|
1789
1802
|
if (tryWithPlaceholder) {
|
|
1803
|
+
renderData = self[tryWithPlaceholder["$global" /* Global */].runtimeId]?.[tryWithPlaceholder["$global" /* Global */].renderId];
|
|
1804
|
+
awaitCounter = tryWithPlaceholder["#AwaitCounter" /* AwaitCounter */] ||= renderData?.p?.[tryWithPlaceholder["#Id" /* Id */]];
|
|
1805
|
+
if (!awaitCounter?.i) {
|
|
1806
|
+
awaitCounter = tryWithPlaceholder["#AwaitCounter" /* AwaitCounter */] = {
|
|
1807
|
+
d: 1,
|
|
1808
|
+
i: 0,
|
|
1809
|
+
c() {
|
|
1810
|
+
if (!--awaitCounter.i) {
|
|
1811
|
+
const placeholderBranch = tryWithPlaceholder["#PlaceholderBranch" /* PlaceholderBranch */];
|
|
1812
|
+
tryWithPlaceholder["#PlaceholderBranch" /* PlaceholderBranch */] = 0;
|
|
1813
|
+
if (placeholderBranch) {
|
|
1814
|
+
placeholderBranch["#StartNode" /* StartNode */].parentNode.insertBefore(
|
|
1815
|
+
tryWithPlaceholder["#StartNode" /* StartNode */].parentNode,
|
|
1816
|
+
placeholderBranch["#StartNode" /* StartNode */]
|
|
1817
|
+
);
|
|
1818
|
+
removeAndDestroyBranch(placeholderBranch);
|
|
1819
|
+
}
|
|
1820
|
+
queueEffect(tryWithPlaceholder, (scope2) => {
|
|
1821
|
+
const pendingEffects2 = scope2["#PendingEffects" /* PendingEffects */];
|
|
1822
|
+
if (pendingEffects2) {
|
|
1823
|
+
scope2["#PendingEffects" /* PendingEffects */] = [];
|
|
1824
|
+
runEffects(pendingEffects2, true);
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1790
1831
|
placeholderShown.add(pendingEffects);
|
|
1791
|
-
if (!scope[promiseAccessor] &&
|
|
1832
|
+
if (!scope[promiseAccessor] && !awaitCounter.i++) {
|
|
1792
1833
|
requestAnimationFrame(
|
|
1793
|
-
() =>
|
|
1834
|
+
() => awaitCounter.i && runEffects(
|
|
1794
1835
|
prepareEffects(
|
|
1795
1836
|
() => queueRender(
|
|
1796
1837
|
tryWithPlaceholder,
|
|
@@ -1813,12 +1854,12 @@ function _await(nodeAccessor, template, walks, setup, params) {
|
|
|
1813
1854
|
)
|
|
1814
1855
|
);
|
|
1815
1856
|
}
|
|
1816
|
-
} else if (
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1857
|
+
} else if (scope[branchAccessor] && !scope[promiseAccessor]) {
|
|
1858
|
+
scope[branchAccessor]["#StartNode" /* StartNode */].parentNode.insertBefore(
|
|
1859
|
+
scope[nodeAccessor],
|
|
1860
|
+
scope[branchAccessor]["#StartNode" /* StartNode */]
|
|
1820
1861
|
);
|
|
1821
|
-
tempDetachBranch(
|
|
1862
|
+
tempDetachBranch(scope[branchAccessor]);
|
|
1822
1863
|
}
|
|
1823
1864
|
const thisPromise = scope[promiseAccessor] = promise.then(
|
|
1824
1865
|
(data) => {
|
|
@@ -1828,45 +1869,47 @@ function _await(nodeAccessor, template, walks, setup, params) {
|
|
|
1828
1869
|
queueRender(
|
|
1829
1870
|
scope,
|
|
1830
1871
|
() => {
|
|
1831
|
-
if (
|
|
1872
|
+
if (scope[branchAccessor]) {
|
|
1832
1873
|
if (!tryWithPlaceholder) {
|
|
1833
|
-
|
|
1834
|
-
|
|
1874
|
+
scope[nodeAccessor].replaceWith(
|
|
1875
|
+
scope[branchAccessor]["#StartNode" /* StartNode */].parentNode
|
|
1835
1876
|
);
|
|
1836
1877
|
}
|
|
1837
1878
|
} else {
|
|
1838
1879
|
insertBranchBefore(
|
|
1839
|
-
|
|
1880
|
+
scope[branchAccessor] = createAndSetupBranch(
|
|
1840
1881
|
scope["$global" /* Global */],
|
|
1841
|
-
|
|
1882
|
+
scope[rendererAccessor],
|
|
1842
1883
|
scope,
|
|
1843
|
-
|
|
1884
|
+
scope[nodeAccessor].parentNode
|
|
1844
1885
|
),
|
|
1845
|
-
|
|
1846
|
-
|
|
1886
|
+
scope[nodeAccessor].parentNode,
|
|
1887
|
+
scope[nodeAccessor]
|
|
1847
1888
|
);
|
|
1848
|
-
|
|
1889
|
+
scope[nodeAccessor].remove();
|
|
1849
1890
|
}
|
|
1850
|
-
params?.(
|
|
1851
|
-
if (
|
|
1891
|
+
params?.(scope[branchAccessor], [data]);
|
|
1892
|
+
if (awaitCounter) {
|
|
1852
1893
|
placeholderShown.add(pendingEffects);
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
)
|
|
1861
|
-
|
|
1894
|
+
awaitCounter.c();
|
|
1895
|
+
if (!awaitCounter.d) {
|
|
1896
|
+
const fnScopes = /* @__PURE__ */ new Map();
|
|
1897
|
+
const effects = renderData.m();
|
|
1898
|
+
for (let i = 0; i < pendingEffects.length; ) {
|
|
1899
|
+
const fn = pendingEffects[i++];
|
|
1900
|
+
let scopes = fnScopes.get(fn);
|
|
1901
|
+
if (!scopes) {
|
|
1902
|
+
fnScopes.set(fn, scopes = /* @__PURE__ */ new Set());
|
|
1903
|
+
}
|
|
1904
|
+
scopes.add(pendingEffects[i++]);
|
|
1862
1905
|
}
|
|
1863
|
-
|
|
1864
|
-
const
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1906
|
+
for (let i = 0; i < effects.length; ) {
|
|
1907
|
+
const fn = effects[i++];
|
|
1908
|
+
const scope2 = effects[i++];
|
|
1909
|
+
if (!fnScopes.get(fn)?.has(scope2)) {
|
|
1910
|
+
queueEffect(scope2, fn);
|
|
1868
1911
|
}
|
|
1869
|
-
}
|
|
1912
|
+
}
|
|
1870
1913
|
}
|
|
1871
1914
|
}
|
|
1872
1915
|
},
|
|
@@ -1876,8 +1919,7 @@ function _await(nodeAccessor, template, walks, setup, params) {
|
|
|
1876
1919
|
},
|
|
1877
1920
|
(error) => {
|
|
1878
1921
|
if (thisPromise === scope[promiseAccessor]) {
|
|
1879
|
-
if (
|
|
1880
|
-
tryWithPlaceholder["#PendingAsyncCount" /* PendingAsyncCount */] = 0;
|
|
1922
|
+
if (awaitCounter) awaitCounter.i = 0;
|
|
1881
1923
|
scope[promiseAccessor] = 0;
|
|
1882
1924
|
schedule();
|
|
1883
1925
|
queueRender(scope, renderCatch, -1, error);
|
|
@@ -1886,6 +1928,13 @@ function _await(nodeAccessor, template, walks, setup, params) {
|
|
|
1886
1928
|
);
|
|
1887
1929
|
};
|
|
1888
1930
|
}
|
|
1931
|
+
function _await_content(nodeAccessor, template, walks, setup) {
|
|
1932
|
+
const rendererAccessor = "ConditionalRenderer:" /* ConditionalRenderer */ + (true ? nodeAccessor : decodeAccessor4(nodeAccessor));
|
|
1933
|
+
const renderer = _content("", template, walks, setup)();
|
|
1934
|
+
return (scope) => {
|
|
1935
|
+
scope[rendererAccessor] = renderer;
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1889
1938
|
function _try(nodeAccessor, template, walks, setup) {
|
|
1890
1939
|
if (false) nodeAccessor = decodeAccessor4(nodeAccessor);
|
|
1891
1940
|
const branchAccessor = "BranchScopes:" /* BranchScopes */ + nodeAccessor;
|
|
@@ -1917,7 +1966,8 @@ function renderCatch(scope, error) {
|
|
|
1917
1966
|
const owner = tryWithCatch["_" /* Owner */];
|
|
1918
1967
|
const placeholderBranch = tryWithCatch["#PlaceholderBranch" /* PlaceholderBranch */];
|
|
1919
1968
|
if (placeholderBranch) {
|
|
1920
|
-
tryWithCatch["#
|
|
1969
|
+
if (tryWithCatch["#AwaitCounter" /* AwaitCounter */])
|
|
1970
|
+
tryWithCatch["#AwaitCounter" /* AwaitCounter */].i = 0;
|
|
1921
1971
|
owner["BranchScopes:" /* BranchScopes */ + tryWithCatch["#BranchAccessor" /* BranchAccessor */]] = placeholderBranch;
|
|
1922
1972
|
destroyBranch(tryWithCatch);
|
|
1923
1973
|
}
|
|
@@ -2294,7 +2344,7 @@ var _enable_catch = () => {
|
|
|
2294
2344
|
enableBranches();
|
|
2295
2345
|
const handlePendingTry = (fn, scope, branch) => {
|
|
2296
2346
|
while (branch) {
|
|
2297
|
-
if (branch["#
|
|
2347
|
+
if (branch["#AwaitCounter" /* AwaitCounter */]?.i) {
|
|
2298
2348
|
return (branch["#PendingEffects" /* PendingEffects */] ||= []).push(fn, scope);
|
|
2299
2349
|
}
|
|
2300
2350
|
branch = branch["#ParentBranch" /* ParentBranch */];
|