@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.
- package/LICENSE +24 -0
- package/README.md +56 -2
- package/account-table/account-table.component.d.ts +72 -0
- package/action-log/action-log.component.d.ts +41 -0
- package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
- package/agent-inbox/agent-inbox.component.d.ts +75 -0
- package/agent-lanes/agent-lanes.component.d.ts +152 -0
- package/agent-phases/agent-phases.component.d.ts +62 -0
- package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
- package/agent-tree/agent-tree.component.d.ts +80 -0
- package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
- package/artifact-card/artifact-card.component.d.ts +145 -0
- package/attachment-tray/attachment-tray.component.d.ts +84 -0
- package/badge/badge.component.d.ts +25 -0
- package/bar-chart/bar-chart.component.d.ts +87 -0
- package/browser-session/browser-session.component.d.ts +70 -0
- package/buttons/buttons.component.d.ts +63 -0
- package/card/card.component.d.ts +21 -0
- package/change-review/change-review.component.d.ts +97 -0
- package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
- package/code-viewer/code-viewer.component.d.ts +86 -0
- package/composer/composer.component.d.ts +114 -0
- package/context-meter/context-meter.component.d.ts +60 -0
- package/core/icon.component.d.ts +10 -0
- package/core/reduced-motion.service.d.ts +15 -0
- package/decision-prompt/decision-prompt.component.d.ts +56 -0
- package/design-review/design-review.component.d.ts +108 -0
- package/design-tuner/design-tuner.component.d.ts +75 -0
- package/details-panel/details-panel.component.d.ts +150 -0
- package/donut-chart/donut-chart.component.d.ts +63 -0
- package/draft-review/draft-review.component.d.ts +128 -0
- package/error-recovery/error-recovery.component.d.ts +59 -0
- package/esm2022/account-table/account-table.component.mjs +399 -0
- package/esm2022/action-log/action-log.component.mjs +177 -0
- package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
- package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
- package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
- package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
- package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
- package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
- package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
- package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
- package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
- package/esm2022/badge/badge.component.mjs +97 -0
- package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
- package/esm2022/browser-session/browser-session.component.mjs +352 -0
- package/esm2022/buttons/buttons.component.mjs +215 -0
- package/esm2022/card/card.component.mjs +107 -0
- package/esm2022/change-review/change-review.component.mjs +398 -0
- package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
- package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
- package/esm2022/composer/composer.component.mjs +743 -0
- package/esm2022/context-meter/context-meter.component.mjs +275 -0
- package/esm2022/core/icon.component.mjs +111 -0
- package/esm2022/core/reduced-motion.service.mjs +34 -0
- package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
- package/esm2022/design-review/design-review.component.mjs +428 -0
- package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
- package/esm2022/details-panel/details-panel.component.mjs +537 -0
- package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
- package/esm2022/draft-review/draft-review.component.mjs +549 -0
- package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
- package/esm2022/eval-results/eval-results.component.mjs +368 -0
- package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
- package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
- package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
- package/esm2022/grid/grid.component.mjs +66 -0
- package/esm2022/health-score/health-score.component.mjs +420 -0
- package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
- package/esm2022/image-generation/image-generation.component.mjs +1028 -0
- package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
- package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
- package/esm2022/line-chart/line-chart.component.mjs +417 -0
- package/esm2022/live-answer/live-answer.component.mjs +411 -0
- package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
- package/esm2022/modal/modal.component.mjs +202 -0
- package/esm2022/model-picker/model-picker.component.mjs +491 -0
- package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
- package/esm2022/plan-review/plan-review.component.mjs +432 -0
- package/esm2022/progress/progress.component.mjs +503 -0
- package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
- package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
- package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
- package/esm2022/public-api.mjs +88 -0
- package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
- package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
- package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
- package/esm2022/response-versions/response-versions.component.mjs +288 -0
- package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
- package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
- package/esm2022/run-cost/run-cost.component.mjs +215 -0
- package/esm2022/run-queue/run-queue.component.mjs +481 -0
- package/esm2022/run-summary/run-summary.component.mjs +331 -0
- package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
- package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
- package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
- package/esm2022/source-stack/source-stack.component.mjs +245 -0
- package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
- package/esm2022/status-pill/status-pill.component.mjs +305 -0
- package/esm2022/steering/steering.component.mjs +343 -0
- package/esm2022/step-loader/step-loader.component.mjs +209 -0
- package/esm2022/task-table/task-table.component.mjs +534 -0
- package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
- package/esm2022/thinking/thinking.component.mjs +276 -0
- package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
- package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
- package/esm2022/toast/toast.component.mjs +195 -0
- package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
- package/esm2022/tool-call/tool-call.component.mjs +273 -0
- package/esm2022/tooltip/tooltip.component.mjs +417 -0
- package/esm2022/top-pages/top-pages.component.mjs +240 -0
- package/esm2022/trace-view/trace-view.component.mjs +440 -0
- package/esm2022/visuno-angular.mjs +5 -0
- package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
- package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
- package/esm2022/web-search/web-search.component.mjs +374 -0
- package/eval-results/eval-results.component.d.ts +67 -0
- package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
- package/fesm2022/visuno-angular.mjs +31992 -0
- package/fesm2022/visuno-angular.mjs.map +1 -0
- package/field-extraction/field-extraction.component.d.ts +82 -0
- package/funnel-chart/funnel-chart.component.d.ts +70 -0
- package/grid/grid.component.d.ts +22 -0
- package/health-score/health-score.component.d.ts +87 -0
- package/human-handoff/human-handoff.component.d.ts +125 -0
- package/image-generation/image-generation.component.d.ts +253 -0
- package/index.d.ts +5 -0
- package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
- package/launch-checklist/launch-checklist.component.d.ts +46 -0
- package/line-chart/line-chart.component.d.ts +89 -0
- package/live-answer/live-answer.component.d.ts +110 -0
- package/metric-insight/metric-insight.component.d.ts +110 -0
- package/modal/modal.component.d.ts +37 -0
- package/model-picker/model-picker.component.d.ts +97 -0
- package/package.json +51 -4
- package/permission-gate/permission-gate.component.d.ts +100 -0
- package/plan-review/plan-review.component.d.ts +86 -0
- package/progress/progress.component.d.ts +91 -0
- package/prompt-library/prompt-library.component.d.ts +121 -0
- package/prompt-starters/prompt-starters.component.d.ts +65 -0
- package/proposal-card/proposal-card.component.d.ts +101 -0
- package/public-api.d.ts +82 -0
- package/radar-chart/radar-chart.component.d.ts +110 -0
- package/radial-goals/radial-goals.component.d.ts +90 -0
- package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
- package/response-versions/response-versions.component.d.ts +54 -0
- package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
- package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
- package/run-cost/run-cost.component.d.ts +43 -0
- package/run-queue/run-queue.component.d.ts +93 -0
- package/run-summary/run-summary.component.d.ts +81 -0
- package/scatter-chart/scatter-chart.component.d.ts +139 -0
- package/score-breakdown/score-breakdown.component.d.ts +107 -0
- package/segmented-control/segmented-control.component.d.ts +44 -0
- package/source-stack/source-stack.component.d.ts +60 -0
- package/stat-cards/stat-cards.component.d.ts +86 -0
- package/status-pill/status-pill.component.d.ts +64 -0
- package/steering/steering.component.d.ts +75 -0
- package/step-loader/step-loader.component.d.ts +40 -0
- package/styles.css +424 -0
- package/task-table/task-table.component.d.ts +114 -0
- package/terminal-stream/terminal-stream.component.d.ts +110 -0
- package/thinking/thinking.component.d.ts +63 -0
- package/thinking-states/thinking-states.component.d.ts +51 -0
- package/thread-panel/thread-panel.component.d.ts +75 -0
- package/toast/toast.component.d.ts +56 -0
- package/toast-stack/toast-stack.component.d.ts +72 -0
- package/tokens.css +424 -0
- package/tool-call/tool-call.component.d.ts +61 -0
- package/tooltip/tooltip.component.d.ts +89 -0
- package/top-pages/top-pages.component.d.ts +75 -0
- package/trace-view/trace-view.component.d.ts +95 -0
- package/voice-capture/voice-capture.component.d.ts +103 -0
- package/voice-orb/voice-orb.component.d.ts +78 -0
- package/web-search/web-search.component.d.ts +77 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
// framework/angular/voice-orb/voice-orb.component.ts
|
|
2
|
+
//
|
|
3
|
+
// Native Angular port of framework/react/voice-orb/VoiceOrb.tsx.
|
|
4
|
+
// A hands-free voice chat: an orb that swells with whoever is talking, the accent
|
|
5
|
+
// colour for you and violet for the agent, what was said under it, and mute and
|
|
6
|
+
// end below. It draws what you pass; it never opens the microphone itself.
|
|
7
|
+
// Inputs mirror the React props; React callbacks become @Output() EventEmitters.
|
|
8
|
+
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject, } from '@angular/core';
|
|
9
|
+
import { VoIconComponent } from '../core/icon.component';
|
|
10
|
+
import { ReducedMotionService } from '../core/reduced-motion.service';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
const DEFAULTS = {
|
|
13
|
+
ready: 'Ready',
|
|
14
|
+
listening: 'Listening',
|
|
15
|
+
thinking: 'Thinking',
|
|
16
|
+
speaking: 'Speaking',
|
|
17
|
+
muted: 'Muted',
|
|
18
|
+
ended: 'Ended',
|
|
19
|
+
start: 'Start talking',
|
|
20
|
+
end: 'End',
|
|
21
|
+
mute: 'Mute',
|
|
22
|
+
unmute: 'Unmute',
|
|
23
|
+
mutedNotice: "You're muted. Unmute so the agent can hear you.",
|
|
24
|
+
endedTitle: 'Voice chat ended',
|
|
25
|
+
restart: 'Start again',
|
|
26
|
+
};
|
|
27
|
+
const fmt = (s) => `${Math.floor(s / 60)}:${String(Math.floor(s) % 60).padStart(2, '0')}`;
|
|
28
|
+
export class VoiceOrbComponent {
|
|
29
|
+
constructor() {
|
|
30
|
+
/** idle, listening, thinking, speaking or ended. */
|
|
31
|
+
this.state = 'idle';
|
|
32
|
+
/** How loud whoever is talking is, 0 to 1. The orb swells with it. */
|
|
33
|
+
this.level = 0;
|
|
34
|
+
/** Your microphone is off. Listening shows as Muted, the mute button is pressed. */
|
|
35
|
+
this.muted = false;
|
|
36
|
+
/** Shows "You're muted" with an Unmute button, for when someone talks while muted. */
|
|
37
|
+
this.mutedNotice = false;
|
|
38
|
+
/** What was said last and who said it; each word fades in as it arrives. */
|
|
39
|
+
this.caption = null;
|
|
40
|
+
/** Shown before anything is said, like "Talk to the agent about Pricing v4". */
|
|
41
|
+
this.hint = '';
|
|
42
|
+
/** Seconds since the chat started, shown top right. */
|
|
43
|
+
this.elapsed = 0;
|
|
44
|
+
this.labels = {};
|
|
45
|
+
this.className = '';
|
|
46
|
+
this.mutedChange = new EventEmitter();
|
|
47
|
+
this.start = new EventEmitter();
|
|
48
|
+
this.end = new EventEmitter();
|
|
49
|
+
/** Start again, from the row that shows once the chat has ended. */
|
|
50
|
+
this.restart = new EventEmitter();
|
|
51
|
+
this.motion = inject(ReducedMotionService);
|
|
52
|
+
this.L = DEFAULTS;
|
|
53
|
+
this.fmt = fmt;
|
|
54
|
+
// the lit glass sphere, drawn on a canvas in the colours of whoever is talking,
|
|
55
|
+
// faster and brighter as they get louder. With reduced motion it is one still
|
|
56
|
+
// frame, drawn again when the speaker changes; where no canvas can draw the core
|
|
57
|
+
// keeps its plain gradient (set by CSS).
|
|
58
|
+
this.shader = null;
|
|
59
|
+
this.raf = 0;
|
|
60
|
+
this.flow = 0;
|
|
61
|
+
this.last = 0;
|
|
62
|
+
this.cols = null;
|
|
63
|
+
this.colsAt = -1e9;
|
|
64
|
+
this.seen = true;
|
|
65
|
+
this.started = false;
|
|
66
|
+
}
|
|
67
|
+
// muted only changes how listening looks: the agent can still think and speak
|
|
68
|
+
get mode() {
|
|
69
|
+
return this.muted && this.state === 'listening' ? 'muted' : this.state;
|
|
70
|
+
}
|
|
71
|
+
get status() {
|
|
72
|
+
const map = {
|
|
73
|
+
idle: this.L.ready,
|
|
74
|
+
listening: this.L.listening,
|
|
75
|
+
thinking: this.L.thinking,
|
|
76
|
+
speaking: this.L.speaking,
|
|
77
|
+
muted: this.L.muted,
|
|
78
|
+
ended: this.L.ended,
|
|
79
|
+
};
|
|
80
|
+
return map[this.mode] ?? '';
|
|
81
|
+
}
|
|
82
|
+
get on() {
|
|
83
|
+
return this.state !== 'idle' && this.state !== 'ended';
|
|
84
|
+
}
|
|
85
|
+
get noticeOpen() {
|
|
86
|
+
return this.mutedNotice && this.muted && this.on;
|
|
87
|
+
}
|
|
88
|
+
get lv() {
|
|
89
|
+
return Math.max(0, Math.min(1, this.level)).toFixed(3);
|
|
90
|
+
}
|
|
91
|
+
get defaultDetail() {
|
|
92
|
+
return `${fmt(this.elapsed)} · Transcript saved`;
|
|
93
|
+
}
|
|
94
|
+
words(text) {
|
|
95
|
+
return text.split(' ').filter(Boolean);
|
|
96
|
+
}
|
|
97
|
+
emitMuted(next) {
|
|
98
|
+
this.mutedChange.emit(next);
|
|
99
|
+
}
|
|
100
|
+
ngOnChanges(changes) {
|
|
101
|
+
if (changes['labels'])
|
|
102
|
+
this.L = { ...DEFAULTS, ...this.labels };
|
|
103
|
+
// draw once more when the speaker (data-m) changes under reduced motion
|
|
104
|
+
if (this.started && this.motion.reduce() && (changes['state'] || changes['muted'])) {
|
|
105
|
+
this.cols = null;
|
|
106
|
+
queueMicrotask(() => this.draw(this.flow));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
ngAfterViewInit() {
|
|
110
|
+
const cv = this.glRef?.nativeElement;
|
|
111
|
+
if (!cv)
|
|
112
|
+
return;
|
|
113
|
+
this.shader = orbShader(cv);
|
|
114
|
+
if (!this.shader)
|
|
115
|
+
return;
|
|
116
|
+
cv.classList.add('vo-on');
|
|
117
|
+
this.started = true;
|
|
118
|
+
if ('IntersectionObserver' in window) {
|
|
119
|
+
this.io = new IntersectionObserver((e) => (this.seen = e[0].isIntersecting));
|
|
120
|
+
this.io.observe(cv);
|
|
121
|
+
}
|
|
122
|
+
this.draw(0);
|
|
123
|
+
if (!this.motion.reduce()) {
|
|
124
|
+
const tick = (t) => {
|
|
125
|
+
this.flow += Math.min(50, t - (this.last || t)) * (1 + Math.max(0, Math.min(1, this.level)) * 2.5);
|
|
126
|
+
this.last = t;
|
|
127
|
+
if (this.seen)
|
|
128
|
+
this.draw(this.flow);
|
|
129
|
+
this.raf = requestAnimationFrame(tick);
|
|
130
|
+
};
|
|
131
|
+
this.raf = requestAnimationFrame(tick);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
draw(ms) {
|
|
135
|
+
const cv = this.glRef?.nativeElement;
|
|
136
|
+
if (!this.shader || !cv)
|
|
137
|
+
return;
|
|
138
|
+
const now = performance.now();
|
|
139
|
+
if (!this.cols || now - this.colsAt > 250) {
|
|
140
|
+
const box = cv.closest('.vo-vor');
|
|
141
|
+
const dot = box?.querySelector('.vo-vor-dot');
|
|
142
|
+
const pc = box?.querySelector('.vo-vor-pc');
|
|
143
|
+
if (dot && pc) {
|
|
144
|
+
this.cols = [getComputedStyle(dot).backgroundColor, getComputedStyle(pc).backgroundColor];
|
|
145
|
+
this.colsAt = now;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (this.cols)
|
|
149
|
+
this.shader.paint(ms, Math.max(0, Math.min(1, this.level)), this.cols[0], this.cols[1]);
|
|
150
|
+
}
|
|
151
|
+
ngOnDestroy() {
|
|
152
|
+
cancelAnimationFrame(this.raf);
|
|
153
|
+
this.io?.disconnect();
|
|
154
|
+
this.shader?.lose();
|
|
155
|
+
}
|
|
156
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceOrbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
157
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: VoiceOrbComponent, isStandalone: true, selector: "vo-voice-orb", inputs: { state: "state", level: "level", muted: "muted", mutedNotice: "mutedNotice", caption: "caption", hint: "hint", elapsed: "elapsed", endedDetail: "endedDetail", labels: "labels", className: "className" }, outputs: { mutedChange: "mutedChange", start: "start", end: "end", restart: "restart" }, viewQueries: [{ propertyName: "glRef", first: true, predicate: ["gl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
158
|
+
<div data-vo="" [class]="className" style="width:100%">
|
|
159
|
+
<div class="vo-vor vo-panel" [class.vo-on]="on" [attr.data-m]="mode">
|
|
160
|
+
<div class="vo-vor-top">
|
|
161
|
+
<span class="vo-vor-dot"></span>
|
|
162
|
+
<span class="vo-vor-st">{{ status }}</span>
|
|
163
|
+
<span class="vo-vor-t vo-num vo-muted">{{ fmt(elapsed) }}</span>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="vo-vor-orb" aria-hidden="true" [style.--vo-lv]="lv">
|
|
166
|
+
<i class="vo-vor-pc"></i>
|
|
167
|
+
<i class="vo-vor-core"><canvas #gl class="vo-vor-gl"></canvas></i>
|
|
168
|
+
</div>
|
|
169
|
+
<div class="vo-vor-cap" aria-live="polite">
|
|
170
|
+
<span class="vo-vor-who vo-muted">{{ caption?.speaker ?? '' }}</span>
|
|
171
|
+
@if (caption; as cap) {
|
|
172
|
+
<p class="vo-vor-tx">
|
|
173
|
+
@for (w of words(cap.text); track $index) {
|
|
174
|
+
<span class="vo-w">{{ w }} </span>
|
|
175
|
+
}
|
|
176
|
+
</p>
|
|
177
|
+
} @else {
|
|
178
|
+
<p class="vo-vor-tx vo-hint">{{ hint }}</p>
|
|
179
|
+
}
|
|
180
|
+
</div>
|
|
181
|
+
<div class="vo-fold vo-vor-mf" [class.vo-shut]="!noticeOpen" [attr.inert]="noticeOpen ? null : ''">
|
|
182
|
+
<div>
|
|
183
|
+
<div class="vo-vor-mw">
|
|
184
|
+
<p><vo-icon name="alert" size="xs"></vo-icon><span>{{ L.mutedNotice }}</span></p>
|
|
185
|
+
<button type="button" class="vo-pill vo-sm vo-vor-un" (click)="emitMuted(false)">{{ L.unmute }}</button>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
@if (state === 'ended') {
|
|
190
|
+
<div class="vo-vor-done vo-enter">
|
|
191
|
+
<vo-icon name="ok"></vo-icon>
|
|
192
|
+
<span class="vo-t">{{ L.endedTitle }}<span class="vo-muted">{{ endedDetail ?? defaultDetail }}</span></span>
|
|
193
|
+
<button type="button" class="vo-pill vo-sm" (click)="restart.emit()">{{ L.restart }}</button>
|
|
194
|
+
</div>
|
|
195
|
+
} @else {
|
|
196
|
+
<div class="vo-vor-f">
|
|
197
|
+
<button type="button" class="vo-pill vo-primary vo-sm vo-vor-go" (click)="start.emit()">
|
|
198
|
+
<vo-icon name="comment" size="xs"></vo-icon>{{ L.start }}
|
|
199
|
+
</button>
|
|
200
|
+
<button
|
|
201
|
+
type="button"
|
|
202
|
+
class="vo-ib vo-fill vo-vor-mute"
|
|
203
|
+
[attr.aria-label]="L.mute"
|
|
204
|
+
[attr.aria-pressed]="muted"
|
|
205
|
+
[attr.data-tip]="muted ? L.unmute : L.mute"
|
|
206
|
+
(click)="emitMuted(!muted)"
|
|
207
|
+
>
|
|
208
|
+
<vo-icon name="comment"></vo-icon>
|
|
209
|
+
</button>
|
|
210
|
+
<span class="vo-sp"></span>
|
|
211
|
+
<button type="button" class="vo-pill vo-sm vo-vor-end" (click)="end.emit()">{{ L.end }}</button>
|
|
212
|
+
</div>
|
|
213
|
+
}
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
`, isInline: true, styles: [".vo-vor{position:relative;width:100%;max-width:380px;margin:0 auto;padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3);--vo-oc:var(--vo-faint);--vo-oc2:var(--vo-accent)}.vo-vor[data-m=listening]{--vo-oc:var(--vo-accent);--vo-oc2:color-mix(in oklch,var(--vo-pl) 45%,var(--vo-accent))}.vo-vor[data-m=speaking]{--vo-oc:var(--vo-pl);--vo-oc2:color-mix(in oklch,var(--vo-accent) 45%,var(--vo-pl))}.vo-vor[data-m=thinking]{--vo-oc:color-mix(in oklch,var(--vo-accent) 50%,var(--vo-pl));--vo-oc2:var(--vo-accent)}.vo-vor[data-m=muted]{--vo-oc:color-mix(in srgb,var(--vo-muted) 55%,var(--vo-faint));--vo-oc2:var(--vo-faint)}.vo-vor-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vor-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-oc);transition:background .4s}.vo-vor[data-m=listening] .vo-vor-dot,.vo-vor[data-m=speaking] .vo-vor-dot{animation:vo-vor-pulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vor-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-oc) 35%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vor-t{margin-left:auto;font-size:12.5px}.vo-vor-orb{position:relative;width:112px;height:112px;margin:var(--vo-s-2) auto;--vo-lv:0}.vo-vor-orb i{position:absolute;inset:0;border-radius:50%}.vo-vor .vo-vor-orb i{border-radius:50%!important}.vo-vor-core{overflow:hidden;background-color:color-mix(in srgb,var(--vo-oc) 80%,var(--vo-surface));background-image:radial-gradient(circle at 34% 28%,#fff6,#fff0 60%);box-shadow:inset 0 -10px 20px color-mix(in srgb,var(--vo-oc) 55%,#000 10%);transform:scale(calc(.9 + var(--vo-lv) * .1));transition:background-color .4s}.vo-vor-gl{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;opacity:0;transition:opacity .4s}.vo-vor-gl.vo-on{opacity:1}.vo-vor-core:has(>.vo-vor-gl.vo-on){background:none;box-shadow:none}.vo-vor-pc{visibility:hidden;background:var(--vo-oc2);transition:background .4s}.vo-vor-cap,.vo-vor-mf,.vo-vor-f{position:relative}.vo-vor[data-m=thinking] .vo-vor-core{animation:vo-vor-br 1.6s var(--vo-ease-io) infinite alternate}@keyframes vo-vor-br{0%{transform:scale(.9)}to{transform:scale(.96)}}.vo-vor-cap{min-height:88px;display:flex;flex-direction:column;gap:2px;text-align:center}.vo-vor-who{font-size:12px;min-height:18px}.vo-vor-tx{margin:0;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vor-tx.vo-hint{color:var(--vo-muted);font-size:13px}.vo-vor-tx .vo-w{animation:vo-vor-w .45s var(--vo-ease) both}@keyframes vo-vor-w{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vor-mw{display:flex;align-items:center;gap:10px;padding:var(--vo-s-2) var(--vo-s-2) var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-warn-bg)}.vo-vor-mw p{margin:0;flex:1;display:flex;gap:var(--vo-s-2);font-size:13px;line-height:1.45;color:var(--vo-fg)}.vo-vor-mw p svg{color:var(--vo-warn);flex:none;margin-top:3px}.vo-vor-mw .vo-pill,.vo-vor-done .vo-pill{background:var(--vo-surface);color:var(--vo-fg);box-shadow:var(--vo-shadow)}.vo-vor-f{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vor-f .vo-sp{flex:1}.vo-vor:not(.vo-on) .vo-vor-f{justify-content:center}.vo-vor:not(.vo-on) .vo-vor-mute,.vo-vor:not(.vo-on) .vo-vor-end,.vo-vor:not(.vo-on) .vo-vor-f .vo-sp,.vo-vor.vo-on .vo-vor-go{display:none}.vo-vor-mute{position:relative}.vo-vor-mute[aria-pressed=true]{background:var(--vo-bad-bg);color:var(--vo-bad);box-shadow:none}.vo-vor-mute:after{content:\"\";position:absolute;left:50%;top:50%;width:1.5px;height:18px;margin:-9px 0 0 -.75px;border-radius:2px;background:currentColor;transform:rotate(-45deg) scaleY(0);transition:transform .25s var(--vo-ease)}.vo-vor-mute[aria-pressed=true]:after{transform:rotate(-45deg) scaleY(1)}.vo-vor-end{background:var(--vo-bad);color:var(--vo-on-ink)}@media (hover:hover) and (pointer:fine){.vo-vor-end:hover{background:color-mix(in srgb,var(--vo-bad) 86%,#000)}}.vo-vor-done{display:flex;align-items:center;gap:var(--vo-s-3);padding:10px 10px 10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-chip);font-size:13.5px}.vo-vor-done>svg{color:var(--vo-fg2);flex:none}.vo-vor-done .vo-t{flex:1;min-width:0;display:flex;flex-direction:column}.vo-vor-done .vo-t span{font-size:13px}.vo-sp{flex:1}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-soft);box-shadow:var(--vo-soft-ring)}@media (hover:hover) and (pointer:fine){.vo-ib.vo-fill:hover{background:var(--vo-soft-h)}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-fold{display:grid;grid-template-rows:1fr;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:hidden;min-height:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
217
|
+
}
|
|
218
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VoiceOrbComponent, decorators: [{
|
|
219
|
+
type: Component,
|
|
220
|
+
args: [{ selector: 'vo-voice-orb', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
|
|
221
|
+
<div data-vo="" [class]="className" style="width:100%">
|
|
222
|
+
<div class="vo-vor vo-panel" [class.vo-on]="on" [attr.data-m]="mode">
|
|
223
|
+
<div class="vo-vor-top">
|
|
224
|
+
<span class="vo-vor-dot"></span>
|
|
225
|
+
<span class="vo-vor-st">{{ status }}</span>
|
|
226
|
+
<span class="vo-vor-t vo-num vo-muted">{{ fmt(elapsed) }}</span>
|
|
227
|
+
</div>
|
|
228
|
+
<div class="vo-vor-orb" aria-hidden="true" [style.--vo-lv]="lv">
|
|
229
|
+
<i class="vo-vor-pc"></i>
|
|
230
|
+
<i class="vo-vor-core"><canvas #gl class="vo-vor-gl"></canvas></i>
|
|
231
|
+
</div>
|
|
232
|
+
<div class="vo-vor-cap" aria-live="polite">
|
|
233
|
+
<span class="vo-vor-who vo-muted">{{ caption?.speaker ?? '' }}</span>
|
|
234
|
+
@if (caption; as cap) {
|
|
235
|
+
<p class="vo-vor-tx">
|
|
236
|
+
@for (w of words(cap.text); track $index) {
|
|
237
|
+
<span class="vo-w">{{ w }} </span>
|
|
238
|
+
}
|
|
239
|
+
</p>
|
|
240
|
+
} @else {
|
|
241
|
+
<p class="vo-vor-tx vo-hint">{{ hint }}</p>
|
|
242
|
+
}
|
|
243
|
+
</div>
|
|
244
|
+
<div class="vo-fold vo-vor-mf" [class.vo-shut]="!noticeOpen" [attr.inert]="noticeOpen ? null : ''">
|
|
245
|
+
<div>
|
|
246
|
+
<div class="vo-vor-mw">
|
|
247
|
+
<p><vo-icon name="alert" size="xs"></vo-icon><span>{{ L.mutedNotice }}</span></p>
|
|
248
|
+
<button type="button" class="vo-pill vo-sm vo-vor-un" (click)="emitMuted(false)">{{ L.unmute }}</button>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
@if (state === 'ended') {
|
|
253
|
+
<div class="vo-vor-done vo-enter">
|
|
254
|
+
<vo-icon name="ok"></vo-icon>
|
|
255
|
+
<span class="vo-t">{{ L.endedTitle }}<span class="vo-muted">{{ endedDetail ?? defaultDetail }}</span></span>
|
|
256
|
+
<button type="button" class="vo-pill vo-sm" (click)="restart.emit()">{{ L.restart }}</button>
|
|
257
|
+
</div>
|
|
258
|
+
} @else {
|
|
259
|
+
<div class="vo-vor-f">
|
|
260
|
+
<button type="button" class="vo-pill vo-primary vo-sm vo-vor-go" (click)="start.emit()">
|
|
261
|
+
<vo-icon name="comment" size="xs"></vo-icon>{{ L.start }}
|
|
262
|
+
</button>
|
|
263
|
+
<button
|
|
264
|
+
type="button"
|
|
265
|
+
class="vo-ib vo-fill vo-vor-mute"
|
|
266
|
+
[attr.aria-label]="L.mute"
|
|
267
|
+
[attr.aria-pressed]="muted"
|
|
268
|
+
[attr.data-tip]="muted ? L.unmute : L.mute"
|
|
269
|
+
(click)="emitMuted(!muted)"
|
|
270
|
+
>
|
|
271
|
+
<vo-icon name="comment"></vo-icon>
|
|
272
|
+
</button>
|
|
273
|
+
<span class="vo-sp"></span>
|
|
274
|
+
<button type="button" class="vo-pill vo-sm vo-vor-end" (click)="end.emit()">{{ L.end }}</button>
|
|
275
|
+
</div>
|
|
276
|
+
}
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
`, styles: [".vo-vor{position:relative;width:100%;max-width:380px;margin:0 auto;padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3);--vo-oc:var(--vo-faint);--vo-oc2:var(--vo-accent)}.vo-vor[data-m=listening]{--vo-oc:var(--vo-accent);--vo-oc2:color-mix(in oklch,var(--vo-pl) 45%,var(--vo-accent))}.vo-vor[data-m=speaking]{--vo-oc:var(--vo-pl);--vo-oc2:color-mix(in oklch,var(--vo-accent) 45%,var(--vo-pl))}.vo-vor[data-m=thinking]{--vo-oc:color-mix(in oklch,var(--vo-accent) 50%,var(--vo-pl));--vo-oc2:var(--vo-accent)}.vo-vor[data-m=muted]{--vo-oc:color-mix(in srgb,var(--vo-muted) 55%,var(--vo-faint));--vo-oc2:var(--vo-faint)}.vo-vor-top{display:flex;align-items:center;gap:var(--vo-s-2);font-size:13px}.vo-vor-dot{width:8px;height:8px;border-radius:50%;background:var(--vo-oc);transition:background .4s}.vo-vor[data-m=listening] .vo-vor-dot,.vo-vor[data-m=speaking] .vo-vor-dot{animation:vo-vor-pulse 1.4s var(--vo-ease-io) infinite}@keyframes vo-vor-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--vo-oc) 35%,transparent)}50%{box-shadow:0 0 0 5px transparent}}.vo-vor-t{margin-left:auto;font-size:12.5px}.vo-vor-orb{position:relative;width:112px;height:112px;margin:var(--vo-s-2) auto;--vo-lv:0}.vo-vor-orb i{position:absolute;inset:0;border-radius:50%}.vo-vor .vo-vor-orb i{border-radius:50%!important}.vo-vor-core{overflow:hidden;background-color:color-mix(in srgb,var(--vo-oc) 80%,var(--vo-surface));background-image:radial-gradient(circle at 34% 28%,#fff6,#fff0 60%);box-shadow:inset 0 -10px 20px color-mix(in srgb,var(--vo-oc) 55%,#000 10%);transform:scale(calc(.9 + var(--vo-lv) * .1));transition:background-color .4s}.vo-vor-gl{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;opacity:0;transition:opacity .4s}.vo-vor-gl.vo-on{opacity:1}.vo-vor-core:has(>.vo-vor-gl.vo-on){background:none;box-shadow:none}.vo-vor-pc{visibility:hidden;background:var(--vo-oc2);transition:background .4s}.vo-vor-cap,.vo-vor-mf,.vo-vor-f{position:relative}.vo-vor[data-m=thinking] .vo-vor-core{animation:vo-vor-br 1.6s var(--vo-ease-io) infinite alternate}@keyframes vo-vor-br{0%{transform:scale(.9)}to{transform:scale(.96)}}.vo-vor-cap{min-height:88px;display:flex;flex-direction:column;gap:2px;text-align:center}.vo-vor-who{font-size:12px;min-height:18px}.vo-vor-tx{margin:0;font-size:14px;line-height:1.6;color:var(--vo-fg)}.vo-vor-tx.vo-hint{color:var(--vo-muted);font-size:13px}.vo-vor-tx .vo-w{animation:vo-vor-w .45s var(--vo-ease) both}@keyframes vo-vor-w{0%{opacity:0;filter:blur(3px)}to{opacity:1;filter:none}}.vo-vor-mw{display:flex;align-items:center;gap:10px;padding:var(--vo-s-2) var(--vo-s-2) var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-warn-bg)}.vo-vor-mw p{margin:0;flex:1;display:flex;gap:var(--vo-s-2);font-size:13px;line-height:1.45;color:var(--vo-fg)}.vo-vor-mw p svg{color:var(--vo-warn);flex:none;margin-top:3px}.vo-vor-mw .vo-pill,.vo-vor-done .vo-pill{background:var(--vo-surface);color:var(--vo-fg);box-shadow:var(--vo-shadow)}.vo-vor-f{display:flex;align-items:center;gap:var(--vo-s-2);min-height:32px}.vo-vor-f .vo-sp{flex:1}.vo-vor:not(.vo-on) .vo-vor-f{justify-content:center}.vo-vor:not(.vo-on) .vo-vor-mute,.vo-vor:not(.vo-on) .vo-vor-end,.vo-vor:not(.vo-on) .vo-vor-f .vo-sp,.vo-vor.vo-on .vo-vor-go{display:none}.vo-vor-mute{position:relative}.vo-vor-mute[aria-pressed=true]{background:var(--vo-bad-bg);color:var(--vo-bad);box-shadow:none}.vo-vor-mute:after{content:\"\";position:absolute;left:50%;top:50%;width:1.5px;height:18px;margin:-9px 0 0 -.75px;border-radius:2px;background:currentColor;transform:rotate(-45deg) scaleY(0);transition:transform .25s var(--vo-ease)}.vo-vor-mute[aria-pressed=true]:after{transform:rotate(-45deg) scaleY(1)}.vo-vor-end{background:var(--vo-bad);color:var(--vo-on-ink)}@media (hover:hover) and (pointer:fine){.vo-vor-end:hover{background:color-mix(in srgb,var(--vo-bad) 86%,#000)}}.vo-vor-done{display:flex;align-items:center;gap:var(--vo-s-3);padding:10px 10px 10px var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-chip);font-size:13.5px}.vo-vor-done>svg{color:var(--vo-fg2);flex:none}.vo-vor-done .vo-t{flex:1;min-width:0;display:flex;flex-direction:column}.vo-vor-done .vo-t span{font-size:13px}.vo-sp{flex:1}.vo-num{font-variant-numeric:tabular-nums}.vo-muted{color:var(--vo-muted)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-ib{width:30px;height:30px;border-radius:50%;display:inline-grid;place-items:center;color:var(--vo-fg2);cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),transform .15s}@media (hover:hover) and (pointer:fine){.vo-ib:hover{background:var(--vo-row);color:var(--vo-fg)}}.vo-ib:active{transform:scale(.94)}.vo-ib.vo-fill{background:var(--vo-soft);box-shadow:var(--vo-soft-ring)}@media (hover:hover) and (pointer:fine){.vo-ib.vo-fill:hover{background:var(--vo-soft-h)}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-primary{background:var(--vo-accent);color:var(--vo-on-accent)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-primary:hover{background:var(--vo-accent-2)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-fold{display:grid;grid-template-rows:1fr;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:hidden;min-height:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}\n"] }]
|
|
280
|
+
}], propDecorators: { state: [{
|
|
281
|
+
type: Input
|
|
282
|
+
}], level: [{
|
|
283
|
+
type: Input
|
|
284
|
+
}], muted: [{
|
|
285
|
+
type: Input
|
|
286
|
+
}], mutedNotice: [{
|
|
287
|
+
type: Input
|
|
288
|
+
}], caption: [{
|
|
289
|
+
type: Input
|
|
290
|
+
}], hint: [{
|
|
291
|
+
type: Input
|
|
292
|
+
}], elapsed: [{
|
|
293
|
+
type: Input
|
|
294
|
+
}], endedDetail: [{
|
|
295
|
+
type: Input
|
|
296
|
+
}], labels: [{
|
|
297
|
+
type: Input
|
|
298
|
+
}], className: [{
|
|
299
|
+
type: Input
|
|
300
|
+
}], mutedChange: [{
|
|
301
|
+
type: Output
|
|
302
|
+
}], start: [{
|
|
303
|
+
type: Output
|
|
304
|
+
}], end: [{
|
|
305
|
+
type: Output
|
|
306
|
+
}], restart: [{
|
|
307
|
+
type: Output
|
|
308
|
+
}], glRef: [{
|
|
309
|
+
type: ViewChild,
|
|
310
|
+
args: ['gl']
|
|
311
|
+
}] } });
|
|
312
|
+
// the glass sphere, as a fragment shader (the site's own source, ported from the
|
|
313
|
+
// Vanilla/React originals): a ball lit from the top left, a deeper shifted hue past
|
|
314
|
+
// the terminator, light gathered through the glass on the far side, a fresnel edge,
|
|
315
|
+
// a broad sheen and a sharp highlight. Inside, deep pools of the two colours and a
|
|
316
|
+
// third hue swirl, liquid light flows through the middle and two ribbons turn near
|
|
317
|
+
// the surface. The level speeds the flow, brightens the heart and shimmers the
|
|
318
|
+
// highlight. Where WebGL is missing the same picture is drawn in a few gradients on
|
|
319
|
+
// a 2D canvas. At its widest the sphere still sits inside the canvas.
|
|
320
|
+
const FRAG = `#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
321
|
+
precision highp float;
|
|
322
|
+
#else
|
|
323
|
+
precision mediump float;
|
|
324
|
+
#endif
|
|
325
|
+
uniform vec2 R;uniform float T,L;uniform vec3 A0,B0;
|
|
326
|
+
float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
|
|
327
|
+
float n(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.-2.*f);return mix(mix(h(i),h(i+vec2(1,0)),f.x),mix(h(i+vec2(0,1)),h(i+1.),f.x),f.y);}
|
|
328
|
+
float fbm(vec2 p){float v=0.,a=.5;for(int i=0;i<4;i++){v+=a*n(p);p=mat2(1.6,1.2,-1.2,1.6)*p+vec2(1.7,9.2);a*=.5;}return v;}
|
|
329
|
+
mat2 rot(float a){float c=cos(a),s=sin(a);return mat2(c,s,-s,c);}
|
|
330
|
+
vec3 tn(vec3 c){float mx=max(c.r,max(c.g,c.b)),d=mx-min(c.r,min(c.g,c.b));c*=max(1.,.5/max(mx,.01));mx=max(mx,.5);d=mx-min(c.r,min(c.g,c.b));return max(mx-(mx-c)*mix(1.,clamp(.55*mx/max(d,.001),1.,3.),smoothstep(.03,.12,d)),0.);}
|
|
331
|
+
vec3 hue(vec3 c,float a){vec3 k=vec3(.57735);float co=cos(a);return c*co+cross(k,c)*sin(a)+k*dot(k,c)*(1.-co);}
|
|
332
|
+
void main(){
|
|
333
|
+
vec3 A=tn(A0),B=tn(B0),C=hue(A,mix(-.9,1.4,smoothstep(-.1,.1,A.b-A.g)));
|
|
334
|
+
vec2 u=(gl_FragCoord.xy*2.-R)/R.y;
|
|
335
|
+
float t=T*.001,an=atan(u.y,u.x);
|
|
336
|
+
float w=(.002+.008*L)*(sin(3.*an+t*1.9)+.6*sin(5.*an-t*2.7)+.4*sin(2.*an-t*1.1));
|
|
337
|
+
float rad=.955*(1.+.008*sin(t*.9)+w);
|
|
338
|
+
vec2 q=u/rad;float r=length(q),e=3./(R.y*rad);
|
|
339
|
+
float a=1.-smoothstep(1.-e,1.,r);
|
|
340
|
+
if(a<=0.){gl_FragColor=vec4(0.);return;}
|
|
341
|
+
float z=sqrt(max(1.-r*r,0.));
|
|
342
|
+
vec3 N=vec3(q,z);
|
|
343
|
+
N.xy+=(vec2(n(q*5.+t*1.6),n(q*5.-t*1.3+7.))-.5)*(.03+.12*L);N=normalize(N);
|
|
344
|
+
vec3 S=vec3(q,z),D=refract(vec3(0,0,-1),N,.72),P1=S+D*z*.35,P2=S+D*z*.9,P3=S+D*z*1.5;
|
|
345
|
+
float s=t*.22;
|
|
346
|
+
vec3 d1=P3-vec3(.55*sin(s*1.3),.5*cos(s*1.1),.3*sin(s*.7)),d2=P3-vec3(.55*cos(s*.9+2.),.5*sin(s*1.2+1.),.3*cos(s*.8+3.)),d3=P3-vec3(.5*sin(s*1.6+4.),.5*cos(s*1.4+5.),.3*sin(s+1.));
|
|
347
|
+
float g1=exp(-dot(d1,d1)*2.6),g2=exp(-dot(d2,d2)*2.6),g3=exp(-dot(d3,d3)*3.2);
|
|
348
|
+
vec3 col=mix(mix(mix(mix(A,B,.4)*.55,B,g2*.8),C,g3*.7),A,g1*.95);
|
|
349
|
+
vec2 m=rot(t*.09)*P2.xy*1.5,o=vec2(fbm(m+vec2(0.,t*.3)),fbm(m+vec2(5.2,1.3)-t*.25));
|
|
350
|
+
float f=fbm(m+(o-.5)*(2.5+2.*L)+vec2(t*.12,-t*.08));
|
|
351
|
+
col=mix(col,mix(mix(A,B,.5),vec3(1.),.15),smoothstep(.45,.8,f)*.5)*(.8+.35*smoothstep(.2,.6,f));
|
|
352
|
+
vec2 k=rot(-t*.33)*P1.xy;
|
|
353
|
+
float b1=k.y+.32*sin(k.x*2.4+t*1.4)+.12*sin(k.x*5.3-t*2.2)+(o.x-.5)*.5,b2=k.x-.3*sin(k.y*2.1-t*1.1)+.4;
|
|
354
|
+
col+=mix(mix(A,C,.35),vec3(1.),.35)*(exp(-b1*b1*40.)+.6*exp(-b2*b2*55.))*(.25+.35*L)*z;
|
|
355
|
+
col+=mix(A,vec3(1.),.4)*exp(-dot(P2.xy,P2.xy)*3.)*(.08+.3*L);
|
|
356
|
+
vec3 lk=normalize(vec3(-.5,.62,.6)),dk=hue(col,.35);
|
|
357
|
+
col=mix(dk*dk*.6,col*1.06,smoothstep(-.55,.75,dot(N,lk)));
|
|
358
|
+
col+=mix(B,vec3(1.),.5)*pow(1.-z,1.6)*smoothstep(.1,.95,dot(q/max(r,1e-3),-normalize(lk.xy)))*.55;
|
|
359
|
+
col=mix(col,mix(vec3(.06),vec3(1.),smoothstep(-.3,.9,N.y*.7-N.x*.4)),pow(1.-N.z,3.)*.5);
|
|
360
|
+
float nh=max(dot(N,normalize(lk+vec3(0,0,1))),0.);
|
|
361
|
+
col+=pow(nh,700.)*(1.2+.8*L*sin(t*9.+q.x*8.))+pow(nh,60.)*.25+pow(nh,8.)*.1;
|
|
362
|
+
gl_FragColor=vec4(clamp(col,0.,1.)*a,a);
|
|
363
|
+
}`;
|
|
364
|
+
/** Draws the sphere on the orb's canvas: one draw a frame, at most 2 device pixels a
|
|
365
|
+
CSS pixel, nothing made anew each frame. Where WebGL is missing it falls back to a
|
|
366
|
+
few gradients on a 2D canvas. Returns { paint, lose }, or null when neither can draw. */
|
|
367
|
+
function orbShader(cv) {
|
|
368
|
+
// a computed colour to 0..1 channels; mid-transition it can come as oklab() or
|
|
369
|
+
// color(), so a 1px canvas reads it. Only a colour that changed is read.
|
|
370
|
+
const px = document.createElement('canvas').getContext('2d', { willReadFrequently: true });
|
|
371
|
+
if (!px)
|
|
372
|
+
return null;
|
|
373
|
+
px.canvas.width = px.canvas.height = 1;
|
|
374
|
+
const rgb = (s, o) => {
|
|
375
|
+
px.clearRect(0, 0, 1, 1);
|
|
376
|
+
px.fillStyle = '#000';
|
|
377
|
+
px.fillStyle = s;
|
|
378
|
+
px.fillRect(0, 0, 1, 1);
|
|
379
|
+
const d = px.getImageData(0, 0, 1, 1).data;
|
|
380
|
+
o[0] = d[0] / 255;
|
|
381
|
+
o[1] = d[1] / 255;
|
|
382
|
+
o[2] = d[2] / 255;
|
|
383
|
+
};
|
|
384
|
+
const ta = new Float32Array(3), tb = new Float32Array(3), ca = new Float32Array(3), cb = new Float32Array(3);
|
|
385
|
+
let sa = '', sb = '', w = 0, at = -1e9, prev = -1e9;
|
|
386
|
+
const fit = (now) => {
|
|
387
|
+
if (w && now - at < 300)
|
|
388
|
+
return false;
|
|
389
|
+
at = now;
|
|
390
|
+
const n = Math.round(cv.clientWidth * Math.min(2, devicePixelRatio || 1)) || 1;
|
|
391
|
+
if (n === w)
|
|
392
|
+
return false;
|
|
393
|
+
w = cv.width = cv.height = n;
|
|
394
|
+
return true;
|
|
395
|
+
};
|
|
396
|
+
const tint = (a, b, now, snap) => {
|
|
397
|
+
if (a !== sa) {
|
|
398
|
+
sa = a;
|
|
399
|
+
rgb(a, ta);
|
|
400
|
+
}
|
|
401
|
+
if (b !== sb) {
|
|
402
|
+
sb = b;
|
|
403
|
+
rgb(b, tb);
|
|
404
|
+
}
|
|
405
|
+
const k = snap || now - prev > 200 ? 1 : Math.min(1, (now - prev) / 110);
|
|
406
|
+
prev = now;
|
|
407
|
+
for (let i = 0; i < 3; i++) {
|
|
408
|
+
ca[i] += (ta[i] - ca[i]) * k;
|
|
409
|
+
cb[i] += (tb[i] - cb[i]) * k;
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const gl = cv.getContext('webgl', { premultipliedAlpha: true, antialias: false, powerPreference: 'low-power' });
|
|
413
|
+
if (gl) {
|
|
414
|
+
const sh = (type, src) => {
|
|
415
|
+
const s = gl.createShader(type);
|
|
416
|
+
gl.shaderSource(s, src);
|
|
417
|
+
gl.compileShader(s);
|
|
418
|
+
return s;
|
|
419
|
+
};
|
|
420
|
+
const pr = gl.createProgram();
|
|
421
|
+
gl.attachShader(pr, sh(gl.VERTEX_SHADER, 'attribute vec2 p;void main(){gl_Position=vec4(p,0.,1.);}'));
|
|
422
|
+
gl.attachShader(pr, sh(gl.FRAGMENT_SHADER, FRAG));
|
|
423
|
+
gl.linkProgram(pr);
|
|
424
|
+
const lose = () => { gl.getExtension('WEBGL_lose_context')?.loseContext(); };
|
|
425
|
+
if (!gl.getProgramParameter(pr, gl.LINK_STATUS)) {
|
|
426
|
+
lose();
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
gl.useProgram(pr);
|
|
430
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
|
|
431
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
432
|
+
const p = gl.getAttribLocation(pr, 'p');
|
|
433
|
+
gl.enableVertexAttribArray(p);
|
|
434
|
+
gl.vertexAttribPointer(p, 2, gl.FLOAT, false, 0, 0);
|
|
435
|
+
const U = (k) => gl.getUniformLocation(pr, k);
|
|
436
|
+
const uR = U('R'), uT = U('T'), uL = U('L'), uA = U('A0'), uB = U('B0');
|
|
437
|
+
return {
|
|
438
|
+
paint(ms, lv, a, b) {
|
|
439
|
+
const now = performance.now();
|
|
440
|
+
if (fit(now))
|
|
441
|
+
gl.viewport(0, 0, w, w);
|
|
442
|
+
tint(a, b, now, false);
|
|
443
|
+
gl.uniform2f(uR, w, w);
|
|
444
|
+
gl.uniform1f(uT, ms);
|
|
445
|
+
gl.uniform1f(uL, lv);
|
|
446
|
+
gl.uniform3fv(uA, ca);
|
|
447
|
+
gl.uniform3fv(uB, cb);
|
|
448
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
449
|
+
},
|
|
450
|
+
lose,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
const x = cv.getContext('2d');
|
|
454
|
+
if (!x)
|
|
455
|
+
return null;
|
|
456
|
+
// the shader's colours: dark ones lifted, pale ones given more chroma, a third hue
|
|
457
|
+
// turned round the grey axis toward the warm side
|
|
458
|
+
const tn = (o, d) => {
|
|
459
|
+
const lift = Math.max(1, 0.5 / Math.max(0.01, o[0], o[1], o[2]));
|
|
460
|
+
const mx = Math.max(o[0], o[1], o[2]) * lift;
|
|
461
|
+
const dd = mx - Math.min(o[0], o[1], o[2]) * lift;
|
|
462
|
+
const s = Math.min(1, Math.max(0, (dd - 0.03) / 0.09));
|
|
463
|
+
const k = 1 + (Math.min(3, Math.max(1, 0.55 * mx / Math.max(dd, 0.001))) - 1) * s * s * (3 - 2 * s);
|
|
464
|
+
for (let i = 0; i < 3; i++)
|
|
465
|
+
d[i] = Math.max(0, mx - (mx - o[i] * lift) * k);
|
|
466
|
+
};
|
|
467
|
+
const hue = (o, d, ang) => {
|
|
468
|
+
const co = Math.cos(ang), si = Math.sin(ang) * 0.57735, m = ((o[0] + o[1] + o[2]) / 3) * (1 - co);
|
|
469
|
+
d[0] = o[0] * co + (o[2] - o[1]) * si + m;
|
|
470
|
+
d[1] = o[1] * co + (o[0] - o[2]) * si + m;
|
|
471
|
+
d[2] = o[2] * co + (o[1] - o[0]) * si + m;
|
|
472
|
+
};
|
|
473
|
+
const A = new Float32Array(3), B = new Float32Array(3), C = new Float32Array(3), M = new Float32Array(3);
|
|
474
|
+
const cssCol = (o, al, f = 1) => `rgba(${[0, 1, 2].map((i) => Math.round(Math.min(1, Math.max(0, o[i] * f)) * 255)).join(',')},${al})`;
|
|
475
|
+
const grad = (cx, cy, r, stops) => {
|
|
476
|
+
const g = x.createRadialGradient(cx, cy, 0, cx, cy, r);
|
|
477
|
+
for (let i = 0; i < stops.length; i += 2)
|
|
478
|
+
g.addColorStop(stops[i], stops[i + 1]);
|
|
479
|
+
return g;
|
|
480
|
+
};
|
|
481
|
+
const shade = grad(-0.35, -0.4, 1.6, [0, 'rgba(255,255,255,.16)', 0.45, 'rgba(0,0,0,0)', 1, 'rgba(0,0,0,.5)']);
|
|
482
|
+
const rim = grad(0, 0, 1, [0.78, 'rgba(255,255,255,0)', 1, 'rgba(255,255,255,.28)']);
|
|
483
|
+
const sheen = grad(-0.32, -0.38, 0.6, [0, 'rgba(255,255,255,.22)', 1, 'rgba(255,255,255,0)']);
|
|
484
|
+
const spec = grad(-0.4, -0.46, 0.14, [0, 'rgba(255,255,255,.95)', 1, 'rgba(255,255,255,0)']);
|
|
485
|
+
let g = null;
|
|
486
|
+
let mid = 0, rad = 0;
|
|
487
|
+
const put = (fill, dx, dy, sz) => {
|
|
488
|
+
x.setTransform(rad * sz, 0, 0, rad * sz, mid + rad * dx, mid + rad * dy);
|
|
489
|
+
x.fillStyle = fill;
|
|
490
|
+
x.fillRect(-1, -1, 2, 2);
|
|
491
|
+
};
|
|
492
|
+
return {
|
|
493
|
+
paint(ms, lv, a, b) {
|
|
494
|
+
const now = performance.now();
|
|
495
|
+
fit(now);
|
|
496
|
+
if (!g || a !== sa || b !== sb) {
|
|
497
|
+
tint(a, b, now, true);
|
|
498
|
+
tn(ca, A);
|
|
499
|
+
tn(cb, B);
|
|
500
|
+
hue(A, C, A[2] > A[1] ? 1.4 : -0.9);
|
|
501
|
+
for (let i = 0; i < 3; i++)
|
|
502
|
+
M[i] = (A[i] + B[i]) / 2;
|
|
503
|
+
g = {
|
|
504
|
+
base: cssCol(M, 1, 0.7),
|
|
505
|
+
a: grad(0, 0, 1, [0, cssCol(A, 0.95), 1, cssCol(A, 0)]),
|
|
506
|
+
b: grad(0, 0, 1, [0, cssCol(B, 0.95), 1, cssCol(B, 0)]),
|
|
507
|
+
c: grad(0, 0, 1, [0, cssCol(C, 0.55), 1, cssCol(C, 0)]),
|
|
508
|
+
core: grad(0, 0, 1, [0, cssCol(A, 1, 1.4), 1, cssCol(A, 0)]),
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
const t = ms * 0.001, s = t * 0.22;
|
|
512
|
+
mid = w / 2;
|
|
513
|
+
rad = mid * 0.955 * (1 + 0.008 * Math.sin(t * 0.9));
|
|
514
|
+
x.setTransform(1, 0, 0, 1, 0, 0);
|
|
515
|
+
x.clearRect(0, 0, w, w);
|
|
516
|
+
x.save();
|
|
517
|
+
x.beginPath();
|
|
518
|
+
x.arc(mid, mid, rad, 0, Math.PI * 2);
|
|
519
|
+
x.clip();
|
|
520
|
+
x.fillStyle = g.base;
|
|
521
|
+
x.fillRect(0, 0, w, w);
|
|
522
|
+
put(g.a, 0.55 * Math.sin(s * 1.3), -0.5 * Math.cos(s * 1.1), 1.1);
|
|
523
|
+
put(g.b, 0.55 * Math.cos(s * 0.9 + 2), -0.5 * Math.sin(s * 1.2 + 1), 1.1);
|
|
524
|
+
put(g.c, 0.5 * Math.sin(s * 1.6 + 4), -0.5 * Math.cos(s * 1.4 + 5), 0.9);
|
|
525
|
+
x.globalAlpha = 0.15 + 0.45 * lv;
|
|
526
|
+
put(g.core, 0, 0, 0.7);
|
|
527
|
+
x.globalAlpha = 1;
|
|
528
|
+
put(shade, 0, 0, 1);
|
|
529
|
+
put(rim, 0, 0, 1);
|
|
530
|
+
put(sheen, 0, 0, 1);
|
|
531
|
+
x.globalAlpha = 0.85 + 0.15 * lv * Math.sin(t * 9);
|
|
532
|
+
put(spec, 0, 0, 1);
|
|
533
|
+
x.restore();
|
|
534
|
+
},
|
|
535
|
+
lose() { },
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2Utb3JiLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3ZvaWNlLW9yYi92b2ljZS1vcmIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFEQUFxRDtBQUNyRCxFQUFFO0FBQ0YsaUVBQWlFO0FBQ2pFLGtGQUFrRjtBQUNsRixnRkFBZ0Y7QUFDaEYsMkVBQTJFO0FBQzNFLGlGQUFpRjtBQUVqRixPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVOLFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7QUE2QnRFLE1BQU0sUUFBUSxHQUE2QjtJQUN6QyxLQUFLLEVBQUUsT0FBTztJQUNkLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLEtBQUssRUFBRSxPQUFPO0lBQ2QsS0FBSyxFQUFFLE9BQU87SUFDZCxLQUFLLEVBQUUsZUFBZTtJQUN0QixHQUFHLEVBQUUsS0FBSztJQUNWLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLFFBQVE7SUFDaEIsV0FBVyxFQUFFLGlEQUFpRDtJQUM5RCxVQUFVLEVBQUUsa0JBQWtCO0lBQzlCLE9BQU8sRUFBRSxhQUFhO0NBQ3ZCLENBQUM7QUFFRixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVMsRUFBVSxFQUFFLENBQ2hDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFB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QUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNwRyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUMsQ0FBQztJQUNGLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBZSxFQUFFLENBQWUsRUFBRSxHQUFXLEVBQVEsRUFBRTtRQUNsRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbEcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekcsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFlLEVBQUUsRUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQVUsRUFBRSxDQUM1RCxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUM7SUFDeEcs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QUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDcEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7b0JBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDckQsQ0FBQyxHQUFHO29CQUNGLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUM7b0JBQ3ZCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN2RCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdkQsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZELElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FB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QztRQUNkLENBQUM7UUFDRCxJQUFJLEtBQVUsQ0FBQztLQUNoQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGZyYW1ld29yay9hbmd1bGFyL3ZvaWNlLW9yYi92b2ljZS1vcmIuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiBmcmFtZXdvcmsvcmVhY3Qvdm9pY2Utb3JiL1ZvaWNlT3JiLnRzeC5cbi8vIEEgaGFuZHMtZnJlZSB2b2ljZSBjaGF0OiBhbiBvcmIgdGhhdCBzd2VsbHMgd2l0aCB3aG9ldmVyIGlzIHRhbGtpbmcsIHRoZSBhY2NlbnRcbi8vIGNvbG91ciBmb3IgeW91IGFuZCB2aW9sZXQgZm9yIHRoZSBhZ2VudCwgd2hhdCB3YXMgc2FpZCB1bmRlciBpdCwgYW5kIG11dGUgYW5kXG4vLyBlbmQgYmVsb3cuIEl0IGRyYXdzIHdoYXQgeW91IHBhc3M7IGl0IG5ldmVyIG9wZW5zIHRoZSBtaWNyb3Bob25lIGl0c2VsZi5cbi8vIElucHV0cyBtaXJyb3IgdGhlIFJlYWN0IHByb3BzOyBSZWFjdCBjYWxsYmFja3MgYmVjb21lIEBPdXRwdXQoKSBFdmVudEVtaXR0ZXJzLlxuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWb0ljb25Db21wb25lbnQgfSBmcm9tICcuLi9jb3JlL2ljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFJlZHVjZWRNb3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9yZWR1Y2VkLW1vdGlvbi5zZXJ2aWNlJztcblxuLyoqIGlkbGUgKG5vdCBzdGFydGVkKSwgbGlzdGVuaW5nLCB0aGlua2luZywgc3BlYWtpbmcgKHRoZSBhZ2VudCkgb3IgZW5kZWQuICovXG5leHBvcnQgdHlwZSBWb2ljZVN0YXRlID0gJ2lkbGUnIHwgJ2xpc3RlbmluZycgfCAndGhpbmtpbmcnIHwgJ3NwZWFraW5nJyB8ICdlbmRlZCc7XG5cbi8qKiBXaGF0IHdhcyBzYWlkIGxhc3QgYW5kIHdobyBzYWlkIGl0LiBBIG5ldyBpZCAob3Igc3BlYWtlcikgc3RhcnRzIGEgbmV3IGxpbmUuICovXG5leHBvcnQgaW50ZXJmYWNlIFZvaWNlQ2FwdGlvbiB7XG4gIHNwZWFrZXI6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICBpZD86IHN0cmluZztcbn1cblxuLyoqIExhYmVscywgc28gZXZlcnkgYml0IG9mIHRleHQgY2FuIGJlIGxvY2FsaXNlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVm9pY2VPcmJMYWJlbHMge1xuICByZWFkeT86IHN0cmluZztcbiAgbGlzdGVuaW5nPzogc3RyaW5nO1xuICB0aGlua2luZz86IHN0cmluZztcbiAgc3BlYWtpbmc/OiBzdHJpbmc7XG4gIG11dGVkPzogc3RyaW5nO1xuICBlbmRlZD86IHN0cmluZztcbiAgc3RhcnQ/OiBzdHJpbmc7XG4gIGVuZD86IHN0cmluZztcbiAgbXV0ZT86IHN0cmluZztcbiAgdW5tdXRlPzogc3RyaW5nO1xuICBtdXRlZE5vdGljZT86IHN0cmluZztcbiAgZW5kZWRUaXRsZT86IHN0cmluZztcbiAgcmVzdGFydD86IHN0cmluZztcbn1cblxuY29uc3QgREVGQVVMVFM6IFJlcXVpcmVkPFZvaWNlT3JiTGFiZWxzPiA9IHtcbiAgcmVhZHk6ICdSZWFkeScsXG4gIGxpc3RlbmluZzogJ0xpc3RlbmluZycsXG4gIHRoaW5raW5nOiAnVGhpbmtpbmcnLFxuICBzcGVha2luZzogJ1NwZWFraW5nJyxcbiAgbXV0ZWQ6ICdNdXRlZCcsXG4gIGVuZGVkOiAnRW5kZWQnLFxuICBzdGFydDogJ1N0YXJ0IHRhbGtpbmcnLFxuICBlbmQ6ICdFbmQnLFxuICBtdXRlOiAnTXV0ZScsXG4gIHVubXV0ZTogJ1VubXV0ZScsXG4gIG11dGVkTm90aWNlOiBcIllvdSdyZSBtdXRlZC4gVW5tdXRlIHNvIHRoZSBhZ2VudCBjYW4gaGVhciB5b3UuXCIsXG4gIGVuZGVkVGl0bGU6ICdWb2ljZSBjaGF0IGVuZGVkJyxcbiAgcmVzdGFydDogJ1N0YXJ0IGFnYWluJyxcbn07XG5cbmNvbnN0IGZtdCA9IChzOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgYCR7TWF0aC5mbG9vcihzIC8gNjApfToke1N0cmluZyhNYXRoLmZsb29yKHMpICUgNjApLnBhZFN0YXJ0KDIsICcwJyl9YDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndm8tdm9pY2Utb3JiJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaW1wb3J0czogW1ZvSWNvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBkYXRhLXZvPVwiXCIgW2NsYXNzXT1cImNsYXNzTmFtZVwiIHN0eWxlPVwid2lkdGg6MTAwJVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInZvLXZvciB2by1wYW5lbFwiIFtjbGFzcy52by1vbl09XCJvblwiIFthdHRyLmRhdGEtbV09XCJtb2RlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by12b3ItdG9wXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12b3ItZG90XCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdm9yLXN0XCI+e3sgc3RhdHVzIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdm9yLXQgdm8tbnVtIHZvLW11dGVkXCI+e3sgZm10KGVsYXBzZWQpIH19PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInZvLXZvci1vcmJcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBbc3R5bGUuLS12by1sdl09XCJsdlwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwidm8tdm9yLXBjXCI+PC9pPlxuICAgICAgICAgIDxpIGNsYXNzPVwidm8tdm9yLWNvcmVcIj48Y2FudmFzICNnbCBjbGFzcz1cInZvLXZvci1nbFwiPjwvY2FudmFzPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by12b3ItY2FwXCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by12b3Itd2hvIHZvLW11dGVkXCI+e3sgY2FwdGlvbj8uc3BlYWtlciA/PyAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICBAaWYgKGNhcHRpb247IGFzIGNhcCkge1xuICAgICAgICAgICAgPHAgY2xhc3M9XCJ2by12b3ItdHhcIj5cbiAgICAgICAgICAgICAgQGZvciAodyBvZiB3b3JkcyhjYXAudGV4dCk7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8td1wiPnt7IHcgfX0gPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8cCBjbGFzcz1cInZvLXZvci10eCB2by1oaW50XCI+e3sgaGludCB9fTwvcD5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tZm9sZCB2by12b3ItbWZcIiBbY2xhc3Mudm8tc2h1dF09XCIhbm90aWNlT3BlblwiIFthdHRyLmluZXJ0XT1cIm5vdGljZU9wZW4gPyBudWxsIDogJydcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXZvci1td1wiPlxuICAgICAgICAgICAgICA8cD48dm8taWNvbiBuYW1lPVwiYWxlcnRcIiBzaXplPVwieHNcIj48L3ZvLWljb24+PHNwYW4+e3sgTC5tdXRlZE5vdGljZSB9fTwvc3Bhbj48L3A+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbSB2by12b3ItdW5cIiAoY2xpY2spPVwiZW1pdE11dGVkKGZhbHNlKVwiPnt7IEwudW5tdXRlIH19PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIEBpZiAoc3RhdGUgPT09ICdlbmRlZCcpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tdm9yLWRvbmUgdm8tZW50ZXJcIj5cbiAgICAgICAgICAgIDx2by1pY29uIG5hbWU9XCJva1wiPjwvdm8taWNvbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tdFwiPnt7IEwuZW5kZWRUaXRsZSB9fTxzcGFuIGNsYXNzPVwidm8tbXV0ZWRcIj57eyBlbmRlZERldGFpbCA/PyBkZWZhdWx0RGV0YWlsIH19PC9zcGFuPjwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbVwiIChjbGljayk9XCJyZXN0YXJ0LmVtaXQoKVwiPnt7IEwucmVzdGFydCB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tdm9yLWZcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1wcmltYXJ5IHZvLXNtIHZvLXZvci1nb1wiIChjbGljayk9XCJzdGFydC5lbWl0KClcIj5cbiAgICAgICAgICAgICAgPHZvLWljb24gbmFtZT1cImNvbW1lbnRcIiBzaXplPVwieHNcIj48L3ZvLWljb24+e3sgTC5zdGFydCB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cInZvLWliIHZvLWZpbGwgdm8tdm9yLW11dGVcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIkwubXV0ZVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJtdXRlZFwiXG4gICAgICAgICAgICAgIFthdHRyLmRhdGEtdGlwXT1cIm11dGVkID8gTC51bm11dGUgOiBMLm11dGVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZW1pdE11dGVkKCFtdXRlZClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8dm8taWNvbiBuYW1lPVwiY29tbWVudFwiPjwvdm8taWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidm8tcGlsbCB2by1zbSB2by12b3ItZW5kXCIgKGNsaWNrKT1cImVuZC5lbWl0KClcIj57eyBMLmVuZCB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmw6ICcuL3ZvaWNlLW9yYi5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBWb2ljZU9yYkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIGlkbGUsIGxpc3RlbmluZywgdGhpbmtpbmcsIHNwZWFraW5nIG9yIGVuZGVkLiAqL1xuICBASW5wdXQoKSBzdGF0ZTogVm9pY2VTdGF0ZSA9ICdpZGxlJztcbiAgLyoqIEhvdyBsb3VkIHdob2V2ZXIgaXMgdGFsa2luZyBpcywgMCB0byAxLiBUaGUgb3JiIHN3ZWxscyB3aXRoIGl0LiAqL1xuICBASW5wdXQoKSBsZXZlbCA9IDA7XG4gIC8qKiBZb3VyIG1pY3JvcGhvbmUgaXMgb2ZmLiBMaXN0ZW5pbmcgc2hvd3MgYXMgTXV0ZWQsIHRoZSBtdXRlIGJ1dHRvbiBpcyBwcmVzc2VkLiAqL1xuICBASW5wdXQoKSBtdXRlZCA9IGZhbHNlO1xuICAvKiogU2hvd3MgXCJZb3UncmUgbXV0ZWRcIiB3aXRoIGFuIFVubXV0ZSBidXR0b24sIGZvciB3aGVuIHNvbWVvbmUgdGFsa3Mgd2hpbGUgbXV0ZWQuICovXG4gIEBJbnB1dCgpIG11dGVkTm90aWNlID0gZmFsc2U7XG4gIC8qKiBXaGF0IHdhcyBzYWlkIGxhc3QgYW5kIHdobyBzYWlkIGl0OyBlYWNoIHdvcmQgZmFkZXMgaW4gYXMgaXQgYXJyaXZlcy4gKi9cbiAgQElucHV0KCkgY2FwdGlvbjogVm9pY2VDYXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBTaG93biBiZWZvcmUgYW55dGhpbmcgaXMgc2FpZCwgbGlrZSBcIlRhbGsgdG8gdGhlIGFnZW50IGFib3V0IFByaWNpbmcgdjRcIi4gKi9cbiAgQElucHV0KCkgaGludCA9ICcnO1xuICAvKiogU2Vjb25kcyBzaW5jZSB0aGUgY2hhdCBzdGFydGVkLCBzaG93biB0b3AgcmlnaHQuICovXG4gIEBJbnB1dCgpIGVsYXBzZWQgPSAwO1xuICAvKiogVGhlIHF1aWV0IGxpbmUgdW5kZXIgXCJWb2ljZSBjaGF0IGVuZGVkXCIuIERlZmF1bHRzIHRvIHRoZSBsZW5ndGggYW5kIFwiVHJhbnNjcmlwdCBzYXZlZFwiLiAqL1xuICBASW5wdXQoKSBlbmRlZERldGFpbD86IHN0cmluZztcbiAgQElucHV0KCkgbGFiZWxzOiBWb2ljZU9yYkxhYmVscyA9IHt9O1xuICBASW5wdXQoKSBjbGFzc05hbWUgPSAnJztcblxuICBAT3V0cHV0KCkgbXV0ZWRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBPdXRwdXQoKSBzdGFydCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGVuZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLyoqIFN0YXJ0IGFnYWluLCBmcm9tIHRoZSByb3cgdGhhdCBzaG93cyBvbmNlIHRoZSBjaGF0IGhhcyBlbmRlZC4gKi9cbiAgQE91dHB1dCgpIHJlc3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZ2wnKSBwcml2YXRlIGdsUmVmPzogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBtb3Rpb24gPSBpbmplY3QoUmVkdWNlZE1vdGlvblNlcnZpY2UpO1xuXG4gIEw6IFJlcXVpcmVkPFZvaWNlT3JiTGFiZWxzPiA9IERFRkFVTFRTO1xuXG4gIC8vIG11dGVkIG9ubHkgY2hhbmdlcyBob3cgbGlzdGVuaW5nIGxvb2tzOiB0aGUgYWdlbnQgY2FuIHN0aWxsIHRoaW5rIGFuZCBzcGVha1xuICBnZXQgbW9kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm11dGVkICYmIHRoaXMuc3RhdGUgPT09ICdsaXN0ZW5pbmcnID8gJ211dGVkJyA6IHRoaXMuc3RhdGU7XG4gIH1cbiAgZ2V0IHN0YXR1cygpOiBzdHJpbmcge1xuICAgIGNvbnN0IG1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIGlkbGU6IHRoaXMuTC5yZWFkeSxcbiAgICAgIGxpc3RlbmluZzogdGhpcy5MLmxpc3RlbmluZyxcbiAgICAgIHRoaW5raW5nOiB0aGlzLkwudGhpbmtpbmcsXG4gICAgICBzcGVha2luZzogdGhpcy5MLnNwZWFraW5nLFxuICAgICAgbXV0ZWQ6IHRoaXMuTC5tdXRlZCxcbiAgICAgIGVuZGVkOiB0aGlzLkwuZW5kZWQsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3RoaXMubW9kZV0gPz8gJyc7XG4gIH1cbiAgZ2V0IG9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlICE9PSAnaWRsZScgJiYgdGhpcy5zdGF0ZSAhPT0gJ2VuZGVkJztcbiAgfVxuICBnZXQgbm90aWNlT3BlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tdXRlZE5vdGljZSAmJiB0aGlzLm11dGVkICYmIHRoaXMub247XG4gIH1cbiAgZ2V0IGx2KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHRoaXMubGV2ZWwpKS50b0ZpeGVkKDMpO1xuICB9XG4gIGdldCBkZWZhdWx0RGV0YWlsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke2ZtdCh0aGlzLmVsYXBzZWQpfSDCtyBUcmFuc2NyaXB0IHNhdmVkYDtcbiAgfVxuXG4gIHJlYWRvbmx5IGZtdCA9IGZtdDtcbiAgd29yZHModGV4dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0ZXh0LnNwbGl0KCcgJykuZmlsdGVyKEJvb2xlYW4pO1xuICB9XG5cbiAgZW1pdE11dGVkKG5leHQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLm11dGVkQ2hhbmdlLmVtaXQobmV4dCk7XG4gIH1cblxuICAvLyB0aGUgbGl0IGdsYXNzIHNwaGVyZSwgZHJhd24gb24gYSBjYW52YXMgaW4gdGhlIGNvbG91cnMgb2Ygd2hvZXZlciBpcyB0YWxraW5nLFxuICAvLyBmYXN0ZXIgYW5kIGJyaWdodGVyIGFzIHRoZXkgZ2V0IGxvdWRlci4gV2l0aCByZWR1Y2VkIG1vdGlvbiBpdCBpcyBvbmUgc3RpbGxcbiAgLy8gZnJhbWUsIGRyYXduIGFnYWluIHdoZW4gdGhlIHNwZWFrZXIgY2hhbmdlczsgd2hlcmUgbm8gY2FudmFzIGNhbiBkcmF3IHRoZSBjb3JlXG4gIC8vIGtlZXBzIGl0cyBwbGFpbiBncmFkaWVudCAoc2V0IGJ5IENTUykuXG4gIHByaXZhdGUgc2hhZGVyOiBPcmJTaGFkZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByYWYgPSAwO1xuICBwcml2YXRlIGZsb3cgPSAwO1xuICBwcml2YXRlIGxhc3QgPSAwO1xuICBwcml2YXRlIGNvbHM6IFtzdHJpbmcsIHN0cmluZ10gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjb2xzQXQgPSAtMWU5O1xuICBwcml2YXRlIGlvPzogSW50ZXJzZWN0aW9uT2JzZXJ2ZXI7XG4gIHByaXZhdGUgc2VlbiA9IHRydWU7XG4gIHByaXZhdGUgc3RhcnRlZCA9IGZhbHNlO1xuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snbGFiZWxzJ10pIHRoaXMuTCA9IHsgLi4uREVGQVVMVFMsIC4uLnRoaXMubGFiZWxzIH07XG4gICAgLy8gZHJhdyBvbmNlIG1vcmUgd2hlbiB0aGUgc3BlYWtlciAoZGF0YS1tKSBjaGFuZ2VzIHVuZGVyIHJlZHVjZWQgbW90aW9uXG4gICAgaWYgKHRoaXMuc3RhcnRlZCAmJiB0aGlzLm1vdGlvbi5yZWR1Y2UoKSAmJiAoY2hhbmdlc1snc3RhdGUnXSB8fCBjaGFuZ2VzWydtdXRlZCddKSkge1xuICAgICAgdGhpcy5jb2xzID0gbnVsbDtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHRoaXMuZHJhdyh0aGlzLmZsb3cpKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgY29uc3QgY3YgPSB0aGlzLmdsUmVmPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghY3YpIHJldHVybjtcbiAgICB0aGlzLnNoYWRlciA9IG9yYlNoYWRlcihjdik7XG4gICAgaWYgKCF0aGlzLnNoYWRlcikgcmV0dXJuO1xuICAgIGN2LmNsYXNzTGlzdC5hZGQoJ3ZvLW9uJyk7XG4gICAgdGhpcy5zdGFydGVkID0gdHJ1ZTtcbiAgICBpZiAoJ0ludGVyc2VjdGlvbk9ic2VydmVyJyBpbiB3aW5kb3cpIHtcbiAgICAgIHRoaXMuaW8gPSBuZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGUpID0+ICh0aGlzLnNlZW4gPSBlWzBdLmlzSW50ZXJzZWN0aW5nKSk7XG4gICAgICB0aGlzLmlvLm9ic2VydmUoY3YpO1xuICAgIH1cbiAgICB0aGlzLmRyYXcoMCk7XG4gICAgaWYgKCF0aGlzLm1vdGlvbi5yZWR1Y2UoKSkge1xuICAgICAgY29uc3QgdGljayA9ICh0OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5mbG93ICs9IE1hdGgubWluKDUwLCB0IC0gKHRoaXMubGFzdCB8fCB0KSkgKiAoMSArIE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHRoaXMubGV2ZWwpKSAqIDIuNSk7XG4gICAgICAgIHRoaXMubGFzdCA9IHQ7XG4gICAgICAgIGlmICh0aGlzLnNlZW4pIHRoaXMuZHJhdyh0aGlzLmZsb3cpO1xuICAgICAgICB0aGlzLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICAgIH07XG4gICAgICB0aGlzLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRyYXcobXM6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN2ID0gdGhpcy5nbFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXRoaXMuc2hhZGVyIHx8ICFjdikgcmV0dXJuO1xuICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGlmICghdGhpcy5jb2xzIHx8IG5vdyAtIHRoaXMuY29sc0F0ID4gMjUwKSB7XG4gICAgICBjb25zdCBib3ggPSBjdi5jbG9zZXN0PEhUTUxFbGVtZW50PignLnZvLXZvcicpO1xuICAgICAgY29uc3QgZG90ID0gYm94Py5xdWVyeVNlbGVjdG9yKCcudm8tdm9yLWRvdCcpO1xuICAgICAgY29uc3QgcGMgPSBib3g/LnF1ZXJ5U2VsZWN0b3IoJy52by12b3ItcGMnKTtcbiAgICAgIGlmIChkb3QgJiYgcGMpIHtcbiAgICAgICAgdGhpcy5jb2xzID0gW2dldENvbXB1dGVkU3R5bGUoZG90KS5iYWNrZ3JvdW5kQ29sb3IsIGdldENvbXB1dGVkU3R5bGUocGMpLmJhY2tncm91bmRDb2xvcl07XG4gICAgICAgIHRoaXMuY29sc0F0ID0gbm93O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5jb2xzKSB0aGlzLnNoYWRlci5wYWludChtcywgTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdGhpcy5sZXZlbCkpLCB0aGlzLmNvbHNbMF0sIHRoaXMuY29sc1sxXSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJhZik7XG4gICAgdGhpcy5pbz8uZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuc2hhZGVyPy5sb3NlKCk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIE9yYlNoYWRlciB7XG4gIHBhaW50KG1zOiBudW1iZXIsIGx2OiBudW1iZXIsIGE6IHN0cmluZywgYjogc3RyaW5nKTogdm9pZDtcbiAgbG9zZSgpOiB2b2lkO1xufVxuXG4vLyB0aGUgZ2xhc3Mgc3BoZXJlLCBhcyBhIGZyYWdtZW50IHNoYWRlciAodGhlIHNpdGUncyBvd24gc291cmNlLCBwb3J0ZWQgZnJvbSB0aGVcbi8vIFZhbmlsbGEvUmVhY3Qgb3JpZ2luYWxzKTogYSBiYWxsIGxpdCBmcm9tIHRoZSB0b3AgbGVmdCwgYSBkZWVwZXIgc2hpZnRlZCBodWUgcGFzdFxuLy8gdGhlIHRlcm1pbmF0b3IsIGxpZ2h0IGdhdGhlcmVkIHRocm91Z2ggdGhlIGdsYXNzIG9uIHRoZSBmYXIgc2lkZSwgYSBmcmVzbmVsIGVkZ2UsXG4vLyBhIGJyb2FkIHNoZWVuIGFuZCBhIHNoYXJwIGhpZ2hsaWdodC4gSW5zaWRlLCBkZWVwIHBvb2xzIG9mIHRoZSB0d28gY29sb3VycyBhbmQgYVxuLy8gdGhpcmQgaHVlIHN3aXJsLCBsaXF1aWQgbGlnaHQgZmxvd3MgdGhyb3VnaCB0aGUgbWlkZGxlIGFuZCB0d28gcmliYm9ucyB0dXJuIG5lYXJcbi8vIHRoZSBzdXJmYWNlLiBUaGUgbGV2ZWwgc3BlZWRzIHRoZSBmbG93LCBicmlnaHRlbnMgdGhlIGhlYXJ0IGFuZCBzaGltbWVycyB0aGVcbi8vIGhpZ2hsaWdodC4gV2hlcmUgV2ViR0wgaXMgbWlzc2luZyB0aGUgc2FtZSBwaWN0dXJlIGlzIGRyYXduIGluIGEgZmV3IGdyYWRpZW50cyBvblxuLy8gYSAyRCBjYW52YXMuIEF0IGl0cyB3aWRlc3QgdGhlIHNwaGVyZSBzdGlsbCBzaXRzIGluc2lkZSB0aGUgY2FudmFzLlxuY29uc3QgRlJBRyA9IGAjaWZkZWYgR0xfRlJBR01FTlRfUFJFQ0lTSU9OX0hJR0hcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiNlbHNlXG5wcmVjaXNpb24gbWVkaXVtcCBmbG9hdDtcbiNlbmRpZlxudW5pZm9ybSB2ZWMyIFI7dW5pZm9ybSBmbG9hdCBULEw7dW5pZm9ybSB2ZWMzIEEwLEIwO1xuZmxvYXQgaCh2ZWMyIHApe3JldHVybiBmcmFjdChzaW4oZG90KHAsdmVjMigxMjcuMSwzMTEuNykpKSo0Mzc1OC41NDUzKTt9XG5mbG9hdCBuKHZlYzIgcCl7dmVjMiBpPWZsb29yKHApLGY9ZnJhY3QocCk7Zj1mKmYqKDMuLTIuKmYpO3JldHVybiBtaXgobWl4KGgoaSksaChpK3ZlYzIoMSwwKSksZi54KSxtaXgoaChpK3ZlYzIoMCwxKSksaChpKzEuKSxmLngpLGYueSk7fVxuZmxvYXQgZmJtKHZlYzIgcCl7ZmxvYXQgdj0wLixhPS41O2ZvcihpbnQgaT0wO2k8NDtpKyspe3YrPWEqbihwKTtwPW1hdDIoMS42LDEuMiwtMS4yLDEuNikqcCt2ZWMyKDEuNyw5LjIpO2EqPS41O31yZXR1cm4gdjt9XG5tYXQyIHJvdChmbG9hdCBhKXtmbG9hdCBjPWNvcyhhKSxzPXNpbihhKTtyZXR1cm4gbWF0MihjLHMsLXMsYyk7fVxudmVjMyB0bih2ZWMzIGMpe2Zsb2F0IG14PW1heChjLnIsbWF4KGMuZyxjLmIpKSxkPW14LW1pbihjLnIsbWluKGMuZyxjLmIpKTtjKj1tYXgoMS4sLjUvbWF4KG14LC4wMSkpO214PW1heChteCwuNSk7ZD1teC1taW4oYy5yLG1pbihjLmcsYy5iKSk7cmV0dXJuIG1heChteC0obXgtYykqbWl4KDEuLGNsYW1wKC41NSpteC9tYXgoZCwuMDAxKSwxLiwzLiksc21vb3Roc3RlcCguMDMsLjEyLGQpKSwwLik7fVxudmVjMyBodWUodmVjMyBjLGZsb2F0IGEpe3ZlYzMgaz12ZWMzKC41NzczNSk7ZmxvYXQgY289Y29zKGEpO3JldHVybiBjKmNvK2Nyb3NzKGssYykqc2luKGEpK2sqZG90KGssYykqKDEuLWNvKTt9XG52b2lkIG1haW4oKXtcbiAgdmVjMyBBPXRuKEEwKSxCPXRuKEIwKSxDPWh1ZShBLG1peCgtLjksMS40LHNtb290aHN0ZXAoLS4xLC4xLEEuYi1BLmcpKSk7XG4gIHZlYzIgdT0oZ2xfRnJhZ0Nvb3JkLnh5KjIuLVIpL1IueTtcbiAgZmxvYXQgdD1UKi4wMDEsYW49YXRhbih1LnksdS54KTtcbiAgZmxvYXQgdz0oLjAwMisuMDA4KkwpKihzaW4oMy4qYW4rdCoxLjkpKy42KnNpbig1Liphbi10KjIuNykrLjQqc2luKDIuKmFuLXQqMS4xKSk7XG4gIGZsb2F0IHJhZD0uOTU1KigxLisuMDA4KnNpbih0Ki45KSt3KTtcbiAgdmVjMiBxPXUvcmFkO2Zsb2F0IHI9bGVuZ3RoKHEpLGU9My4vKFIueSpyYWQpO1xuICBmbG9hdCBhPTEuLXNtb290aHN0ZXAoMS4tZSwxLixyKTtcbiAgaWYoYTw9MC4pe2dsX0ZyYWdDb2xvcj12ZWM0KDAuKTtyZXR1cm47fVxuICBmbG9hdCB6PXNxcnQobWF4KDEuLXIqciwwLikpO1xuICB2ZWMzIE49dmVjMyhxLHopO1xuICBOLnh5Kz0odmVjMihuKHEqNS4rdCoxLjYpLG4ocSo1Li10KjEuMys3LikpLS41KSooLjAzKy4xMipMKTtOPW5vcm1hbGl6ZShOKTtcbiAgdmVjMyBTPXZlYzMocSx6KSxEPXJlZnJhY3QodmVjMygwLDAsLTEpLE4sLjcyKSxQMT1TK0QqeiouMzUsUDI9UytEKnoqLjksUDM9UytEKnoqMS41O1xuICBmbG9hdCBzPXQqLjIyO1xuICB2ZWMzIGQxPVAzLXZlYzMoLjU1KnNpbihzKjEuMyksLjUqY29zKHMqMS4xKSwuMypzaW4ocyouNykpLGQyPVAzLXZlYzMoLjU1KmNvcyhzKi45KzIuKSwuNSpzaW4ocyoxLjIrMS4pLC4zKmNvcyhzKi44KzMuKSksZDM9UDMtdmVjMyguNSpzaW4ocyoxLjYrNC4pLC41KmNvcyhzKjEuNCs1LiksLjMqc2luKHMrMS4pKTtcbiAgZmxvYXQgZzE9ZXhwKC1kb3QoZDEsZDEpKjIuNiksZzI9ZXhwKC1kb3QoZDIsZDIpKjIuNiksZzM9ZXhwKC1kb3QoZDMsZDMpKjMuMik7XG4gIHZlYzMgY29sPW1peChtaXgobWl4KG1peChBLEIsLjQpKi41NSxCLGcyKi44KSxDLGczKi43KSxBLGcxKi45NSk7XG4gIHZlYzIgbT1yb3QodCouMDkpKlAyLnh5KjEuNSxvPXZlYzIoZmJtKG0rdmVjMigwLix0Ki4zKSksZmJtKG0rdmVjMig1LjIsMS4zKS10Ki4yNSkpO1xuICBmbG9hdCBmPWZibShtKyhvLS41KSooMi41KzIuKkwpK3ZlYzIodCouMTIsLXQqLjA4KSk7XG4gIGNvbD1taXgoY29sLG1peChtaXgoQSxCLC41KSx2ZWMzKDEuKSwuMTUpLHNtb290aHN0ZXAoLjQ1LC44LGYpKi41KSooLjgrLjM1KnNtb290aHN0ZXAoLjIsLjYsZikpO1xuICB2ZWMyIGs9cm90KC10Ki4zMykqUDEueHk7XG4gIGZsb2F0IGIxPWsueSsuMzIqc2luKGsueCoyLjQrdCoxLjQpKy4xMipzaW4oay54KjUuMy10KjIuMikrKG8ueC0uNSkqLjUsYjI9ay54LS4zKnNpbihrLnkqMi4xLXQqMS4xKSsuNDtcbiAgY29sKz1taXgobWl4KEEsQywuMzUpLHZlYzMoMS4pLC4zNSkqKGV4cCgtYjEqYjEqNDAuKSsuNipleHAoLWIyKmIyKjU1LikpKiguMjUrLjM1KkwpKno7XG4gIGNvbCs9bWl4KEEsdmVjMygxLiksLjQpKmV4cCgtZG90KFAyLnh5LFAyLnh5KSozLikqKC4wOCsuMypMKTtcbiAgdmVjMyBsaz1ub3JtYWxpemUodmVjMygtLjUsLjYyLC42KSksZGs9aHVlKGNvbCwuMzUpO1xuICBjb2w9bWl4KGRrKmRrKi42LGNvbCoxLjA2LHNtb290aHN0ZXAoLS41NSwuNzUsZG90KE4sbGspKSk7XG4gIGNvbCs9bWl4KEIsdmVjMygxLiksLjUpKnBvdygxLi16LDEuNikqc21vb3Roc3RlcCguMSwuOTUsZG90KHEvbWF4KHIsMWUtMyksLW5vcm1hbGl6ZShsay54eSkpKSouNTU7XG4gIGNvbD1taXgoY29sLG1peCh2ZWMzKC4wNiksdmVjMygxLiksc21vb3Roc3RlcCgtLjMsLjksTi55Ki43LU4ueCouNCkpLHBvdygxLi1OLnosMy4pKi41KTtcbiAgZmxvYXQgbmg9bWF4KGRvdChOLG5vcm1hbGl6ZShsayt2ZWMzKDAsMCwxKSkpLDAuKTtcbiAgY29sKz1wb3cobmgsNzAwLikqKDEuMisuOCpMKnNpbih0KjkuK3EueCo4LikpK3BvdyhuaCw2MC4pKi4yNStwb3cobmgsOC4pKi4xO1xuICBnbF9GcmFnQ29sb3I9dmVjNChjbGFtcChjb2wsMC4sMS4pKmEsYSk7XG59YDtcblxuLyoqIERyYXdzIHRoZSBzcGhlcmUgb24gdGhlIG9yYidzIGNhbnZhczogb25lIGRyYXcgYSBmcmFtZSwgYXQgbW9zdCAyIGRldmljZSBwaXhlbHMgYVxuICAgIENTUyBwaXhlbCwgbm90aGluZyBtYWRlIGFuZXcgZWFjaCBmcmFtZS4gV2hlcmUgV2ViR0wgaXMgbWlzc2luZyBpdCBmYWxscyBiYWNrIHRvIGFcbiAgICBmZXcgZ3JhZGllbnRzIG9uIGEgMkQgY2FudmFzLiBSZXR1cm5zIHsgcGFpbnQsIGxvc2UgfSwgb3IgbnVsbCB3aGVuIG5laXRoZXIgY2FuIGRyYXcuICovXG5mdW5jdGlvbiBvcmJTaGFkZXIoY3Y6IEhUTUxDYW52YXNFbGVtZW50KTogT3JiU2hhZGVyIHwgbnVsbCB7XG4gIC8vIGEgY29tcHV0ZWQgY29sb3VyIHRvIDAuLjEgY2hhbm5lbHM7IG1pZC10cmFuc2l0aW9uIGl0IGNhbiBjb21lIGFzIG9rbGFiKCkgb3JcbiAgLy8gY29sb3IoKSwgc28gYSAxcHggY2FudmFzIHJlYWRzIGl0LiBPbmx5IGEgY29sb3VyIHRoYXQgY2hhbmdlZCBpcyByZWFkLlxuICBjb25zdCBweCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJywgeyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUgfSk7XG4gIGlmICghcHgpIHJldHVybiBudWxsO1xuICBweC5jYW52YXMud2lkdGggPSBweC5jYW52YXMuaGVpZ2h0ID0gMTtcbiAgY29uc3QgcmdiID0gKHM6IHN0cmluZywgbzogRmxvYXQzMkFycmF5KTogdm9pZCA9PiB7XG4gICAgcHguY2xlYXJSZWN0KDAsIDAsIDEsIDEpO1xuICAgIHB4LmZpbGxTdHlsZSA9ICcjMDAwJztcbiAgICBweC5maWxsU3R5bGUgPSBzO1xuICAgIHB4LmZpbGxSZWN0KDAsIDAsIDEsIDEpO1xuICAgIGNvbnN0IGQgPSBweC5nZXRJbWFnZURhdGEoMCwgMCwgMSwgMSkuZGF0YTtcbiAgICBvWzBdID0gZFswXSAvIDI1NTtcbiAgICBvWzFdID0gZFsxXSAvIDI1NTtcbiAgICBvWzJdID0gZFsyXSAvIDI1NTtcbiAgfTtcbiAgY29uc3QgdGEgPSBuZXcgRmxvYXQzMkFycmF5KDMpLCB0YiA9IG5ldyBGbG9hdDMyQXJyYXkoMyksIGNhID0gbmV3IEZsb2F0MzJBcnJheSgzKSwgY2IgPSBuZXcgRmxvYXQzMkFycmF5KDMpO1xuICBsZXQgc2EgPSAnJywgc2IgPSAnJywgdyA9IDAsIGF0ID0gLTFlOSwgcHJldiA9IC0xZTk7XG4gIGNvbnN0IGZpdCA9IChub3c6IG51bWJlcik6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh3ICYmIG5vdyAtIGF0IDwgMzAwKSByZXR1cm4gZmFsc2U7XG4gICAgYXQgPSBub3c7XG4gICAgY29uc3QgbiA9IE1hdGgucm91bmQoY3YuY2xpZW50V2lkdGggKiBNYXRoLm1pbigyLCBkZXZpY2VQaXhlbFJhdGlvIHx8IDEpKSB8fCAxO1xuICAgIGlmIChuID09PSB3KSByZXR1cm4gZmFsc2U7XG4gICAgdyA9IGN2LndpZHRoID0gY3YuaGVpZ2h0ID0gbjtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcbiAgY29uc3QgdGludCA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgbm93OiBudW1iZXIsIHNuYXA6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICBpZiAoYSAhPT0gc2EpIHsgc2EgPSBhOyByZ2IoYSwgdGEpOyB9XG4gICAgaWYgKGIgIT09IHNiKSB7IHNiID0gYjsgcmdiKGIsIHRiKTsgfVxuICAgIGNvbnN0IGsgPSBzbmFwIHx8IG5vdyAtIHByZXYgPiAyMDAgPyAxIDogTWF0aC5taW4oMSwgKG5vdyAtIHByZXYpIC8gMTEwKTtcbiAgICBwcmV2ID0gbm93O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSB7IGNhW2ldICs9ICh0YVtpXSAtIGNhW2ldKSAqIGs7IGNiW2ldICs9ICh0YltpXSAtIGNiW2ldKSAqIGs7IH1cbiAgfTtcbiAgY29uc3QgZ2wgPSBjdi5nZXRDb250ZXh0KCd3ZWJnbCcsIHsgcHJlbXVsdGlwbGllZEFscGhhOiB0cnVlLCBhbnRpYWxpYXM6IGZhbHNlLCBwb3dlclByZWZlcmVuY2U6ICdsb3ctcG93ZXInIH0pO1xuICBpZiAoZ2wpIHtcbiAgICBjb25zdCBzaCA9ICh0eXBlOiBudW1iZXIsIHNyYzogc3RyaW5nKTogV2ViR0xTaGFkZXIgPT4ge1xuICAgICAgY29uc3QgcyA9IGdsLmNyZWF0ZVNoYWRlcih0eXBlKSE7XG4gICAgICBnbC5zaGFkZXJTb3VyY2Uocywgc3JjKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIocyk7XG4gICAgICByZXR1cm4gcztcbiAgICB9O1xuICAgIGNvbnN0IHByID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHIsIHNoKGdsLlZFUlRFWF9TSEFERVIsICdhdHRyaWJ1dGUgdmVjMiBwO3ZvaWQgbWFpbigpe2dsX1Bvc2l0aW9uPXZlYzQocCwwLiwxLik7fScpKTtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHIsIHNoKGdsLkZSQUdNRU5UX1NIQURFUiwgRlJBRykpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByKTtcbiAgICBjb25zdCBsb3NlID0gKCk6IHZvaWQgPT4geyBnbC5nZXRFeHRlbnNpb24oJ1dFQkdMX2xvc2VfY29udGV4dCcpPy5sb3NlQ29udGV4dCgpOyB9O1xuICAgIGlmICghZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwciwgZ2wuTElOS19TVEFUVVMpKSB7IGxvc2UoKTsgcmV0dXJuIG51bGw7IH1cbiAgICBnbC51c2VQcm9ncmFtKHByKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgZ2wuY3JlYXRlQnVmZmVyKCkpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIDEsIC0xLCAtMSwgMSwgMSwgMV0pLCBnbC5TVEFUSUNfRFJBVyk7XG4gICAgY29uc3QgcCA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHByLCAncCcpO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHApO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocCwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTtcbiAgICBjb25zdCBVID0gKGs6IHN0cmluZyk6IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHwgbnVsbCA9PiBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHIsIGspO1xuICAgIGNvbnN0IHVSID0gVSgnUicpLCB1VCA9IFUoJ1QnKSwgdUwgPSBVKCdMJyksIHVBID0gVSgnQTAnKSwgdUIgPSBVKCdCMCcpO1xuICAgIHJldHVybiB7XG4gICAgICBwYWludChtczogbnVtYmVyLCBsdjogbnVtYmVyLCBhOiBzdHJpbmcsIGI6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBub3cgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgaWYgKGZpdChub3cpKSBnbC52aWV3cG9ydCgwLCAwLCB3LCB3KTtcbiAgICAgICAgdGludChhLCBiLCBub3csIGZhbHNlKTtcbiAgICAgICAgZ2wudW5pZm9ybTJmKHVSLCB3LCB3KTtcbiAgICAgICAgZ2wudW5pZm9ybTFmKHVULCBtcyk7XG4gICAgICAgIGdsLnVuaWZvcm0xZih1TCwgbHYpO1xuICAgICAgICBnbC51bmlmb3JtM2Z2KHVBLCBjYSk7XG4gICAgICAgIGdsLnVuaWZvcm0zZnYodUIsIGNiKTtcbiAgICAgICAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRV9TVFJJUCwgMCwgNCk7XG4gICAgICB9LFxuICAgICAgbG9zZSxcbiAgICB9O1xuICB9XG4gIGNvbnN0IHggPSBjdi5nZXRDb250ZXh0KCcyZCcpO1xuICBpZiAoIXgpIHJldHVybiBudWxsO1xuICAvLyB0aGUgc2hhZGVyJ3MgY29sb3VyczogZGFyayBvbmVzIGxpZnRlZCwgcGFsZSBvbmVzIGdpdmVuIG1vcmUgY2hyb21hLCBhIHRoaXJkIGh1ZVxuICAvLyB0dXJuZWQgcm91bmQgdGhlIGdyZXkgYXhpcyB0b3dhcmQgdGhlIHdhcm0gc2lkZVxuICBjb25zdCB0biA9IChvOiBGbG9hdDMyQXJyYXksIGQ6IEZsb2F0MzJBcnJheSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGxpZnQgPSBNYXRoLm1heCgxLCAwLjUgLyBNYXRoLm1heCgwLjAxLCBvWzBdLCBvWzFdLCBvWzJdKSk7XG4gICAgY29uc3QgbXggPSBNYXRoLm1heChvWzBdLCBvWzFdLCBvWzJdKSAqIGxpZnQ7XG4gICAgY29uc3QgZGQgPSBteCAtIE1hdGgubWluKG9bMF0sIG9bMV0sIG9bMl0pICogbGlmdDtcbiAgICBjb25zdCBzID0gTWF0aC5taW4oMSwgTWF0aC5tYXgoMCwgKGRkIC0gMC4wMykgLyAwLjA5KSk7XG4gICAgY29uc3QgayA9IDEgKyAoTWF0aC5taW4oMywgTWF0aC5tYXgoMSwgMC41NSAqIG14IC8gTWF0aC5tYXgoZGQsIDAuMDAxKSkpIC0gMSkgKiBzICogcyAqICgzIC0gMiAqIHMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSBkW2ldID0gTWF0aC5tYXgoMCwgbXggLSAobXggLSBvW2ldICogbGlmdCkgKiBrKTtcbiAgfTtcbiAgY29uc3QgaHVlID0gKG86IEZsb2F0MzJBcnJheSwgZDogRmxvYXQzMkFycmF5LCBhbmc6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGNvID0gTWF0aC5jb3MoYW5nKSwgc2kgPSBNYXRoLnNpbihhbmcpICogMC41NzczNSwgbSA9ICgob1swXSArIG9bMV0gKyBvWzJdKSAvIDMpICogKDEgLSBjbyk7XG4gICAgZFswXSA9IG9bMF0gKiBjbyArIChvWzJdIC0gb1sxXSkgKiBzaSArIG07XG4gICAgZFsxXSA9IG9bMV0gKiBjbyArIChvWzBdIC0gb1syXSkgKiBzaSArIG07XG4gICAgZFsyXSA9IG9bMl0gKiBjbyArIChvWzFdIC0gb1swXSkgKiBzaSArIG07XG4gIH07XG4gIGNvbnN0IEEgPSBuZXcgRmxvYXQzMkFycmF5KDMpLCBCID0gbmV3IEZsb2F0MzJBcnJheSgzKSwgQyA9IG5ldyBGbG9hdDMyQXJyYXkoMyksIE0gPSBuZXcgRmxvYXQzMkFycmF5KDMpO1xuICBjb25zdCBjc3NDb2wgPSAobzogRmxvYXQzMkFycmF5LCBhbDogbnVtYmVyLCBmID0gMSk6IHN0cmluZyA9PlxuICAgIGByZ2JhKCR7WzAsIDEsIDJdLm1hcCgoaSkgPT4gTWF0aC5yb3VuZChNYXRoLm1pbigxLCBNYXRoLm1heCgwLCBvW2ldICogZikpICogMjU1KSkuam9pbignLCcpfSwke2FsfSlgO1xuICBjb25zdCBncmFkID0gKGN4OiBudW1iZXIsIGN5OiBudW1iZXIsIHI6IG51bWJlciwgc3RvcHM6IChudW1iZXIgfCBzdHJpbmcpW10pOiBDYW52YXNHcmFkaWVudCA9PiB7XG4gICAgY29uc3QgZyA9IHguY3JlYXRlUmFkaWFsR3JhZGllbnQoY3gsIGN5LCAwLCBjeCwgY3ksIHIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RvcHMubGVuZ3RoOyBpICs9IDIpIGcuYWRkQ29sb3JTdG9wKHN0b3BzW2ldIGFzIG51bWJlciwgc3RvcHNbaSArIDFdIGFzIHN0cmluZyk7XG4gICAgcmV0dXJuIGc7XG4gIH07XG4gIGNvbnN0IHNoYWRlID0gZ3JhZCgtMC4zNSwgLTAuNCwgMS42LCBbMCwgJ3JnYmEoMjU1LDI1NSwyNTUsLjE2KScsIDAuNDUsICdyZ2JhKDAsMCwwLDApJywgMSwgJ3JnYmEoMCwwLDAsLjUpJ10pO1xuICBjb25zdCByaW0gPSBncmFkKDAsIDAsIDEsIFswLjc4LCAncmdiYSgyNTUsMjU1LDI1NSwwKScsIDEsICdyZ2JhKDI1NSwyNTUsMjU1LC4yOCknXSk7XG4gIGNvbnN0IHNoZWVuID0gZ3JhZCgtMC4zMiwgLTAuMzgsIDAuNiwgWzAsICdyZ2JhKDI1NSwyNTUsMjU1LC4yMiknLCAxLCAncmdiYSgyNTUsMjU1LDI1NSwwKSddKTtcbiAgY29uc3Qgc3BlYyA9IGdyYWQoLTAuNCwgLTAuNDYsIDAuMTQsIFswLCAncmdiYSgyNTUsMjU1LDI1NSwuOTUpJywgMSwgJ3JnYmEoMjU1LDI1NSwyNTUsMCknXSk7XG4gIGxldCBnOiB7IGJhc2U6IHN0cmluZzsgYTogQ2FudmFzR3JhZGllbnQ7IGI6IENhbnZhc0dyYWRpZW50OyBjOiBDYW52YXNHcmFkaWVudDsgY29yZTogQ2FudmFzR3JhZGllbnQgfSB8IG51bGwgPSBudWxsO1xuICBsZXQgbWlkID0gMCwgcmFkID0gMDtcbiAgY29uc3QgcHV0ID0gKGZpbGw6IHN0cmluZyB8IENhbnZhc0dyYWRpZW50LCBkeDogbnVtYmVyLCBkeTogbnVtYmVyLCBzejogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgeC5zZXRUcmFuc2Zvcm0ocmFkICogc3osIDAsIDAsIHJhZCAqIHN6LCBtaWQgKyByYWQgKiBkeCwgbWlkICsgcmFkICogZHkpO1xuICAgIHguZmlsbFN0eWxlID0gZmlsbDtcbiAgICB4LmZpbGxSZWN0KC0xLCAtMSwgMiwgMik7XG4gIH07XG4gIHJldHVybiB7XG4gICAgcGFpbnQobXM6IG51bWJlciwgbHY6IG51bWJlciwgYTogc3RyaW5nLCBiOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgZml0KG5vdyk7XG4gICAgICBpZiAoIWcgfHwgYSAhPT0gc2EgfHwgYiAhPT0gc2IpIHtcbiAgICAgICAgdGludChhLCBiLCBub3csIHRydWUpO1xuICAgICAgICB0bihjYSwgQSk7XG4gICAgICAgIHRuKGNiLCBCKTtcbiAgICAgICAgaHVlKEEsIEMsIEFbMl0gPiBBWzFdID8gMS40IDogLTAuOSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzsgaSsrKSBNW2ldID0gKEFbaV0gKyBCW2ldKSAvIDI7XG4gICAgICAgIGcgPSB7XG4gICAgICAgICAgYmFzZTogY3NzQ29sKE0sIDEsIDAuNyksXG4gICAgICAgICAgYTogZ3JhZCgwLCAwLCAxLCBbMCwgY3NzQ29sKEEsIDAuOTUpLCAxLCBjc3NDb2woQSwgMCldKSxcbiAgICAgICAgICBiOiBncmFkKDAsIDAsIDEsIFswLCBjc3NDb2woQiwgMC45NSksIDEsIGNzc0NvbChCLCAwKV0pLFxuICAgICAgICAgIGM6IGdyYWQoMCwgMCwgMSwgWzAsIGNzc0NvbChDLCAwLjU1KSwgMSwgY3NzQ29sKEMsIDApXSksXG4gICAgICAgICAgY29yZTogZ3JhZCgwLCAwLCAxLCBbMCwgY3NzQ29sKEEsIDEsIDEuNCksIDEsIGNzc0NvbChBLCAwKV0pLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgY29uc3QgdCA9IG1zICogMC4wMDEsIHMgPSB0ICogMC4yMjtcbiAgICAgIG1pZCA9IHcgLyAyO1xuICAgICAgcmFkID0gbWlkICogMC45NTUgKiAoMSArIDAuMDA4ICogTWF0aC5zaW4odCAqIDAuOSkpO1xuICAgICAgeC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICB4LmNsZWFyUmVjdCgwLCAwLCB3LCB3KTtcbiAgICAgIHguc2F2ZSgpO1xuICAgICAgeC5iZWdpblBhdGgoKTtcbiAgICAgIHguYXJjKG1pZCwgbWlkLCByYWQsIDAsIE1hdGguUEkgKiAyKTtcbiAgICAgIHguY2xpcCgpO1xuICAgICAgeC5maWxsU3R5bGUgPSBnLmJhc2U7XG4gICAgICB4LmZpbGxSZWN0KDAsIDAsIHcsIHcpO1xuICAgICAgcHV0KGcuYSwgMC41NSAqIE1hdGguc2luKHMgKiAxLjMpLCAtMC41ICogTWF0aC5jb3MocyAqIDEuMSksIDEuMSk7XG4gICAgICBwdXQoZy5iLCAwLjU1ICogTWF0aC5jb3MocyAqIDAuOSArIDIpLCAtMC41ICogTWF0aC5zaW4ocyAqIDEuMiArIDEpLCAxLjEpO1xuICAgICAgcHV0KGcuYywgMC41ICogTWF0aC5zaW4ocyAqIDEuNiArIDQpLCAtMC41ICogTWF0aC5jb3MocyAqIDEuNCArIDUpLCAwLjkpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDAuMTUgKyAwLjQ1ICogbHY7XG4gICAgICBwdXQoZy5jb3JlLCAwLCAwLCAwLjcpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDE7XG4gICAgICBwdXQoc2hhZGUsIDAsIDAsIDEpO1xuICAgICAgcHV0KHJpbSwgMCwgMCwgMSk7XG4gICAgICBwdXQoc2hlZW4sIDAsIDAsIDEpO1xuICAgICAgeC5nbG9iYWxBbHBoYSA9IDAuODUgKyAwLjE1ICogbHYgKiBNYXRoLnNpbih0ICogOSk7XG4gICAgICBwdXQoc3BlYywgMCwgMCwgMSk7XG4gICAgICB4LnJlc3RvcmUoKTtcbiAgICB9LFxuICAgIGxvc2UoKTogdm9pZCB7fSxcbiAgfTtcbn1cbiJdfQ==
|