@cratis/scene.engine 4.25.0 → 4.27.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/cjs/editing/resolveEffectiveConfiguration.js +8 -0
- package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -1
- package/dist/cjs/index.js +64 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/navigation/NavigationDiagnosticCode.js +5 -0
- package/dist/cjs/navigation/NavigationDiagnosticCode.js.map +1 -1
- package/dist/cjs/navigation/NavigationEditKind.js +16 -0
- package/dist/cjs/navigation/NavigationEditKind.js.map +1 -0
- package/dist/cjs/navigation/NavigationItemOrigin.js +14 -0
- package/dist/cjs/navigation/NavigationItemOrigin.js.map +1 -0
- package/dist/cjs/navigation/NavigationSourcesKind.js +16 -0
- package/dist/cjs/navigation/NavigationSourcesKind.js.map +1 -0
- package/dist/cjs/navigation/diagnoseNavigation.js +8 -1
- package/dist/cjs/navigation/diagnoseNavigation.js.map +1 -1
- package/dist/cjs/navigation/diagnoseNavigationRegions.js +99 -0
- package/dist/cjs/navigation/diagnoseNavigationRegions.js.map +1 -0
- package/dist/cjs/navigation/effectiveNavigation.js +133 -0
- package/dist/cjs/navigation/effectiveNavigation.js.map +1 -0
- package/dist/cjs/navigation/navigationEdits.js +230 -0
- package/dist/cjs/navigation/navigationEdits.js.map +1 -0
- package/dist/cjs/navigation/navigationRegions.js +42 -0
- package/dist/cjs/navigation/navigationRegions.js.map +1 -0
- package/dist/cjs/sampleData/SampleRandom.js +77 -0
- package/dist/cjs/sampleData/SampleRandom.js.map +1 -0
- package/dist/cjs/sampleData/describeSampleDataCatalog.js +61 -0
- package/dist/cjs/sampleData/describeSampleDataCatalog.js.map +1 -0
- package/dist/cjs/sampleData/findSampleDataSet.js +18 -0
- package/dist/cjs/sampleData/findSampleDataSet.js.map +1 -0
- package/dist/cjs/sampleData/findSampleRowLiterals.js +73 -0
- package/dist/cjs/sampleData/findSampleRowLiterals.js.map +1 -0
- package/dist/cjs/sampleData/generateSample.js +188 -0
- package/dist/cjs/sampleData/generateSample.js.map +1 -0
- package/dist/cjs/sampleData/inferSampleFieldKind.js +176 -0
- package/dist/cjs/sampleData/inferSampleFieldKind.js.map +1 -0
- package/dist/cjs/sampleData/resolveSampleData.js +107 -0
- package/dist/cjs/sampleData/resolveSampleData.js.map +1 -0
- package/dist/cjs/sampleData/sampleDataRules.js +26 -0
- package/dist/cjs/sampleData/sampleDataRules.js.map +1 -0
- package/dist/cjs/sampleData/sampleLocales.js +359 -0
- package/dist/cjs/sampleData/sampleLocales.js.map +1 -0
- package/dist/cjs/sampleData/validateSampleDataPack.js +44 -0
- package/dist/cjs/sampleData/validateSampleDataPack.js.map +1 -0
- package/dist/cjs/sampleData/validateSampleDataPackages.js +71 -0
- package/dist/cjs/sampleData/validateSampleDataPackages.js.map +1 -0
- package/dist/cjs/sampleData/validateSampleDataSelection.js +52 -0
- package/dist/cjs/sampleData/validateSampleDataSelection.js.map +1 -0
- package/dist/cjs/validateNavigationDestinations.js +2 -0
- package/dist/cjs/validateNavigationDestinations.js.map +1 -1
- package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -1
- package/dist/esm/editing/resolveEffectiveConfiguration.js +8 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +19 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/navigation/EffectiveNavItem.d.ts +14 -0
- package/dist/esm/navigation/EffectiveNavItem.d.ts.map +1 -0
- package/dist/esm/navigation/EffectiveNavItem.js +2 -0
- package/dist/esm/navigation/EffectiveNavItem.js.map +1 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.d.ts +11 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.d.ts.map +1 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.js +2 -0
- package/dist/esm/navigation/EffectiveNavigationRegion.js.map +1 -0
- package/dist/esm/navigation/NavigationDiagnosticCode.d.ts +6 -1
- package/dist/esm/navigation/NavigationDiagnosticCode.d.ts.map +1 -1
- package/dist/esm/navigation/NavigationDiagnosticCode.js +5 -0
- package/dist/esm/navigation/NavigationDiagnosticCode.js.map +1 -1
- package/dist/esm/navigation/NavigationEdit.d.ts +13 -0
- package/dist/esm/navigation/NavigationEdit.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEdit.js +2 -0
- package/dist/esm/navigation/NavigationEdit.js.map +1 -0
- package/dist/esm/navigation/NavigationEditKind.d.ts +7 -0
- package/dist/esm/navigation/NavigationEditKind.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditKind.js +14 -0
- package/dist/esm/navigation/NavigationEditKind.js.map +1 -0
- package/dist/esm/navigation/NavigationEditOutcome.d.ts +7 -0
- package/dist/esm/navigation/NavigationEditOutcome.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditOutcome.js +2 -0
- package/dist/esm/navigation/NavigationEditOutcome.js.map +1 -0
- package/dist/esm/navigation/NavigationEditPlan.d.ts +6 -0
- package/dist/esm/navigation/NavigationEditPlan.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationEditPlan.js +2 -0
- package/dist/esm/navigation/NavigationEditPlan.js.map +1 -0
- package/dist/esm/navigation/NavigationGraph.d.ts +4 -1
- package/dist/esm/navigation/NavigationGraph.d.ts.map +1 -1
- package/dist/esm/navigation/NavigationItemOrigin.d.ts +5 -0
- package/dist/esm/navigation/NavigationItemOrigin.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationItemOrigin.js +12 -0
- package/dist/esm/navigation/NavigationItemOrigin.js.map +1 -0
- package/dist/esm/navigation/NavigationSources.d.ts +6 -0
- package/dist/esm/navigation/NavigationSources.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationSources.js +2 -0
- package/dist/esm/navigation/NavigationSources.js.map +1 -0
- package/dist/esm/navigation/NavigationSourcesKind.d.ts +7 -0
- package/dist/esm/navigation/NavigationSourcesKind.d.ts.map +1 -0
- package/dist/esm/navigation/NavigationSourcesKind.js +14 -0
- package/dist/esm/navigation/NavigationSourcesKind.js.map +1 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.d.ts +6 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.d.ts.map +1 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.js +2 -0
- package/dist/esm/navigation/ResolvedNavigationTarget.js.map +1 -0
- package/dist/esm/navigation/diagnoseNavigation.d.ts.map +1 -1
- package/dist/esm/navigation/diagnoseNavigation.js +8 -1
- package/dist/esm/navigation/diagnoseNavigation.js.map +1 -1
- package/dist/esm/navigation/diagnoseNavigationRegions.d.ts +8 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.d.ts.map +1 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.js +97 -0
- package/dist/esm/navigation/diagnoseNavigationRegions.js.map +1 -0
- package/dist/esm/navigation/effectiveNavigation.d.ts +5 -0
- package/dist/esm/navigation/effectiveNavigation.d.ts.map +1 -0
- package/dist/esm/navigation/effectiveNavigation.js +131 -0
- package/dist/esm/navigation/effectiveNavigation.js.map +1 -0
- package/dist/esm/navigation/index.d.ts +14 -0
- package/dist/esm/navigation/index.d.ts.map +1 -1
- package/dist/esm/navigation/index.js +14 -0
- package/dist/esm/navigation/index.js.map +1 -1
- package/dist/esm/navigation/navigationEdits.d.ts +11 -0
- package/dist/esm/navigation/navigationEdits.d.ts.map +1 -0
- package/dist/esm/navigation/navigationEdits.js +225 -0
- package/dist/esm/navigation/navigationEdits.js.map +1 -0
- package/dist/esm/navigation/navigationRegions.d.ts +9 -0
- package/dist/esm/navigation/navigationRegions.d.ts.map +1 -0
- package/dist/esm/navigation/navigationRegions.js +34 -0
- package/dist/esm/navigation/navigationRegions.js.map +1 -0
- package/dist/esm/sampleData/SampleDataPackSource.d.ts +6 -0
- package/dist/esm/sampleData/SampleDataPackSource.d.ts.map +1 -0
- package/dist/esm/sampleData/SampleDataPackSource.js +2 -0
- package/dist/esm/sampleData/SampleDataPackSource.js.map +1 -0
- package/dist/esm/sampleData/SampleDataResolution.d.ts +29 -0
- package/dist/esm/sampleData/SampleDataResolution.d.ts.map +1 -0
- package/dist/esm/sampleData/SampleDataResolution.js +2 -0
- package/dist/esm/sampleData/SampleDataResolution.js.map +1 -0
- package/dist/esm/sampleData/SampleRandom.d.ts +14 -0
- package/dist/esm/sampleData/SampleRandom.d.ts.map +1 -0
- package/dist/esm/sampleData/SampleRandom.js +72 -0
- package/dist/esm/sampleData/SampleRandom.js.map +1 -0
- package/dist/esm/sampleData/describeSampleDataCatalog.d.ts +24 -0
- package/dist/esm/sampleData/describeSampleDataCatalog.d.ts.map +1 -0
- package/dist/esm/sampleData/describeSampleDataCatalog.js +57 -0
- package/dist/esm/sampleData/describeSampleDataCatalog.js.map +1 -0
- package/dist/esm/sampleData/findSampleDataSet.d.ts +3 -0
- package/dist/esm/sampleData/findSampleDataSet.d.ts.map +1 -0
- package/dist/esm/sampleData/findSampleDataSet.js +16 -0
- package/dist/esm/sampleData/findSampleDataSet.js.map +1 -0
- package/dist/esm/sampleData/findSampleRowLiterals.d.ts +11 -0
- package/dist/esm/sampleData/findSampleRowLiterals.d.ts.map +1 -0
- package/dist/esm/sampleData/findSampleRowLiterals.js +69 -0
- package/dist/esm/sampleData/findSampleRowLiterals.js.map +1 -0
- package/dist/esm/sampleData/generateSample.d.ts +6 -0
- package/dist/esm/sampleData/generateSample.d.ts.map +1 -0
- package/dist/esm/sampleData/generateSample.js +183 -0
- package/dist/esm/sampleData/generateSample.js.map +1 -0
- package/dist/esm/sampleData/index.d.ts +15 -0
- package/dist/esm/sampleData/index.d.ts.map +1 -0
- package/dist/esm/sampleData/index.js +15 -0
- package/dist/esm/sampleData/index.js.map +1 -0
- package/dist/esm/sampleData/inferSampleFieldKind.d.ts +3 -0
- package/dist/esm/sampleData/inferSampleFieldKind.d.ts.map +1 -0
- package/dist/esm/sampleData/inferSampleFieldKind.js +174 -0
- package/dist/esm/sampleData/inferSampleFieldKind.js.map +1 -0
- package/dist/esm/sampleData/resolveSampleData.d.ts +3 -0
- package/dist/esm/sampleData/resolveSampleData.d.ts.map +1 -0
- package/dist/esm/sampleData/resolveSampleData.js +105 -0
- package/dist/esm/sampleData/resolveSampleData.js.map +1 -0
- package/dist/esm/sampleData/sampleDataRules.d.ts +7 -0
- package/dist/esm/sampleData/sampleDataRules.d.ts.map +1 -0
- package/dist/esm/sampleData/sampleDataRules.js +19 -0
- package/dist/esm/sampleData/sampleDataRules.js.map +1 -0
- package/dist/esm/sampleData/sampleLocales.d.ts +13 -0
- package/dist/esm/sampleData/sampleLocales.d.ts.map +1 -0
- package/dist/esm/sampleData/sampleLocales.js +355 -0
- package/dist/esm/sampleData/sampleLocales.js.map +1 -0
- package/dist/esm/sampleData/validateSampleDataPack.d.ts +3 -0
- package/dist/esm/sampleData/validateSampleDataPack.d.ts.map +1 -0
- package/dist/esm/sampleData/validateSampleDataPack.js +42 -0
- package/dist/esm/sampleData/validateSampleDataPack.js.map +1 -0
- package/dist/esm/sampleData/validateSampleDataPackages.d.ts +3 -0
- package/dist/esm/sampleData/validateSampleDataPackages.d.ts.map +1 -0
- package/dist/esm/sampleData/validateSampleDataPackages.js +69 -0
- package/dist/esm/sampleData/validateSampleDataPackages.js.map +1 -0
- package/dist/esm/sampleData/validateSampleDataSelection.d.ts +3 -0
- package/dist/esm/sampleData/validateSampleDataSelection.d.ts.map +1 -0
- package/dist/esm/sampleData/validateSampleDataSelection.js +50 -0
- package/dist/esm/sampleData/validateSampleDataSelection.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/validateNavigationDestinations.js +2 -0
- package/dist/esm/validateNavigationDestinations.js.map +1 -1
- package/editing/resolveEffectiveConfiguration.ts +13 -0
- package/index.ts +1 -0
- package/navigation/EffectiveNavItem.ts +37 -0
- package/navigation/EffectiveNavigationRegion.ts +26 -0
- package/navigation/NavigationDiagnosticCode.ts +15 -0
- package/navigation/NavigationEdit.ts +36 -0
- package/navigation/NavigationEditKind.ts +19 -0
- package/navigation/NavigationEditOutcome.ts +18 -0
- package/navigation/NavigationEditPlan.ts +15 -0
- package/navigation/NavigationGraph.ts +10 -1
- package/navigation/NavigationItemOrigin.ts +13 -0
- package/navigation/NavigationSources.ts +15 -0
- package/navigation/NavigationSourcesKind.ts +19 -0
- package/navigation/ResolvedNavigationTarget.ts +19 -0
- package/navigation/diagnoseNavigation.ts +7 -1
- package/navigation/diagnoseNavigationRegions.ts +122 -0
- package/navigation/effectiveNavigation.ts +105 -0
- package/navigation/index.ts +14 -0
- package/navigation/navigationEdits.ts +176 -0
- package/navigation/navigationRegions.ts +39 -0
- package/package.json +3 -3
- package/sampleData/SampleDataPackSource.ts +13 -0
- package/sampleData/SampleDataResolution.ts +93 -0
- package/sampleData/SampleRandom.ts +85 -0
- package/sampleData/describeSampleDataCatalog.ts +108 -0
- package/sampleData/findSampleDataSet.ts +18 -0
- package/sampleData/findSampleRowLiterals.ts +86 -0
- package/sampleData/generateSample.ts +156 -0
- package/sampleData/index.ts +17 -0
- package/sampleData/inferSampleFieldKind.ts +64 -0
- package/sampleData/resolveSampleData.ts +96 -0
- package/sampleData/sampleDataRules.ts +30 -0
- package/sampleData/sampleLocales.ts +91 -0
- package/sampleData/validateSampleDataPack.ts +48 -0
- package/sampleData/validateSampleDataPackages.ts +79 -0
- package/sampleData/validateSampleDataSelection.ts +55 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DestinationKind } from '@cratis/scene.model';
|
|
2
2
|
import { collectOutlets } from './collectOutlets.js';
|
|
3
|
+
import { diagnoseNavigationRegions } from './diagnoseNavigationRegions.js';
|
|
3
4
|
import { findHostingCycles } from './findHostingCycles.js';
|
|
4
5
|
import { NavigationDiagnosticCode } from './NavigationDiagnosticCode.js';
|
|
5
6
|
import { authoredRouteKey, navigationTarget } from './navigationRoute.js';
|
|
@@ -12,7 +13,8 @@ import { authoredRouteKey, navigationTarget } from './navigationRoute.js';
|
|
|
12
13
|
*
|
|
13
14
|
* Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no
|
|
14
15
|
* URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and
|
|
15
|
-
* messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`.
|
|
16
|
+
* messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`. When the graph carries
|
|
17
|
+
an application `structure` and `navigation` regions, the regions are checked too ({@link diagnoseNavigationRegions}).
|
|
16
18
|
*/ function diagnoseNavigation(graph, routeKey = authoredRouteKey) {
|
|
17
19
|
const diagnostics = [];
|
|
18
20
|
const outlets = collectOutlets(graph, diagnostics);
|
|
@@ -69,6 +71,11 @@ import { authoredRouteKey, navigationTarget } from './navigationRoute.js';
|
|
|
69
71
|
].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`
|
|
70
72
|
});
|
|
71
73
|
}
|
|
74
|
+
if (graph.structure && graph.navigation) {
|
|
75
|
+
diagnostics.push(...diagnoseNavigationRegions(graph.structure, graph.navigation, {
|
|
76
|
+
slots: graph.slots
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
72
79
|
return diagnostics;
|
|
73
80
|
}
|
|
74
81
|
function diagnoseTarget(graph, screens, destination, kind, entry, report) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnoseNavigation.js","sources":["../../../navigation/diagnoseNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DestinationKind, DestinationReference, Screen } from '@cratis/scene.model';\nimport { collectOutlets } from './collectOutlets';\nimport { findHostingCycles } from './findHostingCycles';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { NavigationGraph } from './NavigationGraph';\nimport { NavigationRouteKey, authoredRouteKey, navigationTarget } from './navigationRoute';\nimport { OutletOwner } from './OutletOwner';\n\n/**\n * Diagnoses how destinations, outlets, routes and targets fit together: duplicate routes, duplicate,\n * missing or incompatible outlets, hosting cycles and unavailable targets.\n *\n * Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no\n * URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and\n * messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`.\n */\nexport function diagnoseNavigation(graph: NavigationGraph, routeKey: NavigationRouteKey = authoredRouteKey): NavigationDiagnostic[] {\n const diagnostics: NavigationDiagnostic[] = [];\n const outlets = collectOutlets(graph, diagnostics);\n const screens = graph.screens ? new Map(graph.screens.map(screen => [screen.name, screen])) : undefined;\n const routes = new Map<string, { entry: string; target: string }>();\n const hostedIn = new Map<string, string[]>();\n\n graph.entries.forEach((navigationEntry, index) => {\n const entry = navigationEntry.id ?? `#${index + 1}`;\n const destination = navigationEntry.destination;\n const kind = destination.kind ?? (destination.dialog ? DestinationKind.Dialog : DestinationKind.Outlet);\n const report = (code: NavigationDiagnosticCode, message: string) => diagnostics.push({ code, message, entry });\n\n if (!destination.screen && !destination.module && !destination.route && !destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' names no screen, stable identity, route or dialog.`);\n return;\n }\n\n diagnoseTarget(graph, screens, destination, kind, entry, report);\n const owner = diagnoseOutlet(graph, outlets, screens, destination, kind, entry, report);\n if (owner?.ownerKind === 'ScreenTemplate' && destination.screen && screens?.has(destination.screen)) {\n const hosts = graph.screens!.filter(screen => screen.screenTemplate === owner.owner).map(screen => screen.name);\n hostedIn.set(destination.screen, [...new Set([...(hostedIn.get(destination.screen) ?? []), ...hosts])]);\n }\n\n const route = kind === DestinationKind.External ? undefined : routeKey(destination);\n if (route) {\n const target = navigationTarget(destination, kind);\n const existing = routes.get(route);\n if (!existing) {\n routes.set(route, { entry, target });\n } else if (existing.target !== target) {\n report(NavigationDiagnosticCode.DuplicateRoute, `Route '${destination.route ?? route}' is used by destinations '${existing.entry}' and '${entry}', which open different targets.`);\n }\n }\n });\n\n for (const cycle of findHostingCycles(graph.screens?.map(screen => screen.name) ?? [], hostedIn)) {\n diagnostics.push({\n code: NavigationDiagnosticCode.NavigationCycle,\n message: `Navigation cycle ${[...cycle, cycle[0]].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`,\n });\n }\n\n return diagnostics;\n}\n\ntype Report = (code: NavigationDiagnosticCode, message: string) => void;\n\nfunction diagnoseTarget(\n graph: NavigationGraph,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n) {\n if (kind === DestinationKind.Dialog) {\n if (!destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Dialog destination '${entry}' names no dialog.`);\n } else if (graph.dialogTemplates && !graph.dialogTemplates.some(template => template.name === destination.dialog)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens dialog '${destination.dialog}', which no dialog template provides.`);\n }\n return;\n }\n\n if (kind === DestinationKind.Outlet && destination.screen && screens && !screens.has(destination.screen)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens screen '${destination.screen}', which does not exist.`);\n }\n}\n\nfunction diagnoseOutlet(\n graph: NavigationGraph,\n outlets: Map<string, OutletOwner>,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n): OutletOwner | undefined {\n if (!destination.outlet) return undefined;\n\n if (kind !== DestinationKind.Outlet) {\n const opens = kind === DestinationKind.Dialog ? 'a dialog' : 'an external target';\n report(NavigationDiagnosticCode.IncompatibleOutlet, `Destination '${entry}' opens ${opens} but names outlet '${destination.outlet}'; only outlet destinations render in outlets.`);\n return undefined;\n }\n\n const owner = outlets.get(destination.outlet);\n if (!owner) {\n report(NavigationDiagnosticCode.MissingOutlet, `Destination '${entry}' targets missing outlet '${destination.outlet}'.`);\n return undefined;\n }\n\n const screen = destination.screen ? screens?.get(destination.screen) : undefined;\n if (!screen) return owner;\n\n if (owner.ownerKind === 'Layout' && screen.layout !== owner.owner) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' belongs to layout '${owner.owner}', but destination '${entry}' places '${screen.name}', which renders in layout '${screen.layout}'.`,\n );\n }\n\n if (owner.outlet.accepts) {\n const type = graph.screenTemplates?.find(template => template.name === screen.screenTemplate)?.metadata?.type;\n if (!type || !owner.outlet.accepts.includes(type)) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' accepts ${owner.outlet.accepts.join(', ')} screens, but destination '${entry}' places '${screen.name}' of type '${type ?? 'untyped'}'.`,\n );\n }\n }\n\n return owner;\n}\n"],"names":["diagnoseNavigation","graph","routeKey","authoredRouteKey","diagnostics","outlets","collectOutlets","screens","Map","map","screen","name","undefined","routes","hostedIn","entries","forEach","navigationEntry","index","entry","id","destination","kind","dialog","DestinationKind","Dialog","Outlet","report","code","message","push","module","route","NavigationDiagnosticCode","UnavailableTarget","diagnoseTarget","owner","diagnoseOutlet","ownerKind","has","hosts","filter","screenTemplate","set","Set","get","External","target","navigationTarget","existing","DuplicateRoute","cycle","findHostingCycles","NavigationCycle","join","dialogTemplates","some","template","outlet","opens","IncompatibleOutlet","MissingOutlet","layout","accepts","type","screenTemplates","find","metadata","includes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"diagnoseNavigation.js","sources":["../../../navigation/diagnoseNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DestinationKind, DestinationReference, Screen } from '@cratis/scene.model';\nimport { collectOutlets } from './collectOutlets';\nimport { diagnoseNavigationRegions } from './diagnoseNavigationRegions';\nimport { findHostingCycles } from './findHostingCycles';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { NavigationGraph } from './NavigationGraph';\nimport { NavigationRouteKey, authoredRouteKey, navigationTarget } from './navigationRoute';\nimport { OutletOwner } from './OutletOwner';\n\n/**\n * Diagnoses how destinations, outlets, routes and targets fit together: duplicate routes, duplicate,\n * missing or incompatible outlets, hosting cycles and unavailable targets.\n *\n * Routes are compared by `routeKey` - by default the authored route override, since the engine constructs no\n * URLs. Nothing is rewritten. The C# engine (`NavigationDiagnostics.Diagnose`) reports the same codes and\n * messages in the same order for the same model; both are asserted against `navigation-diagnostic-fixtures.json`. When the graph carries\nan application `structure` and `navigation` regions, the regions are checked too ({@link diagnoseNavigationRegions}).\n */\nexport function diagnoseNavigation(graph: NavigationGraph, routeKey: NavigationRouteKey = authoredRouteKey): NavigationDiagnostic[] {\n const diagnostics: NavigationDiagnostic[] = [];\n const outlets = collectOutlets(graph, diagnostics);\n const screens = graph.screens ? new Map(graph.screens.map(screen => [screen.name, screen])) : undefined;\n const routes = new Map<string, { entry: string; target: string }>();\n const hostedIn = new Map<string, string[]>();\n\n graph.entries.forEach((navigationEntry, index) => {\n const entry = navigationEntry.id ?? `#${index + 1}`;\n const destination = navigationEntry.destination;\n const kind = destination.kind ?? (destination.dialog ? DestinationKind.Dialog : DestinationKind.Outlet);\n const report = (code: NavigationDiagnosticCode, message: string) => diagnostics.push({ code, message, entry });\n\n if (!destination.screen && !destination.module && !destination.route && !destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' names no screen, stable identity, route or dialog.`);\n return;\n }\n\n diagnoseTarget(graph, screens, destination, kind, entry, report);\n const owner = diagnoseOutlet(graph, outlets, screens, destination, kind, entry, report);\n if (owner?.ownerKind === 'ScreenTemplate' && destination.screen && screens?.has(destination.screen)) {\n const hosts = graph.screens!.filter(screen => screen.screenTemplate === owner.owner).map(screen => screen.name);\n hostedIn.set(destination.screen, [...new Set([...(hostedIn.get(destination.screen) ?? []), ...hosts])]);\n }\n\n const route = kind === DestinationKind.External ? undefined : routeKey(destination);\n if (route) {\n const target = navigationTarget(destination, kind);\n const existing = routes.get(route);\n if (!existing) {\n routes.set(route, { entry, target });\n } else if (existing.target !== target) {\n report(NavigationDiagnosticCode.DuplicateRoute, `Route '${destination.route ?? route}' is used by destinations '${existing.entry}' and '${entry}', which open different targets.`);\n }\n }\n });\n\n for (const cycle of findHostingCycles(graph.screens?.map(screen => screen.name) ?? [], hostedIn)) {\n diagnostics.push({\n code: NavigationDiagnosticCode.NavigationCycle,\n message: `Navigation cycle ${[...cycle, cycle[0]].join(' -> ')}: each screen is placed in an outlet owned by the next, so composition never terminates.`,\n });\n }\n\n if (graph.structure && graph.navigation) {\n diagnostics.push(...diagnoseNavigationRegions(graph.structure, graph.navigation, { slots: graph.slots }));\n }\n\n return diagnostics;\n}\n\ntype Report = (code: NavigationDiagnosticCode, message: string) => void;\n\nfunction diagnoseTarget(\n graph: NavigationGraph,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n) {\n if (kind === DestinationKind.Dialog) {\n if (!destination.dialog) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Dialog destination '${entry}' names no dialog.`);\n } else if (graph.dialogTemplates && !graph.dialogTemplates.some(template => template.name === destination.dialog)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens dialog '${destination.dialog}', which no dialog template provides.`);\n }\n return;\n }\n\n if (kind === DestinationKind.Outlet && destination.screen && screens && !screens.has(destination.screen)) {\n report(NavigationDiagnosticCode.UnavailableTarget, `Destination '${entry}' opens screen '${destination.screen}', which does not exist.`);\n }\n}\n\nfunction diagnoseOutlet(\n graph: NavigationGraph,\n outlets: Map<string, OutletOwner>,\n screens: Map<string, Screen> | undefined,\n destination: DestinationReference,\n kind: DestinationKind,\n entry: string,\n report: Report,\n): OutletOwner | undefined {\n if (!destination.outlet) return undefined;\n\n if (kind !== DestinationKind.Outlet) {\n const opens = kind === DestinationKind.Dialog ? 'a dialog' : 'an external target';\n report(NavigationDiagnosticCode.IncompatibleOutlet, `Destination '${entry}' opens ${opens} but names outlet '${destination.outlet}'; only outlet destinations render in outlets.`);\n return undefined;\n }\n\n const owner = outlets.get(destination.outlet);\n if (!owner) {\n report(NavigationDiagnosticCode.MissingOutlet, `Destination '${entry}' targets missing outlet '${destination.outlet}'.`);\n return undefined;\n }\n\n const screen = destination.screen ? screens?.get(destination.screen) : undefined;\n if (!screen) return owner;\n\n if (owner.ownerKind === 'Layout' && screen.layout !== owner.owner) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' belongs to layout '${owner.owner}', but destination '${entry}' places '${screen.name}', which renders in layout '${screen.layout}'.`,\n );\n }\n\n if (owner.outlet.accepts) {\n const type = graph.screenTemplates?.find(template => template.name === screen.screenTemplate)?.metadata?.type;\n if (!type || !owner.outlet.accepts.includes(type)) {\n report(\n NavigationDiagnosticCode.IncompatibleOutlet,\n `Outlet '${owner.outlet.name}' accepts ${owner.outlet.accepts.join(', ')} screens, but destination '${entry}' places '${screen.name}' of type '${type ?? 'untyped'}'.`,\n );\n }\n }\n\n return owner;\n}\n"],"names":["diagnoseNavigation","graph","routeKey","authoredRouteKey","diagnostics","outlets","collectOutlets","screens","Map","map","screen","name","undefined","routes","hostedIn","entries","forEach","navigationEntry","index","entry","id","destination","kind","dialog","DestinationKind","Dialog","Outlet","report","code","message","push","module","route","NavigationDiagnosticCode","UnavailableTarget","diagnoseTarget","owner","diagnoseOutlet","ownerKind","has","hosts","filter","screenTemplate","set","Set","get","External","target","navigationTarget","existing","DuplicateRoute","cycle","findHostingCycles","NavigationCycle","join","structure","navigation","diagnoseNavigationRegions","slots","dialogTemplates","some","template","outlet","opens","IncompatibleOutlet","MissingOutlet","layout","accepts","type","screenTemplates","find","metadata","includes"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ApplicationStructure, NavigationModel } from '@cratis/scene.model';
|
|
2
|
+
import { ApplicationStructureIndex } from '../structure';
|
|
3
|
+
import { NavigationDiagnostic } from './NavigationDiagnostic';
|
|
4
|
+
export interface NavigationRegionDiagnosticOptions {
|
|
5
|
+
slots?: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function diagnoseNavigationRegions(structure: ApplicationStructure | ApplicationStructureIndex, navigation: NavigationModel, options?: NavigationRegionDiagnosticOptions): NavigationDiagnostic[];
|
|
8
|
+
//# sourceMappingURL=diagnoseNavigationRegions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnoseNavigationRegions.d.ts","sourceRoot":"","sources":["../../../navigation/diagnoseNavigationRegions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAyE,MAAM,qBAAqB,CAAC;AACnJ,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAK9D,MAAM,WAAW,iCAAiC;IAE9C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAgBD,wBAAgB,yBAAyB,CACrC,SAAS,EAAE,oBAAoB,GAAG,yBAAyB,EAC3D,UAAU,EAAE,eAAe,EAC3B,OAAO,GAAE,iCAAsC,GAChD,oBAAoB,EAAE,CAqBxB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { NavigationRegionMode, NavigationRegionKind } from '@cratis/scene.model';
|
|
2
|
+
import { ApplicationStructureIndex } from '../structure/ApplicationStructureIndex.js';
|
|
3
|
+
import { NavigationDiagnosticCode } from './NavigationDiagnosticCode.js';
|
|
4
|
+
import { primarySlot, navigationRegionOrder, findNavigationRegion, collectItemIds, applicationItems } from './navigationRegions.js';
|
|
5
|
+
|
|
6
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
7
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
8
|
+
/**
|
|
9
|
+
* Diagnoses the navigation regions of an application against its structure: duplicate item ids, targets that are
|
|
10
|
+
* missing, out of scope or lead nowhere, and slots the layout does not declare. The application is checked first,
|
|
11
|
+
* then each module in the order they are declared; within a level the topbar comes before the sidebar and items are
|
|
12
|
+
* visited depth first.
|
|
13
|
+
*
|
|
14
|
+
* The C# engine (`NavigationRegionDiagnostics`) reports the same codes and messages in the same order; both are
|
|
15
|
+
* asserted against `navigation-inheritance-fixtures.json`, `navigation-targets-fixtures.json` and
|
|
16
|
+
* `navigation-diagnostic-fixtures.json`.
|
|
17
|
+
*
|
|
18
|
+
* @param structure The modules, features and slices of the application.
|
|
19
|
+
* @param navigation The application and module regions.
|
|
20
|
+
* @param options The slots items may render into.
|
|
21
|
+
*/ function diagnoseNavigationRegions(structure, navigation, options = {}) {
|
|
22
|
+
const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);
|
|
23
|
+
const slots = options.slots ?? [
|
|
24
|
+
primarySlot
|
|
25
|
+
];
|
|
26
|
+
const diagnostics = [];
|
|
27
|
+
for (const region of navigationRegionOrder){
|
|
28
|
+
const defined = findNavigationRegion(navigation.application.regions, region);
|
|
29
|
+
if (defined) checkRegion(index, slots, diagnostics, undefined, defined, []);
|
|
30
|
+
}
|
|
31
|
+
for (const moduleNavigation of navigation.modules){
|
|
32
|
+
for (const region of navigationRegionOrder){
|
|
33
|
+
const defined = findNavigationRegion(moduleNavigation.regions, region);
|
|
34
|
+
if (!defined) continue;
|
|
35
|
+
const inherited = defined.mode === NavigationRegionMode.Extend ? collectItemIds(applicationItems(navigation.application, region), region) : [];
|
|
36
|
+
checkRegion(index, slots, diagnostics, moduleNavigation.module, defined, inherited);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return diagnostics;
|
|
40
|
+
}
|
|
41
|
+
function checkRegion(index, slots, diagnostics, owner, defined, applicationIds) {
|
|
42
|
+
const scope = owner === undefined ? 'the application' : `module '${owner}'`;
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
const visit = (items)=>{
|
|
45
|
+
for (const item of items){
|
|
46
|
+
const entry = `${owner ?? 'application'}:${defined.region}:${item.id}`;
|
|
47
|
+
const report = (code, message)=>{
|
|
48
|
+
diagnostics.push({
|
|
49
|
+
code,
|
|
50
|
+
message,
|
|
51
|
+
entry
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
if (seen.has(item.id)) {
|
|
55
|
+
report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' is used more than once in ${scope} ${defined.region}.`);
|
|
56
|
+
} else if (applicationIds.includes(item.id)) {
|
|
57
|
+
report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' in ${scope} ${defined.region} is also used by an application item, and the region extends the application.`);
|
|
58
|
+
}
|
|
59
|
+
seen.add(item.id);
|
|
60
|
+
checkTarget(index, owner, item, report);
|
|
61
|
+
const slot = item.slot ?? primarySlot;
|
|
62
|
+
if (!slots.includes(slot)) {
|
|
63
|
+
report(NavigationDiagnosticCode.NavSlotUnknown, `Navigation item '${item.id}' renders into slot '${slot}', which the layout does not declare.`);
|
|
64
|
+
}
|
|
65
|
+
if (defined.region === NavigationRegionKind.Sidebar && item.children) visit(item.children);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
visit(defined.items);
|
|
69
|
+
}
|
|
70
|
+
function checkTarget(index, owner, item, report) {
|
|
71
|
+
const module = item.target?.module;
|
|
72
|
+
const hasChildren = (item.children?.length ?? 0) > 0;
|
|
73
|
+
if (!module) {
|
|
74
|
+
// A sidebar item that only groups sub-items needs no target of its own.
|
|
75
|
+
if (!hasChildren) report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' has no target.`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (!index.findModule(module)) {
|
|
79
|
+
report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets module '${module}', which does not exist.`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (owner !== undefined && module !== owner) {
|
|
83
|
+
report(NavigationDiagnosticCode.NavTargetOutOfScope, `Navigation item '${item.id}' of module '${owner}' targets module '${module}'; a module's own items may only target that module.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const feature = item.target?.feature;
|
|
87
|
+
if (feature) {
|
|
88
|
+
if (!index.findFeature(`${module}.${feature}`)) {
|
|
89
|
+
report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets feature '${module}.${feature}', which does not exist.`);
|
|
90
|
+
}
|
|
91
|
+
} else if (!index.firstFeature(module)) {
|
|
92
|
+
report(NavigationDiagnosticCode.NavModuleWithoutFeatures, `Navigation item '${item.id}' targets module '${module}', which has no features to go to.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { diagnoseNavigationRegions };
|
|
97
|
+
//# sourceMappingURL=diagnoseNavigationRegions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnoseNavigationRegions.js","sources":["../../../navigation/diagnoseNavigationRegions.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ApplicationStructure, NavigationModel, NavigationRegion, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\nimport { ApplicationStructureIndex } from '../structure';\nimport { NavigationDiagnostic } from './NavigationDiagnostic';\nimport { NavigationDiagnosticCode } from './NavigationDiagnosticCode';\nimport { applicationItems, collectItemIds, findNavigationRegion, navigationRegionOrder, primarySlot } from './navigationRegions';\n\n/** What the region diagnostics are checked against. */\nexport interface NavigationRegionDiagnosticOptions {\n /** The rendering slots items may render into; `content` only when absent. */\n slots?: string[];\n}\n\n/**\n * Diagnoses the navigation regions of an application against its structure: duplicate item ids, targets that are\n * missing, out of scope or lead nowhere, and slots the layout does not declare. The application is checked first,\n * then each module in the order they are declared; within a level the topbar comes before the sidebar and items are\n * visited depth first.\n *\n * The C# engine (`NavigationRegionDiagnostics`) reports the same codes and messages in the same order; both are\n * asserted against `navigation-inheritance-fixtures.json`, `navigation-targets-fixtures.json` and\n * `navigation-diagnostic-fixtures.json`.\n *\n * @param structure The modules, features and slices of the application.\n * @param navigation The application and module regions.\n * @param options The slots items may render into.\n */\nexport function diagnoseNavigationRegions(\n structure: ApplicationStructure | ApplicationStructureIndex,\n navigation: NavigationModel,\n options: NavigationRegionDiagnosticOptions = {},\n): NavigationDiagnostic[] {\n const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);\n const slots = options.slots ?? [primarySlot];\n const diagnostics: NavigationDiagnostic[] = [];\n\n for (const region of navigationRegionOrder) {\n const defined = findNavigationRegion(navigation.application.regions, region);\n if (defined) checkRegion(index, slots, diagnostics, undefined, defined, []);\n }\n\n for (const moduleNavigation of navigation.modules) {\n for (const region of navigationRegionOrder) {\n const defined = findNavigationRegion(moduleNavigation.regions, region);\n if (!defined) continue;\n\n const inherited = defined.mode === NavigationRegionMode.Extend ? collectItemIds(applicationItems(navigation.application, region), region) : [];\n checkRegion(index, slots, diagnostics, moduleNavigation.module, defined, inherited);\n }\n }\n\n return diagnostics;\n}\n\nfunction checkRegion(\n index: ApplicationStructureIndex,\n slots: string[],\n diagnostics: NavigationDiagnostic[],\n owner: string | undefined,\n defined: NavigationRegion,\n applicationIds: string[],\n): void {\n const scope = owner === undefined ? 'the application' : `module '${owner}'`;\n const seen = new Set<string>();\n\n const visit = (items: NavItem[]): void => {\n for (const item of items) {\n const entry = `${owner ?? 'application'}:${defined.region}:${item.id}`;\n const report = (code: NavigationDiagnosticCode, message: string): void => { diagnostics.push({ code, message, entry }); };\n\n if (seen.has(item.id)) {\n report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' is used more than once in ${scope} ${defined.region}.`);\n } else if (applicationIds.includes(item.id)) {\n report(NavigationDiagnosticCode.NavDuplicateId, `Navigation item '${item.id}' in ${scope} ${defined.region} is also used by an application item, and the region extends the application.`);\n }\n seen.add(item.id);\n\n checkTarget(index, owner, item, report);\n\n const slot = item.slot ?? primarySlot;\n if (!slots.includes(slot)) {\n report(NavigationDiagnosticCode.NavSlotUnknown, `Navigation item '${item.id}' renders into slot '${slot}', which the layout does not declare.`);\n }\n\n if (defined.region === NavigationRegionKind.Sidebar && item.children) visit(item.children);\n }\n };\n\n visit(defined.items);\n}\n\nfunction checkTarget(index: ApplicationStructureIndex, owner: string | undefined, item: NavItem, report: (code: NavigationDiagnosticCode, message: string) => void): void {\n const module = item.target?.module;\n const hasChildren = (item.children?.length ?? 0) > 0;\n\n if (!module) {\n // A sidebar item that only groups sub-items needs no target of its own.\n if (!hasChildren) report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' has no target.`);\n return;\n }\n\n if (!index.findModule(module)) {\n report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets module '${module}', which does not exist.`);\n return;\n }\n\n if (owner !== undefined && module !== owner) {\n report(NavigationDiagnosticCode.NavTargetOutOfScope, `Navigation item '${item.id}' of module '${owner}' targets module '${module}'; a module's own items may only target that module.`);\n return;\n }\n\n const feature = item.target?.feature;\n if (feature) {\n if (!index.findFeature(`${module}.${feature}`)) {\n report(NavigationDiagnosticCode.NavTargetMissing, `Navigation item '${item.id}' targets feature '${module}.${feature}', which does not exist.`);\n }\n } else if (!index.firstFeature(module)) {\n report(NavigationDiagnosticCode.NavModuleWithoutFeatures, `Navigation item '${item.id}' targets module '${module}', which has no features to go to.`);\n }\n}\n"],"names":["diagnoseNavigationRegions","structure","navigation","options","index","ApplicationStructureIndex","slots","primarySlot","diagnostics","region","navigationRegionOrder","defined","findNavigationRegion","application","regions","checkRegion","undefined","moduleNavigation","modules","inherited","mode","NavigationRegionMode","Extend","collectItemIds","applicationItems","module","owner","applicationIds","scope","seen","Set","visit","items","item","entry","id","report","code","message","push","has","NavigationDiagnosticCode","NavDuplicateId","includes","add","checkTarget","slot","NavSlotUnknown","NavigationRegionKind","Sidebar","children","target","hasChildren","length","NavTargetMissing","findModule","NavTargetOutOfScope","feature","findFeature","firstFeature","NavModuleWithoutFeatures"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ApplicationStructure, NavigationModel, NavigationRegionKind } from '@cratis/scene.model';
|
|
2
|
+
import { ApplicationStructureIndex } from '../structure';
|
|
3
|
+
import { EffectiveNavigationRegion } from './EffectiveNavigationRegion';
|
|
4
|
+
export declare function effectiveNavigation(structure: ApplicationStructure | ApplicationStructureIndex, navigation: NavigationModel, module: string | undefined, region: NavigationRegionKind): EffectiveNavigationRegion;
|
|
5
|
+
//# sourceMappingURL=effectiveNavigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effectiveNavigation.d.ts","sourceRoot":"","sources":["../../../navigation/effectiveNavigation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,oBAAoB,EAAiC,MAAM,qBAAqB,CAAC;AACjI,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AA6BxE,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,oBAAoB,GAAG,yBAAyB,EAC3D,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,oBAAoB,GAC7B,yBAAyB,CA0B3B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { NavigationRegionMode, NavigationRegionKind } from '@cratis/scene.model';
|
|
2
|
+
import { ApplicationStructureIndex } from '../structure/ApplicationStructureIndex.js';
|
|
3
|
+
import { NavigationItemOrigin } from './NavigationItemOrigin.js';
|
|
4
|
+
import { NavigationSourcesKind } from './NavigationSourcesKind.js';
|
|
5
|
+
import { applicationItems, modeOfModuleRegion, findNavigationRegion, findModuleNavigation, primarySlot } from './navigationRegions.js';
|
|
6
|
+
|
|
7
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
8
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the items a navigation region effectively shows, for the application or for one module.
|
|
11
|
+
*
|
|
12
|
+
* - Application (no `module`): the application items, editable, `defined here`.
|
|
13
|
+
* - `inherit` (the default at a module): the application items, read-only; the module's own items are cleared.
|
|
14
|
+
* - `extend`: the application items, read-only, followed by the module's items.
|
|
15
|
+
* - `override`: the module's items only.
|
|
16
|
+
*
|
|
17
|
+
* Each item carries its `origin`, whether it is `readOnly`, a `reason`, and its target resolved against the
|
|
18
|
+
* structure: a module target goes to the module's first feature. Sub-items belong to the sidebar; a topbar is flat
|
|
19
|
+
* and its sub-items are ignored. This is the one function React renderers, Stage, Studio design mode and Studio
|
|
20
|
+
* preview call; nothing re-implements it.
|
|
21
|
+
*
|
|
22
|
+
* The C# engine (`EffectiveNavigation.Resolve`) returns the same result; both are asserted against
|
|
23
|
+
* `navigation-inheritance-fixtures.json` and `navigation-targets-fixtures.json`.
|
|
24
|
+
*
|
|
25
|
+
* @param structure The modules, features and slices of the application.
|
|
26
|
+
* @param navigation The application and module regions.
|
|
27
|
+
* @param module The module to resolve for; undefined for the application.
|
|
28
|
+
* @param region Which region to resolve.
|
|
29
|
+
*/ function effectiveNavigation(structure, navigation, module, region) {
|
|
30
|
+
const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);
|
|
31
|
+
const applicationOwned = applicationItems(navigation.application, region);
|
|
32
|
+
if (module === undefined) {
|
|
33
|
+
return {
|
|
34
|
+
region,
|
|
35
|
+
sources: {
|
|
36
|
+
kind: NavigationSourcesKind.DefinedHere,
|
|
37
|
+
label: 'defined here'
|
|
38
|
+
},
|
|
39
|
+
items: applicationOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.Application, false, 'Defined here.'))
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const mode = modeOfModuleRegion(navigation, module, region);
|
|
43
|
+
const moduleOwned = findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];
|
|
44
|
+
const name = index.findModule(module)?.name ?? module;
|
|
45
|
+
const inherited = ()=>applicationOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.Application, true, 'Inherited from the application; edit it there.'));
|
|
46
|
+
const own = ()=>moduleOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.Module, false, `Defined in ${name}.`));
|
|
47
|
+
switch(mode){
|
|
48
|
+
case NavigationRegionMode.Extend:
|
|
49
|
+
return {
|
|
50
|
+
region,
|
|
51
|
+
module,
|
|
52
|
+
mode,
|
|
53
|
+
sources: sourcesOf(NavigationSourcesKind.Extended, name),
|
|
54
|
+
items: [
|
|
55
|
+
...inherited(),
|
|
56
|
+
...own()
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
case NavigationRegionMode.Override:
|
|
60
|
+
return {
|
|
61
|
+
region,
|
|
62
|
+
module,
|
|
63
|
+
mode,
|
|
64
|
+
sources: sourcesOf(NavigationSourcesKind.Overridden, name),
|
|
65
|
+
items: own()
|
|
66
|
+
};
|
|
67
|
+
default:
|
|
68
|
+
return {
|
|
69
|
+
region,
|
|
70
|
+
module,
|
|
71
|
+
mode: NavigationRegionMode.Inherit,
|
|
72
|
+
sources: sourcesOf(NavigationSourcesKind.Inherited, name),
|
|
73
|
+
items: inherited()
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function sourcesOf(kind, moduleName) {
|
|
78
|
+
switch(kind){
|
|
79
|
+
case NavigationSourcesKind.Extended:
|
|
80
|
+
return {
|
|
81
|
+
kind,
|
|
82
|
+
label: `Application + ${moduleName}`
|
|
83
|
+
};
|
|
84
|
+
case NavigationSourcesKind.Overridden:
|
|
85
|
+
return {
|
|
86
|
+
kind,
|
|
87
|
+
label: `${moduleName} only`
|
|
88
|
+
};
|
|
89
|
+
default:
|
|
90
|
+
return {
|
|
91
|
+
kind: NavigationSourcesKind.Inherited,
|
|
92
|
+
label: 'inherited'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function resolveItem(index, region, item, origin, readOnly, reason) {
|
|
97
|
+
const resolved = {
|
|
98
|
+
id: item.id,
|
|
99
|
+
title: item.title,
|
|
100
|
+
slot: item.slot ?? primarySlot,
|
|
101
|
+
origin,
|
|
102
|
+
readOnly,
|
|
103
|
+
reason
|
|
104
|
+
};
|
|
105
|
+
if (item.icon !== undefined) resolved.icon = item.icon;
|
|
106
|
+
const target = resolveTarget(index, item);
|
|
107
|
+
if (target) resolved.target = target;
|
|
108
|
+
if (region === NavigationRegionKind.Sidebar && item.children && item.children.length > 0) {
|
|
109
|
+
resolved.children = item.children.map((child)=>resolveItem(index, region, child, origin, readOnly, reason));
|
|
110
|
+
}
|
|
111
|
+
return resolved;
|
|
112
|
+
}
|
|
113
|
+
function resolveTarget(index, item) {
|
|
114
|
+
const module = item.target?.module;
|
|
115
|
+
if (!module) return undefined;
|
|
116
|
+
const target = {
|
|
117
|
+
module
|
|
118
|
+
};
|
|
119
|
+
const feature = item.target?.feature;
|
|
120
|
+
if (feature) {
|
|
121
|
+
target.feature = feature;
|
|
122
|
+
if (index.findFeature(`${module}.${feature}`)) target.resolvedFeature = `${module}.${feature}`;
|
|
123
|
+
} else {
|
|
124
|
+
const first = index.firstFeatureId(module);
|
|
125
|
+
if (first !== undefined) target.resolvedFeature = first;
|
|
126
|
+
}
|
|
127
|
+
return target;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { effectiveNavigation };
|
|
131
|
+
//# sourceMappingURL=effectiveNavigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effectiveNavigation.js","sources":["../../../navigation/effectiveNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ApplicationStructure, NavigationModel, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\nimport { ApplicationStructureIndex } from '../structure';\nimport { EffectiveNavigationRegion } from './EffectiveNavigationRegion';\nimport { EffectiveNavItem } from './EffectiveNavItem';\nimport { NavigationItemOrigin } from './NavigationItemOrigin';\nimport { NavigationSources } from './NavigationSources';\nimport { NavigationSourcesKind } from './NavigationSourcesKind';\nimport { applicationItems, findModuleNavigation, findNavigationRegion, modeOfModuleRegion, primarySlot } from './navigationRegions';\nimport { ResolvedNavigationTarget } from './ResolvedNavigationTarget';\n\n/**\n * Resolves the items a navigation region effectively shows, for the application or for one module.\n *\n * - Application (no `module`): the application items, editable, `defined here`.\n * - `inherit` (the default at a module): the application items, read-only; the module's own items are cleared.\n * - `extend`: the application items, read-only, followed by the module's items.\n * - `override`: the module's items only.\n *\n * Each item carries its `origin`, whether it is `readOnly`, a `reason`, and its target resolved against the\n * structure: a module target goes to the module's first feature. Sub-items belong to the sidebar; a topbar is flat\n * and its sub-items are ignored. This is the one function React renderers, Stage, Studio design mode and Studio\n * preview call; nothing re-implements it.\n *\n * The C# engine (`EffectiveNavigation.Resolve`) returns the same result; both are asserted against\n * `navigation-inheritance-fixtures.json` and `navigation-targets-fixtures.json`.\n *\n * @param structure The modules, features and slices of the application.\n * @param navigation The application and module regions.\n * @param module The module to resolve for; undefined for the application.\n * @param region Which region to resolve.\n */\nexport function effectiveNavigation(\n structure: ApplicationStructure | ApplicationStructureIndex,\n navigation: NavigationModel,\n module: string | undefined,\n region: NavigationRegionKind,\n): EffectiveNavigationRegion {\n const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);\n const applicationOwned = applicationItems(navigation.application, region);\n\n if (module === undefined) {\n return {\n region,\n sources: { kind: NavigationSourcesKind.DefinedHere, label: 'defined here' },\n items: applicationOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Application, false, 'Defined here.')),\n };\n }\n\n const mode = modeOfModuleRegion(navigation, module, region);\n const moduleOwned = findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];\n const name = index.findModule(module)?.name ?? module;\n const inherited = (): EffectiveNavItem[] => applicationOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Application, true, 'Inherited from the application; edit it there.'));\n const own = (): EffectiveNavItem[] => moduleOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Module, false, `Defined in ${name}.`));\n\n switch (mode) {\n case NavigationRegionMode.Extend:\n return { region, module, mode, sources: sourcesOf(NavigationSourcesKind.Extended, name), items: [...inherited(), ...own()] };\n case NavigationRegionMode.Override:\n return { region, module, mode, sources: sourcesOf(NavigationSourcesKind.Overridden, name), items: own() };\n default:\n return { region, module, mode: NavigationRegionMode.Inherit, sources: sourcesOf(NavigationSourcesKind.Inherited, name), items: inherited() };\n }\n}\n\nfunction sourcesOf(kind: NavigationSourcesKind, moduleName: string): NavigationSources {\n switch (kind) {\n case NavigationSourcesKind.Extended: return { kind, label: `Application + ${moduleName}` };\n case NavigationSourcesKind.Overridden: return { kind, label: `${moduleName} only` };\n default: return { kind: NavigationSourcesKind.Inherited, label: 'inherited' };\n }\n}\n\nfunction resolveItem(index: ApplicationStructureIndex, region: NavigationRegionKind, item: NavItem, origin: NavigationItemOrigin, readOnly: boolean, reason: string): EffectiveNavItem {\n const resolved: EffectiveNavItem = { id: item.id, title: item.title, slot: item.slot ?? primarySlot, origin, readOnly, reason };\n if (item.icon !== undefined) resolved.icon = item.icon;\n\n const target = resolveTarget(index, item);\n if (target) resolved.target = target;\n\n if (region === NavigationRegionKind.Sidebar && item.children && item.children.length > 0) {\n resolved.children = item.children.map(child => resolveItem(index, region, child, origin, readOnly, reason));\n }\n\n return resolved;\n}\n\nfunction resolveTarget(index: ApplicationStructureIndex, item: NavItem): ResolvedNavigationTarget | undefined {\n const module = item.target?.module;\n if (!module) return undefined;\n\n const target: ResolvedNavigationTarget = { module };\n const feature = item.target?.feature;\n if (feature) {\n target.feature = feature;\n if (index.findFeature(`${module}.${feature}`)) target.resolvedFeature = `${module}.${feature}`;\n } else {\n const first = index.firstFeatureId(module);\n if (first !== undefined) target.resolvedFeature = first;\n }\n\n return target;\n}\n"],"names":["effectiveNavigation","structure","navigation","module","region","index","ApplicationStructureIndex","applicationOwned","applicationItems","application","undefined","sources","kind","NavigationSourcesKind","DefinedHere","label","items","map","item","resolveItem","NavigationItemOrigin","Application","mode","modeOfModuleRegion","moduleOwned","findNavigationRegion","findModuleNavigation","regions","name","findModule","inherited","own","Module","NavigationRegionMode","Extend","sourcesOf","Extended","Override","Overridden","Inherit","Inherited","moduleName","origin","readOnly","reason","resolved","id","title","slot","primarySlot","icon","target","resolveTarget","NavigationRegionKind","Sidebar","children","length","child","feature","findFeature","resolvedFeature","first","firstFeatureId"],"mappings":"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"}
|
|
@@ -5,4 +5,18 @@ export * from './NavigationGraph';
|
|
|
5
5
|
export * from './diagnoseNavigation';
|
|
6
6
|
export * from './navigationEntriesFrom';
|
|
7
7
|
export * from './navigationRoute';
|
|
8
|
+
export * from './navigationRegions';
|
|
9
|
+
export * from './NavigationItemOrigin';
|
|
10
|
+
export * from './NavigationSourcesKind';
|
|
11
|
+
export * from './NavigationSources';
|
|
12
|
+
export * from './ResolvedNavigationTarget';
|
|
13
|
+
export * from './EffectiveNavItem';
|
|
14
|
+
export * from './EffectiveNavigationRegion';
|
|
15
|
+
export * from './effectiveNavigation';
|
|
16
|
+
export * from './diagnoseNavigationRegions';
|
|
17
|
+
export * from './NavigationEditKind';
|
|
18
|
+
export * from './NavigationEdit';
|
|
19
|
+
export * from './NavigationEditPlan';
|
|
20
|
+
export * from './NavigationEditOutcome';
|
|
21
|
+
export * from './navigationEdits';
|
|
8
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../navigation/index.ts"],"names":[],"mappings":"AAGA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../navigation/index.ts"],"names":[],"mappings":"AAGA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC"}
|
|
@@ -5,4 +5,18 @@ export * from './NavigationGraph';
|
|
|
5
5
|
export * from './diagnoseNavigation';
|
|
6
6
|
export * from './navigationEntriesFrom';
|
|
7
7
|
export * from './navigationRoute';
|
|
8
|
+
export * from './navigationRegions';
|
|
9
|
+
export * from './NavigationItemOrigin';
|
|
10
|
+
export * from './NavigationSourcesKind';
|
|
11
|
+
export * from './NavigationSources';
|
|
12
|
+
export * from './ResolvedNavigationTarget';
|
|
13
|
+
export * from './EffectiveNavItem';
|
|
14
|
+
export * from './EffectiveNavigationRegion';
|
|
15
|
+
export * from './effectiveNavigation';
|
|
16
|
+
export * from './diagnoseNavigationRegions';
|
|
17
|
+
export * from './NavigationEditKind';
|
|
18
|
+
export * from './NavigationEdit';
|
|
19
|
+
export * from './NavigationEditPlan';
|
|
20
|
+
export * from './NavigationEditOutcome';
|
|
21
|
+
export * from './navigationEdits';
|
|
8
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../navigation/index.ts"],"names":[],"mappings":"AAGA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../navigation/index.ts"],"names":[],"mappings":"AAGA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ApplicationLogo, NavigationModel, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';
|
|
2
|
+
import { NavigationEdit } from './NavigationEdit';
|
|
3
|
+
import { NavigationEditOutcome } from './NavigationEditOutcome';
|
|
4
|
+
import { NavigationEditPlan } from './NavigationEditPlan';
|
|
5
|
+
export declare function switchRegionMode(navigation: NavigationModel, module: string | undefined, region: NavigationRegionKind, mode: NavigationRegionMode, options?: {
|
|
6
|
+
copy?: boolean;
|
|
7
|
+
}): NavigationEditPlan;
|
|
8
|
+
export declare function addNavItem(navigation: NavigationModel, module: string | undefined, region: NavigationRegionKind, item: NavItem, parent?: string): NavigationEditPlan;
|
|
9
|
+
export declare function setApplicationLogo(navigation: NavigationModel, module: string | undefined, logo: ApplicationLogo): NavigationEditPlan;
|
|
10
|
+
export declare function applyNavigationEdits(navigation: NavigationModel, edits: NavigationEdit[]): NavigationEditOutcome;
|
|
11
|
+
//# sourceMappingURL=navigationEdits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigationEdits.d.ts","sourceRoot":"","sources":["../../../navigation/navigationEdits.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAoB,oBAAoB,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9I,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAgB1D,wBAAgB,gBAAgB,CAC5B,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,kBAAkB,CAgBpB;AAWD,wBAAgB,UAAU,CACtB,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GAChB,kBAAkB,CAepB;AAQD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,kBAAkB,CAGrI;AAOD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,qBAAqB,CAQhH"}
|