@visuno/angular 0.0.0-stage → 0.1.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 (175) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +56 -2
  3. package/account-table/account-table.component.d.ts +72 -0
  4. package/action-log/action-log.component.d.ts +41 -0
  5. package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
  6. package/agent-inbox/agent-inbox.component.d.ts +75 -0
  7. package/agent-lanes/agent-lanes.component.d.ts +152 -0
  8. package/agent-phases/agent-phases.component.d.ts +62 -0
  9. package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
  10. package/agent-tree/agent-tree.component.d.ts +80 -0
  11. package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
  12. package/artifact-card/artifact-card.component.d.ts +145 -0
  13. package/attachment-tray/attachment-tray.component.d.ts +84 -0
  14. package/badge/badge.component.d.ts +25 -0
  15. package/bar-chart/bar-chart.component.d.ts +87 -0
  16. package/browser-session/browser-session.component.d.ts +70 -0
  17. package/buttons/buttons.component.d.ts +63 -0
  18. package/card/card.component.d.ts +21 -0
  19. package/change-review/change-review.component.d.ts +97 -0
  20. package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
  21. package/code-viewer/code-viewer.component.d.ts +86 -0
  22. package/composer/composer.component.d.ts +114 -0
  23. package/context-meter/context-meter.component.d.ts +60 -0
  24. package/core/icon.component.d.ts +10 -0
  25. package/core/reduced-motion.service.d.ts +15 -0
  26. package/decision-prompt/decision-prompt.component.d.ts +56 -0
  27. package/design-review/design-review.component.d.ts +108 -0
  28. package/design-tuner/design-tuner.component.d.ts +75 -0
  29. package/details-panel/details-panel.component.d.ts +150 -0
  30. package/donut-chart/donut-chart.component.d.ts +63 -0
  31. package/draft-review/draft-review.component.d.ts +128 -0
  32. package/error-recovery/error-recovery.component.d.ts +59 -0
  33. package/esm2022/account-table/account-table.component.mjs +399 -0
  34. package/esm2022/action-log/action-log.component.mjs +177 -0
  35. package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
  36. package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
  37. package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
  38. package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
  39. package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
  40. package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
  41. package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
  42. package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
  43. package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
  44. package/esm2022/badge/badge.component.mjs +97 -0
  45. package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
  46. package/esm2022/browser-session/browser-session.component.mjs +352 -0
  47. package/esm2022/buttons/buttons.component.mjs +215 -0
  48. package/esm2022/card/card.component.mjs +107 -0
  49. package/esm2022/change-review/change-review.component.mjs +398 -0
  50. package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
  51. package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
  52. package/esm2022/composer/composer.component.mjs +743 -0
  53. package/esm2022/context-meter/context-meter.component.mjs +275 -0
  54. package/esm2022/core/icon.component.mjs +111 -0
  55. package/esm2022/core/reduced-motion.service.mjs +34 -0
  56. package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
  57. package/esm2022/design-review/design-review.component.mjs +428 -0
  58. package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
  59. package/esm2022/details-panel/details-panel.component.mjs +537 -0
  60. package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
  61. package/esm2022/draft-review/draft-review.component.mjs +549 -0
  62. package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
  63. package/esm2022/eval-results/eval-results.component.mjs +368 -0
  64. package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
  65. package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
  66. package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
  67. package/esm2022/grid/grid.component.mjs +66 -0
  68. package/esm2022/health-score/health-score.component.mjs +420 -0
  69. package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
  70. package/esm2022/image-generation/image-generation.component.mjs +1028 -0
  71. package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
  72. package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
  73. package/esm2022/line-chart/line-chart.component.mjs +417 -0
  74. package/esm2022/live-answer/live-answer.component.mjs +411 -0
  75. package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
  76. package/esm2022/modal/modal.component.mjs +202 -0
  77. package/esm2022/model-picker/model-picker.component.mjs +491 -0
  78. package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
  79. package/esm2022/plan-review/plan-review.component.mjs +432 -0
  80. package/esm2022/progress/progress.component.mjs +503 -0
  81. package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
  82. package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
  83. package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
  84. package/esm2022/public-api.mjs +88 -0
  85. package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
  86. package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
  87. package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
  88. package/esm2022/response-versions/response-versions.component.mjs +288 -0
  89. package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
  90. package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
  91. package/esm2022/run-cost/run-cost.component.mjs +215 -0
  92. package/esm2022/run-queue/run-queue.component.mjs +481 -0
  93. package/esm2022/run-summary/run-summary.component.mjs +331 -0
  94. package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
  95. package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
  96. package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
  97. package/esm2022/source-stack/source-stack.component.mjs +245 -0
  98. package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
  99. package/esm2022/status-pill/status-pill.component.mjs +305 -0
  100. package/esm2022/steering/steering.component.mjs +343 -0
  101. package/esm2022/step-loader/step-loader.component.mjs +209 -0
  102. package/esm2022/task-table/task-table.component.mjs +534 -0
  103. package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
  104. package/esm2022/thinking/thinking.component.mjs +276 -0
  105. package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
  106. package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
  107. package/esm2022/toast/toast.component.mjs +195 -0
  108. package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
  109. package/esm2022/tool-call/tool-call.component.mjs +273 -0
  110. package/esm2022/tooltip/tooltip.component.mjs +417 -0
  111. package/esm2022/top-pages/top-pages.component.mjs +240 -0
  112. package/esm2022/trace-view/trace-view.component.mjs +440 -0
  113. package/esm2022/visuno-angular.mjs +5 -0
  114. package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
  115. package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
  116. package/esm2022/web-search/web-search.component.mjs +374 -0
  117. package/eval-results/eval-results.component.d.ts +67 -0
  118. package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
  119. package/fesm2022/visuno-angular.mjs +31992 -0
  120. package/fesm2022/visuno-angular.mjs.map +1 -0
  121. package/field-extraction/field-extraction.component.d.ts +82 -0
  122. package/funnel-chart/funnel-chart.component.d.ts +70 -0
  123. package/grid/grid.component.d.ts +22 -0
  124. package/health-score/health-score.component.d.ts +87 -0
  125. package/human-handoff/human-handoff.component.d.ts +125 -0
  126. package/image-generation/image-generation.component.d.ts +253 -0
  127. package/index.d.ts +5 -0
  128. package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
  129. package/launch-checklist/launch-checklist.component.d.ts +46 -0
  130. package/line-chart/line-chart.component.d.ts +89 -0
  131. package/live-answer/live-answer.component.d.ts +110 -0
  132. package/metric-insight/metric-insight.component.d.ts +110 -0
  133. package/modal/modal.component.d.ts +37 -0
  134. package/model-picker/model-picker.component.d.ts +97 -0
  135. package/package.json +51 -4
  136. package/permission-gate/permission-gate.component.d.ts +100 -0
  137. package/plan-review/plan-review.component.d.ts +86 -0
  138. package/progress/progress.component.d.ts +91 -0
  139. package/prompt-library/prompt-library.component.d.ts +121 -0
  140. package/prompt-starters/prompt-starters.component.d.ts +65 -0
  141. package/proposal-card/proposal-card.component.d.ts +101 -0
  142. package/public-api.d.ts +82 -0
  143. package/radar-chart/radar-chart.component.d.ts +110 -0
  144. package/radial-goals/radial-goals.component.d.ts +90 -0
  145. package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
  146. package/response-versions/response-versions.component.d.ts +54 -0
  147. package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
  148. package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
  149. package/run-cost/run-cost.component.d.ts +43 -0
  150. package/run-queue/run-queue.component.d.ts +93 -0
  151. package/run-summary/run-summary.component.d.ts +81 -0
  152. package/scatter-chart/scatter-chart.component.d.ts +139 -0
  153. package/score-breakdown/score-breakdown.component.d.ts +107 -0
  154. package/segmented-control/segmented-control.component.d.ts +44 -0
  155. package/source-stack/source-stack.component.d.ts +60 -0
  156. package/stat-cards/stat-cards.component.d.ts +86 -0
  157. package/status-pill/status-pill.component.d.ts +64 -0
  158. package/steering/steering.component.d.ts +75 -0
  159. package/step-loader/step-loader.component.d.ts +40 -0
  160. package/styles.css +424 -0
  161. package/task-table/task-table.component.d.ts +114 -0
  162. package/terminal-stream/terminal-stream.component.d.ts +110 -0
  163. package/thinking/thinking.component.d.ts +63 -0
  164. package/thinking-states/thinking-states.component.d.ts +51 -0
  165. package/thread-panel/thread-panel.component.d.ts +75 -0
  166. package/toast/toast.component.d.ts +56 -0
  167. package/toast-stack/toast-stack.component.d.ts +72 -0
  168. package/tokens.css +424 -0
  169. package/tool-call/tool-call.component.d.ts +61 -0
  170. package/tooltip/tooltip.component.d.ts +89 -0
  171. package/top-pages/top-pages.component.d.ts +75 -0
  172. package/trace-view/trace-view.component.d.ts +95 -0
  173. package/voice-capture/voice-capture.component.d.ts +103 -0
  174. package/voice-orb/voice-orb.component.d.ts +78 -0
  175. package/web-search/web-search.component.d.ts +77 -0
