@furystack/shades 11.0.35 → 12.0.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/CHANGELOG.md +337 -0
- package/README.md +99 -13
- package/esm/compile-route.spec.d.ts +2 -0
- package/esm/compile-route.spec.d.ts.map +1 -0
- package/esm/compile-route.spec.js +34 -0
- package/esm/compile-route.spec.js.map +1 -0
- package/esm/component-factory.spec.js +13 -5
- package/esm/component-factory.spec.js.map +1 -1
- package/esm/components/index.d.ts +4 -1
- package/esm/components/index.d.ts.map +1 -1
- package/esm/components/index.js +4 -1
- package/esm/components/index.js.map +1 -1
- package/esm/components/lazy-load.d.ts +2 -4
- package/esm/components/lazy-load.d.ts.map +1 -1
- package/esm/components/lazy-load.js +40 -24
- package/esm/components/lazy-load.js.map +1 -1
- package/esm/components/lazy-load.spec.js +57 -50
- package/esm/components/lazy-load.spec.js.map +1 -1
- package/esm/components/link-to-route.d.ts +2 -0
- package/esm/components/link-to-route.d.ts.map +1 -1
- package/esm/components/link-to-route.js +3 -2
- package/esm/components/link-to-route.js.map +1 -1
- package/esm/components/link-to-route.spec.js +13 -9
- package/esm/components/link-to-route.spec.js.map +1 -1
- package/esm/components/nested-route-link.d.ts +62 -0
- package/esm/components/nested-route-link.d.ts.map +1 -0
- package/esm/components/nested-route-link.js +66 -0
- package/esm/components/nested-route-link.js.map +1 -0
- package/esm/components/nested-route-link.spec.d.ts +2 -0
- package/esm/components/nested-route-link.spec.d.ts.map +1 -0
- package/esm/components/nested-route-link.spec.js +179 -0
- package/esm/components/nested-route-link.spec.js.map +1 -0
- package/esm/components/nested-route-types.d.ts +37 -0
- package/esm/components/nested-route-types.d.ts.map +1 -0
- package/esm/components/nested-route-types.js +2 -0
- package/esm/components/nested-route-types.js.map +1 -0
- package/esm/components/nested-router.d.ts +103 -0
- package/esm/components/nested-router.d.ts.map +1 -0
- package/esm/components/nested-router.js +178 -0
- package/esm/components/nested-router.js.map +1 -0
- package/esm/components/nested-router.spec.d.ts +2 -0
- package/esm/components/nested-router.spec.d.ts.map +1 -0
- package/esm/components/nested-router.spec.js +659 -0
- package/esm/components/nested-router.spec.js.map +1 -0
- package/esm/components/route-link.d.ts +4 -0
- package/esm/components/route-link.d.ts.map +1 -1
- package/esm/components/route-link.js +9 -10
- package/esm/components/route-link.js.map +1 -1
- package/esm/components/route-link.spec.js +16 -12
- package/esm/components/route-link.spec.js.map +1 -1
- package/esm/components/router.d.ts +20 -2
- package/esm/components/router.d.ts.map +1 -1
- package/esm/components/router.js +3 -0
- package/esm/components/router.js.map +1 -1
- package/esm/components/router.spec.js +75 -74
- package/esm/components/router.spec.js.map +1 -1
- package/esm/css-generator.d.ts +50 -0
- package/esm/css-generator.d.ts.map +1 -0
- package/esm/css-generator.js +107 -0
- package/esm/css-generator.js.map +1 -0
- package/esm/css-generator.spec.d.ts +2 -0
- package/esm/css-generator.spec.d.ts.map +1 -0
- package/esm/css-generator.spec.js +162 -0
- package/esm/css-generator.spec.js.map +1 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -1
- package/esm/initialize.d.ts +11 -0
- package/esm/initialize.d.ts.map +1 -1
- package/esm/initialize.js +5 -0
- package/esm/initialize.js.map +1 -1
- package/esm/jsx.d.ts +83 -2
- package/esm/jsx.d.ts.map +1 -1
- package/esm/models/children-list.d.ts +5 -1
- package/esm/models/children-list.d.ts.map +1 -1
- package/esm/models/css-object.d.ts +33 -0
- package/esm/models/css-object.d.ts.map +1 -0
- package/esm/models/css-object.js +2 -0
- package/esm/models/css-object.js.map +1 -0
- package/esm/models/index.d.ts +1 -0
- package/esm/models/index.d.ts.map +1 -1
- package/esm/models/index.js +1 -0
- package/esm/models/index.js.map +1 -1
- package/esm/models/partial-element.d.ts +12 -2
- package/esm/models/partial-element.d.ts.map +1 -1
- package/esm/models/render-options.d.ts +89 -3
- package/esm/models/render-options.d.ts.map +1 -1
- package/esm/models/selection-state.d.ts +4 -0
- package/esm/models/selection-state.d.ts.map +1 -1
- package/esm/services/location-service.d.ts +11 -0
- package/esm/services/location-service.d.ts.map +1 -1
- package/esm/services/location-service.js +11 -0
- package/esm/services/location-service.js.map +1 -1
- package/esm/services/resource-manager.d.ts +24 -0
- package/esm/services/resource-manager.d.ts.map +1 -1
- package/esm/services/resource-manager.js +30 -0
- package/esm/services/resource-manager.js.map +1 -1
- package/esm/services/resource-manager.spec.js +93 -0
- package/esm/services/resource-manager.spec.js.map +1 -1
- package/esm/services/screen-service.d.ts +81 -4
- package/esm/services/screen-service.d.ts.map +1 -1
- package/esm/services/screen-service.js +75 -4
- package/esm/services/screen-service.js.map +1 -1
- package/esm/services/screen-service.spec.js +91 -7
- package/esm/services/screen-service.spec.js.map +1 -1
- package/esm/shade-component.d.ts +17 -4
- package/esm/shade-component.d.ts.map +1 -1
- package/esm/shade-component.js +67 -5
- package/esm/shade-component.js.map +1 -1
- package/esm/shade-host-props-ref.integration.spec.d.ts +2 -0
- package/esm/shade-host-props-ref.integration.spec.d.ts.map +1 -0
- package/esm/shade-host-props-ref.integration.spec.js +381 -0
- package/esm/shade-host-props-ref.integration.spec.js.map +1 -0
- package/esm/shade-resources.integration.spec.js +208 -39
- package/esm/shade-resources.integration.spec.js.map +1 -1
- package/esm/shade.d.ts +34 -15
- package/esm/shade.d.ts.map +1 -1
- package/esm/shade.js +180 -33
- package/esm/shade.js.map +1 -1
- package/esm/shade.spec.d.ts +2 -0
- package/esm/shade.spec.d.ts.map +1 -0
- package/esm/shade.spec.js +198 -0
- package/esm/shade.spec.js.map +1 -0
- package/esm/shades.integration.spec.js +135 -72
- package/esm/shades.integration.spec.js.map +1 -1
- package/esm/style-manager.d.ts +65 -0
- package/esm/style-manager.d.ts.map +1 -0
- package/esm/style-manager.js +95 -0
- package/esm/style-manager.js.map +1 -0
- package/esm/style-manager.spec.d.ts +2 -0
- package/esm/style-manager.spec.d.ts.map +1 -0
- package/esm/style-manager.spec.js +179 -0
- package/esm/style-manager.spec.js.map +1 -0
- package/esm/styled-element.spec.d.ts +2 -0
- package/esm/styled-element.spec.d.ts.map +1 -0
- package/esm/styled-element.spec.js +86 -0
- package/esm/styled-element.spec.js.map +1 -0
- package/esm/styled-shade.spec.d.ts +2 -0
- package/esm/styled-shade.spec.d.ts.map +1 -0
- package/esm/styled-shade.spec.js +66 -0
- package/esm/styled-shade.spec.js.map +1 -0
- package/esm/svg-types.d.ts +389 -0
- package/esm/svg-types.d.ts.map +1 -0
- package/esm/svg-types.js +9 -0
- package/esm/svg-types.js.map +1 -0
- package/esm/svg.d.ts +15 -0
- package/esm/svg.d.ts.map +1 -0
- package/esm/svg.js +76 -0
- package/esm/svg.js.map +1 -0
- package/esm/svg.spec.d.ts +2 -0
- package/esm/svg.spec.d.ts.map +1 -0
- package/esm/svg.spec.js +80 -0
- package/esm/svg.spec.js.map +1 -0
- package/esm/vnode.d.ts +103 -0
- package/esm/vnode.d.ts.map +1 -0
- package/esm/vnode.integration.spec.d.ts +2 -0
- package/esm/vnode.integration.spec.d.ts.map +1 -0
- package/esm/vnode.integration.spec.js +494 -0
- package/esm/vnode.integration.spec.js.map +1 -0
- package/esm/vnode.js +453 -0
- package/esm/vnode.js.map +1 -0
- package/esm/vnode.spec.d.ts +2 -0
- package/esm/vnode.spec.d.ts.map +1 -0
- package/esm/vnode.spec.js +473 -0
- package/esm/vnode.spec.js.map +1 -0
- package/package.json +3 -3
- package/src/compile-route.spec.ts +39 -0
- package/src/component-factory.spec.tsx +18 -5
- package/src/components/index.ts +4 -1
- package/src/components/lazy-load.spec.tsx +82 -75
- package/src/components/lazy-load.tsx +49 -27
- package/src/components/link-to-route.spec.tsx +25 -21
- package/src/components/link-to-route.tsx +4 -2
- package/src/components/nested-route-link.spec.tsx +303 -0
- package/src/components/nested-route-link.tsx +100 -0
- package/src/components/nested-route-types.ts +42 -0
- package/src/components/nested-router.spec.tsx +817 -0
- package/src/components/nested-router.tsx +256 -0
- package/src/components/route-link.spec.tsx +22 -18
- package/src/components/route-link.tsx +10 -10
- package/src/components/router.spec.tsx +109 -108
- package/src/components/router.tsx +15 -2
- package/src/css-generator.spec.ts +183 -0
- package/src/css-generator.ts +117 -0
- package/src/index.ts +2 -0
- package/src/initialize.ts +12 -0
- package/src/jsx.ts +129 -2
- package/src/models/children-list.ts +7 -1
- package/src/models/css-object.ts +34 -0
- package/src/models/index.ts +1 -0
- package/src/models/partial-element.ts +13 -2
- package/src/models/render-options.ts +90 -3
- package/src/models/selection-state.ts +4 -0
- package/src/services/location-service.tsx +11 -0
- package/src/services/resource-manager.spec.ts +116 -0
- package/src/services/resource-manager.ts +30 -0
- package/src/services/screen-service.spec.ts +109 -7
- package/src/services/screen-service.ts +81 -4
- package/src/shade-component.ts +72 -6
- package/src/shade-host-props-ref.integration.spec.tsx +460 -0
- package/src/shade-resources.integration.spec.tsx +276 -52
- package/src/shade.spec.tsx +239 -0
- package/src/shade.ts +211 -56
- package/src/shades.integration.spec.tsx +154 -80
- package/src/style-manager.spec.ts +229 -0
- package/src/style-manager.ts +104 -0
- package/src/styled-element.spec.tsx +117 -0
- package/src/styled-shade.spec.ts +86 -0
- package/src/svg-types.ts +437 -0
- package/src/svg.spec.ts +89 -0
- package/src/svg.ts +78 -0
- package/src/vnode.integration.spec.tsx +657 -0
- package/src/vnode.spec.ts +579 -0
- package/src/vnode.ts +508 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Injector } from '@furystack/inject';
|
|
2
|
+
import { usingAsync } from '@furystack/utils';
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, expectTypeOf, it, vi } from 'vitest';
|
|
4
|
+
import { initializeShadeRoot } from '../initialize.js';
|
|
5
|
+
import { LocationService } from '../services/location-service.js';
|
|
6
|
+
import { createComponent } from '../shade-component.js';
|
|
7
|
+
import { flushUpdates } from '../shade.js';
|
|
8
|
+
import { NestedRouteLink, createNestedRouteLink } from './nested-route-link.js';
|
|
9
|
+
describe('NestedRouteLink', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
document.body.innerHTML = '<div id="root"></div>';
|
|
12
|
+
});
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
document.body.innerHTML = '';
|
|
15
|
+
});
|
|
16
|
+
it('Should render a link with the correct href', async () => {
|
|
17
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
18
|
+
const rootElement = document.getElementById('root');
|
|
19
|
+
initializeShadeRoot({
|
|
20
|
+
injector,
|
|
21
|
+
rootElement,
|
|
22
|
+
jsxElement: (createComponent(NestedRouteLink, { id: "link", href: "/buttons" }, "Buttons")),
|
|
23
|
+
});
|
|
24
|
+
await flushUpdates();
|
|
25
|
+
expect(document.body.innerHTML).toBe('<div id="root"><a is="nested-route-link" id="link" href="/buttons">Buttons</a></div>');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
it('Should trigger SPA navigation on click', async () => {
|
|
29
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
30
|
+
const rootElement = document.getElementById('root');
|
|
31
|
+
const onRouteChange = vi.fn();
|
|
32
|
+
injector.getInstance(LocationService).onLocationPathChanged.subscribe(onRouteChange);
|
|
33
|
+
initializeShadeRoot({
|
|
34
|
+
injector,
|
|
35
|
+
rootElement,
|
|
36
|
+
jsxElement: (createComponent(NestedRouteLink, { id: "link", href: "/buttons" }, "Buttons")),
|
|
37
|
+
});
|
|
38
|
+
await flushUpdates();
|
|
39
|
+
expect(onRouteChange).not.toBeCalled();
|
|
40
|
+
document.getElementById('link')?.click();
|
|
41
|
+
expect(onRouteChange).toBeCalledTimes(1);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('Should compile route params in the href', async () => {
|
|
45
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
46
|
+
const rootElement = document.getElementById('root');
|
|
47
|
+
initializeShadeRoot({
|
|
48
|
+
injector,
|
|
49
|
+
rootElement,
|
|
50
|
+
jsxElement: (createComponent(NestedRouteLink, { id: "link", href: "/users/:id", params: { id: '42' } }, "User 42")),
|
|
51
|
+
});
|
|
52
|
+
await flushUpdates();
|
|
53
|
+
expect(document.body.innerHTML).toBe('<div id="root"><a is="nested-route-link" id="link" href="/users/42">User 42</a></div>');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it('Should compile route params with multiple segments', async () => {
|
|
57
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
58
|
+
const rootElement = document.getElementById('root');
|
|
59
|
+
initializeShadeRoot({
|
|
60
|
+
injector,
|
|
61
|
+
rootElement,
|
|
62
|
+
jsxElement: (createComponent(NestedRouteLink, { id: "link", href: "/users/:userId/posts/:postId", params: { userId: '1', postId: '99' } }, "Post")),
|
|
63
|
+
});
|
|
64
|
+
await flushUpdates();
|
|
65
|
+
expect(document.body.innerHTML).toBe('<div id="root"><a is="nested-route-link" id="link" href="/users/1/posts/99">Post</a></div>');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('Type utilities', () => {
|
|
70
|
+
describe('ConcatPaths', () => {
|
|
71
|
+
it('Should strip root "/" when concatenating', () => {
|
|
72
|
+
expectTypeOf().toEqualTypeOf();
|
|
73
|
+
});
|
|
74
|
+
it('Should concatenate non-root parent paths', () => {
|
|
75
|
+
expectTypeOf().toEqualTypeOf();
|
|
76
|
+
});
|
|
77
|
+
it('Should handle deeply nested paths', () => {
|
|
78
|
+
expectTypeOf().toEqualTypeOf();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe('ExtractRouteParams', () => {
|
|
82
|
+
it('Should return Record<string, never> for paths without params', () => {
|
|
83
|
+
expectTypeOf().toEqualTypeOf();
|
|
84
|
+
});
|
|
85
|
+
it('Should extract a single param', () => {
|
|
86
|
+
expectTypeOf().toEqualTypeOf();
|
|
87
|
+
});
|
|
88
|
+
it('Should extract multiple params', () => {
|
|
89
|
+
expectTypeOf().toEqualTypeOf();
|
|
90
|
+
});
|
|
91
|
+
it('Should handle params at the beginning of the path', () => {
|
|
92
|
+
expectTypeOf().toEqualTypeOf();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('ExtractRoutePaths', () => {
|
|
96
|
+
it('Should extract top-level paths', () => {
|
|
97
|
+
expectTypeOf().toEqualTypeOf();
|
|
98
|
+
});
|
|
99
|
+
it('Should extract nested child paths with root parent', () => {
|
|
100
|
+
expectTypeOf().toEqualTypeOf();
|
|
101
|
+
});
|
|
102
|
+
it('Should extract nested child paths with non-root parent', () => {
|
|
103
|
+
expectTypeOf().toEqualTypeOf();
|
|
104
|
+
});
|
|
105
|
+
it('Should handle mixed flat and nested routes', () => {
|
|
106
|
+
expectTypeOf().toEqualTypeOf();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('UrlTree', () => {
|
|
110
|
+
it('Should accept a flat object of valid paths', () => {
|
|
111
|
+
const urls = {
|
|
112
|
+
a: '/a',
|
|
113
|
+
b: '/b',
|
|
114
|
+
};
|
|
115
|
+
expectTypeOf(urls).toExtend();
|
|
116
|
+
});
|
|
117
|
+
it('Should accept nested objects of valid paths', () => {
|
|
118
|
+
const urls = {
|
|
119
|
+
home: '/',
|
|
120
|
+
buttons: '/buttons',
|
|
121
|
+
layoutTests: {
|
|
122
|
+
index: '/layout-tests',
|
|
123
|
+
appBarOnly: '/layout-tests/appbar-only',
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
expectTypeOf(urls).toExtend();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('TypedNestedRouteLinkProps', () => {
|
|
130
|
+
it('Should make params optional for paths without parameters', () => {
|
|
131
|
+
expectTypeOf().toEqualTypeOf();
|
|
132
|
+
expectTypeOf().toExtend();
|
|
133
|
+
});
|
|
134
|
+
it('Should require params for parameterized paths', () => {
|
|
135
|
+
expectTypeOf().toEqualTypeOf();
|
|
136
|
+
expectTypeOf().toExtend();
|
|
137
|
+
});
|
|
138
|
+
it('Should require all params for multi-param paths', () => {
|
|
139
|
+
expectTypeOf().toExtend();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe('NestedRouteLink param inference', () => {
|
|
143
|
+
it('Should infer params as optional when href has no parameters', () => {
|
|
144
|
+
expectTypeOf(NestedRouteLink).parameter(0).toHaveProperty('params');
|
|
145
|
+
expectTypeOf((NestedRouteLink))
|
|
146
|
+
.parameter(0)
|
|
147
|
+
.toExtend();
|
|
148
|
+
});
|
|
149
|
+
it('Should infer params as required when href has a parameter', () => {
|
|
150
|
+
expectTypeOf((NestedRouteLink))
|
|
151
|
+
.parameter(0)
|
|
152
|
+
.toExtend();
|
|
153
|
+
});
|
|
154
|
+
it('Should infer multiple params from href', () => {
|
|
155
|
+
expectTypeOf((NestedRouteLink))
|
|
156
|
+
.parameter(0)
|
|
157
|
+
.toExtend();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe('createNestedRouteLink', () => {
|
|
161
|
+
it('Should constrain href to valid route paths', () => {
|
|
162
|
+
const AppLink = createNestedRouteLink();
|
|
163
|
+
expectTypeOf(AppLink).parameter(0).toHaveProperty('href');
|
|
164
|
+
});
|
|
165
|
+
it('Should require params for parameterized routes in the tree', () => {
|
|
166
|
+
const AppLink = createNestedRouteLink();
|
|
167
|
+
expectTypeOf((AppLink))
|
|
168
|
+
.parameter(0)
|
|
169
|
+
.toExtend();
|
|
170
|
+
});
|
|
171
|
+
it('Should require combined params from parent and child route segments', () => {
|
|
172
|
+
const AppLink = createNestedRouteLink();
|
|
173
|
+
expectTypeOf((AppLink))
|
|
174
|
+
.parameter(0)
|
|
175
|
+
.toExtend();
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=nested-route-link.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-link.spec.js","sourceRoot":"","sources":["../../src/components/nested-route-link.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { NestedRoute } from './nested-router.js';
|
|
2
|
+
/**
|
|
3
|
+
* Concatenates parent and child route paths, handling the '/' root specially
|
|
4
|
+
* to avoid double slashes.
|
|
5
|
+
* @typeParam Parent - The parent route path
|
|
6
|
+
* @typeParam Child - The child route path
|
|
7
|
+
*/
|
|
8
|
+
export type ConcatPaths<Parent extends string, Child extends string> = Parent extends '/' ? Child : `${Parent}${Child}`;
|
|
9
|
+
/**
|
|
10
|
+
* Recursively extracts all valid full URL paths from a nested route tree.
|
|
11
|
+
* @typeParam T - A record of route patterns to NestedRoute definitions
|
|
12
|
+
*/
|
|
13
|
+
export type ExtractRoutePaths<T extends Record<string, NestedRoute<unknown>>> = {
|
|
14
|
+
[K in keyof T & string]: K | (T[K] extends {
|
|
15
|
+
children: infer C extends Record<string, NestedRoute<unknown>>;
|
|
16
|
+
} ? ConcatPaths<K, ExtractRoutePaths<C> & string> : never);
|
|
17
|
+
}[keyof T & string];
|
|
18
|
+
/**
|
|
19
|
+
* Extracts route parameter names from a URL pattern and creates a record type
|
|
20
|
+
* mapping each parameter name to `string`.
|
|
21
|
+
* Returns `Record<string, never>` when no parameters are present.
|
|
22
|
+
* @typeParam T - A URL pattern string potentially containing `:param` segments
|
|
23
|
+
*/
|
|
24
|
+
export type ExtractRouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? {
|
|
25
|
+
[K in Param | keyof ExtractRouteParams<`/${Rest}`>]: string;
|
|
26
|
+
} : T extends `${string}:${infer Param}` ? {
|
|
27
|
+
[K in Param]: string;
|
|
28
|
+
} : Record<string, never>;
|
|
29
|
+
/**
|
|
30
|
+
* A recursive type for validating URL constant objects against a set of valid paths.
|
|
31
|
+
* Leaf values must be valid route paths, and intermediate values can be nested UrlTree objects.
|
|
32
|
+
* @typeParam TPaths - Union of valid route path strings
|
|
33
|
+
*/
|
|
34
|
+
export type UrlTree<TPaths extends string> = {
|
|
35
|
+
[key: string]: TPaths | UrlTree<TPaths>;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=nested-route-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-types.d.ts","sourceRoot":"","sources":["../../src/components/nested-route-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,MAAM,EAAE,KAAK,SAAS,MAAM,IAAI,MAAM,SAAS,GAAG,GAAG,KAAK,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAA;AAEvH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI;KAC7E,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAClB,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;KAAE,GAC5E,WAAW,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAC7C,KAAK,CAAC;CACf,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,GACjG;KAAG,CAAC,IAAI,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,MAAM;CAAE,GAC/D,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,EAAE,GAClC;KAAG,CAAC,IAAI,KAAK,GAAG,MAAM;CAAE,GACxB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAE3B;;;;GAIG;AACH,MAAM,MAAM,OAAO,CAAC,MAAM,SAAS,MAAM,IAAI;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACxC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-route-types.js","sourceRoot":"","sources":["../../src/components/nested-route-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { MatchOptions, MatchResult } from 'path-to-regexp';
|
|
2
|
+
import type { RenderOptions } from '../models/render-options.js';
|
|
3
|
+
/**
|
|
4
|
+
* A single route entry in a NestedRouter configuration.
|
|
5
|
+
* Unlike flat `Route`, the URL is the Record key (not a field), and the
|
|
6
|
+
* `component` receives an `outlet` for rendering matched child content.
|
|
7
|
+
* @typeParam TMatchResult - The type of matched URL parameters
|
|
8
|
+
*/
|
|
9
|
+
export type NestedRoute<TMatchResult = unknown> = {
|
|
10
|
+
component: (options: {
|
|
11
|
+
currentUrl: string;
|
|
12
|
+
match: MatchResult<TMatchResult extends object ? TMatchResult : object>;
|
|
13
|
+
outlet?: JSX.Element;
|
|
14
|
+
}) => JSX.Element;
|
|
15
|
+
routingOptions?: MatchOptions;
|
|
16
|
+
onVisit?: (options: RenderOptions<unknown> & {
|
|
17
|
+
element: JSX.Element;
|
|
18
|
+
}) => Promise<void>;
|
|
19
|
+
onLeave?: (options: RenderOptions<unknown> & {
|
|
20
|
+
element: JSX.Element;
|
|
21
|
+
}) => Promise<void>;
|
|
22
|
+
children?: Record<string, NestedRoute<any>>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Props for the NestedRouter component.
|
|
26
|
+
* Routes are defined as a Record where keys are URL patterns.
|
|
27
|
+
*/
|
|
28
|
+
export type NestedRouterProps = {
|
|
29
|
+
routes: Record<string, NestedRoute<any>>;
|
|
30
|
+
notFound?: JSX.Element;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A single entry in a match chain, pairing a matched route with its match result.
|
|
34
|
+
*/
|
|
35
|
+
export type MatchChainEntry = {
|
|
36
|
+
route: NestedRoute<unknown>;
|
|
37
|
+
match: MatchResult<object>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Internal state for the NestedRouter component.
|
|
41
|
+
* `matchChain` is `null` when a notFound fallback has been rendered,
|
|
42
|
+
* distinguishing it from the initial empty array (not yet processed).
|
|
43
|
+
*/
|
|
44
|
+
export type NestedRouterState = {
|
|
45
|
+
matchChain: MatchChainEntry[] | null;
|
|
46
|
+
jsx: JSX.Element;
|
|
47
|
+
chainElements: JSX.Element[];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Recursively builds a match chain from outermost to innermost matched route.
|
|
51
|
+
*
|
|
52
|
+
* For routes with children, a prefix match (`end: false`) is attempted first.
|
|
53
|
+
* If a child matches the remaining URL, the parent and child chain are combined.
|
|
54
|
+
* If no child matches, an exact match on the parent alone is attempted.
|
|
55
|
+
*
|
|
56
|
+
* For leaf routes (no children), only exact matching is used.
|
|
57
|
+
*
|
|
58
|
+
* @param routes - The route definitions to match against
|
|
59
|
+
* @param currentUrl - The URL path to match
|
|
60
|
+
* @returns An array of matched chain entries from outermost to innermost, or null if no match
|
|
61
|
+
*/
|
|
62
|
+
export declare const buildMatchChain: (routes: Record<string, NestedRoute<any>>, currentUrl: string) => MatchChainEntry[] | null;
|
|
63
|
+
/**
|
|
64
|
+
* Finds the first index where two match chains diverge.
|
|
65
|
+
* Returns the length of the shorter chain if one is a prefix of the other.
|
|
66
|
+
*/
|
|
67
|
+
export declare const findDivergenceIndex: (oldChain: MatchChainEntry[], newChain: MatchChainEntry[]) => number;
|
|
68
|
+
/**
|
|
69
|
+
* The result of rendering a match chain, containing both the fully composed
|
|
70
|
+
* JSX tree and per-entry elements for scoped lifecycle animations.
|
|
71
|
+
*/
|
|
72
|
+
export type RenderMatchChainResult = {
|
|
73
|
+
jsx: JSX.Element;
|
|
74
|
+
chainElements: JSX.Element[];
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Renders a match chain inside-out: starts with the innermost (leaf) route
|
|
78
|
+
* rendered with `outlet: undefined`, then passes its JSX as `outlet` to
|
|
79
|
+
* each successive parent up the chain.
|
|
80
|
+
*
|
|
81
|
+
* Returns per-entry elements so that lifecycle hooks (`onLeave`/`onVisit`)
|
|
82
|
+
* receive only the element for their own route level, not the full tree.
|
|
83
|
+
*
|
|
84
|
+
* @param chain - The match chain from outermost to innermost
|
|
85
|
+
* @param currentUrl - The current URL path
|
|
86
|
+
* @returns The fully composed JSX element and per-entry rendered elements
|
|
87
|
+
*/
|
|
88
|
+
export declare const renderMatchChain: (chain: MatchChainEntry[], currentUrl: string) => RenderMatchChainResult;
|
|
89
|
+
/**
|
|
90
|
+
* A nested router component that supports hierarchical route definitions
|
|
91
|
+
* with parent/child relationships. Parent routes receive an `outlet` prop
|
|
92
|
+
* containing the rendered child route, enabling layout composition.
|
|
93
|
+
*
|
|
94
|
+
* Routes are defined as a Record where keys are URL patterns (following the
|
|
95
|
+
* RestApi pattern). The matching algorithm builds a chain from outermost to
|
|
96
|
+
* innermost route, then renders inside-out so each parent wraps its child.
|
|
97
|
+
*/
|
|
98
|
+
export declare const NestedRouter: (props: NestedRouterProps & Omit<Partial<HTMLElement>, "style"> & {
|
|
99
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
100
|
+
} & {
|
|
101
|
+
ref?: import("../models/render-options.js").RefObject<Element>;
|
|
102
|
+
}, children?: import("../index.js").ChildrenList) => JSX.Element;
|
|
103
|
+
//# sourceMappingURL=nested-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-router.d.ts","sourceRoot":"","sources":["../../src/components/nested-router.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAKhE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,YAAY,GAAG,OAAO,IAAI;IAChD,SAAS,EAAE,CAAC,OAAO,EAAE;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,WAAW,CAAC,YAAY,SAAS,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC,CAAA;QACvE,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;KACrB,KAAK,GAAG,CAAC,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,YAAY,CAAA;IAC7B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;CAC5C,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IACxC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC3B,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,eAAe,EAAE,GAAG,IAAI,CAAA;IACpC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;IAChB,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;CAC7B,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EACxC,YAAY,MAAM,KACjB,eAAe,EAAE,GAAG,IAuCtB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,eAAe,EAAE,EAAE,UAAU,eAAe,EAAE,KAAG,MAW9F,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;IAChB,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;CAC7B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,EAAE,EAAE,YAAY,MAAM,KAAG,sBAe/E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;;gEA+EvB,CAAA"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { ObservableAlreadyDisposedError } from '@furystack/utils';
|
|
2
|
+
import { match } from 'path-to-regexp';
|
|
3
|
+
import { Lock } from 'semaphore-async-await';
|
|
4
|
+
import { LocationService } from '../services/location-service.js';
|
|
5
|
+
import { createComponent, setRenderMode } from '../shade-component.js';
|
|
6
|
+
import { Shade } from '../shade.js';
|
|
7
|
+
/**
|
|
8
|
+
* Recursively builds a match chain from outermost to innermost matched route.
|
|
9
|
+
*
|
|
10
|
+
* For routes with children, a prefix match (`end: false`) is attempted first.
|
|
11
|
+
* If a child matches the remaining URL, the parent and child chain are combined.
|
|
12
|
+
* If no child matches, an exact match on the parent alone is attempted.
|
|
13
|
+
*
|
|
14
|
+
* For leaf routes (no children), only exact matching is used.
|
|
15
|
+
*
|
|
16
|
+
* @param routes - The route definitions to match against
|
|
17
|
+
* @param currentUrl - The URL path to match
|
|
18
|
+
* @returns An array of matched chain entries from outermost to innermost, or null if no match
|
|
19
|
+
*/
|
|
20
|
+
export const buildMatchChain = (routes, currentUrl) => {
|
|
21
|
+
for (const [pattern, route] of Object.entries(routes)) {
|
|
22
|
+
if (route.children) {
|
|
23
|
+
const prefixMatchFn = match(pattern, { ...route.routingOptions, end: false });
|
|
24
|
+
let prefixResult = prefixMatchFn(currentUrl);
|
|
25
|
+
// In path-to-regexp v8, match('/', { end: false }) only matches exact '/'.
|
|
26
|
+
// For the root pattern, any URL is logically under '/', so force a prefix match.
|
|
27
|
+
if (!prefixResult && pattern === '/') {
|
|
28
|
+
prefixResult = { path: '/', params: {} };
|
|
29
|
+
}
|
|
30
|
+
if (prefixResult) {
|
|
31
|
+
let remainingUrl = currentUrl.slice(prefixResult.path.length);
|
|
32
|
+
if (!remainingUrl.startsWith('/')) {
|
|
33
|
+
remainingUrl = `/${remainingUrl}`;
|
|
34
|
+
}
|
|
35
|
+
const childChain = buildMatchChain(route.children, remainingUrl);
|
|
36
|
+
if (childChain) {
|
|
37
|
+
return [{ route, match: prefixResult }, ...childChain];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const exactMatchFn = match(pattern, route.routingOptions);
|
|
41
|
+
const exactResult = exactMatchFn(currentUrl);
|
|
42
|
+
if (exactResult) {
|
|
43
|
+
return [{ route, match: exactResult }];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const matchFn = match(pattern, route.routingOptions);
|
|
48
|
+
const matchResult = matchFn(currentUrl);
|
|
49
|
+
if (matchResult) {
|
|
50
|
+
return [{ route, match: matchResult }];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Finds the first index where two match chains diverge.
|
|
58
|
+
* Returns the length of the shorter chain if one is a prefix of the other.
|
|
59
|
+
*/
|
|
60
|
+
export const findDivergenceIndex = (oldChain, newChain) => {
|
|
61
|
+
const minLength = Math.min(oldChain.length, newChain.length);
|
|
62
|
+
for (let i = 0; i < minLength; i++) {
|
|
63
|
+
if (oldChain[i].route !== newChain[i].route ||
|
|
64
|
+
JSON.stringify(oldChain[i].match.params) !== JSON.stringify(newChain[i].match.params)) {
|
|
65
|
+
return i;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return minLength;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Renders a match chain inside-out: starts with the innermost (leaf) route
|
|
72
|
+
* rendered with `outlet: undefined`, then passes its JSX as `outlet` to
|
|
73
|
+
* each successive parent up the chain.
|
|
74
|
+
*
|
|
75
|
+
* Returns per-entry elements so that lifecycle hooks (`onLeave`/`onVisit`)
|
|
76
|
+
* receive only the element for their own route level, not the full tree.
|
|
77
|
+
*
|
|
78
|
+
* @param chain - The match chain from outermost to innermost
|
|
79
|
+
* @param currentUrl - The current URL path
|
|
80
|
+
* @returns The fully composed JSX element and per-entry rendered elements
|
|
81
|
+
*/
|
|
82
|
+
export const renderMatchChain = (chain, currentUrl) => {
|
|
83
|
+
let outlet;
|
|
84
|
+
const chainElements = new Array(chain.length);
|
|
85
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
86
|
+
const entry = chain[i];
|
|
87
|
+
outlet = entry.route.component({
|
|
88
|
+
currentUrl,
|
|
89
|
+
match: entry.match,
|
|
90
|
+
outlet,
|
|
91
|
+
});
|
|
92
|
+
chainElements[i] = outlet;
|
|
93
|
+
}
|
|
94
|
+
return { jsx: outlet, chainElements };
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A nested router component that supports hierarchical route definitions
|
|
98
|
+
* with parent/child relationships. Parent routes receive an `outlet` prop
|
|
99
|
+
* containing the rendered child route, enabling layout composition.
|
|
100
|
+
*
|
|
101
|
+
* Routes are defined as a Record where keys are URL patterns (following the
|
|
102
|
+
* RestApi pattern). The matching algorithm builds a chain from outermost to
|
|
103
|
+
* innermost route, then renders inside-out so each parent wraps its child.
|
|
104
|
+
*/
|
|
105
|
+
export const NestedRouter = Shade({
|
|
106
|
+
shadowDomName: 'shade-nested-router',
|
|
107
|
+
render: (options) => {
|
|
108
|
+
const { useState, useObservable, injector } = options;
|
|
109
|
+
const [lock] = useState('lock', new Lock());
|
|
110
|
+
const [state, setState] = useState('routerState', {
|
|
111
|
+
matchChain: [],
|
|
112
|
+
jsx: createComponent("div", null),
|
|
113
|
+
chainElements: [],
|
|
114
|
+
});
|
|
115
|
+
const updateUrl = async (currentUrl) => {
|
|
116
|
+
const [lastState] = useState('routerState', state);
|
|
117
|
+
const { matchChain: lastChain, chainElements: lastChainElements } = lastState;
|
|
118
|
+
try {
|
|
119
|
+
await lock.acquire();
|
|
120
|
+
const newChain = buildMatchChain(options.props.routes, currentUrl);
|
|
121
|
+
if (newChain) {
|
|
122
|
+
const lastChainEntries = lastChain ?? [];
|
|
123
|
+
const divergeIndex = findDivergenceIndex(lastChainEntries, newChain);
|
|
124
|
+
const hasChanged = divergeIndex < lastChainEntries.length ||
|
|
125
|
+
divergeIndex < newChain.length ||
|
|
126
|
+
lastChainEntries.length !== newChain.length;
|
|
127
|
+
if (hasChanged) {
|
|
128
|
+
// Call onLeave for routes that are being left (from divergence point to end of old chain)
|
|
129
|
+
for (let i = lastChainEntries.length - 1; i >= divergeIndex; i--) {
|
|
130
|
+
await lastChainEntries[i].route.onLeave?.({ ...options, element: lastChainElements[i] });
|
|
131
|
+
}
|
|
132
|
+
let newResult;
|
|
133
|
+
setRenderMode(true);
|
|
134
|
+
try {
|
|
135
|
+
newResult = renderMatchChain(newChain, currentUrl);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
setRenderMode(false);
|
|
139
|
+
}
|
|
140
|
+
setState({ matchChain: newChain, jsx: newResult.jsx, chainElements: newResult.chainElements });
|
|
141
|
+
// Call onVisit for routes that are being entered (from divergence point to end of new chain)
|
|
142
|
+
for (let i = divergeIndex; i < newChain.length; i++) {
|
|
143
|
+
await newChain[i].route.onVisit?.({ ...options, element: newResult.chainElements[i] });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (lastChain !== null) {
|
|
148
|
+
// No match found — call onLeave for all active routes and show notFound.
|
|
149
|
+
// The null sentinel prevents re-entering this block on re-render.
|
|
150
|
+
for (let i = (lastChain?.length ?? 0) - 1; i >= 0; i--) {
|
|
151
|
+
await lastChain[i].route.onLeave?.({ ...options, element: lastChainElements[i] });
|
|
152
|
+
}
|
|
153
|
+
setState({
|
|
154
|
+
matchChain: null,
|
|
155
|
+
jsx: options.props.notFound || createComponent("div", null),
|
|
156
|
+
chainElements: [],
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
if (!(e instanceof ObservableAlreadyDisposedError)) {
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
lock?.release();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const [locationPath] = useObservable('locationPathChanged', injector.getInstance(LocationService).onLocationPathChanged, {
|
|
170
|
+
onChange: (newValue) => {
|
|
171
|
+
void updateUrl(newValue);
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
void updateUrl(locationPath);
|
|
175
|
+
return state.jsx;
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=nested-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-router.js","sourceRoot":"","sources":["../../src/components/nested-router.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-router.spec.d.ts","sourceRoot":"","sources":["../../src/components/nested-router.spec.tsx"],"names":[],"mappings":""}
|