@nanisoft/prism-ui 0.5.1 → 0.6.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.
Files changed (126) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/blocks/cta-01/cta.d.ts +66 -6
  3. package/dist/blocks/cta-01/cta.d.ts.map +1 -1
  4. package/dist/blocks/cta-01/cta.js +8 -3
  5. package/dist/blocks/cta-01/index.d.ts +1 -0
  6. package/dist/blocks/cta-01/index.d.ts.map +1 -1
  7. package/dist/blocks/feature-grid-01/feature-grid.d.ts +57 -6
  8. package/dist/blocks/feature-grid-01/feature-grid.d.ts.map +1 -1
  9. package/dist/blocks/feature-grid-01/feature-grid.js +12 -2
  10. package/dist/blocks/feature-grid-01/index.d.ts +1 -0
  11. package/dist/blocks/feature-grid-01/index.d.ts.map +1 -1
  12. package/dist/blocks/hero-01/hero.d.ts +30 -1
  13. package/dist/blocks/hero-01/hero.d.ts.map +1 -1
  14. package/dist/blocks/hero-01/hero.js +14 -2
  15. package/dist/blocks/index.d.ts +10 -0
  16. package/dist/blocks/index.d.ts.map +1 -1
  17. package/dist/blocks/index.js +9 -0
  18. package/dist/blocks/instrument-panel-01/index.d.ts +3 -0
  19. package/dist/blocks/instrument-panel-01/index.d.ts.map +1 -0
  20. package/dist/blocks/instrument-panel-01/index.js +1 -0
  21. package/dist/blocks/instrument-panel-01/instrument-panel.d.ts +114 -0
  22. package/dist/blocks/instrument-panel-01/instrument-panel.d.ts.map +1 -0
  23. package/dist/blocks/instrument-panel-01/instrument-panel.js +64 -0
  24. package/dist/blocks/logo-strip-01/index.d.ts +3 -0
  25. package/dist/blocks/logo-strip-01/index.d.ts.map +1 -0
  26. package/dist/blocks/logo-strip-01/index.js +1 -0
  27. package/dist/blocks/logo-strip-01/logo-strip.d.ts +84 -0
  28. package/dist/blocks/logo-strip-01/logo-strip.d.ts.map +1 -0
  29. package/dist/blocks/logo-strip-01/logo-strip.js +40 -0
  30. package/dist/blocks/note-grid-01/index.d.ts +3 -0
  31. package/dist/blocks/note-grid-01/index.d.ts.map +1 -0
  32. package/dist/blocks/note-grid-01/index.js +1 -0
  33. package/dist/blocks/note-grid-01/note-grid.d.ts +79 -0
  34. package/dist/blocks/note-grid-01/note-grid.d.ts.map +1 -0
  35. package/dist/blocks/note-grid-01/note-grid.js +37 -0
  36. package/dist/blocks/pricing-01/pricing.js +1 -1
  37. package/dist/blocks/process-rail-01/index.d.ts +3 -0
  38. package/dist/blocks/process-rail-01/index.d.ts.map +1 -0
  39. package/dist/blocks/process-rail-01/index.js +1 -0
  40. package/dist/blocks/process-rail-01/process-rail.d.ts +99 -0
  41. package/dist/blocks/process-rail-01/process-rail.d.ts.map +1 -0
  42. package/dist/blocks/process-rail-01/process-rail.js +58 -0
  43. package/dist/blocks/product-grid-01/index.d.ts +3 -0
  44. package/dist/blocks/product-grid-01/index.d.ts.map +1 -0
  45. package/dist/blocks/product-grid-01/index.js +1 -0
  46. package/dist/blocks/product-grid-01/product-grid.d.ts +114 -0
  47. package/dist/blocks/product-grid-01/product-grid.d.ts.map +1 -0
  48. package/dist/blocks/product-grid-01/product-grid.js +51 -0
  49. package/dist/blocks/site-footer/index.d.ts +3 -0
  50. package/dist/blocks/site-footer/index.d.ts.map +1 -0
  51. package/dist/blocks/site-footer/index.js +1 -0
  52. package/dist/blocks/site-footer/site-footer.d.ts +135 -0
  53. package/dist/blocks/site-footer/site-footer.d.ts.map +1 -0
  54. package/dist/blocks/site-footer/site-footer.js +41 -0
  55. package/dist/blocks/site-header/index.d.ts +3 -0
  56. package/dist/blocks/site-header/index.d.ts.map +1 -0
  57. package/dist/blocks/site-header/index.js +1 -0
  58. package/dist/blocks/site-header/site-header.d.ts +142 -0
  59. package/dist/blocks/site-header/site-header.d.ts.map +1 -0
  60. package/dist/blocks/site-header/site-header.js +46 -0
  61. package/dist/blocks/stack-grid-01/index.d.ts +3 -0
  62. package/dist/blocks/stack-grid-01/index.d.ts.map +1 -0
  63. package/dist/blocks/stack-grid-01/index.js +1 -0
  64. package/dist/blocks/stack-grid-01/stack-grid.d.ts +118 -0
  65. package/dist/blocks/stack-grid-01/stack-grid.d.ts.map +1 -0
  66. package/dist/blocks/stack-grid-01/stack-grid.js +49 -0
  67. package/dist/blocks/status-ledger-01/index.d.ts +3 -0
  68. package/dist/blocks/status-ledger-01/index.d.ts.map +1 -0
  69. package/dist/blocks/status-ledger-01/index.js +1 -0
  70. package/dist/blocks/status-ledger-01/status-ledger.d.ts +131 -0
  71. package/dist/blocks/status-ledger-01/status-ledger.d.ts.map +1 -0
  72. package/dist/blocks/status-ledger-01/status-ledger.js +80 -0
  73. package/dist/catalog.d.ts.map +1 -1
  74. package/dist/catalog.js +170 -0
  75. package/dist/components/index.d.ts +11 -0
  76. package/dist/components/index.d.ts.map +1 -1
  77. package/dist/components/index.js +6 -0
  78. package/dist/components/ui/card.d.ts +25 -0
  79. package/dist/components/ui/card.d.ts.map +1 -1
  80. package/dist/components/ui/card.js +25 -0
  81. package/dist/components/ui/cta-link.d.ts +45 -0
  82. package/dist/components/ui/cta-link.d.ts.map +1 -0
  83. package/dist/components/ui/cta-link.js +81 -0
  84. package/dist/components/ui/diagram.d.ts +154 -0
  85. package/dist/components/ui/diagram.d.ts.map +1 -0
  86. package/dist/components/ui/diagram.js +150 -0
  87. package/dist/components/ui/fact-list.d.ts +90 -0
  88. package/dist/components/ui/fact-list.d.ts.map +1 -0
  89. package/dist/components/ui/fact-list.js +38 -0
  90. package/dist/components/ui/product-mark.d.ts +115 -0
  91. package/dist/components/ui/product-mark.d.ts.map +1 -0
  92. package/dist/components/ui/product-mark.js +82 -0
  93. package/dist/components/ui/product-switcher.d.ts +108 -0
  94. package/dist/components/ui/product-switcher.d.ts.map +1 -0
  95. package/dist/components/ui/product-switcher.js +47 -0
  96. package/dist/components/ui/prose.d.ts +88 -0
  97. package/dist/components/ui/prose.d.ts.map +1 -0
  98. package/dist/components/ui/prose.js +53 -0
  99. package/dist/components/ui/section.d.ts +24 -1
  100. package/dist/components/ui/section.d.ts.map +1 -1
  101. package/dist/components/ui/section.js +11 -2
  102. package/dist/components/ui/slider.d.ts.map +1 -1
  103. package/dist/components/ui/slider.js +7 -1
  104. package/dist/index.d.ts +24 -0
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +17 -0
  107. package/dist/pages/blog-post-page/index.d.ts +174 -0
  108. package/dist/pages/blog-post-page/index.d.ts.map +1 -0
  109. package/dist/pages/blog-post-page/index.js +49 -0
  110. package/dist/pages/index.d.ts +4 -0
  111. package/dist/pages/index.d.ts.map +1 -1
  112. package/dist/pages/index.js +2 -0
  113. package/dist/pages/not-found-page/index.d.ts +112 -0
  114. package/dist/pages/not-found-page/index.d.ts.map +1 -0
  115. package/dist/pages/not-found-page/index.js +46 -0
  116. package/dist/provider/provider.d.ts +5 -0
  117. package/dist/provider/provider.d.ts.map +1 -1
  118. package/dist/provider/provider.js +129 -38
  119. package/dist/provider/theme-script.d.ts +41 -3
  120. package/dist/provider/theme-script.d.ts.map +1 -1
  121. package/dist/provider/theme-script.js +68 -17
  122. package/dist/styles.css +493 -12
  123. package/dist/theming/index.d.ts +132 -2
  124. package/dist/theming/index.d.ts.map +1 -1
  125. package/dist/theming/index.js +127 -1
  126. package/package.json +14 -4
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from 'class-variance-authority';
3
+ import { cn } from '../../lib/utils';
4
+ /*
5
+ * Why this is a second Component rather than an `as` or `href` prop on `Button`.
6
+ * The design system has already answered this twice, in the two places a trail
7
+ * of links and a list of page links each needed both a non-link slot and a link
8
+ * slot: `BreadcrumbItem` renders an `<li>` and `BreadcrumbLink` renders an
9
+ * `<a>` (`src/components/ui/breadcrumb.tsx`), and `PaginationItem` renders an
10
+ * `<li>` and `PaginationLink` renders an `<a>`
11
+ * (`src/components/ui/pagination.tsx`). Both wrote a second export rather than
12
+ * widening one element into a prop, and both are the shape this Component takes.
13
+ * A polymorphic `as` would make the rendered element a runtime value that only
14
+ * the reader of the call site knows, which is exactly the disagreement between a
15
+ * type and a screen this ticket closes. It also costs nothing: both halves of
16
+ * that pair are server components, so the swap adds no client JavaScript.
17
+ *
18
+ * The recipe is written here rather than imported from `button.tsx`, because
19
+ * `buttonVariants` is module-internal and DESIGN.md keeps a raw variant map off
20
+ * the export surface: "There is no variant recipe on the surface." The base
21
+ * string and every shared variant below are therefore kept deliberately
22
+ * identical to `buttonVariants`, so swapping `Button` for `CtaLink` changes the
23
+ * element and the destination and nothing else on screen. If one recipe moves,
24
+ * the other moves with it.
25
+ */
26
+ const ctaLinkVariants = cva(
27
+ // The focus ring is `ring-ring` at full strength, for the reason
28
+ // `button.tsx` states at length: half alpha composites to between 1.14:1 and
29
+ // 2.74:1 against every surface in all six themes and clears 3:1 in none of
30
+ // them, which fails WCAG 1.4.11 on the one indicator a keyboard user has.
31
+ //
32
+ // Two utilities are dropped from the button base, and each is dropped for a
33
+ // reason rather than by omission. `aria-invalid:*` is a form-control state and
34
+ // an anchor has no invalid state. `disabled:*` is likewise a button state: an
35
+ // anchor with a destination always navigates, and a control that should not
36
+ // navigate is not a call to action.
37
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium outline-none transition-[color,box-shadow,background-color] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring focus-visible:ring-[3px]", {
38
+ variants: {
39
+ variant: {
40
+ default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
41
+ outline: 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',
42
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
43
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
44
+ },
45
+ // The desktop metrics and the coarse-pointer 44px step are `Button`'s, for
46
+ // the reason `button.tsx` states: the target grows with the input method
47
+ // and not with the viewport, so a phone-sized metric never ships to a
48
+ // mouse. An `icon` size is absent because a call to action carries a label.
49
+ size: {
50
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3 pointer-coarse:h-11 pointer-coarse:min-w-11 pointer-coarse:px-5 pointer-coarse:has-[>svg]:px-4',
51
+ sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5 pointer-coarse:h-11 pointer-coarse:min-w-11',
52
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4 pointer-coarse:h-11',
53
+ },
54
+ },
55
+ defaultVariants: {
56
+ variant: 'default',
57
+ size: 'default',
58
+ },
59
+ });
60
+ /**
61
+ * The call to action that goes somewhere.
62
+ *
63
+ * Renders a native `<a>`, so assistive technology announces a link and the
64
+ * browser's own link affordances all work: a status bar showing the destination,
65
+ * a context menu to copy it, middle-click to open a new tab. `Button` cannot
66
+ * offer any of that, and a call to action that is a button is announced as a
67
+ * command that does nothing.
68
+ *
69
+ * It is a Component in its own right rather than a mode of `Button`, which is the
70
+ * answer `BreadcrumbLink` and `PaginationLink` already give twice in this
71
+ * package. The two carry the same visual weight as the button they replace, so
72
+ * the only difference on screen is that this one has a destination.
73
+ *
74
+ * When `newTab` is set, `rel` defaults to `noopener noreferrer`, so the opened
75
+ * document cannot reach back through `window.opener` or read the referrer. A
76
+ * consumer that needs a different relationship passes `rel` and it wins.
77
+ */
78
+ function CtaLink({ className, variant, size, href, newTab = false, rel, ...props }) {
79
+ return (_jsx("a", { "data-slot": "cta-link", href: href, rel: rel ?? (newTab ? 'noopener noreferrer' : undefined), target: newTab ? '_blank' : undefined, className: cn(ctaLinkVariants({ variant, size, className })), ...props }));
80
+ }
81
+ export { CtaLink };
@@ -0,0 +1,154 @@
1
+ /**
2
+ * One named thing in a Diagram, at a position the caller chooses.
3
+ *
4
+ * `x` and `y` are in the caller's own coordinate space and are normalised into
5
+ * the Diagram's canvas, so fractions, pixels or any other monotonic scale all
6
+ * draw the same shape. Two nodes given the same position collapse onto one
7
+ * another, so a caller that means a column spreads it rather than repeating a
8
+ * number.
9
+ *
10
+ * `emphasis` marks the one node the drawing is about, and it is the only
11
+ * difference a node may carry: the emphasised node takes the brand ink, which
12
+ * DESIGN.md's Brand Ink Rule names as the colour for something that must read
13
+ * as the brand rather than as body text. Two emphasised nodes are a caller's
14
+ * mistake, not a second emphasis level.
15
+ */
16
+ export type DiagramNode = {
17
+ /**
18
+ * A key unique within the diagram. Relations name a node by this, and it is
19
+ * carried on the markup as `data-node` so a test can address one node rather
20
+ * than the first one.
21
+ */
22
+ id: string;
23
+ /**
24
+ * The name printed under the node. It is a label on a picture, so a screen
25
+ * reader does not read it: see `DiagramProps` for what carries the meaning.
26
+ */
27
+ name: string;
28
+ /** The node's position along the horizontal axis, in the caller's space. */
29
+ x: number;
30
+ /** The node's position along the vertical axis, in the caller's space. */
31
+ y: number;
32
+ /** Marks the node the diagram is about. See the Brand Ink Rule. */
33
+ emphasis?: boolean;
34
+ };
35
+ /**
36
+ * One relation between two nodes, with the word that says what it is.
37
+ *
38
+ * A relation is drawn as a straight line between the two node marks, so the
39
+ * geometry a caller lays out is the geometry a reader sees. The label is placed
40
+ * beside the line rather than on it, because a label drawn over a line has to
41
+ * be knocked out with a halo, and a halo has to be filled with the colour of
42
+ * the surface the diagram happens to sit on, which the component is not told.
43
+ *
44
+ * `indirect` draws the line dashed. That is the standing convention for "this
45
+ * holds, but not by this route", and it is chosen over fading the line because
46
+ * a dashed line keeps its contrast while a faded one does not.
47
+ */
48
+ export type DiagramRelation = {
49
+ /** The `id` of the node the relation leaves. */
50
+ from: string;
51
+ /** The `id` of the node the relation arrives at. */
52
+ to: string;
53
+ /** The word printed beside the line. */
54
+ label: string;
55
+ /** Draws the line dashed, for a relation that holds but not by this route. */
56
+ indirect?: boolean;
57
+ };
58
+ /** What both arms of `DiagramProps` carry. */
59
+ type DiagramFigure = {
60
+ /** The things drawn. At least one, or the Diagram renders an empty canvas. */
61
+ nodes: DiagramNode[];
62
+ /** The relations drawn between them. A relation naming a node that is not in `nodes` is dropped. */
63
+ relations: DiagramRelation[];
64
+ /**
65
+ * Layout only, exactly as on every Component: grid placement and width.
66
+ * Changing a Prism-owned visual property from here is prohibited, and this
67
+ * Component spreads no other prop, so there is no second way to do it.
68
+ */
69
+ className?: string;
70
+ };
71
+ /**
72
+ * The props a Diagram takes.
73
+ *
74
+ * The name is required unless the drawing is decorative, and it is forbidden
75
+ * when it is. That is a union rather than `label?: string` because only a union
76
+ * lets the type system see the exception: an optional label on one type can
77
+ * only be optional everywhere or required everywhere, and both halves of that
78
+ * are wrong. `Separator` takes the same shape as `decorative`.
79
+ */
80
+ export type DiagramProps = DiagramFigure & ({
81
+ /**
82
+ * Hides the drawing from assistive technology and drops the name. Use it
83
+ * when the surrounding sentence already says what the diagram shows, and
84
+ * nothing inside the hidden tree is named either: there is no `<title>`
85
+ * here, so there is no name stranded inside an `aria-hidden` subtree.
86
+ */
87
+ decorative: true;
88
+ label?: never;
89
+ } | {
90
+ /** The name of the drawing, and the only thing a screen reader reads from it. */
91
+ label: string;
92
+ decorative?: false;
93
+ });
94
+ /**
95
+ * A diagram of named things and the relations between them.
96
+ *
97
+ * Data in, vector markup out. Every stroke and every fill is a semantic token
98
+ * named as a utility, never a value read from anywhere, so a scoped `data-pack`
99
+ * boundary above the drawing restyles it through the cascade exactly as it
100
+ * restyles a heading. That is the whole reason this is a Component and the
101
+ * reason a canvas was not: a canvas paints pixels it has already resolved, and
102
+ * a resolved value does not move when the pack beneath it does.
103
+ *
104
+ * It is a server Component. It ships no client code, takes no hook, has no mode
105
+ * of its own and reads no context, so a consumer renders it from a server file
106
+ * with no provider mounted. `check-client-budget.mjs` keeps it off the client
107
+ * roster, and a `'use client'` line added here would put it back on that roster.
108
+ *
109
+ * **Accessibility.** A diagram carries meaning, so by default it is one image
110
+ * with a name: `role="img"` and the `label` the caller passes. Everything inside
111
+ * a `role="img"` is presentational, so the node names and relation words are
112
+ * drawn for sighted readers and the surrounding sentence is what a screen reader
113
+ * gets. Pass `decorative` when the sentence already says what the drawing
114
+ * shows, and the whole tree leaves the accessibility tree with nothing named
115
+ * inside it.
116
+ *
117
+ * **Shape.** Nodes are circles and relations are paths. Both are shapes with no
118
+ * radius concept, so no corner radius here is a function of `--radius` and a
119
+ * pack boundary above the drawing moves nothing about its shape. A `<rect>` was
120
+ * rejected for the opposite reason: its corner attribute is a CSS property and
121
+ * does follow a boundary, and no utility pins it.
122
+ *
123
+ * **The node mark's base edges must draw.** Two things go wrong when a shape is
124
+ * left to its defaults, and this file answers both explicitly on every mark.
125
+ *
126
+ * 1. A shape with no `fill` and no `fill: none` paints opaque black, which
127
+ * hides every label behind it. A relation path therefore names `fill-none`
128
+ * and a node circle names a fill, and neither relies on an initial value.
129
+ * 2. A stroke only exists if something draws it. `stroke-width`'s initial
130
+ * value is 1 rather than 0, so the width is not what fails here; what fails
131
+ * is a mark whose stroke colour is `currentColor` on a surface whose text
132
+ * colour is that same surface, which is an invisible edge, or a width
133
+ * utility dropped in an edit. So every mark names an explicit width, an
134
+ * explicit stroke from a token, and never `current` or `currentColor`.
135
+ *
136
+ * A Component whose nodes render as invisible rectangles is worse than no
137
+ * Component, so this is stated here and covered by `test/diagram.test.tsx`.
138
+ *
139
+ * It spreads no other prop. `Separator` and `Kbd` spread a native element's
140
+ * props because there is no other route to them; a Diagram whose entire claim
141
+ * is that every ink is a token would be undermined by a spread that hands a
142
+ * caller `stroke`, so the surface is `nodes`, `relations`, `label`,
143
+ * `decorative` and `className` and nothing else.
144
+ *
145
+ * Positions are the caller's: the Component fits and draws, and it does not lay
146
+ * out a graph, so it cannot know that two labels will not collide. A relation
147
+ * naming a node that is not in `nodes` is dropped, and the count of dropped
148
+ * relations is on the element as `data-unresolved-relations` rather than
149
+ * swallowed, because a line that silently did not draw is the failure this
150
+ * Component exists to make impossible.
151
+ */
152
+ declare function Diagram({ nodes, relations, label, decorative, className, }: DiagramProps): import("react").JSX.Element;
153
+ export { Diagram };
154
+ //# sourceMappingURL=diagram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../src/components/ui/diagram.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,CAAC,EAAE,MAAM,CAAA;IACT,0EAA0E;IAC1E,CAAC,EAAE,MAAM,CAAA;IACT,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAA;IACV,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,8CAA8C;AAC9C,KAAK,aAAa,GAAG;IACnB,8EAA8E;IAC9E,KAAK,EAAE,WAAW,EAAE,CAAA;IACpB,oGAAoG;IACpG,SAAS,EAAE,eAAe,EAAE,CAAA;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GACtC,CACI;IACE;;;;;OAKG;IACH,UAAU,EAAE,IAAI,CAAA;IAChB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GACD;IACE,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB,CACJ,CAAA;AAoFH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,iBAAS,OAAO,CAAC,EACf,KAAK,EACL,SAAS,EACT,KAAK,EACL,UAAkB,EAClB,SAAS,GACV,EAAE,YAAY,+BAsFd;AAED,OAAO,EAAE,OAAO,EAAE,CAAA"}
@@ -0,0 +1,150 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../lib/utils';
3
+ /**
4
+ * The canvas the Diagram draws into, in its own user units.
5
+ *
6
+ * A fixed canvas rather than a viewBox derived from the caller's numbers, for
7
+ * one reason: type inside a scaled SVG is sized in the SVG's own user units, so
8
+ * a viewBox derived from a caller's coordinates would make the label size a
9
+ * function of how large a number the caller happened to use, and the same
10
+ * drawing would come out with 3px labels in one call and 40px labels in another.
11
+ * Fitting the caller's points into a fixed canvas makes the label a constant
12
+ * and makes the drawing a function of the shape rather than of the scale.
13
+ */
14
+ const CANVAS_WIDTH = 640;
15
+ const CANVAS_HEIGHT = 400;
16
+ /**
17
+ * The band left empty around the fitted points, in user units.
18
+ *
19
+ * It reserves room for what is drawn beside a node rather than for the node: a
20
+ * node mark is 5 units in radius and its name is set about 20 units below it,
21
+ * and a name is wider than the mark. The band is the honest cost of a server
22
+ * component not being able to measure text, and it is why a name that runs long
23
+ * still lands inside the canvas rather than off its edge.
24
+ */
25
+ const PADDING = 56;
26
+ /** The node mark's radius. A circle, so there is no corner radius for the pack to move. */
27
+ const NODE_RADIUS = 5;
28
+ /**
29
+ * Type sizes, in user units rather than in `rem`.
30
+ *
31
+ * The authored type scale is in `rem` and cannot be used inside a viewBox, where
32
+ * a font size is a coordinate and not a length on the page. These are geometry,
33
+ * the one thing Tailwind stays authoritative for, and they are the only numbers
34
+ * in this file that are not a token.
35
+ */
36
+ const NODE_NAME_SIZE = 13;
37
+ const NODE_NAME_OFFSET = 20;
38
+ const RELATION_NAME_SIZE = 11;
39
+ /**
40
+ * How far a relation's label sits off its line, in user units. Perpendicular to
41
+ * the line, so the label never sits on the stroke it belongs to.
42
+ */
43
+ const RELATION_NAME_LIFT = 7;
44
+ /**
45
+ * The caller's points, fitted into the canvas with their aspect ratio kept and
46
+ * the leftover shared out evenly.
47
+ *
48
+ * A caller whose points span one axis only, or who passes a single node, gets
49
+ * the other axis centred rather than a division by zero: the scale is taken
50
+ * over the axes that have an extent, and a diagram with no extent at all keeps
51
+ * the caller's own numbers.
52
+ */
53
+ function fit(nodes) {
54
+ if (nodes.length === 0)
55
+ return () => ({ x: CANVAS_WIDTH / 2, y: CANVAS_HEIGHT / 2 });
56
+ const xs = nodes.map((node) => node.x);
57
+ const ys = nodes.map((node) => node.y);
58
+ const minX = Math.min(...xs);
59
+ const minY = Math.min(...ys);
60
+ const spanX = Math.max(...xs) - minX;
61
+ const spanY = Math.max(...ys) - minY;
62
+ const roomX = CANVAS_WIDTH - PADDING * 2;
63
+ const roomY = CANVAS_HEIGHT - PADDING * 2;
64
+ const scale = Math.min(spanX === 0 ? Number.POSITIVE_INFINITY : roomX / spanX, spanY === 0 ? Number.POSITIVE_INFINITY : roomY / spanY);
65
+ const unit = Number.isFinite(scale) && scale > 0 ? scale : 1;
66
+ const offsetX = PADDING + (roomX - spanX * unit) / 2 - minX * unit;
67
+ const offsetY = PADDING + (roomY - spanY * unit) / 2 - minY * unit;
68
+ return (node) => ({ x: node.x * unit + offsetX, y: node.y * unit + offsetY });
69
+ }
70
+ /**
71
+ * A diagram of named things and the relations between them.
72
+ *
73
+ * Data in, vector markup out. Every stroke and every fill is a semantic token
74
+ * named as a utility, never a value read from anywhere, so a scoped `data-pack`
75
+ * boundary above the drawing restyles it through the cascade exactly as it
76
+ * restyles a heading. That is the whole reason this is a Component and the
77
+ * reason a canvas was not: a canvas paints pixels it has already resolved, and
78
+ * a resolved value does not move when the pack beneath it does.
79
+ *
80
+ * It is a server Component. It ships no client code, takes no hook, has no mode
81
+ * of its own and reads no context, so a consumer renders it from a server file
82
+ * with no provider mounted. `check-client-budget.mjs` keeps it off the client
83
+ * roster, and a `'use client'` line added here would put it back on that roster.
84
+ *
85
+ * **Accessibility.** A diagram carries meaning, so by default it is one image
86
+ * with a name: `role="img"` and the `label` the caller passes. Everything inside
87
+ * a `role="img"` is presentational, so the node names and relation words are
88
+ * drawn for sighted readers and the surrounding sentence is what a screen reader
89
+ * gets. Pass `decorative` when the sentence already says what the drawing
90
+ * shows, and the whole tree leaves the accessibility tree with nothing named
91
+ * inside it.
92
+ *
93
+ * **Shape.** Nodes are circles and relations are paths. Both are shapes with no
94
+ * radius concept, so no corner radius here is a function of `--radius` and a
95
+ * pack boundary above the drawing moves nothing about its shape. A `<rect>` was
96
+ * rejected for the opposite reason: its corner attribute is a CSS property and
97
+ * does follow a boundary, and no utility pins it.
98
+ *
99
+ * **The node mark's base edges must draw.** Two things go wrong when a shape is
100
+ * left to its defaults, and this file answers both explicitly on every mark.
101
+ *
102
+ * 1. A shape with no `fill` and no `fill: none` paints opaque black, which
103
+ * hides every label behind it. A relation path therefore names `fill-none`
104
+ * and a node circle names a fill, and neither relies on an initial value.
105
+ * 2. A stroke only exists if something draws it. `stroke-width`'s initial
106
+ * value is 1 rather than 0, so the width is not what fails here; what fails
107
+ * is a mark whose stroke colour is `currentColor` on a surface whose text
108
+ * colour is that same surface, which is an invisible edge, or a width
109
+ * utility dropped in an edit. So every mark names an explicit width, an
110
+ * explicit stroke from a token, and never `current` or `currentColor`.
111
+ *
112
+ * A Component whose nodes render as invisible rectangles is worse than no
113
+ * Component, so this is stated here and covered by `test/diagram.test.tsx`.
114
+ *
115
+ * It spreads no other prop. `Separator` and `Kbd` spread a native element's
116
+ * props because there is no other route to them; a Diagram whose entire claim
117
+ * is that every ink is a token would be undermined by a spread that hands a
118
+ * caller `stroke`, so the surface is `nodes`, `relations`, `label`,
119
+ * `decorative` and `className` and nothing else.
120
+ *
121
+ * Positions are the caller's: the Component fits and draws, and it does not lay
122
+ * out a graph, so it cannot know that two labels will not collide. A relation
123
+ * naming a node that is not in `nodes` is dropped, and the count of dropped
124
+ * relations is on the element as `data-unresolved-relations` rather than
125
+ * swallowed, because a line that silently did not draw is the failure this
126
+ * Component exists to make impossible.
127
+ */
128
+ function Diagram({ nodes, relations, label, decorative = false, className, }) {
129
+ const place = fit(nodes);
130
+ const byId = new Map(nodes.map((node) => [node.id, node]));
131
+ const drawn = relations.flatMap((relation) => {
132
+ const from = byId.get(relation.from);
133
+ const to = byId.get(relation.to);
134
+ return from && to ? [{ relation, from: place(from), to: place(to) }] : [];
135
+ });
136
+ return (_jsxs("svg", { "data-slot": "diagram", "data-unresolved-relations": relations.length - drawn.length, viewBox: `0 0 ${CANVAS_WIDTH} ${CANVAS_HEIGHT}`, xmlns: "http://www.w3.org/2000/svg", role: decorative ? undefined : 'img', "aria-label": decorative ? undefined : label, "aria-hidden": decorative || undefined, className: cn('h-auto w-full', className), children: [drawn.map(({ relation, from, to }) => {
137
+ // A label placed beside its line rather than on it. The offset is the
138
+ // line's normal, so a vertical relation's label sits beside it and a
139
+ // horizontal one's sits above it, and neither ever sits on the stroke.
140
+ const dx = to.x - from.x;
141
+ const dy = to.y - from.y;
142
+ const length = Math.hypot(dx, dy);
143
+ const lift = length === 0 ? 0 : RELATION_NAME_LIFT / length;
144
+ return (_jsxs("g", { "data-slot": "diagram-relation", "data-relation": `${relation.from}-${relation.to}`, children: [_jsx("path", { d: `M ${from.x} ${from.y} L ${to.x} ${to.y}`, strokeWidth: 1, strokeDasharray: relation.indirect ? '4 4' : undefined, className: "stroke-muted-foreground fill-none" }), _jsx("text", { x: (from.x + to.x) / 2 - dy * lift, y: (from.y + to.y) / 2 + dx * lift, fontSize: RELATION_NAME_SIZE, textAnchor: "middle", className: "fill-muted-foreground font-mono", children: relation.label })] }, `${relation.from}-${relation.to}`));
145
+ }), nodes.map((node) => {
146
+ const at = place(node);
147
+ return (_jsxs("g", { "data-slot": "diagram-node", "data-node": node.id, "data-emphasis": node.emphasis || undefined, children: [_jsx("circle", { cx: at.x, cy: at.y, r: NODE_RADIUS, strokeWidth: node.emphasis ? 2 : 1, className: cn(node.emphasis ? 'fill-accent stroke-brand-ink' : 'fill-card stroke-border') }), _jsx("text", { x: at.x, y: at.y + NODE_NAME_OFFSET, fontSize: NODE_NAME_SIZE, textAnchor: "middle", className: "fill-foreground font-mono", children: node.name })] }, node.id));
148
+ })] }));
149
+ }
150
+ export { Diagram };
@@ -0,0 +1,90 @@
1
+ import type { ComponentProps, ReactNode } from 'react';
2
+ /**
3
+ * One fact: the term that names it and the value that answers it.
4
+ *
5
+ * `label` is required and `value` is required, because a fact with no value is a
6
+ * heading and a fact with no term is a value with nothing to answer. A fact whose
7
+ * value is a destination passes `href` and gets an anchor, so a reader can
8
+ * follow it rather than read it.
9
+ */
10
+ export type Fact = {
11
+ /**
12
+ * The name of the fact, the term side of the pair. It is a label rather than
13
+ * prose: a column of these is read by scanning the left edge, so a term that
14
+ * wraps to two lines costs the whole column its alignment.
15
+ */
16
+ label: ReactNode;
17
+ /** The answer. A string, or any node a consumer composes. */
18
+ value: ReactNode;
19
+ /**
20
+ * Makes the value a link to where the fact is kept. Omit it for a fact whose
21
+ * value is the whole answer, such as a count or a version.
22
+ */
23
+ href?: string;
24
+ /**
25
+ * Opens the destination in a new browsing context, which defaults the link
26
+ * relationship to `noopener noreferrer`. Prism does not decide what counts as
27
+ * external: a cross-origin destination is not by itself a reason to open a tab.
28
+ */
29
+ newTab?: boolean;
30
+ };
31
+ /**
32
+ * The props a FactList takes.
33
+ *
34
+ * The facts are the content and the content is a prop: the list ships no fact,
35
+ * no sample row and no placeholder. An empty list renders nothing rather than an
36
+ * empty frame, so a caller that has nothing to say does not get a bordered box
37
+ * with a title above it.
38
+ */
39
+ export type FactListProps = ComponentProps<'dl'> & {
40
+ /**
41
+ * The facts, in the order a reader should meet them. Order is the caller's
42
+ * because it is a claim about importance, and a list that sorted itself would
43
+ * be making that claim on the caller's behalf.
44
+ */
45
+ facts: readonly Fact[];
46
+ /**
47
+ * A heading above the list, for a set of facts that needs to say what it is.
48
+ * Rendered as a `dt`-level caption rather than as a heading, so it does not
49
+ * compete with the document's own outline.
50
+ */
51
+ label?: ReactNode;
52
+ /**
53
+ * Layout only, exactly as on every Component. Changing a Prism-owned visual
54
+ * property from here is prohibited.
55
+ */
56
+ className?: string;
57
+ };
58
+ /**
59
+ * A short list of named facts, as a definition list.
60
+ *
61
+ * One job: put a term beside its value in a column a reader can scan, and make
62
+ * the pair a real description list so a screen reader announces the term before
63
+ * the value. Every NaniSoft site states facts beside prose: what a plan costs,
64
+ * what a feed carries, which version a document describes, when a collector went
65
+ * live. Each one re-derived a `<dl>` and each one got the alignment and the
66
+ * term-before-value wiring subtly wrong.
67
+ *
68
+ * It is a Component rather than a Block because it has no content of its own to
69
+ * be passed, and because the fact set is data rather than a section: a Block
70
+ * models a region of a page and this models a shape that appears inside one.
71
+ *
72
+ * The term column is a fixed fraction rather than a content width, so a column
73
+ * of facts lines up down its whole length and a long term pushes the value rather
74
+ * than resizing every other row. Values align to the top, because a value that
75
+ * wraps and a value that does not are both common and centring one of them reads
76
+ * as an error.
77
+ *
78
+ * The hairline between rows is `border-border`, so a list of facts reads as a
79
+ * table without becoming one: no header row, because a fact has no column
80
+ * header, and no `Table` semantics, because these are terms and their answers
81
+ * rather than records.
82
+ *
83
+ * A fact with no value renders the term and nothing else, so a caller that is
84
+ * missing an answer shows a gap rather than a blank that reads as a value.
85
+ *
86
+ * It is a server Component: no hook, no context and no client code.
87
+ */
88
+ declare function FactList({ facts, label, className, ...props }: FactListProps): import("react").JSX.Element | null;
89
+ export { FactList };
90
+ //# sourceMappingURL=fact-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fact-list.d.ts","sourceRoot":"","sources":["../../../src/components/ui/fact-list.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItD;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB;;;;OAIG;IACH,KAAK,EAAE,SAAS,CAAA;IAChB,6DAA6D;IAC7D,KAAK,EAAE,SAAS,CAAA;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG;IACjD;;;;OAIG;IACH,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,iBAAS,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,sCAuCrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../lib/utils';
3
+ /**
4
+ * A short list of named facts, as a definition list.
5
+ *
6
+ * One job: put a term beside its value in a column a reader can scan, and make
7
+ * the pair a real description list so a screen reader announces the term before
8
+ * the value. Every NaniSoft site states facts beside prose: what a plan costs,
9
+ * what a feed carries, which version a document describes, when a collector went
10
+ * live. Each one re-derived a `<dl>` and each one got the alignment and the
11
+ * term-before-value wiring subtly wrong.
12
+ *
13
+ * It is a Component rather than a Block because it has no content of its own to
14
+ * be passed, and because the fact set is data rather than a section: a Block
15
+ * models a region of a page and this models a shape that appears inside one.
16
+ *
17
+ * The term column is a fixed fraction rather than a content width, so a column
18
+ * of facts lines up down its whole length and a long term pushes the value rather
19
+ * than resizing every other row. Values align to the top, because a value that
20
+ * wraps and a value that does not are both common and centring one of them reads
21
+ * as an error.
22
+ *
23
+ * The hairline between rows is `border-border`, so a list of facts reads as a
24
+ * table without becoming one: no header row, because a fact has no column
25
+ * header, and no `Table` semantics, because these are terms and their answers
26
+ * rather than records.
27
+ *
28
+ * A fact with no value renders the term and nothing else, so a caller that is
29
+ * missing an answer shows a gap rather than a blank that reads as a value.
30
+ *
31
+ * It is a server Component: no hook, no context and no client code.
32
+ */
33
+ function FactList({ facts, label, className, ...props }) {
34
+ if (facts.length === 0)
35
+ return null;
36
+ return (_jsxs("dl", { "data-slot": "fact-list", className: cn('flex w-full flex-col text-sm', className), ...props, children: [label ? (_jsx("dt", { className: "text-muted-foreground mb-2 text-xs font-medium tracking-wide uppercase", children: label })) : null, facts.map((fact, index) => (_jsxs("div", { "data-slot": "fact-list-row", className: "border-border flex items-start justify-between gap-6 border-b py-2 last:border-b-0", children: [_jsx("dt", { className: "text-muted-foreground shrink-0 font-medium", children: fact.label }), _jsx("dd", { className: "text-right text-balance", children: fact.href ? (_jsx("a", { href: fact.href, rel: fact.newTab ? 'noopener noreferrer' : undefined, target: fact.newTab ? '_blank' : undefined, className: "underline underline-offset-4 hover:underline", children: fact.value })) : (fact.value) })] }, index)))] }));
37
+ }
38
+ export { FactList };
@@ -0,0 +1,115 @@
1
+ import type { PackId } from '../../theming';
2
+ /**
3
+ * The three sizes a product mark is drawn at: the mark's diameter and the name
4
+ * beside it, taken together so the two parts of the mark stay in proportion.
5
+ *
6
+ * The mark is one of a fixed set rather than something a caller sizes through
7
+ * `className`, because `className` is layout only and a mark sized by a layout
8
+ * class is a mark the layout owns. A product set shows its marks in a switcher,
9
+ * in a row and on a page header, and those three are the sizes a set needs.
10
+ */
11
+ declare const SIZES: {
12
+ readonly sm: {
13
+ readonly mark: "size-4";
14
+ readonly name: "text-xs";
15
+ };
16
+ readonly md: {
17
+ readonly mark: "size-5";
18
+ readonly name: "text-sm";
19
+ };
20
+ readonly lg: {
21
+ readonly mark: "size-6";
22
+ readonly name: "text-base";
23
+ };
24
+ };
25
+ /**
26
+ * The three sizes a product mark is drawn at.
27
+ *
28
+ * @defaultValue 'md'
29
+ */
30
+ export type ProductMarkSize = keyof typeof SIZES;
31
+ /**
32
+ * The props a ProductMark takes.
33
+ *
34
+ * There is no product directory in this package. A product's identity is the
35
+ * consumer's data, so the Component takes the three facts the mark is drawn
36
+ * from and owns none of them: `id` for the markup, `name` for the second part,
37
+ * and `pack` for the hue. Where the set of products is published is the
38
+ * consumer's decision, and Prism ships the mark rather than a list of products.
39
+ */
40
+ export type ProductMarkProps = {
41
+ /**
42
+ * The product's key within the set it is distinguished in. It is carried on
43
+ * the markup as `data-product` so a test can name one mark rather than the
44
+ * first one, and so two marks in one document are individually addressable.
45
+ */
46
+ id: string;
47
+ /**
48
+ * The product's name, which is the mark's second part and the word that
49
+ * carries the identity. The mark sets it in `brand-ink` rather than in
50
+ * `foreground`, which is DESIGN.md's Brand Ink Rule: a name that has to read
51
+ * as the brand reads `brand-ink`, and `foreground` is a tinted neutral with
52
+ * almost no chroma by design.
53
+ */
54
+ name: string;
55
+ /**
56
+ * The product's pack, which is the mark's hue. Omit it, or pass `null`, for
57
+ * the one entry in a set that has no pack of its own: that entry is drawn as
58
+ * the full spectrum rather than as a colourless mark. See `SPECTRUM` above.
59
+ *
60
+ * `default` is a real answer and not the same as the empty one. The base pack
61
+ * is a pack a product can wear, and it is the absence of a `data-pack`
62
+ * attribute, so a product whose pack is `default` carries no attribute and its
63
+ * core resolves the base pack's `primary` from the page.
64
+ */
65
+ pack?: PackId | null;
66
+ /**
67
+ * Which of the three drawn sizes to use. @defaultValue 'md'
68
+ */
69
+ size?: ProductMarkSize;
70
+ /**
71
+ * Layout only, exactly as on every Component. Changing a Prism-owned visual
72
+ * property from here is prohibited, and this Component spreads no other prop,
73
+ * so there is no second route to its ink.
74
+ */
75
+ className?: string;
76
+ };
77
+ /**
78
+ * A product's two-part colour mark: a hairline ring in the brand ink around a
79
+ * core in the pack's own fill, beside the product's name in the brand ink.
80
+ *
81
+ * Two parts, and both colours come from tokens, which is the whole reason this
82
+ * is promoted out of the two hand-written copies it replaces. The ring is
83
+ * `brand-ink`, the pack's brand hue as a stroke; the core is `primary`, the
84
+ * pack's brand value as a fill. That split is not a preference. DESIGN.md's Fill,
85
+ * Not the Ink Rule says a pastel brand value is a fill and never text, so the
86
+ * core may be `primary` and the name may not, and the Brand Ink Rule says the
87
+ * name reads `brand-ink` rather than `foreground` or `primary-foreground`. A
88
+ * hand-written copy gets one of those two wrong and nothing in the rendered
89
+ * result says which.
90
+ *
91
+ * Uniqueness across the set comes from the pack: each product wears its own
92
+ * pack's hue, and the one entry with no pack wears the spectrum, so no two marks
93
+ * in a set resolve to the same pair of colours. The set is the consumer's data.
94
+ * This Component draws one member of it, and it is the same member wherever it is
95
+ * drawn from.
96
+ *
97
+ * The mark carries its own `data-pack` boundary on its root, so a product's hue
98
+ * follows from the pack the caller passed rather than from whichever pack the
99
+ * page happens to be wearing, and a boundary lands on the mark rather than on
100
+ * whatever encloses it. The boundary is on a span carrying no radius utility,
101
+ * which is one of the two placements DESIGN.md's pack-boundary law allows, and
102
+ * the disc itself is fully rounded. Nothing about the mark's shape moves when a
103
+ * pack boundary lands above it, which is the half of that law a consumer
104
+ * implementing only the colour half gets wrong.
105
+ *
106
+ * It is a server Component: no hook, no mode, no context, no client code and no
107
+ * `'use client'` line. A consumer renders it from a server file and needs
108
+ * nothing from the provider mounted.
109
+ *
110
+ * The disc is `aria-hidden` and the name is not, so the mark adds a shape beside
111
+ * the word rather than a second reading of it.
112
+ */
113
+ declare function ProductMark({ id, name, pack, size, className }: ProductMarkProps): import("react").JSX.Element;
114
+ export { ProductMark };
115
+ //# sourceMappingURL=product-mark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-mark.d.ts","sourceRoot":"","sources":["../../../src/components/ui/product-mark.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AA2B3C;;;;;;;;GAQG;AACH,QAAA,MAAM,KAAK;;;;;;;;;;;;;CAID,CAAA;AAEV;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,KAAK,CAAA;AAEhD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,iBAAS,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BA2BhF;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}