@@ -0,0 +1,215 @@
1
+ // framework/angular/buttons/buttons.component.ts
2
+ //
3
+ // Native Angular port of the Button from framework/react/buttons/Buttons.tsx.
4
+ // A pill button in one of five styles and three sizes, with busy, done and
5
+ // pressed states. An async click handler drives the busy -> done face itself.
6
+ // Inputs mirror the React ButtonProps; the label comes via content projection
7
+ // (or the `label` input), callbacks become an @Output() click.
8
+ //
9
+ // The optional round icon button (ButtonIcon) and the copy button (ButtonCopy)
10
+ // are ported in the same file for completeness.
11
+ import { Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
12
+ import { VoIconComponent } from '../core/icon.component';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "../core/reduced-motion.service";
15
+ /** The class for a variant: ink, the old name, draws as primary. */
16
+ const variantClass = (v) => v ? 'vo-' + (v === 'ink' ? 'primary' : v) : null;
17
+ /** A pill button in one of the site's five styles and three sizes, with busy, done and pressed states. */
18
+ export class ButtonComponent {
19
+ constructor(motion) {
20
+ this.motion = motion;
21
+ this.size = 'md';
22
+ /** spin, or think: the agent's four turning dots with a shimmering label. */
23
+ this.busyGlyph = 'spin';
24
+ /** How long the done face stays when the button runs itself. */
25
+ this.doneFor = 1800;
26
+ /** Going back from done to the label blurs across (the default) instead of switching at once. */
27
+ this.fadeBack = true;
28
+ /** Emitted on a plain click (when not busy/done). */
29
+ this.clicked = new EventEmitter();
30
+ // an async handler that returns a promise drives the button itself
31
+ this.auto = 'idle';
32
+ this.alive = true;
33
+ /** True while the face blurs out before it is swapped. */
34
+ this.out = false;
35
+ }
36
+ get isBusy() {
37
+ return this.busy ?? this.auto === 'busy';
38
+ }
39
+ get isDone() {
40
+ return !this.isBusy && (this.done ?? this.auto === 'done');
41
+ }
42
+ get think() {
43
+ return this.isBusy && this.busyGlyph === 'think';
44
+ }
45
+ get variantCls() {
46
+ return variantClass(this.variant);
47
+ }
48
+ get shownLabel() {
49
+ if (this.isBusy)
50
+ return this.busyLabel ?? this.label;
51
+ if (this.isDone)
52
+ return this.doneLabel ?? this.label;
53
+ return this.label;
54
+ }
55
+ onClick(e) {
56
+ if (this.isBusy || this.isDone)
57
+ return;
58
+ this.clicked.emit(e);
59
+ const r = this.handler?.();
60
+ if (!r || typeof r.then !== 'function')
61
+ return;
62
+ this.auto = 'busy';
63
+ r.then(() => {
64
+ if (!this.alive)
65
+ return;
66
+ this.auto = 'done';
67
+ this.timer = setTimeout(() => this.back(), this.doneFor);
68
+ }, () => {
69
+ if (this.alive)
70
+ this.auto = 'idle';
71
+ });
72
+ }
73
+ /** Blurs the done face out before it becomes the idle label again (fadeBack). */
74
+ back() {
75
+ if (!this.fadeBack) {
76
+ this.auto = 'idle';
77
+ return;
78
+ }
79
+ this.out = true;
80
+ this.swapTimer = setTimeout(() => {
81
+ this.auto = 'idle';
82
+ this.out = false;
83
+ }, this.motion.reduce() ? 0 : 170);
84
+ }
85
+ ngOnDestroy() {
86
+ this.alive = false;
87
+ clearTimeout(this.timer);
88
+ clearTimeout(this.swapTimer);
89
+ }
90
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, deps: [{ token: i1.ReducedMotionService }], target: i0.ɵɵFactoryTarget.Component }); }
91
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "vo-button", inputs: { variant: "variant", size: "size", icon: "icon", label: "label", busy: "busy", done: "done", busyLabel: "busyLabel", doneLabel: "doneLabel", doneIcon: "doneIcon", busyGlyph: "busyGlyph", success: "success", doneFor: "doneFor", fadeBack: "fadeBack", pressed: "pressed", handler: "handler" }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
92
+ <span data-vo="" style="display:contents">
93
+ <button
94
+ type="button"
95
+ class="vo-pill"
96
+ [class.vo-sm]="size === 'sm'"
97
+ [class.vo-btx-lg]="size === 'lg'"
98
+ [class.vo-busy]="isBusy"
99
+ [class.vo-done]="isDone"
100
+ [class.vo-btx-load]="isDone && success"
101
+ [class.vo-ok]="isDone && success"
102
+ [class]="variantCls"
103
+ [attr.aria-busy]="isBusy ? true : null"
104
+ [attr.aria-pressed]="pressed ?? null"
105
+ (click)="onClick($event)"
106
+ >
107
+ <span class="vo-sw" [class.vo-out]="out" style="display:inline-flex;align-items:center;gap:7px">
108
+ @if (isBusy) {
109
+ @if (think) {
110
+ <span class="vo-think vo-on" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
111
+ <span class="vo-shim">{{ shownLabel }}</span>
112
+ } @else {
113
+ <span class="vo-spin" aria-hidden="true"></span>
114
+ <span>{{ shownLabel }}</span>
115
+ }
116
+ } @else if (isDone) {
117
+ @if (doneIcon) {
118
+ <span class="vo-enter" style="display:inline-flex;align-items:center;gap:7px">
119
+ <vo-icon [name]="doneIcon" size="xs"></vo-icon>
120
+ </span>
121
+ } @else {
122
+ <vo-icon name="check" size="xs" class="vo-enter"></vo-icon>
123
+ }
124
+ <span>{{ shownLabel }}</span>
125
+ } @else {
126
+ @if (icon) {
127
+ <vo-icon [name]="icon" size="xs"></vo-icon>
128
+ }
129
+ <span><ng-content></ng-content>{{ label }}</span>
130
+ }
131
+ </span>
132
+ </button>
133
+ </span>
134
+ `, isInline: true, styles: [".vo-btx-lg{height:40px;padding:0 18px;font-size:14px}.vo-btx-load{min-width:100px;transition:min-width .4s var(--vo-ease),background .3s}.vo-btx-load .vo-spin{width:13px;height:13px;border-color:color-mix(in srgb,var(--vo-on-ink) 30%,transparent);border-top-color:var(--vo-on-ink)}.vo-pill.vo-btx-load.vo-ok{background:color-mix(in srgb,var(--vo-ok) 16%,var(--vo-surface));color:var(--vo-ok);opacity:1}@media (hover:hover) and (pointer:fine){.vo-pill.vo-btx-load.vo-ok:hover{background:color-mix(in srgb,var(--vo-ok) 16%,var(--vo-surface));color:var(--vo-ok);opacity:1}}.vo-btx-load.vo-busy{cursor:progress}.vo-pill.vo-sw{display:inline-flex}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
135
+ }
136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, decorators: [{
137
+ type: Component,
138
+ args: [{ selector: 'vo-button', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
139
+ <span data-vo="" style="display:contents">
140
+ <button
141
+ type="button"
142
+ class="vo-pill"
143
+ [class.vo-sm]="size === 'sm'"
144
+ [class.vo-btx-lg]="size === 'lg'"
145
+ [class.vo-busy]="isBusy"
146
+ [class.vo-done]="isDone"
147
+ [class.vo-btx-load]="isDone && success"
148
+ [class.vo-ok]="isDone && success"
149
+ [class]="variantCls"
150
+ [attr.aria-busy]="isBusy ? true : null"
151
+ [attr.aria-pressed]="pressed ?? null"
152
+ (click)="onClick($event)"
153
+ >
154
+ <span class="vo-sw" [class.vo-out]="out" style="display:inline-flex;align-items:center;gap:7px">
155
+ @if (isBusy) {
156
+ @if (think) {
157
+ <span class="vo-think vo-on" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
158
+ <span class="vo-shim">{{ shownLabel }}</span>
159
+ } @else {
160
+ <span class="vo-spin" aria-hidden="true"></span>
161
+ <span>{{ shownLabel }}</span>
162
+ }
163
+ } @else if (isDone) {
164
+ @if (doneIcon) {
165
+ <span class="vo-enter" style="display:inline-flex;align-items:center;gap:7px">
166
+ <vo-icon [name]="doneIcon" size="xs"></vo-icon>
167
+ </span>
168
+ } @else {
169
+ <vo-icon name="check" size="xs" class="vo-enter"></vo-icon>
170
+ }
171
+ <span>{{ shownLabel }}</span>
172
+ } @else {
173
+ @if (icon) {
174
+ <vo-icon [name]="icon" size="xs"></vo-icon>
175
+ }
176
+ <span><ng-content></ng-content>{{ label }}</span>
177
+ }
178
+ </span>
179
+ </button>
180
+ </span>
181
+ `, styles: [".vo-btx-lg{height:40px;padding:0 18px;font-size:14px}.vo-btx-load{min-width:100px;transition:min-width .4s var(--vo-ease),background .3s}.vo-btx-load .vo-spin{width:13px;height:13px;border-color:color-mix(in srgb,var(--vo-on-ink) 30%,transparent);border-top-color:var(--vo-on-ink)}.vo-pill.vo-btx-load.vo-ok{background:color-mix(in srgb,var(--vo-ok) 16%,var(--vo-surface));color:var(--vo-ok);opacity:1}@media (hover:hover) and (pointer:fine){.vo-pill.vo-btx-load.vo-ok:hover{background:color-mix(in srgb,var(--vo-ok) 16%,var(--vo-surface));color:var(--vo-ok);opacity:1}}.vo-btx-load.vo-busy{cursor:progress}.vo-pill.vo-sw{display:inline-flex}\n"] }]
182
+ }], ctorParameters: () => [{ type: i1.ReducedMotionService }], propDecorators: { variant: [{
183
+ type: Input
184
+ }], size: [{
185
+ type: Input
186
+ }], icon: [{
187
+ type: Input
188
+ }], label: [{
189
+ type: Input
190
+ }], busy: [{
191
+ type: Input
192
+ }], done: [{
193
+ type: Input
194
+ }], busyLabel: [{
195
+ type: Input
196
+ }], doneLabel: [{
197
+ type: Input
198
+ }], doneIcon: [{
199
+ type: Input
200
+ }], busyGlyph: [{
201
+ type: Input
202
+ }], success: [{
203
+ type: Input
204
+ }], doneFor: [{
205
+ type: Input
206
+ }], fadeBack: [{
207
+ type: Input
208
+ }], pressed: [{
209
+ type: Input
210
+ }], handler: [{
211
+ type: Input
212
+ }], clicked: [{
213
+ type: Output
214
+ }] } });
215
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9ucy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9idXR0b25zL2J1dHRvbnMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlEQUFpRDtBQUNqRCxFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLDJFQUEyRTtBQUMzRSw4RUFBOEU7QUFDOUUsOEVBQThFO0FBQzlFLCtEQUErRDtBQUMvRCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLGdEQUFnRDtBQUVoRCxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFtQixNQUFNLHdCQUF3QixDQUFDOzs7QUFPMUUsb0VBQW9FO0FBQ3BFLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBaUIsRUFBaUIsRUFBRSxDQUN4RCxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUVuRCwwR0FBMEc7QUFvRDFHLE1BQU0sT0FBTyxlQUFlO0lBOEMxQixZQUE2QixNQUE0QjtRQUE1QixXQUFNLEdBQU4sTUFBTSxDQUFzQjtRQTNDaEQsU0FBSSxHQUFlLElBQUksQ0FBQztRQWVqQyw2RUFBNkU7UUFDcEUsY0FBUyxHQUFxQixNQUFNLENBQUM7UUFHOUMsZ0VBQWdFO1FBQ3ZELFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDeEIsaUdBQWlHO1FBQ3hGLGFBQVEsR0FBRyxJQUFJLENBQUM7UUFVekIscURBQXFEO1FBQzNDLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBYyxDQUFDO1FBRW5ELG1FQUFtRTtRQUMzRCxTQUFJLEdBQTZCLE1BQU0sQ0FBQztRQUN4QyxVQUFLLEdBQUcs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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQ1QsOHNCQTVDUyxlQUFlOzs0RkErQ2QsZUFBZTtrQkFuRDNCLFNBQVM7K0JBQ0UsV0FBVyxjQUNULElBQUksaUJBQ0QsaUJBQWlCLENBQUMsSUFBSSxXQUM1QixDQUFDLGVBQWUsQ0FBQyxZQUNoQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJDVDt5RkFLUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBTUcsT0FBTztzQkFBZixLQUFLO2dCQUdJLE9BQU87c0JBQWhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvLyBmcmFtZXdvcmsvYW5ndWxhci9idXR0b25zL2J1dHRvbnMuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiB0aGUgQnV0dG9uIGZyb20gZnJhbWV3b3JrL3JlYWN0L2J1dHRvbnMvQnV0dG9ucy50c3guXG4vLyBBIHBpbGwgYnV0dG9uIGluIG9uZSBvZiBmaXZlIHN0eWxlcyBhbmQgdGhyZWUgc2l6ZXMsIHdpdGggYnVzeSwgZG9uZSBhbmRcbi8vIHByZXNzZWQgc3RhdGVzLiBBbiBhc3luYyBjbGljayBoYW5kbGVyIGRyaXZlcyB0aGUgYnVzeSAtPiBkb25lIGZhY2UgaXRzZWxmLlxuLy8gSW5wdXRzIG1pcnJvciB0aGUgUmVhY3QgQnV0dG9uUHJvcHM7IHRoZSBsYWJlbCBjb21lcyB2aWEgY29udGVudCBwcm9qZWN0aW9uXG4vLyAob3IgdGhlIGBsYWJlbGAgaW5wdXQpLCBjYWxsYmFja3MgYmVjb21lIGFuIEBPdXRwdXQoKSBjbGljay5cbi8vXG4vLyBUaGUgb3B0aW9uYWwgcm91bmQgaWNvbiBidXR0b24gKEJ1dHRvbkljb24pIGFuZCB0aGUgY29weSBidXR0b24gKEJ1dHRvbkNvcHkpXG4vLyBhcmUgcG9ydGVkIGluIHRoZSBzYW1lIGZpbGUgZm9yIGNvbXBsZXRlbmVzcy5cblxuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVm9JY29uQ29tcG9uZW50LCB0eXBlIFZvSWNvbk5hbWUgfSBmcm9tICcuLi9jb3JlL2ljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFJlZHVjZWRNb3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9yZWR1Y2VkLW1vdGlvbi5zZXJ2aWNlJztcblxuLyoqIHByaW1hcnkgaXMgdGhlIG1haW4gYWN0aW9uLCBvbiB0aGUgYWNjZW50LiBpbmsgaXMgdGhlIG9sZCBuYW1lIGZvciBwcmltYXJ5IGFuZCBzdGlsbCB3b3Jrcy4gKi9cbmV4cG9ydCB0eXBlIEJ1dHRvblZhcmlhbnQgPSAncHJpbWFyeScgfCAnYWNjZW50JyB8ICdzb2Z0JyB8ICdsaW5lJyB8ICdnaG9zdCcgfCAnaW5rJztcbmV4cG9ydCB0eXBlIEJ1dHRvblNpemUgPSAnc20nIHwgJ21kJyB8ICdsZyc7XG5cbi8qKiBUaGUgY2xhc3MgZm9yIGEgdmFyaWFudDogaW5rLCB0aGUgb2xkIG5hbWUsIGRyYXdzIGFzIHByaW1hcnkuICovXG5jb25zdCB2YXJpYW50Q2xhc3MgPSAodj86IEJ1dHRvblZhcmlhbnQpOiBzdHJpbmcgfCBudWxsID0+XG4gIHYgPyAndm8tJyArICh2ID09PSAnaW5rJyA/ICdwcmltYXJ5JyA6IHYpIDogbnVsbDtcblxuLyoqIEEgcGlsbCBidXR0b24gaW4gb25lIG9mIHRoZSBzaXRlJ3MgZml2ZSBzdHlsZXMgYW5kIHRocmVlIHNpemVzLCB3aXRoIGJ1c3ksIGRvbmUgYW5kIHByZXNzZWQgc3RhdGVzLiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tYnV0dG9uJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaW1wb3J0czogW1ZvSWNvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPHNwYW4gZGF0YS12bz1cIlwiIHN0eWxlPVwiZGlzcGxheTpjb250ZW50c1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJ2by1waWxsXCJcbiAgICAgICAgW2NsYXNzLnZvLXNtXT1cInNpemUgPT09ICdzbSdcIlxuICAgICAgICBbY2xhc3Mudm8tYnR4LWxnXT1cInNpemUgPT09ICdsZydcIlxuICAgICAgICBbY2xhc3Mudm8tYnVzeV09XCJpc0J1c3lcIlxuICAgICAgICBbY2xhc3Mudm8tZG9uZV09XCJpc0RvbmVcIlxuICAgICAgICBbY2xhc3Mudm8tYnR4LWxvYWRdPVwiaXNEb25lICYmIHN1Y2Nlc3NcIlxuICAgICAgICBbY2xhc3Mudm8tb2tdPVwiaXNEb25lICYmIHN1Y2Nlc3NcIlxuICAgICAgICBbY2xhc3NdPVwidmFyaWFudENsc1wiXG4gICAgICAgIFthdHRyLmFyaWEtYnVzeV09XCJpc0J1c3kgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJwcmVzc2VkID8/IG51bGxcIlxuICAgICAgICAoY2xpY2spPVwib25DbGljaygkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zd1wiIFtjbGFzcy52by1vdXRdPVwib3V0XCIgc3R5bGU9XCJkaXNwbGF5OmlubGluZS1mbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6N3B4XCI+XG4gICAgICAgICAgQGlmIChpc0J1c3kpIHtcbiAgICAgICAgICAgIEBpZiAodGhpbmspIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by10aGluayB2by1vblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjxpPjwvaT48aT48L2k+PGk+PC9pPjxpPjwvaT48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tc2hpbVwiPnt7IHNob3duTGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zcGluXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBzaG93bkxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gQGVsc2UgaWYgKGlzRG9uZSkge1xuICAgICAgICAgICAgQGlmIChkb25lSWNvbikge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWVudGVyXCIgc3R5bGU9XCJkaXNwbGF5OmlubGluZS1mbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6N3B4XCI+XG4gICAgICAgICAgICAgICAgPHZvLWljb24gW25hbWVdPVwiZG9uZUljb25cIiBzaXplPVwieHNcIj48L3ZvLWljb24+XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8dm8taWNvbiBuYW1lPVwiY2hlY2tcIiBzaXplPVwieHNcIiBjbGFzcz1cInZvLWVudGVyXCI+PC92by1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPHNwYW4+e3sgc2hvd25MYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIEBpZiAoaWNvbikge1xuICAgICAgICAgICAgICA8dm8taWNvbiBbbmFtZV09XCJpY29uXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPHNwYW4+PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50Pnt7IGxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9zcGFuPlxuICBgLFxuICBzdHlsZVVybDogJy4vYnV0dG9ucy5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBCdXR0b25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKiogcHJpbWFyeS9hY2NlbnQgZm9yIHRoZSBtYWluIGFjdGlvbiwgc29mdCBhbmQgbGluZSBmb3IgdGhlIHJlc3QsIGdob3N0IGZvciB0aGUgcXVpZXRlc3QuICovXG4gIEBJbnB1dCgpIHZhcmlhbnQ/OiBCdXR0b25WYXJpYW50O1xuICBASW5wdXQoKSBzaXplOiBCdXR0b25TaXplID0gJ21kJztcbiAgLyoqIEFuIGljb24gYmVmb3JlIHRoZSBsYWJlbC4gKi9cbiAgQElucHV0KCkgaWNvbj86IFZvSWNvbk5hbWU7XG4gIC8qKiBUaGUgbGFiZWwgKGFsdGVybmF0aXZlIHRvIHByb2plY3RlZCBjb250ZW50KS4gKi9cbiAgQElucHV0KCkgbGFiZWw/OiBzdHJpbmc7XG4gIC8qKiBTaG93cyB0aGUgYnVzeSBmYWNlOiBhIHNwaW5uZXIgKG9yIHRoaW5raW5nIGRvdHMpIGFuZCBidXN5TGFiZWwuIENsaWNrcyBhcmUgaWdub3JlZC4gKi9cbiAgQElucHV0KCkgYnVzeT86IGJvb2xlYW47XG4gIC8qKiBTaG93cyB0aGUgZG9uZSBmYWNlOiBhIGNoZWNrIHRoYXQgcG9wcyBpbiBhbmQgZG9uZUxhYmVsLiBDbGlja3MgYXJlIGlnbm9yZWQuICovXG4gIEBJbnB1dCgpIGRvbmU/OiBib29sZWFuO1xuICAvKiogVGhlIGxhYmVsIHdoaWxlIGJ1c3ksIGxpa2UgXCJQdWJsaXNoaW5nXCIuIERlZmF1bHRzIHRvIHRoZSBsYWJlbC4gKi9cbiAgQElucHV0KCkgYnVzeUxhYmVsPzogc3RyaW5nO1xuICAvKiogVGhlIGxhYmVsIG9uY2UgZG9uZSwgbGlrZSBcIlB1Ymxpc2hlZFwiLiBEZWZhdWx0cyB0byB0aGUgbGFiZWwuICovXG4gIEBJbnB1dCgpIGRvbmVMYWJlbD86IHN0cmluZztcbiAgLyoqIFRoZSBpY29uIG9uIHRoZSBkb25lIGZhY2UuIERlZmF1bHRzIHRvIGEgY2hlY2sgdGhhdCBwb3BzIGluLiAqL1xuICBASW5wdXQoKSBkb25lSWNvbj86IFZvSWNvbk5hbWU7XG4gIC8qKiBzcGluLCBvciB0aGluazogdGhlIGFnZW50J3MgZm91ciB0dXJuaW5nIGRvdHMgd2l0aCBhIHNoaW1tZXJpbmcgbGFiZWwuICovXG4gIEBJbnB1dCgpIGJ1c3lHbHlwaDogJ3NwaW4nIHwgJ3RoaW5rJyA9ICdzcGluJztcbiAgLyoqIFRoZSBkb25lIGZhY2UgdHVybnMgZ3JlZW4uICovXG4gIEBJbnB1dCgpIHN1Y2Nlc3M/OiBib29sZWFuO1xuICAvKiogSG93IGxvbmcgdGhlIGRvbmUgZmFjZSBzdGF5cyB3aGVuIHRoZSBidXR0b24gcnVucyBpdHNlbGYuICovXG4gIEBJbnB1dCgpIGRvbmVGb3IgPSAxODAwO1xuICAvKiogR29pbmcgYmFjayBmcm9tIGRvbmUgdG8gdGhlIGxhYmVsIGJsdXJzIGFjcm9zcyAodGhlIGRlZmF1bHQpIGluc3RlYWQgb2Ygc3dpdGNoaW5nIGF0IG9uY2UuICovXG4gIEBJbnB1dCgpIGZhZGVCYWNrID0gdHJ1ZTtcbiAgLyoqIEZvciBhIHRvZ2dsZTogd2hldGhlciBpdCBpcyBvbiwgYXMgYXJpYS1wcmVzc2VkLiAqL1xuICBASW5wdXQoKSBwcmVzc2VkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBwbGFpbiBjbGljay4gUmV0dXJuIGEgUHJvbWlzZSAocmVzb2x2ZSB3aXRoIGFueSB2YWx1ZSkgYW5kIHRoZSBidXR0b25cbiAgICogcnVucyBieSBpdHNlbGY6IGJ1c3kgdW50aWwgaXQgc2V0dGxlcywgdGhlbiBkb25lIGZvciBgZG9uZUZvcmAgbXMuXG4gICAqL1xuICBASW5wdXQoKSBoYW5kbGVyPzogKCkgPT4gdm9pZCB8IFByb21pc2U8dW5rbm93bj47XG5cbiAgLyoqIEVtaXR0ZWQgb24gYSBwbGFpbiBjbGljayAod2hlbiBub3QgYnVzeS9kb25lKS4gKi9cbiAgQE91dHB1dCgpIGNsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPE1vdXNlRXZlbnQ+KCk7XG5cbiAgLy8gYW4gYXN5bmMgaGFuZGxlciB0aGF0IHJldHVybnMgYSBwcm9taXNlIGRyaXZlcyB0aGUgYnV0dG9uIGl0c2VsZlxuICBwcml2YXRlIGF1dG86ICdpZGxlJyB8ICdidXN5JyB8ICdkb25lJyA9ICdpZGxlJztcbiAgcHJpdmF0ZSBhbGl2ZSA9IHRydWU7XG4gIHByaXZhdGUgdGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSBzd2FwVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgLyoqIFRydWUgd2hpbGUgdGhlIGZhY2UgYmx1cnMgb3V0IGJlZm9yZSBpdCBpcyBzd2FwcGVkLiAqL1xuICBvdXQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG1vdGlvbjogUmVkdWNlZE1vdGlvblNlcnZpY2UpIHt9XG5cbiAgZ2V0IGlzQnVzeSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5idXN5ID8/IHRoaXMuYXV0byA9PT0gJ2J1c3knO1xuICB9XG4gIGdldCBpc0RvbmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLmlzQnVzeSAmJiAodGhpcy5kb25lID8/IHRoaXMuYXV0byA9PT0gJ2RvbmUnKTtcbiAgfVxuICBnZXQgdGhpbmsoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNCdXN5ICYmIHRoaXMuYnVzeUdseXBoID09PSAndGhpbmsnO1xuICB9XG4gIGdldCB2YXJpYW50Q2xzKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB2YXJpYW50Q2xhc3ModGhpcy52YXJpYW50KTtcbiAgfVxuXG4gIGdldCBzaG93bkxhYmVsKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuaXNCdXN5KSByZXR1cm4gdGhpcy5idXN5TGFiZWwgPz8gdGhpcy5sYWJlbDtcbiAgICBpZiAodGhpcy5pc0RvbmUpIHJldHVybiB0aGlzLmRvbmVMYWJlbCA/PyB0aGlzLmxhYmVsO1xuICAgIHJldHVybiB0aGlzLmxhYmVsO1xuICB9XG5cbiAgb25DbGljayhlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNCdXN5IHx8IHRoaXMuaXNEb25lKSByZXR1cm47XG4gICAgdGhpcy5jbGlja2VkLmVtaXQoZSk7XG4gICAgY29uc3QgciA9IHRoaXMuaGFuZGxlcj8uKCk7XG4gICAgaWYgKCFyIHx8IHR5cGVvZiAociBhcyBQcm9taXNlPHVua25vd24+KS50aGVuICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XG4gICAgdGhpcy5hdXRvID0gJ2J1c3knO1xuICAgIChyIGFzIFByb21pc2U8dW5rbm93bj4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5hbGl2ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmF1dG8gPSAnZG9uZSc7XG4gICAgICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuYmFjaygpLCB0aGlzLmRvbmVGb3IpO1xuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuYWxpdmUpIHRoaXMuYXV0byA9ICdpZGxlJztcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBCbHVycyB0aGUgZG9uZSBmYWNlIG91dCBiZWZvcmUgaXQgYmVjb21lcyB0aGUgaWRsZSBsYWJlbCBhZ2FpbiAoZmFkZUJhY2spLiAqL1xuICBwcml2YXRlIGJhY2soKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmZhZGVCYWNrKSB7XG4gICAgICB0aGlzLmF1dG8gPSAnaWRsZSc7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub3V0ID0gdHJ1ZTtcbiAgICB0aGlzLnN3YXBUaW1lciA9IHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuYXV0byA9ICdpZGxlJztcbiAgICAgICAgdGhpcy5vdXQgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICB0aGlzLm1vdGlvbi5yZWR1Y2UoKSA/IDAgOiAxNzAsXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuYWxpdmUgPSBmYWxzZTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuc3dhcFRpbWVyKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,107 @@
1
+ // framework/angular/card/card.component.ts
2
+ //
3
+ // Native Angular port of framework/react/card/Card.tsx.
4
+ // A surface you drop other components onto, with an optional header, body and
5
+ // footer. Inputs mirror the React props; content is projected via <ng-content>
6
+ // with named slots for the header end and the footer.
7
+ import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
8
+ import * as i0 from "@angular/core";
9
+ export class CardComponent {
10
+ constructor() {
11
+ /** How the footer's actions align. 'end' by default. */
12
+ this.footerAlign = 'end';
13
+ /** Inset for header/body/footer. 'md' by default. */
14
+ this.pad = 'md';
15
+ /** Makes the whole card a hit target: lifts on hover, takes focus, fires (clicked) on Enter/Space. */
16
+ this.interactive = false;
17
+ /** Emitted when an interactive card is activated (click or Enter/Space). */
18
+ this.clicked = new EventEmitter();
19
+ }
20
+ onKeyDown(e) {
21
+ if (!this.interactive)
22
+ return;
23
+ if (e.key === 'Enter' || e.key === ' ') {
24
+ e.preventDefault();
25
+ this.clicked.emit();
26
+ }
27
+ }
28
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CardComponent, isStandalone: true, selector: "vo-card", inputs: { title: "title", subtitle: "subtitle", footerAlign: "footerAlign", pad: "pad", interactive: "interactive" }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
30
+ <div
31
+ class="vo-crd"
32
+ [attr.data-pad]="pad === 'md' ? null : pad"
33
+ [attr.data-interactive]="interactive ? 'true' : null"
34
+ [attr.role]="interactive ? 'button' : null"
35
+ [attr.tabindex]="interactive ? 0 : null"
36
+ (click)="interactive && clicked.emit()"
37
+ (keydown)="onKeyDown($event)"
38
+ >
39
+ @if (title || subtitle) {
40
+ <div class="vo-crd-h">
41
+ <div class="vo-crd-hl">
42
+ @if (title) {
43
+ <span class="vo-crd-t">{{ title }}</span>
44
+ }
45
+ @if (subtitle) {
46
+ <span class="vo-crd-sub vo-muted">{{ subtitle }}</span>
47
+ }
48
+ </div>
49
+ <ng-content select="[card-action]"></ng-content>
50
+ </div>
51
+ }
52
+ <div class="vo-crd-b">
53
+ <ng-content></ng-content>
54
+ </div>
55
+ <div class="vo-crd-f" [attr.data-align]="footerAlign === 'end' ? null : footerAlign">
56
+ <ng-content select="[card-footer]"></ng-content>
57
+ </div>
58
+ </div>
59
+ `, isInline: true, styles: [".vo-crd{--vo-crd-pad:var(--vo-s-4);display:flex;flex-direction:column;min-width:0;background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow)}.vo-crd[data-pad=sm]{--vo-crd-pad:var(--vo-s-3)}.vo-crd[data-pad=none]{--vo-crd-pad:0}.vo-crd-h{display:flex;align-items:flex-start;gap:var(--vo-s-3);padding:var(--vo-crd-pad);padding-bottom:0}.vo-crd-hl{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.vo-crd-t{font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--vo-fg)}.vo-crd-sub{font-size:12.5px}.vo-crd-h>:not(.vo-crd-hl){flex:none}.vo-crd-b{padding:var(--vo-crd-pad);display:flex;flex-direction:column;gap:var(--vo-s-2);min-width:0;font-size:13px;color:var(--vo-fg2)}.vo-crd-b p{margin:0;line-height:1.5}.vo-crd-f{display:flex;align-items:center;justify-content:flex-end;gap:var(--vo-s-2);padding:var(--vo-crd-pad);padding-top:0}.vo-crd-f[data-align=start]{justify-content:flex-start}.vo-crd-f[data-align=between]{justify-content:space-between}.vo-crd-f:empty{display:none}.vo-crd[data-interactive=true]{cursor:pointer;transition:transform .45s var(--vo-ease),box-shadow .3s}@media (hover:hover) and (pointer:fine){.vo-crd[data-interactive=true]:hover{transform:translateY(-2px);box-shadow:var(--vo-shadow-pop)}}.vo-crd[data-interactive=true]:focus-visible{outline:2px solid var(--vo-focus);outline-offset:2px}@media (prefers-reduced-motion:reduce){.vo-crd[data-interactive=true]{transition:box-shadow .3s}}@media (prefers-reduced-motion:reduce) and (hover:hover) and (pointer:fine){.vo-crd[data-interactive=true]:hover{transform:none}}:root:not([data-style=soft]) .vo-crd:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px var(--vo-line)}\n"], encapsulation: i0.ViewEncapsulation.None }); }
60
+ }
61
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CardComponent, decorators: [{
62
+ type: Component,
63
+ args: [{ selector: 'vo-card', standalone: true, encapsulation: ViewEncapsulation.None, template: `
64
+ <div
65
+ class="vo-crd"
66
+ [attr.data-pad]="pad === 'md' ? null : pad"
67
+ [attr.data-interactive]="interactive ? 'true' : null"
68
+ [attr.role]="interactive ? 'button' : null"
69
+ [attr.tabindex]="interactive ? 0 : null"
70
+ (click)="interactive && clicked.emit()"
71
+ (keydown)="onKeyDown($event)"
72
+ >
73
+ @if (title || subtitle) {
74
+ <div class="vo-crd-h">
75
+ <div class="vo-crd-hl">
76
+ @if (title) {
77
+ <span class="vo-crd-t">{{ title }}</span>
78
+ }
79
+ @if (subtitle) {
80
+ <span class="vo-crd-sub vo-muted">{{ subtitle }}</span>
81
+ }
82
+ </div>
83
+ <ng-content select="[card-action]"></ng-content>
84
+ </div>
85
+ }
86
+ <div class="vo-crd-b">
87
+ <ng-content></ng-content>
88
+ </div>
89
+ <div class="vo-crd-f" [attr.data-align]="footerAlign === 'end' ? null : footerAlign">
90
+ <ng-content select="[card-footer]"></ng-content>
91
+ </div>
92
+ </div>
93
+ `, styles: [".vo-crd{--vo-crd-pad:var(--vo-s-4);display:flex;flex-direction:column;min-width:0;background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow)}.vo-crd[data-pad=sm]{--vo-crd-pad:var(--vo-s-3)}.vo-crd[data-pad=none]{--vo-crd-pad:0}.vo-crd-h{display:flex;align-items:flex-start;gap:var(--vo-s-3);padding:var(--vo-crd-pad);padding-bottom:0}.vo-crd-hl{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.vo-crd-t{font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--vo-fg)}.vo-crd-sub{font-size:12.5px}.vo-crd-h>:not(.vo-crd-hl){flex:none}.vo-crd-b{padding:var(--vo-crd-pad);display:flex;flex-direction:column;gap:var(--vo-s-2);min-width:0;font-size:13px;color:var(--vo-fg2)}.vo-crd-b p{margin:0;line-height:1.5}.vo-crd-f{display:flex;align-items:center;justify-content:flex-end;gap:var(--vo-s-2);padding:var(--vo-crd-pad);padding-top:0}.vo-crd-f[data-align=start]{justify-content:flex-start}.vo-crd-f[data-align=between]{justify-content:space-between}.vo-crd-f:empty{display:none}.vo-crd[data-interactive=true]{cursor:pointer;transition:transform .45s var(--vo-ease),box-shadow .3s}@media (hover:hover) and (pointer:fine){.vo-crd[data-interactive=true]:hover{transform:translateY(-2px);box-shadow:var(--vo-shadow-pop)}}.vo-crd[data-interactive=true]:focus-visible{outline:2px solid var(--vo-focus);outline-offset:2px}@media (prefers-reduced-motion:reduce){.vo-crd[data-interactive=true]{transition:box-shadow .3s}}@media (prefers-reduced-motion:reduce) and (hover:hover) and (pointer:fine){.vo-crd[data-interactive=true]:hover{transform:none}}:root:not([data-style=soft]) .vo-crd:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px var(--vo-line)}\n"] }]
94
+ }], propDecorators: { title: [{
95
+ type: Input
96
+ }], subtitle: [{
97
+ type: Input
98
+ }], footerAlign: [{
99
+ type: Input
100
+ }], pad: [{
101
+ type: Input
102
+ }], interactive: [{
103
+ type: Input
104
+ }], clicked: [{
105
+ type: Output
106
+ }] } });
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jYXJkL2NhcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDJDQUEyQztBQUMzQyxFQUFFO0FBQ0Ysd0RBQXdEO0FBQ3hELDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0Usc0RBQXNEO0FBRXRELE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBMEMxRixNQUFNLE9BQU8sYUFBYTtJQXJDMUI7UUEwQ0Usd0RBQXdEO1FBQy9DLGdCQUFXLEdBQWdDLEtBQUssQ0FBQztRQUMxRCxxREFBcUQ7UUFDNUMsUUFBRyxHQUFZLElBQUksQ0FBQztRQUM3QixzR0FBc0c7UUFDN0YsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFN0IsNEVBQTRFO1FBQ2xFLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0tBUzlDO0lBUEMsU0FBUyxDQUFDLENBQWdCO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU87UUFDOUIsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDOytHQXJCVSxhQUFhO21HQUFiLGFBQWEsME5BakNkOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4QlQ7OzRGQUdVLGFBQWE7a0JBckN6QixTQUFTOytCQUNFLFNBQVMsY0FDUCxJQUFJLGlCQUNELGlCQUFpQixDQUFDLElBQUksWUFDM0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCVDs4QkFLUSxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUdJLE9BQU87c0JBQWhCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvLyBmcmFtZXdvcmsvYW5ndWxhci9jYXJkL2NhcmQuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiBmcmFtZXdvcmsvcmVhY3QvY2FyZC9DYXJkLnRzeC5cbi8vIEEgc3VyZmFjZSB5b3UgZHJvcCBvdGhlciBjb21wb25lbnRzIG9udG8sIHdpdGggYW4gb3B0aW9uYWwgaGVhZGVyLCBib2R5IGFuZFxuLy8gZm9vdGVyLiBJbnB1dHMgbWlycm9yIHRoZSBSZWFjdCBwcm9wczsgY29udGVudCBpcyBwcm9qZWN0ZWQgdmlhIDxuZy1jb250ZW50PlxuLy8gd2l0aCBuYW1lZCBzbG90cyBmb3IgdGhlIGhlYWRlciBlbmQgYW5kIHRoZSBmb290ZXIuXG5cbmltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKiogSG93IG11Y2ggdGhlIGNhcmQgaW5zZXRzIGl0cyBoZWFkZXIsIGJvZHkgYW5kIGZvb3Rlci4gKi9cbmV4cG9ydCB0eXBlIENhcmRQYWQgPSAnbm9uZScgfCAnc20nIHwgJ21kJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tY2FyZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJ2by1jcmRcIlxuICAgICAgW2F0dHIuZGF0YS1wYWRdPVwicGFkID09PSAnbWQnID8gbnVsbCA6IHBhZFwiXG4gICAgICBbYXR0ci5kYXRhLWludGVyYWN0aXZlXT1cImludGVyYWN0aXZlID8gJ3RydWUnIDogbnVsbFwiXG4gICAgICBbYXR0ci5yb2xlXT1cImludGVyYWN0aXZlID8gJ2J1dHRvbicgOiBudWxsXCJcbiAgICAgIFthdHRyLnRhYmluZGV4XT1cImludGVyYWN0aXZlID8gMCA6IG51bGxcIlxuICAgICAgKGNsaWNrKT1cImludGVyYWN0aXZlICYmIGNsaWNrZWQuZW1pdCgpXCJcbiAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICA+XG4gICAgICBAaWYgKHRpdGxlIHx8IHN1YnRpdGxlKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by1jcmQtaFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1jcmQtaGxcIj5cbiAgICAgICAgICAgIEBpZiAodGl0bGUpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1jcmQtdFwiPnt7IHRpdGxlIH19PC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChzdWJ0aXRsZSkge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWNyZC1zdWIgdm8tbXV0ZWRcIj57eyBzdWJ0aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbY2FyZC1hY3Rpb25dXCI+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by1jcmQtYlwiPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by1jcmQtZlwiIFthdHRyLmRhdGEtYWxpZ25dPVwiZm9vdGVyQWxpZ24gPT09ICdlbmQnID8gbnVsbCA6IGZvb3RlckFsaWduXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltjYXJkLWZvb3Rlcl1cIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmw6ICcuL2NhcmQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FyZENvbXBvbmVudCB7XG4gIC8qKiBBIHRpdGxlIHNob3duIGluIHRoZSBoZWFkZXIuICovXG4gIEBJbnB1dCgpIHRpdGxlPzogc3RyaW5nO1xuICAvKiogQSBzdWJ0aXRsZSB1bmRlciB0aGUgdGl0bGUuICovXG4gIEBJbnB1dCgpIHN1YnRpdGxlPzogc3RyaW5nO1xuICAvKiogSG93IHRoZSBmb290ZXIncyBhY3Rpb25zIGFsaWduLiAnZW5kJyBieSBkZWZhdWx0LiAqL1xuICBASW5wdXQoKSBmb290ZXJBbGlnbjogJ3N0YXJ0JyB8ICdlbmQnIHwgJ2JldHdlZW4nID0gJ2VuZCc7XG4gIC8qKiBJbnNldCBmb3IgaGVhZGVyL2JvZHkvZm9vdGVyLiAnbWQnIGJ5IGRlZmF1bHQuICovXG4gIEBJbnB1dCgpIHBhZDogQ2FyZFBhZCA9ICdtZCc7XG4gIC8qKiBNYWtlcyB0aGUgd2hvbGUgY2FyZCBhIGhpdCB0YXJnZXQ6IGxpZnRzIG9uIGhvdmVyLCB0YWtlcyBmb2N1cywgZmlyZXMgKGNsaWNrZWQpIG9uIEVudGVyL1NwYWNlLiAqL1xuICBASW5wdXQoKSBpbnRlcmFjdGl2ZSA9IGZhbHNlO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gYW4gaW50ZXJhY3RpdmUgY2FyZCBpcyBhY3RpdmF0ZWQgKGNsaWNrIG9yIEVudGVyL1NwYWNlKS4gKi9cbiAgQE91dHB1dCgpIGNsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgb25LZXlEb3duKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW50ZXJhY3RpdmUpIHJldHVybjtcbiAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicgfHwgZS5rZXkgPT09ICcgJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5jbGlja2VkLmVtaXQoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==