@cyberismo/backend 0.0.22 → 0.0.23
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/app.js +3 -1
- package/dist/app.js.map +1 -1
- package/dist/domain/cards/index.js +107 -12
- package/dist/domain/cards/index.js.map +1 -1
- package/dist/domain/cards/lib.js +1 -4
- package/dist/domain/cards/lib.js.map +1 -1
- package/dist/domain/cards/presence.d.ts +50 -0
- package/dist/domain/cards/presence.js +93 -0
- package/dist/domain/cards/presence.js.map +1 -0
- package/dist/domain/cards/schema.d.ts +47 -0
- package/dist/domain/cards/schema.js +37 -0
- package/dist/domain/cards/schema.js.map +1 -0
- package/dist/domain/cards/service.d.ts +5 -2
- package/dist/domain/cards/service.js +21 -4
- package/dist/domain/cards/service.js.map +1 -1
- package/dist/domain/connectors/index.d.ts +15 -0
- package/dist/domain/connectors/index.js +37 -0
- package/dist/domain/connectors/index.js.map +1 -0
- package/dist/domain/connectors/service.d.ts +23 -0
- package/dist/domain/connectors/service.js +46 -0
- package/dist/domain/connectors/service.js.map +1 -0
- package/dist/domain/project/index.js +12 -1
- package/dist/domain/project/index.js.map +1 -1
- package/dist/domain/project/schema.d.ts +3 -0
- package/dist/domain/project/schema.js +8 -0
- package/dist/domain/project/schema.js.map +1 -1
- package/dist/domain/project/service.d.ts +3 -1
- package/dist/domain/project/service.js +6 -0
- package/dist/domain/project/service.js.map +1 -1
- package/dist/domain/tree/service.js +0 -1
- package/dist/domain/tree/service.js.map +1 -1
- package/dist/export.js +1 -2
- package/dist/export.js.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/public/THIRD-PARTY.txt +1196 -615
- package/dist/public/assets/index-Cdn_jRWy.js +720 -0
- package/dist/public/assets/index-ypsafPwV.css +1 -0
- package/dist/public/images/broken_link.svg +7 -0
- package/dist/public/index.html +2 -2
- package/package.json +5 -5
- package/src/app.ts +3 -1
- package/src/domain/cards/index.ts +198 -48
- package/src/domain/cards/lib.ts +2 -5
- package/src/domain/cards/presence.ts +124 -0
- package/src/domain/cards/schema.ts +41 -0
- package/src/domain/cards/service.ts +65 -4
- package/src/domain/connectors/index.ts +39 -0
- package/src/domain/connectors/service.ts +67 -0
- package/src/domain/project/index.ts +23 -1
- package/src/domain/project/schema.ts +9 -0
- package/src/domain/project/service.ts +17 -1
- package/src/domain/tree/service.ts +0 -1
- package/src/export.ts +1 -2
- package/src/index.ts +8 -4
- package/dist/public/assets/index-B_lh6qtv.css +0 -1
- package/dist/public/assets/index-CEol8Bfi.js +0 -164949
|
@@ -174,25 +174,86 @@ export async function parseContent(
|
|
|
174
174
|
export async function createLink(
|
|
175
175
|
commands: CommandManager,
|
|
176
176
|
key: string,
|
|
177
|
-
|
|
177
|
+
target: string,
|
|
178
178
|
linkType: string,
|
|
179
|
+
direction: 'outbound' | 'inbound' = 'outbound',
|
|
179
180
|
description?: string,
|
|
180
181
|
) {
|
|
181
|
-
|
|
182
|
+
// For outbound: key is source, target is destination
|
|
183
|
+
// For inbound: target is source, key is destination
|
|
184
|
+
const source = direction === 'outbound' ? key : target;
|
|
185
|
+
const destination = direction === 'outbound' ? target : key;
|
|
186
|
+
|
|
187
|
+
await commands.createCmd.createLink(
|
|
188
|
+
source,
|
|
189
|
+
destination,
|
|
190
|
+
linkType,
|
|
191
|
+
description,
|
|
192
|
+
direction,
|
|
193
|
+
);
|
|
194
|
+
|
|
182
195
|
return { message: 'Link created successfully' };
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
export async function removeLink(
|
|
186
199
|
commands: CommandManager,
|
|
187
200
|
key: string,
|
|
188
|
-
|
|
201
|
+
target: string,
|
|
189
202
|
linkType: string,
|
|
203
|
+
direction: 'outbound' | 'inbound' = 'outbound',
|
|
190
204
|
description?: string,
|
|
191
205
|
) {
|
|
192
|
-
|
|
206
|
+
// For outbound: key is source, target is destination
|
|
207
|
+
// For inbound: target is source, key is destination
|
|
208
|
+
const source = direction === 'outbound' ? key : target;
|
|
209
|
+
const destination = direction === 'outbound' ? target : key;
|
|
210
|
+
await commands.removeCmd.remove(
|
|
211
|
+
'link',
|
|
212
|
+
source,
|
|
213
|
+
destination,
|
|
214
|
+
linkType,
|
|
215
|
+
description,
|
|
216
|
+
);
|
|
193
217
|
return { message: 'Link removed successfully' };
|
|
194
218
|
}
|
|
195
219
|
|
|
220
|
+
export async function updateLink(
|
|
221
|
+
commands: CommandManager,
|
|
222
|
+
key: string,
|
|
223
|
+
toCard: string,
|
|
224
|
+
linkType: string,
|
|
225
|
+
direction: 'outbound' | 'inbound',
|
|
226
|
+
previousToCard: string,
|
|
227
|
+
previousLinkType: string,
|
|
228
|
+
previousDirection: 'outbound' | 'inbound',
|
|
229
|
+
linkDescription?: string,
|
|
230
|
+
previousLinkDescription?: string,
|
|
231
|
+
) {
|
|
232
|
+
// For simplicity create the new link first so that duplicate-link validation runs before
|
|
233
|
+
// the old link is removed. This also handles direction changes.
|
|
234
|
+
return commands.atomic(async () => {
|
|
235
|
+
await createLink(
|
|
236
|
+
commands,
|
|
237
|
+
key,
|
|
238
|
+
toCard,
|
|
239
|
+
linkType,
|
|
240
|
+
direction,
|
|
241
|
+
linkDescription,
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
await removeLink(
|
|
245
|
+
commands,
|
|
246
|
+
key,
|
|
247
|
+
previousToCard,
|
|
248
|
+
previousLinkType,
|
|
249
|
+
previousDirection,
|
|
250
|
+
previousLinkDescription,
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
return { message: 'Link updated successfully' };
|
|
254
|
+
}, `Update link on ${key} to ${toCard}`);
|
|
255
|
+
}
|
|
256
|
+
|
|
196
257
|
export async function getAttachment(
|
|
197
258
|
commands: CommandManager,
|
|
198
259
|
key: string,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2026
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation. This program is distributed in the hope that it
|
|
7
|
+
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
8
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
9
|
+
See the GNU Affero General Public License for more details.
|
|
10
|
+
You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
import { Hono } from 'hono';
|
|
14
|
+
import { isSSGContext } from 'hono/ssg';
|
|
15
|
+
import * as connectorsService from './service.js';
|
|
16
|
+
import { UserRole } from '../../types.js';
|
|
17
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
18
|
+
|
|
19
|
+
const router = new Hono();
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @openapi
|
|
23
|
+
* /api/connectors:
|
|
24
|
+
* get:
|
|
25
|
+
* summary: Returns all available connectors
|
|
26
|
+
* responses:
|
|
27
|
+
* 200:
|
|
28
|
+
* description: List of connectors with their display names
|
|
29
|
+
*/
|
|
30
|
+
router.get('/', requireRole(UserRole.Reader), async (c) => {
|
|
31
|
+
if (isSSGContext(c)) {
|
|
32
|
+
return c.json([]);
|
|
33
|
+
}
|
|
34
|
+
const commands = c.get('commands');
|
|
35
|
+
const connectors = await connectorsService.getConnectors(commands);
|
|
36
|
+
return c.json(connectors);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export default router;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { CommandManager } from '@cyberismo/data-handler';
|
|
15
|
+
|
|
16
|
+
export interface ExternalItem {
|
|
17
|
+
key: string;
|
|
18
|
+
title: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface Connector {
|
|
22
|
+
name: string;
|
|
23
|
+
displayName: string;
|
|
24
|
+
items: ExternalItem[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function getConnectors(
|
|
28
|
+
commands: CommandManager,
|
|
29
|
+
): Promise<Connector[]> {
|
|
30
|
+
const results = await commands.calculateCmd.runQuery(
|
|
31
|
+
'connectors',
|
|
32
|
+
'localApp',
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// Separate connectors from items based on type field
|
|
36
|
+
const connectorsMap = new Map<string, Connector>();
|
|
37
|
+
const items: { connector: string; key: string; title: string }[] = [];
|
|
38
|
+
|
|
39
|
+
for (const r of results) {
|
|
40
|
+
if (r.type === 'connector') {
|
|
41
|
+
connectorsMap.set(r.key, {
|
|
42
|
+
name: r.key,
|
|
43
|
+
displayName: r.displayName ?? r.key,
|
|
44
|
+
items: [],
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
items.push({
|
|
48
|
+
connector: r.connector ?? '',
|
|
49
|
+
key: r.itemKey ?? '',
|
|
50
|
+
title: r.title ?? '',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Associate items with their connectors
|
|
56
|
+
for (const item of items) {
|
|
57
|
+
const connector = connectorsMap.get(item.connector);
|
|
58
|
+
if (connector) {
|
|
59
|
+
connector.items.push({
|
|
60
|
+
key: item.key,
|
|
61
|
+
title: item.title,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return Array.from(connectorsMap.values());
|
|
67
|
+
}
|
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
|
|
14
14
|
import { Hono } from 'hono';
|
|
15
15
|
import { zValidator } from '../../middleware/zvalidator.js';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
importModuleSchema,
|
|
18
|
+
moduleParamSchema,
|
|
19
|
+
updateProjectSchema,
|
|
20
|
+
} from './schema.js';
|
|
17
21
|
import * as projectService from './service.js';
|
|
18
22
|
import { UserRole } from '../../types.js';
|
|
19
23
|
import { requireRole } from '../../middleware/auth.js';
|
|
@@ -58,6 +62,24 @@ router.post(
|
|
|
58
62
|
},
|
|
59
63
|
);
|
|
60
64
|
|
|
65
|
+
router.get('/modules/importable', requireRole(UserRole.Reader), async (c) => {
|
|
66
|
+
const commands = c.get('commands');
|
|
67
|
+
const modules = await projectService.getImportableModules(commands);
|
|
68
|
+
return c.json(modules);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
router.post(
|
|
72
|
+
'/modules',
|
|
73
|
+
requireRole(UserRole.Admin),
|
|
74
|
+
zValidator('json', importModuleSchema),
|
|
75
|
+
async (c) => {
|
|
76
|
+
const commands = c.get('commands');
|
|
77
|
+
const { source } = c.req.valid('json');
|
|
78
|
+
await projectService.importModule(commands, source);
|
|
79
|
+
return c.json({ message: 'Module imported successfully' });
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
61
83
|
router.delete(
|
|
62
84
|
'/modules/:module',
|
|
63
85
|
requireRole(UserRole.Admin),
|
|
@@ -21,3 +21,12 @@ export const updateProjectSchema = z.object({
|
|
|
21
21
|
name: z.string().optional(),
|
|
22
22
|
cardKeyPrefix: z.string().optional(),
|
|
23
23
|
});
|
|
24
|
+
|
|
25
|
+
export const importModuleSchema = z.object({
|
|
26
|
+
source: z
|
|
27
|
+
.string()
|
|
28
|
+
.min(1)
|
|
29
|
+
.refine((s) => s.startsWith('https') || s.startsWith('git@'), {
|
|
30
|
+
message: 'Source must be a git URL (https:// or git@)',
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type CommandManager,
|
|
16
|
+
type ModuleSettingFromHub,
|
|
17
|
+
} from '@cyberismo/data-handler';
|
|
15
18
|
|
|
16
19
|
export interface ProjectModule {
|
|
17
20
|
name: string;
|
|
@@ -94,3 +97,16 @@ export async function updateAllModules(commands: CommandManager) {
|
|
|
94
97
|
export async function deleteModule(commands: CommandManager, module: string) {
|
|
95
98
|
await commands.removeCmd.remove('module', module);
|
|
96
99
|
}
|
|
100
|
+
|
|
101
|
+
export async function getImportableModules(
|
|
102
|
+
commands: CommandManager,
|
|
103
|
+
): Promise<ModuleSettingFromHub[]> {
|
|
104
|
+
return commands.showCmd.showImportableModules(false, true);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function importModule(
|
|
108
|
+
commands: CommandManager,
|
|
109
|
+
source: string,
|
|
110
|
+
): Promise<void> {
|
|
111
|
+
await commands.importCmd.importModule(source);
|
|
112
|
+
}
|
|
@@ -27,7 +27,6 @@ export async function getCardTree(
|
|
|
27
27
|
cardKey?: string,
|
|
28
28
|
recursive?: boolean,
|
|
29
29
|
): ReturnType<typeof commands.calculateCmd.runQuery> {
|
|
30
|
-
await commands.calculateCmd.generate();
|
|
31
30
|
return commands.calculateCmd.runQuery(
|
|
32
31
|
'tree',
|
|
33
32
|
isSsg ? 'exportedSite' : 'localApp',
|
package/src/export.ts
CHANGED
|
@@ -52,7 +52,7 @@ export async function getCardQueryResult(
|
|
|
52
52
|
): Promise<QueryResult<'card'>[]> {
|
|
53
53
|
if (!_cardQueryPromise) {
|
|
54
54
|
// fetch all cards
|
|
55
|
-
_cardQueryPromise = commands.
|
|
55
|
+
_cardQueryPromise = commands.calculateCmd.runQuery(
|
|
56
56
|
'card',
|
|
57
57
|
'exportedSite',
|
|
58
58
|
{},
|
|
@@ -109,7 +109,6 @@ export async function exportSite(
|
|
|
109
109
|
);
|
|
110
110
|
|
|
111
111
|
reset();
|
|
112
|
-
await commands.project.calculationEngine.generate();
|
|
113
112
|
|
|
114
113
|
// estimate total based on the number of cards to export
|
|
115
114
|
const cards = await findAllCards(commands, opts);
|
package/src/index.ts
CHANGED
|
@@ -36,11 +36,14 @@ const DEFAULT_MAX_PORT = DEFAULT_PORT + 100;
|
|
|
36
36
|
export async function previewSite(dir: string, findPort: boolean = true) {
|
|
37
37
|
const app = new Hono();
|
|
38
38
|
app.use(serveStatic({ root: dir }));
|
|
39
|
-
app.get('*', (c) =>
|
|
40
|
-
c.
|
|
39
|
+
app.get('*', (c) => {
|
|
40
|
+
if (c.req.path.startsWith('/api/')) {
|
|
41
|
+
return c.json({ error: 'Resource not found' }, 404);
|
|
42
|
+
}
|
|
43
|
+
return c.html(
|
|
41
44
|
readFile(path.join(dir, 'index.html')).then((file) => file.toString()),
|
|
42
|
-
)
|
|
43
|
-
);
|
|
45
|
+
);
|
|
46
|
+
});
|
|
44
47
|
|
|
45
48
|
let port = parseInt(process.env.PORT || DEFAULT_PORT.toString(), 10);
|
|
46
49
|
|
|
@@ -78,6 +81,7 @@ function startApp<E extends Env, S extends Schema, P extends string>(
|
|
|
78
81
|
{
|
|
79
82
|
fetch: app.fetch,
|
|
80
83
|
port: port,
|
|
84
|
+
hostname: process.env.HOST || '127.0.0.1',
|
|
81
85
|
},
|
|
82
86
|
(info) => {
|
|
83
87
|
console.log(`Running Cyberismo app on http://localhost:${info.port}`);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@media(max-width:800px){.breadcrumbs{display:none}}[role=treeitem][aria-selected=false]:hover{.treenode{background-color:var(--joy-palette-background-level1, #dedede)}}[role=treeitem][aria-selected=true]{outline:none}.resizeHandle{width:2px}.resizeHandle:hover,.resizeHandle:active{background-color:var(--joy-palette-primary-500, #0b6bcb)}.cyberismo-svg-wrapper svg{max-height:100vh}.doc .MuiButton-root{margin-top:12px}.doc table.tableblock{border-collapse:collapse}.doc{color:var(--joy-palette-text-primary, #333);font-size:inherit;-ms-hyphens:auto;hyphens:auto;line-height:1.6;margin:0;padding:0}@media screen and (min-width:1024px){.doc{-webkit-box-flex:1;-ms-flex:auto;flex:auto;font-size:.94444rem;margin:0;min-width:0}}.doc h1,.doc h2,.doc h3,.doc h4,.doc h5,.doc h6{color:var(--joy-palette-text-primary, #191919);font-weight:400;-ms-hyphens:none;hyphens:none;line-height:1.3;margin:1rem 0 0}.doc>h1.page:first-child{font-size:2rem;margin:1.5rem 0}@media screen and (min-width:769px){.doc>h1.page:first-child{margin-top:2.5rem}}.doc>h1.page:first-child+aside.toc.embedded{margin-top:-.5rem}.doc>h2#name+.sectionbody{margin-top:1rem}#preamble+.sect1,.doc .sect1+.sect1{margin-top:2rem}.doc h1.sect0{background:var(--joy-palette-background-surface, #f0f0f0);font-size:1.8em;margin:1.5rem -1rem 0;padding:.5rem 1rem}.doc h2:not(.discrete){border-bottom:1px solid var(--joy-palette-divider, #e1e1e1);margin-left:-1rem;margin-right:-1rem;padding:.4rem 1rem .1rem}.doc h3:not(.discrete),.doc h4:not(.discrete){font-weight:600}.doc h1 .anchor,.doc h2 .anchor,.doc h3 .anchor,.doc h4 .anchor,.doc h5 .anchor,.doc h6 .anchor{position:absolute;text-decoration:none;width:1.75ex;margin-left:-1.5ex;visibility:hidden;font-size:.8em;font-weight:400;padding-top:.05em}.doc h1 .anchor:before,.doc h2 .anchor:before,.doc h3 .anchor:before,.doc h4 .anchor:before,.doc h5 .anchor:before,.doc h6 .anchor:before{content:"§"}.doc h1:hover .anchor,.doc h2:hover .anchor,.doc h3:hover .anchor,.doc h4:hover .anchor,.doc h5:hover .anchor,.doc h6:hover .anchor{visibility:visible}.doc dl,.doc p{margin:0}.doc a{color:var(--joy-palette-primary-600, #1565c0)}.doc a:hover{color:var(--joy-palette-primary-700, #104d92)}.doc a.bare{-ms-hyphens:none;hyphens:none}.doc a.unresolved{color:var(--joy-palette-danger-500, #d32f2f)}.doc i.fa{-ms-hyphens:none;hyphens:none;font-style:normal}.doc .colist>table code,.doc p code,.doc thead code{color:var(--joy-palette-text-primary, #222);background:var(--joy-palette-background-level1, #fafafa);border-radius:.25em;font-size:.95em;padding:.125em .25em}.doc code,.doc pre{-ms-hyphens:none;hyphens:none}.doc pre{font-size:.88889rem;line-height:1.5;margin:0}.doc blockquote{margin:0}.doc .paragraph.lead>p{font-size:1rem}.doc .right{float:right}.doc .left{float:left}.doc .float-gap.right{margin:0 1rem 1rem 0}.doc .float-gap.left{margin:0 0 1rem 1rem}.doc .float-group:after{content:"";display:table;clear:both}.doc .text-left{text-align:left}.doc .text-center{text-align:center}.doc .text-right{text-align:right}.doc .text-justify{text-align:justify}.doc .stretch{width:100%}.doc .big{font-size:larger}.doc .small{font-size:smaller}.doc .underline{text-decoration:underline}.doc .line-through{text-decoration:line-through}.doc .dlist,.doc .exampleblock,.doc .hdlist,.doc .imageblock,.doc .listingblock,.doc .literalblock,.doc .olist,.doc .paragraph,.doc .partintro,.doc .quoteblock,.doc .sidebarblock,.doc .tabs,.doc .ulist,.doc .verseblock,.doc .videoblock,.doc details,.doc hr{margin:1rem 0 0}.doc .tablecontainer,.doc .tablecontainer+*,.doc :not(.tablecontainer)>table.tableblock,.doc :not(.tablecontainer)>table.tableblock+*,.doc>table.tableblock,.doc>table.tableblock+*{margin-top:1.5rem}.doc table.tableblock{font-size:.83333rem}.doc p.tableblock+p.tableblock{margin-top:.5rem}.doc table.tableblock pre{font-size:inherit}.doc td.tableblock>.content{word-wrap:anywhere}.doc td.tableblock>.content>:first-child{margin-top:0}.doc table.tableblock td{padding:.5rem}.doc table.tableblock th{padding:.5rem;background:var(--joy-palette-background-level1, #fbfcfe)}.doc table.tableblock,.doc table.tableblock>*>tr>*{border:0 solid var(--joy-palette-divider, #e1e1e1)}.doc table.grid-all>*>tr>*{border-width:1px}.doc table.grid-cols>*>tr>*{border-width:0 1px}.doc table.grid-rows>*>tr>*{border-width:1px 0}.doc table.grid-all>thead th,.doc table.grid-rows>thead th{border-bottom-width:2.5px}.doc table.frame-all{border-width:1px}.doc table.frame-ends{border-width:1px 0}.doc table.frame-sides{border-width:0 1px}.doc table.frame-none>colgroup+*>:first-child>*,.doc table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}.doc table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}.doc table.frame-ends>*>tr>:first-child,.doc table.frame-none>*>tr>:first-child{border-left-width:0}.doc table.frame-ends>*>tr>:last-child,.doc table.frame-none>*>tr>:last-child{border-right-width:0}.doc table.stripes-all>tbody>tr,.doc table.stripes-even>tbody>tr:nth-of-type(2n),.doc table.stripes-hover>tbody>tr:hover,.doc table.stripes-odd>tbody>tr:nth-of-type(odd){background:var(--joy-palette-background-level1, #fafafa)}.doc table.tableblock>tfoot{background:var(--joy-palette-background-surface, #f0f0f0)}.doc .halign-left{text-align:left}.doc .halign-right{text-align:right}.doc .halign-center{text-align:center}.doc .valign-top{vertical-align:top}.doc .valign-bottom{vertical-align:bottom}.doc .valign-middle{vertical-align:middle}.doc .admonitionblock{margin:1.4rem 0 0}.doc .admonitionblock p,.doc .admonitionblock td.content{font-size:.88889rem}.doc .admonitionblock td.content>.title+*,.doc .admonitionblock td.content>:not(.title):first-child{margin-top:0}.doc .admonitionblock td.content pre{font-size:.83333rem}.doc .admonitionblock>table{table-layout:fixed;position:relative;width:100%}.doc .admonitionblock td.content{padding:1rem 1rem .75rem;background:var(--joy-palette-background-level1, #fafafa);width:100%;word-wrap:anywhere}.doc .admonitionblock td.icon{font-size:.83333rem;left:0;line-height:1;padding:0;position:absolute;top:0;-webkit-transform:translate(-.5rem,-50%);transform:translate(-.5rem,-50%)}.doc .admonitionblock td.icon i{-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-radius:.45rem;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-filter:initial;filter:none;height:1.25rem;padding:0 .5rem;vertical-align:initial;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.doc .admonitionblock td.icon i:after{content:attr(title);font-weight:600;font-style:normal;text-transform:uppercase}.doc .admonitionblock td.icon i.icon-caution{background-color:#a0439c;color:#fff}.doc .admonitionblock td.icon i.icon-important{background-color:#d32f2f;color:#fff}.doc .admonitionblock td.icon i.icon-note{background-color:#217ee7;color:#fff}.doc .admonitionblock td.icon i.icon-tip{background-color:#41af46;color:#fff}.doc .admonitionblock td.icon i.icon-warning{background-color:#e18114;color:#fff}.doc .imageblock,.doc .videoblock{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.doc .imageblock .content{-ms-flex-item-align:stretch;align-self:stretch;text-align:center}.doc .imageblock.text-left,.doc .videoblock.text-left{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.doc .imageblock.text-left .content{text-align:left}.doc .imageblock.text-right,.doc .videoblock.text-right{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.doc .imageblock.text-right .content{text-align:right}.doc .image>img,.doc .image>object,.doc .image>svg,.doc .imageblock img,.doc .imageblock object,.doc .imageblock svg{display:inline-block;max-height:75vh;max-width:100%;vertical-align:middle}.doc .image:not(.left):not(.right)>img{margin-top:-.2em}.doc .videoblock iframe,.doc .videoblock video{max-width:100%;vertical-align:middle}#preamble .abstract blockquote{background:var(--joy-palette-background-surface, #f0f0f0);border-left:5px solid var(--joy-palette-divider, #e1e1e1);color:var(--joy-palette-text-secondary, #4a4a4a);font-size:.88889rem;padding:.75em 1em}.doc .quoteblock,.doc .verseblock{background:var(--joy-palette-background-level1, #fafafa);border-left:5px solid var(--joy-palette-neutral-500, #5d5d5d);color:var(--joy-palette-text-secondary, #5d5d5d)}.doc .quoteblock{padding:.25rem 2rem 1.25rem}.doc .quoteblock .attribution{color:var(--joy-palette-text-tertiary, #8e8e8e);font-size:.83333rem;margin-top:.75rem}.doc .quoteblock blockquote{margin-top:1rem}.doc .quoteblock .paragraph{font-style:italic}.doc .quoteblock cite{padding-left:1em}.doc .verseblock{font-size:1.15em;padding:1rem 2rem}.doc .verseblock pre{font-family:inherit;font-size:inherit}.doc ol,.doc ul{margin:0;padding:0 0 0 2rem}.doc ol.none,.doc ol.unnumbered,.doc ol.unstyled,.doc ul.checklist,.doc ul.no-bullet,.doc ul.none,.doc ul.unstyled{list-style-type:none}.doc ol.unnumbered,.doc ul.no-bullet{padding-left:1.25rem}.doc ol.unstyled,.doc ul.unstyled{padding-left:0}.doc ul.circle{list-style-type:circle}.doc ul.disc{list-style-type:disc}.doc ul.square{list-style-type:square}.doc ul.circle ul:not([class]),.doc ul.disc ul:not([class]),.doc ul.square ul:not([class]){list-style:inherit}.doc ol.arabic{list-style-type:decimal}.doc ol.decimal{list-style-type:decimal-leading-zero}.doc ol.loweralpha{list-style-type:lower-alpha}.doc ol.upperalpha{list-style-type:upper-alpha}.doc ol.lowerroman{list-style-type:lower-roman}.doc ol.upperroman{list-style-type:upper-roman}.doc ol.lowergreek{list-style-type:lower-greek}.doc ul.checklist{padding-left:1.75rem}.doc .dlist .dlist,.doc .dlist .olist,.doc .dlist .ulist,.doc .olist .dlist,.doc .olist .olist,.doc .olist .ulist,.doc .olist li+li,.doc .ulist .dlist,.doc .ulist .olist,.doc .ulist .ulist,.doc .ulist li+li{margin-top:.5rem}.doc .admonitionblock .listingblock,.doc .olist .listingblock,.doc .ulist .listingblock{padding:0}.doc .admonitionblock .title,.doc .exampleblock .title,.doc .imageblock .title,.doc .listingblock .title,.doc .literalblock .title,.doc .openblock .title,.doc .videoblock .title,.doc table.tableblock caption{color:var(--joy-palette-text-secondary, #5d5d5d);font-size:.88889rem;font-style:italic;font-weight:600;-ms-hyphens:none;hyphens:none;letter-spacing:.01em;padding-bottom:.075rem}.doc table.tableblock caption{text-align:left}.doc .olist .title,.doc .ulist .title{font-style:italic;font-weight:600;margin-bottom:.25rem}.doc .imageblock .title,.doc .videoblock .title{margin-top:.5rem;padding-bottom:0}.doc details{margin-left:1rem}.doc details>summary{display:block;position:relative;line-height:1.6;margin-bottom:.5rem}.doc details>summary::-webkit-details-marker{display:none}.doc details>summary:before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1rem;-webkit-transform:translateX(15%);transform:translate(15%)}.doc details[open]>summary:before{border-color:currentColor transparent transparent;border-width:.5rem .3rem 0;-webkit-transform:translateY(15%);transform:translateY(15%)}.doc details>summary:after{content:"";width:1rem;height:1em;position:absolute;top:.3em;left:-1rem}.doc details.result{margin-top:.25rem}.doc details.result>summary{color:var(--joy-palette-text-secondary, #5d5d5d);font-style:italic;margin-bottom:0}.doc details.result>.content{margin-left:-1rem}.doc .exampleblock>.content,.doc details.result>.content{background:var(--joy-palette-background-body, #fff);border:.25rem solid var(--joy-palette-neutral-500, #5d5d5d);border-radius:.5rem;padding:.75rem}.doc .exampleblock>.content:after,.doc details.result>.content:after{content:"";display:table;clear:both}.doc .exampleblock>.content>:first-child,.doc details>.content>:first-child{margin-top:0}.doc .sidebarblock{background:var(--joy-palette-neutral-softBg, #e1e1e1);border-radius:.75rem;padding:.75rem 1.5rem}.doc .sidebarblock>.content>.title{font-size:1.25rem;font-weight:600;line-height:1.3;margin-bottom:.5rem;text-align:center}.doc .sidebarblock>.content>.title+*,.doc .sidebarblock>.content>:not(.title):first-child{margin-top:0}.doc .listingblock.wrap pre,.doc table.tableblock pre{white-space:pre-wrap}.doc .listingblock pre:not(.highlight),.doc .literalblock pre,.doc pre.highlight>code{background:var(--joy-palette-background-level1, #fafafa);-webkit-box-shadow:inset 0 0 1.75px var(--joy-palette-divider, #e1e1e1);box-shadow:inset 0 0 1.75px var(--joy-palette-divider, #e1e1e1);display:block;overflow-x:auto;padding:.875em}.doc .listingblock>.content{position:relative}.doc .source-toolbox{display:-webkit-box;display:-ms-flexbox;display:flex;visibility:hidden;position:absolute;top:.25rem;right:.5rem;color:gray;font-family:Roboto,sans-serif;font-size:.72222rem;line-height:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1}.doc .listingblock:hover .source-toolbox{visibility:visible}.doc .source-toolbox .source-lang{text-transform:uppercase;letter-spacing:.075em}.doc .source-toolbox>:not(:last-child):after{content:"|";letter-spacing:0;padding:0 1ch}.doc .source-toolbox .copy-button{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:none;border:none;color:inherit;outline:none;padding:0;font-size:inherit;line-height:inherit;width:1em;height:1em}.doc .source-toolbox .copy-icon{-webkit-box-flex:0;-ms-flex:none;flex:none;width:inherit;height:inherit}.doc .source-toolbox img.copy-icon{-webkit-filter:invert(50.2%);filter:invert(50.2%)}.doc .source-toolbox svg.copy-icon{fill:currentColor}.doc .source-toolbox .copy-toast{-webkit-box-flex:0;-ms-flex:none;flex:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-top:1em;background-color:var(--joy-palette-neutral-800, #333);border-radius:.25em;padding:.5em;color:var(--joy-palette-common-white, #fff);cursor:auto;opacity:0;-webkit-transition:opacity .5s ease .5s;transition:opacity .5s ease .5s}.doc .source-toolbox .copy-toast:after{content:"";position:absolute;top:0;width:1em;height:1em;border:.55em solid transparent;border-left-color:var(--joy-palette-neutral-800, #333);-webkit-transform:rotate(-90deg) translateX(50%) translateY(50%);transform:rotate(-90deg) translate(50%) translateY(50%);-webkit-transform-origin:left;transform-origin:left}.doc .source-toolbox .copy-button.clicked .copy-toast{opacity:1;-webkit-transition:none;transition:none}.doc .language-console .hljs-meta{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.doc .dlist dt{font-style:italic}.doc .dlist dd{margin:0 0 0 1.5rem}.doc .dlist dd+dt,.doc .dlist dd>p:first-child{margin-top:.5rem}.doc td.hdlist1,.doc td.hdlist2{padding:.5rem 0 0;vertical-align:top}.doc tr:first-child>.hdlist1,.doc tr:first-child>.hdlist2{padding-top:0}.doc td.hdlist1{font-weight:600;padding-right:.25rem}.doc td.hdlist2{padding-left:.25rem}.doc .colist{font-size:.88889rem;margin:.25rem 0 -.25rem}.doc .colist>table>tbody>tr>:first-child,.doc .colist>table>tr>:first-child{padding:.25em .5rem 0;vertical-align:top}.doc .colist>table>tbody>tr>:last-child,.doc .colist>table>tr>:last-child{padding:.25rem 0}.doc .conum[data-value]{border:1px solid;border-radius:100%;display:inline-block;font-family:Roboto,sans-serif;font-size:.75rem;font-style:normal;line-height:1.2;text-align:center;width:1.25em;height:1.25em;letter-spacing:-.25ex;text-indent:-.25ex}.doc .conum[data-value]:after{content:attr(data-value)}.doc .conum[data-value]+b{display:none}.doc hr{border:solid var(--joy-palette-divider, #e1e1e1);border-width:2px 0 0;height:0}.doc b.button{white-space:nowrap}.doc b.button:before{content:"[";padding-right:.25em}.doc b.button:after{content:"]";padding-left:.25em}.doc kbd{display:inline-block;font-size:.66667rem;background:var(--joy-palette-background-level1, #fafafa);border:1px solid var(--joy-palette-neutral-400, #c1c1c1);border-radius:.25em;-webkit-box-shadow:0 1px 0 var(--joy-palette-neutral-400, #c1c1c1),0 0 0 .1em var(--joy-palette-background-body, #fff) inset;box-shadow:0 1px 0 var(--joy-palette-neutral-400, #c1c1c1),inset 0 0 0 .1em var(--joy-palette-background-body, #fff);padding:.25em .5em;vertical-align:text-bottom;white-space:nowrap}.doc .keyseq,.doc kbd{line-height:1}.doc .keyseq{font-size:.88889rem}.doc .keyseq kbd{margin:0 .125em}.doc .keyseq kbd:first-child{margin-left:0}.doc .keyseq kbd:last-child{margin-right:0}.doc .menuseq,.doc .path{-ms-hyphens:none;hyphens:none}.doc .menuseq i.caret:before{content:"›";font-size:1.1em;font-weight:600;line-height:.90909}.doc :not(pre).nowrap{white-space:nowrap}.doc .nobreak{-ms-hyphens:none;hyphens:none;word-wrap:normal}.doc :not(pre).pre-wrap{white-space:pre-wrap}#footnotes{font-size:.85em;line-height:1.5;margin:2rem -.5rem 0}.doc td.tableblock>.content #footnotes{margin:2rem 0 0}#footnotes hr{border-top-width:1px;margin-top:0;width:20%}#footnotes .footnote{margin:.5em 0 0 1em}#footnotes .footnote+.footnote{margin-top:.25em}#footnotes .footnote>a:first-of-type{display:inline-block;margin-left:-2em;text-align:right;width:1.5em}.toc-menu{color:var(--joy-palette-text-secondary, #5d5d5d)}.toc.sidebar .toc-menu{margin-right:.75rem;position:sticky;top:6rem}.toc .toc-menu h3{color:var(--joy-palette-text-primary, #333);font-size:.88889rem;font-weight:600;line-height:1.3;margin:0 -.5px;padding-bottom:.25rem}.toc.sidebar .toc-menu h3{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:2.5rem;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.toc .toc-menu ul{font-size:.83333rem;line-height:1.2;list-style:none;margin:0;padding:0}.toc.sidebar .toc-menu ul{max-height:calc(100vh - 8.5rem);overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none}@supports (scrollbar-width: none){.toc.sidebar .toc-menu ul{scrollbar-width:none}}.toc .toc-menu ul::-webkit-scrollbar{width:0;height:0}@media screen and (min-width:1024px){.toc .toc-menu h3{font-size:.83333rem}.toc .toc-menu ul{font-size:.75rem}}.toc .toc-menu li{margin:0}.toc .toc-menu li[data-level="2"] a{padding-left:1.25rem}.toc .toc-menu li[data-level="3"] a{padding-left:2rem}.toc .toc-menu a{color:inherit;border-left:2px solid var(--joy-palette-divider, #e1e1e1);display:inline-block;padding:.25rem 0 .25rem .5rem;text-decoration:none}.sidebar.toc .toc-menu a{display:block;outline:none}.toc .toc-menu a:hover{color:var(--joy-palette-primary-600, #1565c0)}.toc .toc-menu a.is-active{border-left-color:var(--joy-palette-primary-500, #2a7ee4);color:var(--joy-palette-primary-500, #2a7ee4)}.sidebar.toc .toc-menu a:focus{background:var(--joy-palette-background-level1, #fafafa)}.toc .toc-menu .is-hidden-toc{display:none!important}.contentSidebar{min-width:160px}.doc .videoblock .content{position:relative;width:100%;max-width:100%}.doc .videoblock .content:before{content:"";display:block;padding-top:56.25%}.doc .videoblock .content>iframe,.doc .videoblock .content>video{position:absolute;inset:0;width:100%!important;height:100%!important;border:0;background:#000;display:block}
|