@fcannizzaro/streamdeck-react 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action.d.ts +2 -2
- package/dist/action.js +2 -1
- package/dist/bundler-shared.d.ts +21 -0
- package/dist/bundler-shared.js +37 -2
- package/dist/index.d.ts +2 -1
- package/dist/manifest-extract.d.ts +32 -0
- package/dist/manifest-extract.js +141 -0
- package/dist/manifest-gen.d.ts +52 -0
- package/dist/manifest-gen.js +229 -0
- package/dist/manifest-types.d.ts +238 -0
- package/dist/render/render-pool.js +1 -1
- package/dist/rollup.d.ts +36 -9
- package/dist/rollup.js +41 -14
- package/dist/types.d.ts +20 -34
- package/dist/vite.d.ts +23 -7
- package/dist/vite.js +46 -13
- package/package.json +2 -1
- package/dist/manifest-codegen.d.ts +0 -38
- package/dist/manifest-codegen.js +0 -110
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
export type ManifestController = "Encoder" | "Keypad";
|
|
2
|
+
export interface ManifestOSInfo {
|
|
3
|
+
platform: "mac" | "windows";
|
|
4
|
+
minimumVersion: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ManifestNodejsInfo {
|
|
7
|
+
/**
|
|
8
|
+
* Node.js version to use.
|
|
9
|
+
* @default "24"
|
|
10
|
+
*/
|
|
11
|
+
version: "20" | "24";
|
|
12
|
+
/**
|
|
13
|
+
* Debug configuration. `"enabled"` and `"break"` are shortcuts for
|
|
14
|
+
* `--inspect` and `--inspect-brk` respectively. A custom string is
|
|
15
|
+
* passed as-is (e.g. `"--inspect=127.0.0.1:8090"`).
|
|
16
|
+
*/
|
|
17
|
+
debug?: string;
|
|
18
|
+
/** Enable profiler output. */
|
|
19
|
+
generateProfilerOutput?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ManifestStateInfo {
|
|
22
|
+
/** Path to state image (extension omitted). 72×72 and 144×144 @2x. */
|
|
23
|
+
image: string;
|
|
24
|
+
/** State name (shown in multi-action state selector). */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** Default title text. */
|
|
27
|
+
title?: string;
|
|
28
|
+
/** Whether to show the title. */
|
|
29
|
+
showTitle?: boolean;
|
|
30
|
+
/** Title alignment. */
|
|
31
|
+
titleAlignment?: "bottom" | "middle" | "top";
|
|
32
|
+
/** Title color (hex). */
|
|
33
|
+
titleColor?: string;
|
|
34
|
+
/** Font family for the title. */
|
|
35
|
+
fontFamily?: string;
|
|
36
|
+
/** Font size for the title. */
|
|
37
|
+
fontSize?: number;
|
|
38
|
+
/** Font style for the title. */
|
|
39
|
+
fontStyle?: "" | "Bold" | "Bold Italic" | "Italic" | "Regular";
|
|
40
|
+
/** Whether the title is underlined. */
|
|
41
|
+
fontUnderline?: boolean;
|
|
42
|
+
/** Image shown when the action is in a multi-action. */
|
|
43
|
+
multiActionImage?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ManifestTriggerDescription {
|
|
46
|
+
/** Dial rotation description. */
|
|
47
|
+
rotate?: string;
|
|
48
|
+
/** Dial press description. */
|
|
49
|
+
push?: string;
|
|
50
|
+
/** Touch tap description. */
|
|
51
|
+
touch?: string;
|
|
52
|
+
/** Long touch description. */
|
|
53
|
+
longTouch?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ManifestEncoderInfo {
|
|
56
|
+
/**
|
|
57
|
+
* Touch screen layout. Pre-defined: `$X1`, `$A0`, `$A1`, `$B1`,
|
|
58
|
+
* `$B2`, `$C1`. Or a path to a custom `.json` layout file.
|
|
59
|
+
*/
|
|
60
|
+
layout?: string;
|
|
61
|
+
/** Encoder icon (extension omitted). 72×72 and 144×144 @2x. */
|
|
62
|
+
icon?: string;
|
|
63
|
+
/** Background color for dial stack (hex). */
|
|
64
|
+
stackColor?: string;
|
|
65
|
+
/** Touchscreen background image (extension omitted). 200×100 and 400×200 @2x. */
|
|
66
|
+
background?: string;
|
|
67
|
+
/** Descriptions shown to the user for each interaction type. */
|
|
68
|
+
triggerDescription?: ManifestTriggerDescription;
|
|
69
|
+
}
|
|
70
|
+
export interface ManifestProfileInfo {
|
|
71
|
+
/** Path to .streamDeckProfile file (extension omitted). */
|
|
72
|
+
name: string;
|
|
73
|
+
/**
|
|
74
|
+
* Target device type.
|
|
75
|
+
*
|
|
76
|
+
* Common values:
|
|
77
|
+
* 0 = Stream Deck, 1 = Mini, 2 = XL, 5 = Pedal,
|
|
78
|
+
* 7 = Stream Deck +, 9 = Neo, 10 = Studio
|
|
79
|
+
*/
|
|
80
|
+
deviceType: number;
|
|
81
|
+
/** Auto-install when plugin is installed. @default true */
|
|
82
|
+
autoInstall?: boolean;
|
|
83
|
+
/** Don't auto-switch to profile on first install. @default false */
|
|
84
|
+
dontAutoSwitchWhenInstalled?: boolean;
|
|
85
|
+
/** Profile is read-only. @default false */
|
|
86
|
+
readonly?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface ActionManifestInfo {
|
|
89
|
+
/** Action display name in Stream Deck's action list. */
|
|
90
|
+
name: string;
|
|
91
|
+
/** Path to action icon (extension omitted). 20×20 and 40×40 @2x. */
|
|
92
|
+
icon: string;
|
|
93
|
+
/**
|
|
94
|
+
* Skip this action during auto-extraction for manifest generation.
|
|
95
|
+
* The action is still registered at runtime but excluded from the
|
|
96
|
+
* generated manifest.json.
|
|
97
|
+
*
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
disabled?: boolean;
|
|
101
|
+
/** Hover tooltip in the actions list. */
|
|
102
|
+
tooltip?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Custom states. When omitted, a single state is generated
|
|
105
|
+
* using the `icon` field as the state image.
|
|
106
|
+
* @default [{ image: icon }]
|
|
107
|
+
*/
|
|
108
|
+
states?: ManifestStateInfo[];
|
|
109
|
+
/** Encoder config (layout, triggerDescription, background). */
|
|
110
|
+
encoder?: ManifestEncoderInfo;
|
|
111
|
+
/** Disable automatic state toggling. @default false */
|
|
112
|
+
disableAutomaticStates?: boolean;
|
|
113
|
+
/** Disable Stream Deck image caching. @default false */
|
|
114
|
+
disableCaching?: boolean;
|
|
115
|
+
/** Available in multi-actions. @default true */
|
|
116
|
+
supportedInMultiActions?: boolean;
|
|
117
|
+
/** Available in key logic actions (SD 7.0+). @default true */
|
|
118
|
+
supportedInKeyLogicActions?: boolean;
|
|
119
|
+
/** Visible in the actions list. @default true */
|
|
120
|
+
visibleInActionsList?: boolean;
|
|
121
|
+
/** Allow user to edit title. @default true */
|
|
122
|
+
userTitleEnabled?: boolean;
|
|
123
|
+
/** Action-specific property inspector HTML path. */
|
|
124
|
+
propertyInspectorPath?: string;
|
|
125
|
+
/** Action support URL. */
|
|
126
|
+
supportUrl?: string;
|
|
127
|
+
/** OS restriction for this action. */
|
|
128
|
+
os?: ("mac" | "windows")[];
|
|
129
|
+
/**
|
|
130
|
+
* Controller types.
|
|
131
|
+
*
|
|
132
|
+
* Auto-derived in bundler plugin:
|
|
133
|
+
* - `encoder` field present → `["Encoder"]`
|
|
134
|
+
* - otherwise → `["Keypad"]`
|
|
135
|
+
*
|
|
136
|
+
* @default ["Keypad"]
|
|
137
|
+
*/
|
|
138
|
+
controllers?: [ManifestController, ManifestController?];
|
|
139
|
+
}
|
|
140
|
+
export interface ManifestActionSource {
|
|
141
|
+
uuid: string;
|
|
142
|
+
/** Presence indicates Keypad controller support. */
|
|
143
|
+
key?: unknown;
|
|
144
|
+
/** Presence indicates Encoder controller support. */
|
|
145
|
+
dial?: unknown;
|
|
146
|
+
/** Presence indicates Encoder controller support (touchstrip variant). */
|
|
147
|
+
touchStrip?: unknown;
|
|
148
|
+
/** Action manifest metadata. Required for manifest generation. */
|
|
149
|
+
info?: ActionManifestInfo;
|
|
150
|
+
}
|
|
151
|
+
export interface ManifestConfig extends PluginManifestInfo {
|
|
152
|
+
/**
|
|
153
|
+
* Action definitions from defineAction().
|
|
154
|
+
* Each action must have `info` populated with at least `name` and `icon`.
|
|
155
|
+
* Controllers are auto-derived from key/dial/touchStrip presence.
|
|
156
|
+
*/
|
|
157
|
+
actions: ManifestActionSource[];
|
|
158
|
+
}
|
|
159
|
+
export interface PluginManifestInfo {
|
|
160
|
+
/**
|
|
161
|
+
* Unique plugin identifier in reverse-DNS format.
|
|
162
|
+
*
|
|
163
|
+
* All action UUIDs must be prefixed with this value.
|
|
164
|
+
*/
|
|
165
|
+
uuid: string;
|
|
166
|
+
/** Plugin display name. */
|
|
167
|
+
name: string;
|
|
168
|
+
/** Author name shown on Marketplace. */
|
|
169
|
+
author: string;
|
|
170
|
+
/** Plugin description. */
|
|
171
|
+
description: string;
|
|
172
|
+
/** Path to plugin icon (extension omitted). 256×256 and 512×512 @2x. */
|
|
173
|
+
icon: string;
|
|
174
|
+
/**
|
|
175
|
+
* Plugin version.
|
|
176
|
+
* @example "1.0.0.0"
|
|
177
|
+
*/
|
|
178
|
+
version: string;
|
|
179
|
+
/**
|
|
180
|
+
* Actions list group name.
|
|
181
|
+
* @default Same as `name`
|
|
182
|
+
*/
|
|
183
|
+
category?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Category icon path (extension omitted).
|
|
186
|
+
* @default Same as `icon`
|
|
187
|
+
*/
|
|
188
|
+
categoryIcon?: string;
|
|
189
|
+
/** Plugin website URL. */
|
|
190
|
+
url?: string;
|
|
191
|
+
/** Support website URL. */
|
|
192
|
+
supportUrl?: string;
|
|
193
|
+
/** Global property inspector HTML path. */
|
|
194
|
+
propertyInspectorPath?: string;
|
|
195
|
+
/** Pre-defined profiles distributed with the plugin. */
|
|
196
|
+
profiles?: ManifestProfileInfo[];
|
|
197
|
+
/** Applications to monitor on Mac/Windows. */
|
|
198
|
+
applicationsToMonitor?: {
|
|
199
|
+
mac?: string[];
|
|
200
|
+
windows?: string[];
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Default window size for `window.open()` from the property inspector.
|
|
204
|
+
* @example [500, 650]
|
|
205
|
+
*/
|
|
206
|
+
defaultWindowSize?: [number, number];
|
|
207
|
+
/** macOS-specific entry point override. */
|
|
208
|
+
codePathMac?: string;
|
|
209
|
+
/** Windows-specific entry point override. */
|
|
210
|
+
codePathWin?: string;
|
|
211
|
+
/**
|
|
212
|
+
* Plugin entry point path.
|
|
213
|
+
* @default Derived from bundler output path (e.g. "bin/plugin.mjs")
|
|
214
|
+
*/
|
|
215
|
+
codePath?: string;
|
|
216
|
+
/**
|
|
217
|
+
* Operating system requirements.
|
|
218
|
+
* @default [{ platform: "mac", minimumVersion: "13" }, { platform: "windows", minimumVersion: "10" }]
|
|
219
|
+
*/
|
|
220
|
+
os?: [ManifestOSInfo, ManifestOSInfo?];
|
|
221
|
+
/**
|
|
222
|
+
* Node.js configuration.
|
|
223
|
+
* @default { version: "24" }
|
|
224
|
+
*/
|
|
225
|
+
nodejs?: ManifestNodejsInfo;
|
|
226
|
+
/**
|
|
227
|
+
* SDK version.
|
|
228
|
+
* @default 2
|
|
229
|
+
*/
|
|
230
|
+
sdkVersion?: 2 | 3;
|
|
231
|
+
/**
|
|
232
|
+
* Stream Deck software requirements.
|
|
233
|
+
* @default { minimumVersion: "7.1" }
|
|
234
|
+
*/
|
|
235
|
+
software?: {
|
|
236
|
+
minimumVersion: string;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -36,7 +36,7 @@ var RenderPool = class {
|
|
|
36
36
|
}
|
|
37
37
|
async doInitialize() {
|
|
38
38
|
try {
|
|
39
|
-
this.worker = new Worker(new URL("data:video/mp2t;base64,Ly8g4pSA4pSAIFJlbmRlciBXb3JrZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vCi8vIFJ1bnMgaW4gYSBzZXBhcmF0ZSB0aHJlYWQgdmlhIE5vZGUuanMgd29ya2VyX3RocmVhZHMuICBIYW5kbGVzIHRoZQovLyBmdWxsIHJlbmRlciBwaXBlbGluZTogc2VyaWFsaXplZCBWTm9kZSBkYXRhIOKGkiBUYWt1bWkgbm9kZXMg4oaSIHJhc3Rlci4KLy8KLy8gVXNlcyB0aGUgZGlyZWN0IFZOb2RlIOKGkiBUYWt1bWkgbm9kZSBieXBhc3MgKHNhbWUgYXMgbWFpbiB0aHJlYWQncwovLyB2bm9kZVRvVGFrdW1pTm9kZSBpbiBwaXBlbGluZS50cyksIHNraXBwaW5nIHZub2RlVG9FbGVtZW50KCkgYW5kCi8vIGZyb21Kc3goKSBlbnRpcmVseS4KLy8KLy8gVGhpcyB1bmJsb2NrcyB0aGUgbWFpbiB0aHJlYWQgZHVyaW5nIHRoZSBleHBlbnNpdmUgVGFrdW1pCi8vIHJhc3Rlcml6YXRpb24gc3RlcCAofjXigJMzMG1zIHBlciBmcmFtZSkuCi8vCi8vIFdoeSBjb2RlIGlzIGR1cGxpY2F0ZWQgKGlubGluZWQpOgovLyAgIFdvcmtlciB0aHJlYWRzIGNhbid0IGltcG9ydCBmcm9tIHRoZSBtYWluIGJ1bmRsZSDigJQgdGhleSBsb2FkCi8vICAgdGhlIGNvbXBpbGVkIHdvcmtlci5qcyBmaWxlIGluZGVwZW5kZW50bHkuICBTVkcgc2VyaWFsaXphdGlvbgovLyAgIGFuZCBWTm9kZeKGklRha3VtaSBjb252ZXJzaW9uIG11c3QgYmUgc2VsZi1jb250YWluZWQgaGVyZS4KLy8gICBCb3RoIG1pcnJvciB0aGUgbG9naWMgaW4gc3ZnLnRzIGFuZCBwaXBlbGluZS50cyByZXNwZWN0aXZlbHkuCi8vCi8vIFplcm8tY29weSByZXR1cm46Ci8vICAgVGhlIHJlbmRlcmVkIGJ1ZmZlciBpcyB0cmFuc2ZlcnJlZCAobm90IGNvcGllZCkgYmFjayB0byB0aGUgbWFpbgovLyAgIHRocmVhZCB2aWEgcG9zdE1lc3NhZ2UncyB0cmFuc2ZlciBsaXN0LiAgVGhpcyBhdm9pZHMgY29weWluZwovLyAgIHBvdGVudGlhbGx5IGxhcmdlIHJhc3RlciBidWZmZXJzIChlLmcuIDgwMMOXMTAww5c0ID0gMzIwS0IgZm9yCi8vICAgVG91Y2hTdHJpcCkgYWNyb3NzIHRoZSB0aHJlYWQgYm91bmRhcnkuCgppbXBvcnQgeyBwYXJlbnRQb3J0LCB3b3JrZXJEYXRhIH0gZnJvbSAibm9kZTp3b3JrZXJfdGhyZWFkcyI7CgovLyDilIDilIAgVHlwZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgppbnRlcmZhY2UgU2VyaWFsaXplZFZOb2RlIHsKICB0eXBlOiBzdHJpbmc7CiAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+OwogIGNoaWxkcmVuOiBTZXJpYWxpemVkVk5vZGVbXTsKICB0ZXh0Pzogc3RyaW5nOwp9CgovKiogTWF0Y2hlcyBAdGFrdW1pLXJzL2hlbHBlcnMgTm9kZSB1bmlvbi4gUGxhaW4gb2JqZWN0IGFjY2VwdGVkIGJ5IFJlbmRlcmVyLnJlbmRlcigpLiAqLwppbnRlcmZhY2UgVGFrdW1pTm9kZSB7CiAgdHlwZTogc3RyaW5nOwogIFtrZXk6IHN0cmluZ106IHVua25vd247Cn0KCmludGVyZmFjZSBJbml0TWVzc2FnZSB7CiAgdHlwZTogImluaXQiOwogIGZvbnRzOiBBcnJheTx7CiAgICBuYW1lOiBzdHJpbmc7CiAgICBkYXRhOiBBcnJheUJ1ZmZlciB8IEJ1ZmZlcjsKICAgIHdlaWdodDogbnVtYmVyOwogICAgc3R5bGU6IHN0cmluZzsKICB9PjsKfQoKaW50ZXJmYWNlIFJlbmRlck1lc3NhZ2UgewogIHR5cGU6ICJyZW5kZXIiOwogIGlkOiBudW1iZXI7CiAgdm5vZGVzOiBTZXJpYWxpemVkVk5vZGVbXTsKICB3aWR0aDogbnVtYmVyOwogIGhlaWdodDogbnVtYmVyOwogIGZvcm1hdDogc3RyaW5nOwogIGRwcjogbnVtYmVyOwp9CgppbnRlcmZhY2UgU2h1dGRvd25NZXNzYWdlIHsKICB0eXBlOiAic2h1dGRvd24iOwp9Cgp0eXBlIFdvcmtlck1lc3NhZ2UgPSBJbml0TWVzc2FnZSB8IFJlbmRlck1lc3NhZ2UgfCBTaHV0ZG93bk1lc3NhZ2U7CgovLyDilIDilIAgU1ZHIFNlcmlhbGl6YXRpb24gKGlubGluZWQgZm9yIHdvcmtlciBjb250ZXh0KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8gTWlycm9ycyB0aGUgc2VyaWFsaXplU3ZnVHJlZSgpIGZyb20gc3ZnLnRzLiBJbmxpbmVkIHRvIGF2b2lkCi8vIGNyb3NzLW1vZHVsZSBpbXBvcnQgaXNzdWVzIGluIHRoZSB3b3JrZXIgdGhyZWFkLgoKY29uc3QgU1ZHX0NBTUVMX0FUVFJTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldChbCiAgImFjY2VudEhlaWdodCIsCiAgImFsaWdubWVudEJhc2VsaW5lIiwKICAiYXJhYmljRm9ybSIsCiAgImJhc2VsaW5lU2hpZnQiLAogICJjYXBIZWlnaHQiLAogICJjbGlwUGF0aCIsCiAgImNsaXBQYXRoVW5pdHMiLAogICJjbGlwUnVsZSIsCiAgImNvbG9ySW50ZXJwb2xhdGlvbiIsCiAgImNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnMiLAogICJjb2xvclByb2ZpbGUiLAogICJjb2xvclJlbmRlcmluZyIsCiAgImVuYWJsZUJhY2tncm91bmQiLAogICJmaWxsT3BhY2l0eSIsCiAgImZpbGxSdWxlIiwKICAiZmxvb2RDb2xvciIsCiAgImZsb29kT3BhY2l0eSIsCiAgImZvbnRGYW1pbHkiLAogICJmb250U2l6ZSIsCiAgImZvbnRTaXplQWRqdXN0IiwKICAiZm9udFN0cmV0Y2giLAogICJmb250U3R5bGUiLAogICJmb250VmFyaWFudCIsCiAgImZvbnRXZWlnaHQiLAogICJnbHlwaE5hbWUiLAogICJnbHlwaE9yaWVudGF0aW9uSG9yaXpvbnRhbCIsCiAgImdseXBoT3JpZW50YXRpb25WZXJ0aWNhbCIsCiAgImhvcml6QWR2WCIsCiAgImhvcml6T3JpZ2luWCIsCiAgImltYWdlUmVuZGVyaW5nIiwKICAibGV0dGVyU3BhY2luZyIsCiAgImxpZ2h0aW5nQ29sb3IiLAogICJtYXJrZXJFbmQiLAogICJtYXJrZXJNaWQiLAogICJtYXJrZXJTdGFydCIsCiAgIm92ZXJsaW5lUG9zaXRpb24iLAogICJvdmVybGluZVRoaWNrbmVzcyIsCiAgInBhaW50T3JkZXIiLAogICJwb2ludGVyRXZlbnRzIiwKICAicHJlc2VydmVBc3BlY3RSYXRpbyIsCiAgInNoYXBlUmVuZGVyaW5nIiwKICAic3RvcENvbG9yIiwKICAic3RvcE9wYWNpdHkiLAogICJzdHJva2VEYXNoYXJyYXkiLAogICJzdHJva2VEYXNob2Zmc2V0IiwKICAic3Ryb2tlTGluZWNhcCIsCiAgInN0cm9rZUxpbmVqb2luIiwKICAic3Ryb2tlTWl0ZXJsaW1pdCIsCiAgInN0cm9rZU9wYWNpdHkiLAogICJzdHJva2VXaWR0aCIsCiAgInRleHRBbmNob3IiLAogICJ0ZXh0RGVjb3JhdGlvbiIsCiAgInRleHRSZW5kZXJpbmciLAogICJ0cmFuc2Zvcm1PcmlnaW4iLAogICJ1bmRlcmxpbmVQb3NpdGlvbiIsCiAgInVuZGVybGluZVRoaWNrbmVzcyIsCiAgInVuaWNvZGVCaWRpIiwKICAidW5pY29kZVJhbmdlIiwKICAidW5pdHNQZXJFbSIsCiAgInZBbHBoYWJldGljIiwKICAidkhhbmdpbmciLAogICJ2SWRlb2dyYXBoaWMiLAogICJ2TWF0aGVtYXRpY2FsIiwKICAidmVjdG9yRWZmZWN0IiwKICAidmVydEFkdlkiLAogICJ2ZXJ0T3JpZ2luWCIsCiAgInZlcnRPcmlnaW5ZIiwKICAid29yZFNwYWNpbmciLAogICJ3cml0aW5nTW9kZSIsCl0pOwoKY29uc3QgU1ZHX1NLSVBfUFJPUFM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0KFsKICAiY2hpbGRyZW4iLAogICJrZXkiLAogICJyZWYiLAogICJfX3NlbGYiLAogICJfX3NvdXJjZSIsCl0pOwoKZnVuY3Rpb24gY2FtZWxUb0tlYmFiKHN0cjogc3RyaW5nKTogc3RyaW5nIHsKICByZXR1cm4gc3RyLnJlcGxhY2UoL1tBLVpdL2csIChjaCkgPT4gYC0ke2NoLnRvTG93ZXJDYXNlKCl9YCk7Cn0KCmZ1bmN0aW9uIGVzY2FwZUF0dHIodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7CiAgcmV0dXJuIHZhbHVlCiAgICAucmVwbGFjZSgvJi9nLCAiJmFtcDsiKQogICAgLnJlcGxhY2UoLyIvZywgIiZxdW90OyIpCiAgICAucmVwbGFjZSgvPC9nLCAiJmx0OyIpCiAgICAucmVwbGFjZSgvPi9nLCAiJmd0OyIpOwp9CgpmdW5jdGlvbiBzZXJpYWxpemVTdmdTdHlsZShzdHlsZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBzdHJpbmcgewogIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdOwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlKSkgewogICAgY29uc3QgdmFsdWUgPSBzdHlsZVtrZXldOwogICAgaWYgKHZhbHVlID09IG51bGwpIGNvbnRpbnVlOwogICAgcGFydHMucHVzaChgJHtjYW1lbFRvS2ViYWIoa2V5KX06JHtTdHJpbmcodmFsdWUpLnRyaW0oKX1gKTsKICB9CiAgcmV0dXJuIHBhcnRzLmpvaW4oIjsiKTsKfQoKZnVuY3Rpb24gc2VyaWFsaXplU3ZnQXR0cihrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCBudWxsIHsKICBpZiAoU1ZHX1NLSVBfUFJPUFMuaGFzKGtleSkgfHwgdmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgbGV0IGF0dHJOYW1lOiBzdHJpbmc7CiAgaWYgKGtleSA9PT0gImNsYXNzTmFtZSIpIGF0dHJOYW1lID0gImNsYXNzIjsKICBlbHNlIGlmIChTVkdfQ0FNRUxfQVRUUlMuaGFzKGtleSkpIGF0dHJOYW1lID0gY2FtZWxUb0tlYmFiKGtleSk7CiAgZWxzZSBhdHRyTmFtZSA9IGtleTsKICBpZiAoa2V5ID09PSAic3R5bGUiICYmIHR5cGVvZiB2YWx1ZSA9PT0gIm9iamVjdCIpIHsKICAgIGNvbnN0IGNzcyA9IHNlcmlhbGl6ZVN2Z1N0eWxlKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTsKICAgIGlmICghY3NzKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBgJHthdHRyTmFtZX09IiR7ZXNjYXBlQXR0cihjc3MpfSJgOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09PSAiYm9vbGVhbiIpIHJldHVybiBgJHthdHRyTmFtZX09IiR7U3RyaW5nKHZhbHVlKX0iYDsKICByZXR1cm4gYCR7YXR0ck5hbWV9PSIke2VzY2FwZUF0dHIoU3RyaW5nKHZhbHVlKSl9ImA7Cn0KCmZ1bmN0aW9uIHNlcmlhbGl6ZVN2Z1ZOb2RlKG5vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IHN0cmluZyB7CiAgaWYgKG5vZGUudHlwZSA9PT0gIiN0ZXh0IikgcmV0dXJuIG5vZGUudGV4dCA/PyAiIjsKICBjb25zdCBhdHRyczogc3RyaW5nW10gPSBbXTsKICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhub2RlLnByb3BzKSkgewogICAgY29uc3QgYXR0ciA9IHNlcmlhbGl6ZVN2Z0F0dHIoa2V5LCB2YWx1ZSk7CiAgICBpZiAoYXR0ciAhPSBudWxsKSBhdHRycy5wdXNoKGF0dHIpOwogIH0KICBjb25zdCBjaGlsZE1hcmt1cCA9IG5vZGUuY2hpbGRyZW4ubWFwKHNlcmlhbGl6ZVN2Z1ZOb2RlKS5qb2luKCIiKTsKICBjb25zdCBhdHRyU3RyID0gYXR0cnMubGVuZ3RoID4gMCA/IGAgJHthdHRycy5qb2luKCIgIil9YCA6ICIiOwogIHJldHVybiBgPCR7bm9kZS50eXBlfSR7YXR0clN0cn0+JHtjaGlsZE1hcmt1cH08LyR7bm9kZS50eXBlfT5gOwp9CgpmdW5jdGlvbiBzZXJpYWxpemVTdmdUcmVlKHN2Z05vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IHN0cmluZyB7CiAgaWYgKCEoInhtbG5zIiBpbiBzdmdOb2RlLnByb3BzKSkgewogICAgY29uc3QgYXVnbWVudGVkID0gewogICAgICAuLi5zdmdOb2RlLAogICAgICBwcm9wczogeyAuLi5zdmdOb2RlLnByb3BzLCB4bWxuczogImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB9LAogICAgfTsKICAgIHJldHVybiBzZXJpYWxpemVTdmdWTm9kZShhdWdtZW50ZWQpOwogIH0KICByZXR1cm4gc2VyaWFsaXplU3ZnVk5vZGUoc3ZnTm9kZSk7Cn0KCi8vIOKUgOKUgCBEaXJlY3QgVk5vZGUg4oaSIFRha3VtaSBOb2RlIENvbnZlcnNpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vIE1pcnJvcnMgdGhlIG1haW4tdGhyZWFkIHZub2RlVG9UYWt1bWlOb2RlKCkgZnJvbSBwaXBlbGluZS50cy4KLy8gSW5saW5lZCB0byBhdm9pZCBjcm9zcy1tb2R1bGUgaW1wb3J0IGlzc3VlcyBpbiB3b3JrZXIgY29udGV4dC4KCmZ1bmN0aW9uIHZub2RlVG9UYWt1bWlOb2RlKG5vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IFRha3VtaU5vZGUgewogIC8vIFRleHQgbm9kZXMg4oaSIFRha3VtaSBUZXh0Tm9kZQogIGlmIChub2RlLnR5cGUgPT09ICIjdGV4dCIpIHsKICAgIHJldHVybiB7IHR5cGU6ICJ0ZXh0IiwgdGV4dDogbm9kZS50ZXh0ID8/ICIiIH07CiAgfQoKICBjb25zdCB7IGNoaWxkcmVuOiBfY2hpbGRyZW4sIGNsYXNzTmFtZSwgc3JjLCAuLi5yZXN0UHJvcHMgfSA9IG5vZGUucHJvcHM7CgogIC8vIE1hcCBjbGFzc05hbWUg4oaSIHR3IChzYW1lIGxvZ2ljIGFzIG1haW4gdGhyZWFkKQogIGxldCB0dzogc3RyaW5nIHwgdW5kZWZpbmVkID0gdHlwZW9mIHJlc3RQcm9wcy50dyA9PT0gInN0cmluZyIgPyByZXN0UHJvcHMudHcgOiB1bmRlZmluZWQ7CiAgaWYgKHR5cGVvZiBjbGFzc05hbWUgPT09ICJzdHJpbmciICYmIGNsYXNzTmFtZS5sZW5ndGggPiAwKSB7CiAgICB0dyA9IHR3ID8gdHcgKyAiICIgKyBjbGFzc05hbWUgOiBjbGFzc05hbWU7CiAgfQoKICAvLyBJbWFnZSBub2RlcyDihpIgVGFrdW1pIEltYWdlTm9kZQogIGlmIChub2RlLnR5cGUgPT09ICJpbWciICYmIHR5cGVvZiBzcmMgPT09ICJzdHJpbmciKSB7CiAgICByZXR1cm4gewogICAgICB0eXBlOiAiaW1hZ2UiLAogICAgICBzcmM6IHNyYyBhcyBzdHJpbmcsCiAgICAgIC4uLih0dyA/IHsgdHcgfSA6IHt9KSwKICAgICAgLi4ucmVzdFByb3BzLAogICAgfTsKICB9CgogIC8vIFNWRyBub2RlcyDihpIgVGFrdW1pIEltYWdlTm9kZSAoc2VyaWFsaXplIHN1YnRyZWUgdG8gU1ZHIG1hcmt1cCkKICBpZiAobm9kZS50eXBlID09PSAic3ZnIikgewogICAgY29uc3Qgc3ZnTWFya3VwID0gc2VyaWFsaXplU3ZnVHJlZShub2RlKTsKICAgIGNvbnN0IHdpZHRoID0gdHlwZW9mIG5vZGUucHJvcHMud2lkdGggPT09ICJudW1iZXIiID8gbm9kZS5wcm9wcy53aWR0aCA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IGhlaWdodCA9IHR5cGVvZiBub2RlLnByb3BzLmhlaWdodCA9PT0gIm51bWJlciIgPyBub2RlLnByb3BzLmhlaWdodCA6IHVuZGVmaW5lZDsKICAgIHJldHVybiB7CiAgICAgIHR5cGU6ICJpbWFnZSIsCiAgICAgIHNyYzogc3ZnTWFya3VwLAogICAgICAuLi4od2lkdGggIT0gbnVsbCA/IHsgd2lkdGggfSA6IHt9KSwKICAgICAgLi4uKGhlaWdodCAhPSBudWxsID8geyBoZWlnaHQgfSA6IHt9KSwKICAgICAgLi4uKHR3ID8geyB0dyB9IDoge30pLAogICAgICAuLi4obm9kZS5wcm9wcy5zdHlsZSA/IHsgc3R5bGU6IG5vZGUucHJvcHMuc3R5bGUgfSA6IHt9KSwKICAgICAgdGFnTmFtZTogInN2ZyIsCiAgICB9OwogIH0KCiAgLy8gQWxsIG90aGVyIG5vZGVzIOKGkiBUYWt1bWkgQ29udGFpbmVyTm9kZQogIGNvbnN0IHRha3VtaUNoaWxkcmVuID0KICAgIG5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCA/IG5vZGUuY2hpbGRyZW4ubWFwKHZub2RlVG9UYWt1bWlOb2RlKSA6IHVuZGVmaW5lZDsKCiAgcmV0dXJuIHsKICAgIHR5cGU6ICJjb250YWluZXIiLAogICAgLi4uKHR3ID8geyB0dyB9IDoge30pLAogICAgLi4ucmVzdFByb3BzLAogICAgLi4uKHRha3VtaUNoaWxkcmVuID8geyBjaGlsZHJlbjogdGFrdW1pQ2hpbGRyZW4gfSA6IHt9KSwKICB9Owp9CgovLyDilIDilIAgUm9vdCBzdHlsZSBjb25zdGFudCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmNvbnN0IFJPT1RfU1RZTEUgPSB7IGRpc3BsYXk6ICJmbGV4Iiwgd2lkdGg6ICIxMDAlIiwgaGVpZ2h0OiAiMTAwJSIgfSBhcyBjb25zdDsKCi8vIOKUgOKUgCBXb3JrZXIgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpsZXQgcmVuZGVyZXI6IGltcG9ydCgiQHRha3VtaS1ycy9jb3JlIikuUmVuZGVyZXIgfCBudWxsID0gbnVsbDsKCi8vIOKUgOKUgCBNZXNzYWdlIEhhbmRsZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgphc3luYyBmdW5jdGlvbiBoYW5kbGVNZXNzYWdlKG1zZzogV29ya2VyTWVzc2FnZSk6IFByb21pc2U8dm9pZD4gewogIHN3aXRjaCAobXNnLnR5cGUpIHsKICAgIGNhc2UgImluaXQiOiB7CiAgICAgIHRyeSB7CiAgICAgICAgLy8gRHluYW1pYyBpbXBvcnQg4oCUIG1heSBmYWlsIGlmIHRoZSBuYXRpdmUgYWRkb24gY2FuJ3QgbG9hZCBpbiBhIHdvcmtlcgogICAgICAgIGNvbnN0IGNvcmUgPSBhd2FpdCBpbXBvcnQoIkB0YWt1bWktcnMvY29yZSIpOwoKICAgICAgICByZW5kZXJlciA9IG5ldyBjb3JlLlJlbmRlcmVyKHsKICAgICAgICAgIGZvbnRzOiBtc2cuZm9udHMubWFwKChmKSA9PiAoewogICAgICAgICAgICBuYW1lOiBmLm5hbWUsCiAgICAgICAgICAgIGRhdGE6IGYuZGF0YSwKICAgICAgICAgICAgd2VpZ2h0OiBmLndlaWdodCBhcyAxMDAgfCAyMDAgfCAzMDAgfCA0MDAgfCA1MDAgfCA2MDAgfCA3MDAgfCA4MDAgfCA5MDAsCiAgICAgICAgICAgIHN0eWxlOiBmLnN0eWxlIGFzICJub3JtYWwiIHwgIml0YWxpYyIsCiAgICAgICAgICB9KSksCiAgICAgICAgfSk7CgogICAgICAgIHBhcmVudFBvcnQhLnBvc3RNZXNzYWdlKHsgdHlwZTogInJlYWR5IiB9KTsKICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgcGFyZW50UG9ydCEucG9zdE1lc3NhZ2UoewogICAgICAgICAgdHlwZTogImVycm9yIiwKICAgICAgICAgIGlkOiAtMSwKICAgICAgICAgIGVycm9yOiBgV29ya2VyIGluaXQgZmFpbGVkOiAke2VyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKX1gLAogICAgICAgIH0pOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGNhc2UgInJlbmRlciI6IHsKICAgICAgaWYgKHJlbmRlcmVyID09IG51bGwpIHsKICAgICAgICBwYXJlbnRQb3J0IS5wb3N0TWVzc2FnZSh7CiAgICAgICAgICB0eXBlOiAiZXJyb3IiLAogICAgICAgICAgaWQ6IG1zZy5pZCwKICAgICAgICAgIGVycm9yOiAiV29ya2VyIG5vdCBpbml0aWFsaXplZCIsCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICB0cnkgewogICAgICAgIC8vIDEuIENvbnZlcnQgc2VyaWFsaXplZCBWTm9kZSBkYXRhIOKGkiBUYWt1bWkgbm9kZXMgZGlyZWN0bHkgKGJ5cGFzcyBmcm9tSnN4KQogICAgICAgIGNvbnN0IGNoaWxkcmVuID0gbXNnLnZub2Rlcy5tYXAodm5vZGVUb1Rha3VtaU5vZGUpOwogICAgICAgIGNvbnN0IHJvb3ROb2RlOiBUYWt1bWlOb2RlID0gewogICAgICAgICAgdHlwZTogImNvbnRhaW5lciIsCiAgICAgICAgICBzdHlsZTogUk9PVF9TVFlMRSwKICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgIH07CgogICAgICAgIC8vIDIuIFJlbmRlciB0byByYXN0ZXIgaW1hZ2UKICAgICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCByZW5kZXJlci5yZW5kZXIocm9vdE5vZGUsIHsKICAgICAgICAgIHdpZHRoOiBtc2cud2lkdGgsCiAgICAgICAgICBoZWlnaHQ6IG1zZy5oZWlnaHQsCiAgICAgICAgICBmb3JtYXQ6IG1zZy5mb3JtYXQgYXMgaW1wb3J0KCJAdGFrdW1pLXJzL2NvcmUiKS5PdXRwdXRGb3JtYXQsCiAgICAgICAgICBkZXZpY2VQaXhlbFJhdGlvOiBtc2cuZHByLAogICAgICAgIH0pOwoKICAgICAgICAvLyBUcmFuc2ZlciB0aGUgYnVmZmVyICh6ZXJvLWNvcHkpIGJhY2sgdG8gdGhlIG1haW4gdGhyZWFkCiAgICAgICAgY29uc3QgYWIgPQogICAgICAgICAgYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIKICAgICAgICAgICAgPyBidWZmZXIKICAgICAgICAgICAgOiBidWZmZXIuYnVmZmVyLnNsaWNlKGJ1ZmZlci5ieXRlT2Zmc2V0LCBidWZmZXIuYnl0ZU9mZnNldCArIGJ1ZmZlci5ieXRlTGVuZ3RoKTsKCiAgICAgICAgcGFyZW50UG9ydCEucG9zdE1lc3NhZ2UoCiAgICAgICAgICB7IHR5cGU6ICJyZXN1bHQiLCBpZDogbXNnLmlkLCBidWZmZXI6IGFiIH0sCiAgICAgICAgICB7IHRyYW5zZmVyOiBbYWIgYXMgQXJyYXlCdWZmZXJdIH0sCiAgICAgICAgKTsKICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgcGFyZW50UG9ydCEucG9zdE1lc3NhZ2UoewogICAgICAgICAgdHlwZTogImVycm9yIiwKICAgICAgICAgIGlkOiBtc2cuaWQsCiAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLAogICAgICAgIH0pOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGNhc2UgInNodXRkb3duIjogewogICAgICBwcm9jZXNzLmV4aXQoMCk7CiAgICB9CiAgfQp9CgovLyDilIDilIAgQXV0by1pbml0IGlmIGZvbnRzIHByb3ZpZGVkIHZpYSB3b3JrZXJEYXRhIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKaWYgKHdvcmtlckRhdGE/LmZvbnRzKSB7CiAgaGFuZGxlTWVzc2FnZSh7IHR5cGU6ICJpbml0IiwgZm9udHM6IHdvcmtlckRhdGEuZm9udHMgfSk7Cn0KCnBhcmVudFBvcnQhLm9uKCJtZXNzYWdlIiwgKG1zZzogV29ya2VyTWVzc2FnZSkgPT4gewogIGhhbmRsZU1lc3NhZ2UobXNnKTsKfSk7Cg==", "" + import.meta.url), { workerData: { fonts: this.fonts.map((f) => ({
|
|
39
|
+
this.worker = new Worker(new URL("data:video/mp2t;base64,Ly8g4pSA4pSAIFJlbmRlciBXb3JrZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vCi8vIFJ1bnMgaW4gYSBzZXBhcmF0ZSB0aHJlYWQgdmlhIE5vZGUuanMgd29ya2VyX3RocmVhZHMuICBIYW5kbGVzIHRoZQovLyBmdWxsIHJlbmRlciBwaXBlbGluZTogc2VyaWFsaXplZCBWTm9kZSBkYXRhIOKGkiBUYWt1bWkgbm9kZXMg4oaSIHJhc3Rlci4KLy8KLy8gVXNlcyB0aGUgZGlyZWN0IFZOb2RlIOKGkiBUYWt1bWkgbm9kZSBieXBhc3MgKHNhbWUgYXMgbWFpbiB0aHJlYWQncwovLyB2bm9kZVRvVGFrdW1pTm9kZSBpbiBwaXBlbGluZS50cyksIHNraXBwaW5nIHZub2RlVG9FbGVtZW50KCkgYW5kCi8vIGZyb21Kc3goKSBlbnRpcmVseS4KLy8KLy8gVGhpcyB1bmJsb2NrcyB0aGUgbWFpbiB0aHJlYWQgZHVyaW5nIHRoZSBleHBlbnNpdmUgVGFrdW1pCi8vIHJhc3Rlcml6YXRpb24gc3RlcCAofjXigJMzMG1zIHBlciBmcmFtZSkuCi8vCi8vIFdoeSBjb2RlIGlzIGR1cGxpY2F0ZWQgKGlubGluZWQpOgovLyAgIFdvcmtlciB0aHJlYWRzIGNhbid0IGltcG9ydCBmcm9tIHRoZSBtYWluIGJ1bmRsZSDigJQgdGhleSBsb2FkCi8vICAgdGhlIGNvbXBpbGVkIHdvcmtlci5qcyBmaWxlIGluZGVwZW5kZW50bHkuICBTVkcgc2VyaWFsaXphdGlvbgovLyAgIGFuZCBWTm9kZeKGklRha3VtaSBjb252ZXJzaW9uIG11c3QgYmUgc2VsZi1jb250YWluZWQgaGVyZS4KLy8gICBCb3RoIG1pcnJvciB0aGUgbG9naWMgaW4gc3ZnLnRzIGFuZCBwaXBlbGluZS50cyByZXNwZWN0aXZlbHkuCi8vCi8vIFplcm8tY29weSByZXR1cm46Ci8vICAgVGhlIHJlbmRlcmVkIGJ1ZmZlciBpcyB0cmFuc2ZlcnJlZCAobm90IGNvcGllZCkgYmFjayB0byB0aGUgbWFpbgovLyAgIHRocmVhZCB2aWEgcG9zdE1lc3NhZ2UncyB0cmFuc2ZlciBsaXN0LiAgVGhpcyBhdm9pZHMgY29weWluZwovLyAgIHBvdGVudGlhbGx5IGxhcmdlIHJhc3RlciBidWZmZXJzIChlLmcuIDgwMMOXMTAww5c0ID0gMzIwS0IgZm9yCi8vICAgVG91Y2hTdHJpcCkgYWNyb3NzIHRoZSB0aHJlYWQgYm91bmRhcnkuCgppbXBvcnQgeyBwYXJlbnRQb3J0LCB3b3JrZXJEYXRhIH0gZnJvbSAibm9kZTp3b3JrZXJfdGhyZWFkcyI7CgovLyDilIDilIAgVHlwZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgppbnRlcmZhY2UgU2VyaWFsaXplZFZOb2RlIHsKICB0eXBlOiBzdHJpbmc7CiAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+OwogIGNoaWxkcmVuOiBTZXJpYWxpemVkVk5vZGVbXTsKICB0ZXh0Pzogc3RyaW5nOwp9CgovKiogTWF0Y2hlcyBAdGFrdW1pLXJzL2hlbHBlcnMgTm9kZSB1bmlvbi4gUGxhaW4gb2JqZWN0IGFjY2VwdGVkIGJ5IFJlbmRlcmVyLnJlbmRlcigpLiAqLwppbnRlcmZhY2UgVGFrdW1pTm9kZSB7CiAgdHlwZTogc3RyaW5nOwogIFtrZXk6IHN0cmluZ106IHVua25vd247Cn0KCmludGVyZmFjZSBJbml0TWVzc2FnZSB7CiAgdHlwZTogImluaXQiOwogIGZvbnRzOiBBcnJheTx7CiAgICBuYW1lOiBzdHJpbmc7CiAgICBkYXRhOiBBcnJheUJ1ZmZlciB8IEJ1ZmZlcjsKICAgIHdlaWdodDogbnVtYmVyOwogICAgc3R5bGU6IHN0cmluZzsKICB9PjsKfQoKaW50ZXJmYWNlIFJlbmRlck1lc3NhZ2UgewogIHR5cGU6ICJyZW5kZXIiOwogIGlkOiBudW1iZXI7CiAgdm5vZGVzOiBTZXJpYWxpemVkVk5vZGVbXTsKICB3aWR0aDogbnVtYmVyOwogIGhlaWdodDogbnVtYmVyOwogIGZvcm1hdDogc3RyaW5nOwogIGRwcjogbnVtYmVyOwp9CgppbnRlcmZhY2UgU2h1dGRvd25NZXNzYWdlIHsKICB0eXBlOiAic2h1dGRvd24iOwp9Cgp0eXBlIFdvcmtlck1lc3NhZ2UgPSBJbml0TWVzc2FnZSB8IFJlbmRlck1lc3NhZ2UgfCBTaHV0ZG93bk1lc3NhZ2U7CgovLyDilIDilIAgU1ZHIFNlcmlhbGl6YXRpb24gKGlubGluZWQgZm9yIHdvcmtlciBjb250ZXh0KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8gTWlycm9ycyB0aGUgc2VyaWFsaXplU3ZnVHJlZSgpIGZyb20gc3ZnLnRzLiBJbmxpbmVkIHRvIGF2b2lkCi8vIGNyb3NzLW1vZHVsZSBpbXBvcnQgaXNzdWVzIGluIHRoZSB3b3JrZXIgdGhyZWFkLgoKY29uc3QgU1ZHX0NBTUVMX0FUVFJTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldChbCiAgImFjY2VudEhlaWdodCIsCiAgImFsaWdubWVudEJhc2VsaW5lIiwKICAiYXJhYmljRm9ybSIsCiAgImJhc2VsaW5lU2hpZnQiLAogICJjYXBIZWlnaHQiLAogICJjbGlwUGF0aCIsCiAgImNsaXBQYXRoVW5pdHMiLAogICJjbGlwUnVsZSIsCiAgImNvbG9ySW50ZXJwb2xhdGlvbiIsCiAgImNvbG9ySW50ZXJwb2xhdGlvbkZpbHRlcnMiLAogICJjb2xvclByb2ZpbGUiLAogICJjb2xvclJlbmRlcmluZyIsCiAgImVuYWJsZUJhY2tncm91bmQiLAogICJmaWxsT3BhY2l0eSIsCiAgImZpbGxSdWxlIiwKICAiZmxvb2RDb2xvciIsCiAgImZsb29kT3BhY2l0eSIsCiAgImZvbnRGYW1pbHkiLAogICJmb250U2l6ZSIsCiAgImZvbnRTaXplQWRqdXN0IiwKICAiZm9udFN0cmV0Y2giLAogICJmb250U3R5bGUiLAogICJmb250VmFyaWFudCIsCiAgImZvbnRXZWlnaHQiLAogICJnbHlwaE5hbWUiLAogICJnbHlwaE9yaWVudGF0aW9uSG9yaXpvbnRhbCIsCiAgImdseXBoT3JpZW50YXRpb25WZXJ0aWNhbCIsCiAgImhvcml6QWR2WCIsCiAgImhvcml6T3JpZ2luWCIsCiAgImltYWdlUmVuZGVyaW5nIiwKICAibGV0dGVyU3BhY2luZyIsCiAgImxpZ2h0aW5nQ29sb3IiLAogICJtYXJrZXJFbmQiLAogICJtYXJrZXJNaWQiLAogICJtYXJrZXJTdGFydCIsCiAgIm92ZXJsaW5lUG9zaXRpb24iLAogICJvdmVybGluZVRoaWNrbmVzcyIsCiAgInBhaW50T3JkZXIiLAogICJwb2ludGVyRXZlbnRzIiwKICAicHJlc2VydmVBc3BlY3RSYXRpbyIsCiAgInNoYXBlUmVuZGVyaW5nIiwKICAic3RvcENvbG9yIiwKICAic3RvcE9wYWNpdHkiLAogICJzdHJva2VEYXNoYXJyYXkiLAogICJzdHJva2VEYXNob2Zmc2V0IiwKICAic3Ryb2tlTGluZWNhcCIsCiAgInN0cm9rZUxpbmVqb2luIiwKICAic3Ryb2tlTWl0ZXJsaW1pdCIsCiAgInN0cm9rZU9wYWNpdHkiLAogICJzdHJva2VXaWR0aCIsCiAgInRleHRBbmNob3IiLAogICJ0ZXh0RGVjb3JhdGlvbiIsCiAgInRleHRSZW5kZXJpbmciLAogICJ0cmFuc2Zvcm1PcmlnaW4iLAogICJ1bmRlcmxpbmVQb3NpdGlvbiIsCiAgInVuZGVybGluZVRoaWNrbmVzcyIsCiAgInVuaWNvZGVCaWRpIiwKICAidW5pY29kZVJhbmdlIiwKICAidW5pdHNQZXJFbSIsCiAgInZBbHBoYWJldGljIiwKICAidkhhbmdpbmciLAogICJ2SWRlb2dyYXBoaWMiLAogICJ2TWF0aGVtYXRpY2FsIiwKICAidmVjdG9yRWZmZWN0IiwKICAidmVydEFkdlkiLAogICJ2ZXJ0T3JpZ2luWCIsCiAgInZlcnRPcmlnaW5ZIiwKICAid29yZFNwYWNpbmciLAogICJ3cml0aW5nTW9kZSIsCl0pOwoKY29uc3QgU1ZHX1NLSVBfUFJPUFM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0KFsKICAiY2hpbGRyZW4iLAogICJrZXkiLAogICJyZWYiLAogICJfX3NlbGYiLAogICJfX3NvdXJjZSIsCl0pOwoKZnVuY3Rpb24gY2FtZWxUb0tlYmFiKHN0cjogc3RyaW5nKTogc3RyaW5nIHsKICByZXR1cm4gc3RyLnJlcGxhY2UoL1tBLVpdL2csIChjaCkgPT4gYC0ke2NoLnRvTG93ZXJDYXNlKCl9YCk7Cn0KCmZ1bmN0aW9uIGVzY2FwZUF0dHIodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7CiAgcmV0dXJuIHZhbHVlCiAgICAucmVwbGFjZSgvJi9nLCAiJmFtcDsiKQogICAgLnJlcGxhY2UoLyIvZywgIiZxdW90OyIpCiAgICAucmVwbGFjZSgvPC9nLCAiJmx0OyIpCiAgICAucmVwbGFjZSgvPi9nLCAiJmd0OyIpOwp9CgpmdW5jdGlvbiBzZXJpYWxpemVTdmdTdHlsZShzdHlsZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBzdHJpbmcgewogIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdOwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlKSkgewogICAgY29uc3QgdmFsdWUgPSBzdHlsZVtrZXldOwogICAgaWYgKHZhbHVlID09IG51bGwpIGNvbnRpbnVlOwogICAgcGFydHMucHVzaChgJHtjYW1lbFRvS2ViYWIoa2V5KX06JHtTdHJpbmcodmFsdWUpLnRyaW0oKX1gKTsKICB9CiAgcmV0dXJuIHBhcnRzLmpvaW4oIjsiKTsKfQoKZnVuY3Rpb24gc2VyaWFsaXplU3ZnQXR0cihrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCBudWxsIHsKICBpZiAoU1ZHX1NLSVBfUFJPUFMuaGFzKGtleSkgfHwgdmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgbGV0IGF0dHJOYW1lOiBzdHJpbmc7CiAgaWYgKGtleSA9PT0gImNsYXNzTmFtZSIpIGF0dHJOYW1lID0gImNsYXNzIjsKICBlbHNlIGlmIChTVkdfQ0FNRUxfQVRUUlMuaGFzKGtleSkpIGF0dHJOYW1lID0gY2FtZWxUb0tlYmFiKGtleSk7CiAgZWxzZSBhdHRyTmFtZSA9IGtleTsKICBpZiAoa2V5ID09PSAic3R5bGUiICYmIHR5cGVvZiB2YWx1ZSA9PT0gIm9iamVjdCIpIHsKICAgIGNvbnN0IGNzcyA9IHNlcmlhbGl6ZVN2Z1N0eWxlKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTsKICAgIGlmICghY3NzKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBgJHthdHRyTmFtZX09IiR7ZXNjYXBlQXR0cihjc3MpfSJgOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09PSAiYm9vbGVhbiIpIHJldHVybiBgJHthdHRyTmFtZX09IiR7U3RyaW5nKHZhbHVlKX0iYDsKICByZXR1cm4gYCR7YXR0ck5hbWV9PSIke2VzY2FwZUF0dHIoU3RyaW5nKHZhbHVlKSl9ImA7Cn0KCmZ1bmN0aW9uIHNlcmlhbGl6ZVN2Z1ZOb2RlKG5vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IHN0cmluZyB7CiAgaWYgKG5vZGUudHlwZSA9PT0gIiN0ZXh0IikgcmV0dXJuIG5vZGUudGV4dCA/PyAiIjsKICBjb25zdCBhdHRyczogc3RyaW5nW10gPSBbXTsKICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhub2RlLnByb3BzKSkgewogICAgY29uc3QgYXR0ciA9IHNlcmlhbGl6ZVN2Z0F0dHIoa2V5LCB2YWx1ZSk7CiAgICBpZiAoYXR0ciAhPSBudWxsKSBhdHRycy5wdXNoKGF0dHIpOwogIH0KICBjb25zdCBjaGlsZE1hcmt1cCA9IG5vZGUuY2hpbGRyZW4ubWFwKHNlcmlhbGl6ZVN2Z1ZOb2RlKS5qb2luKCIiKTsKICBjb25zdCBhdHRyU3RyID0gYXR0cnMubGVuZ3RoID4gMCA/IGAgJHthdHRycy5qb2luKCIgIil9YCA6ICIiOwogIHJldHVybiBgPCR7bm9kZS50eXBlfSR7YXR0clN0cn0+JHtjaGlsZE1hcmt1cH08LyR7bm9kZS50eXBlfT5gOwp9CgpmdW5jdGlvbiBzZXJpYWxpemVTdmdUcmVlKHN2Z05vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IHN0cmluZyB7CiAgaWYgKCEoInhtbG5zIiBpbiBzdmdOb2RlLnByb3BzKSkgewogICAgY29uc3QgYXVnbWVudGVkID0gewogICAgICAuLi5zdmdOb2RlLAogICAgICBwcm9wczogeyAuLi5zdmdOb2RlLnByb3BzLCB4bWxuczogImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB9LAogICAgfTsKICAgIHJldHVybiBzZXJpYWxpemVTdmdWTm9kZShhdWdtZW50ZWQpOwogIH0KICByZXR1cm4gc2VyaWFsaXplU3ZnVk5vZGUoc3ZnTm9kZSk7Cn0KCi8vIOKUgOKUgCBEaXJlY3QgVk5vZGUg4oaSIFRha3VtaSBOb2RlIENvbnZlcnNpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vIE1pcnJvcnMgdGhlIG1haW4tdGhyZWFkIHZub2RlVG9UYWt1bWlOb2RlKCkgZnJvbSBwaXBlbGluZS50cy4KLy8gSW5saW5lZCB0byBhdm9pZCBjcm9zcy1tb2R1bGUgaW1wb3J0IGlzc3VlcyBpbiB3b3JrZXIgY29udGV4dC4KCmZ1bmN0aW9uIHZub2RlVG9UYWt1bWlOb2RlKG5vZGU6IFNlcmlhbGl6ZWRWTm9kZSk6IFRha3VtaU5vZGUgewogIC8vIFRleHQgbm9kZXMg4oaSIFRha3VtaSBUZXh0Tm9kZQogIGlmIChub2RlLnR5cGUgPT09ICIjdGV4dCIpIHsKICAgIHJldHVybiB7IHR5cGU6ICJ0ZXh0IiwgdGV4dDogbm9kZS50ZXh0ID8/ICIiIH07CiAgfQoKICBjb25zdCB7IGNoaWxkcmVuOiBfY2hpbGRyZW4sIGNsYXNzTmFtZSwgc3JjLCAuLi5yZXN0UHJvcHMgfSA9IG5vZGUucHJvcHM7CgogIC8vIE1hcCBjbGFzc05hbWUg4oaSIHR3IChzYW1lIGxvZ2ljIGFzIG1haW4gdGhyZWFkKQogIGxldCB0dzogc3RyaW5nIHwgdW5kZWZpbmVkID0gdHlwZW9mIHJlc3RQcm9wcy50dyA9PT0gInN0cmluZyIgPyByZXN0UHJvcHMudHcgOiB1bmRlZmluZWQ7CiAgaWYgKHR5cGVvZiBjbGFzc05hbWUgPT09ICJzdHJpbmciICYmIGNsYXNzTmFtZS5sZW5ndGggPiAwKSB7CiAgICB0dyA9IHR3ID8gdHcgKyAiICIgKyBjbGFzc05hbWUgOiBjbGFzc05hbWU7CiAgfQoKICAvLyBJbWFnZSBub2RlcyDihpIgVGFrdW1pIEltYWdlTm9kZQogIGlmIChub2RlLnR5cGUgPT09ICJpbWciICYmIHR5cGVvZiBzcmMgPT09ICJzdHJpbmciKSB7CiAgICByZXR1cm4gewogICAgICB0eXBlOiAiaW1hZ2UiLAogICAgICBzcmM6IHNyYyBhcyBzdHJpbmcsCiAgICAgIC4uLih0dyA/IHsgdHcgfSA6IHt9KSwKICAgICAgLi4ucmVzdFByb3BzLAogICAgfTsKICB9CgogIC8vIFNWRyBub2RlcyDihpIgVGFrdW1pIEltYWdlTm9kZSAoc2VyaWFsaXplIHN1YnRyZWUgdG8gU1ZHIG1hcmt1cCkKICBpZiAobm9kZS50eXBlID09PSAic3ZnIikgewogICAgY29uc3Qgc3ZnTWFya3VwID0gc2VyaWFsaXplU3ZnVHJlZShub2RlKTsKICAgIGNvbnN0IHdpZHRoID0gdHlwZW9mIG5vZGUucHJvcHMud2lkdGggPT09ICJudW1iZXIiID8gbm9kZS5wcm9wcy53aWR0aCA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IGhlaWdodCA9IHR5cGVvZiBub2RlLnByb3BzLmhlaWdodCA9PT0gIm51bWJlciIgPyBub2RlLnByb3BzLmhlaWdodCA6IHVuZGVmaW5lZDsKICAgIHJldHVybiB7CiAgICAgIHR5cGU6ICJpbWFnZSIsCiAgICAgIHNyYzogc3ZnTWFya3VwLAogICAgICAuLi4od2lkdGggIT0gbnVsbCA/IHsgd2lkdGggfSA6IHt9KSwKICAgICAgLi4uKGhlaWdodCAhPSBudWxsID8geyBoZWlnaHQgfSA6IHt9KSwKICAgICAgLi4uKHR3ID8geyB0dyB9IDoge30pLAogICAgICAuLi4obm9kZS5wcm9wcy5zdHlsZSA/IHsgc3R5bGU6IG5vZGUucHJvcHMuc3R5bGUgfSA6IHt9KSwKICAgICAgdGFnTmFtZTogInN2ZyIsCiAgICB9OwogIH0KCiAgLy8gQWxsIG90aGVyIG5vZGVzIOKGkiBUYWt1bWkgQ29udGFpbmVyTm9kZQogIGNvbnN0IHRha3VtaUNoaWxkcmVuID0KICAgIG5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCA/IG5vZGUuY2hpbGRyZW4ubWFwKHZub2RlVG9UYWt1bWlOb2RlKSA6IHVuZGVmaW5lZDsKCiAgcmV0dXJuIHsKICAgIHR5cGU6ICJjb250YWluZXIiLAogICAgLi4uKHR3ID8geyB0dyB9IDoge30pLAogICAgLi4ucmVzdFByb3BzLAogICAgLi4uKHRha3VtaUNoaWxkcmVuID8geyBjaGlsZHJlbjogdGFrdW1pQ2hpbGRyZW4gfSA6IHt9KSwKICB9Owp9CgovLyDilIDilIAgUm9vdCBzdHlsZSBjb25zdGFudCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmNvbnN0IFJPT1RfU1RZTEUgPSB7IGRpc3BsYXk6ICJmbGV4Iiwgd2lkdGg6ICIxMDAlIiwgaGVpZ2h0OiAiMTAwJSIgfSBhcyBjb25zdDsKCi8vIOKUgOKUgCBXb3JrZXIgU3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpsZXQgcmVuZGVyZXI6IGltcG9ydCgiQHRha3VtaS1ycy9jb3JlIikuUmVuZGVyZXIgfCBudWxsID0gbnVsbDsKCi8vIOKUgOKUgCBNZXNzYWdlIEhhbmRsZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgphc3luYyBmdW5jdGlvbiBoYW5kbGVNZXNzYWdlKG1zZzogV29ya2VyTWVzc2FnZSk6IFByb21pc2U8dm9pZD4gewogIHN3aXRjaCAobXNnLnR5cGUpIHsKICAgIGNhc2UgImluaXQiOiB7CiAgICAgIHRyeSB7CiAgICAgICAgLy8gRHluYW1pYyBpbXBvcnQg4oCUIG1heSBmYWlsIGlmIHRoZSBuYXRpdmUgYWRkb24gY2FuJ3QgbG9hZCBpbiBhIHdvcmtlcgogICAgICAgIGNvbnN0IGNvcmUgPSBhd2FpdCBpbXBvcnQoIkB0YWt1bWktcnMvY29yZSIpOwoKICAgICAgICByZW5kZXJlciA9IG5ldyBjb3JlLlJlbmRlcmVyKHsKICAgICAgICAgIGZvbnRzOiBtc2cuZm9udHMubWFwKChmKSA9PiAoewogICAgICAgICAgICBuYW1lOiBmLm5hbWUsCiAgICAgICAgICAgIGRhdGE6IGYuZGF0YSwKICAgICAgICAgICAgd2VpZ2h0OiBmLndlaWdodCBhcyAxMDAgfCAyMDAgfCAzMDAgfCA0MDAgfCA1MDAgfCA2MDAgfCA3MDAgfCA4MDAgfCA5MDAsCiAgICAgICAgICAgIHN0eWxlOiBmLnN0eWxlIGFzICJub3JtYWwiIHwgIml0YWxpYyIsCiAgICAgICAgICB9KSksCiAgICAgICAgfSk7CgogICAgICAgIHBhcmVudFBvcnQhLnBvc3RNZXNzYWdlKHsgdHlwZTogInJlYWR5IiB9KTsKICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgcGFyZW50UG9ydCEucG9zdE1lc3NhZ2UoewogICAgICAgICAgdHlwZTogImVycm9yIiwKICAgICAgICAgIGlkOiAtMSwKICAgICAgICAgIGVycm9yOiBgV29ya2VyIGluaXQgZmFpbGVkOiAke2VyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKX1gLAogICAgICAgIH0pOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGNhc2UgInJlbmRlciI6IHsKICAgICAgaWYgKHJlbmRlcmVyID09IG51bGwpIHsKICAgICAgICBwYXJlbnRQb3J0IS5wb3N0TWVzc2FnZSh7CiAgICAgICAgICB0eXBlOiAiZXJyb3IiLAogICAgICAgICAgaWQ6IG1zZy5pZCwKICAgICAgICAgIGVycm9yOiAiV29ya2VyIG5vdCBpbml0aWFsaXplZCIsCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICB0cnkgewogICAgICAgIC8vIDEuIENvbnZlcnQgc2VyaWFsaXplZCBWTm9kZSBkYXRhIOKGkiBUYWt1bWkgbm9kZXMgZGlyZWN0bHkgKGJ5cGFzcyBmcm9tSnN4KQogICAgICAgIGNvbnN0IGNoaWxkcmVuID0gbXNnLnZub2Rlcy5tYXAodm5vZGVUb1Rha3VtaU5vZGUpOwogICAgICAgIGNvbnN0IHJvb3ROb2RlOiBUYWt1bWlOb2RlID0gewogICAgICAgICAgdHlwZTogImNvbnRhaW5lciIsCiAgICAgICAgICBzdHlsZTogUk9PVF9TVFlMRSwKICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgIH07CgogICAgICAgIC8vIDIuIFJlbmRlciB0byByYXN0ZXIgaW1hZ2UKICAgICAgICAvLyBDYXN0OiBUYWt1bWlOb2RlIGlzIGEgbG9jYWwgc3RydWN0dXJhbCBkdXBsaWNhdGUgb2YgdGhlCiAgICAgICAgLy8gQHRha3VtaS1ycy9oZWxwZXJzIE5vZGUgdW5pb24g4oCUIHRoZSBzaGFwZXMgbWF0Y2ggYXQgcnVudGltZQogICAgICAgIC8vIGJ1dCBUeXBlU2NyaXB0IGNhbid0IHZlcmlmeSB0aGUgZGlzY3JpbWluYXRlZCB1bmlvbiBtZW1iZXJzCiAgICAgICAgLy8gZnJvbSB0aGUgbG9vc2UgYHR5cGU6IHN0cmluZ2AgaW5kZXggc2lnbmF0dXJlLgogICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHJlbmRlcmVyLnJlbmRlcigKICAgICAgICAgIHJvb3ROb2RlIGFzIHVua25vd24gYXMgaW1wb3J0KCJAdGFrdW1pLXJzL2hlbHBlcnMiKS5Ob2RlLAogICAgICAgICAgewogICAgICAgICAgICB3aWR0aDogbXNnLndpZHRoLAogICAgICAgICAgICBoZWlnaHQ6IG1zZy5oZWlnaHQsCiAgICAgICAgICAgIGZvcm1hdDogbXNnLmZvcm1hdCBhcyBpbXBvcnQoIkB0YWt1bWktcnMvY29yZSIpLk91dHB1dEZvcm1hdCwKICAgICAgICAgICAgZGV2aWNlUGl4ZWxSYXRpbzogbXNnLmRwciwKICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgLy8gVHJhbnNmZXIgdGhlIGJ1ZmZlciAoemVyby1jb3B5KSBiYWNrIHRvIHRoZSBtYWluIHRocmVhZAogICAgICAgIGNvbnN0IGFiID0KICAgICAgICAgIGJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyCiAgICAgICAgICAgID8gYnVmZmVyCiAgICAgICAgICAgIDogYnVmZmVyLmJ1ZmZlci5zbGljZShidWZmZXIuYnl0ZU9mZnNldCwgYnVmZmVyLmJ5dGVPZmZzZXQgKyBidWZmZXIuYnl0ZUxlbmd0aCk7CgogICAgICAgIHBhcmVudFBvcnQhLnBvc3RNZXNzYWdlKAogICAgICAgICAgeyB0eXBlOiAicmVzdWx0IiwgaWQ6IG1zZy5pZCwgYnVmZmVyOiBhYiB9LAogICAgICAgICAgeyB0cmFuc2ZlcjogW2FiIGFzIEFycmF5QnVmZmVyXSB9LAogICAgICAgICk7CiAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgIHBhcmVudFBvcnQhLnBvc3RNZXNzYWdlKHsKICAgICAgICAgIHR5cGU6ICJlcnJvciIsCiAgICAgICAgICBpZDogbXNnLmlkLAogICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSwKICAgICAgICB9KTsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KCiAgICBjYXNlICJzaHV0ZG93biI6IHsKICAgICAgcHJvY2Vzcy5leGl0KDApOwogICAgfQogIH0KfQoKLy8g4pSA4pSAIEF1dG8taW5pdCBpZiBmb250cyBwcm92aWRlZCB2aWEgd29ya2VyRGF0YSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmlmICh3b3JrZXJEYXRhPy5mb250cykgewogIGhhbmRsZU1lc3NhZ2UoeyB0eXBlOiAiaW5pdCIsIGZvbnRzOiB3b3JrZXJEYXRhLmZvbnRzIH0pOwp9CgpwYXJlbnRQb3J0IS5vbigibWVzc2FnZSIsIChtc2c6IFdvcmtlck1lc3NhZ2UpID0+IHsKICBoYW5kbGVNZXNzYWdlKG1zZyk7Cn0pOwo=", "" + import.meta.url), { workerData: { fonts: this.fonts.map((f) => ({
|
|
40
40
|
name: f.name,
|
|
41
41
|
data: f.data,
|
|
42
42
|
weight: f.weight,
|
package/dist/rollup.d.ts
CHANGED
|
@@ -1,14 +1,42 @@
|
|
|
1
1
|
import { Plugin } from 'rollup';
|
|
2
2
|
import { StreamDeckTargetOptions } from './bundler-shared';
|
|
3
|
+
import { PluginManifestInfo } from './manifest-types';
|
|
3
4
|
export type { StreamDeckPlatform, StreamDeckArch, StreamDeckTarget, StreamDeckTargetOptions, TakumiBackend, } from './bundler-shared';
|
|
5
|
+
export type { ManifestActionSource, PluginManifestInfo, ActionManifestInfo, ManifestController, ManifestEncoderInfo, ManifestTriggerDescription, ManifestStateInfo, ManifestOSInfo, ManifestNodejsInfo, ManifestProfileInfo, } from './manifest-types';
|
|
4
6
|
export interface StreamDeckRollupOptions extends StreamDeckTargetOptions {
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
+
* Code-first manifest generation. When a `PluginManifestInfo` object
|
|
9
|
+
* is provided, the plugin generates `manifest.json` in the `.sdPlugin`
|
|
10
|
+
* directory during `writeBundle`.
|
|
8
11
|
*
|
|
9
|
-
*
|
|
12
|
+
* Actions are **auto-extracted** from `defineAction()` calls in the
|
|
13
|
+
* source code — no need to list them here. The plugin scans the
|
|
14
|
+
* module graph during the build and extracts `uuid`, `info`, and
|
|
15
|
+
* component presence from each `defineAction()` call.
|
|
16
|
+
*
|
|
17
|
+
* Actions with `info.disabled: true` are skipped.
|
|
18
|
+
*
|
|
19
|
+
* Auto-derived defaults:
|
|
20
|
+
* - `CodePath` from the bundler output path
|
|
21
|
+
* - `Controllers` from key/dial/touchStrip presence
|
|
22
|
+
* - `OS`, `Nodejs`, `SDKVersion`, `Software` have defaults
|
|
23
|
+
* - `States` default to `[{ Image: icon }]`
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* streamDeckReact({
|
|
28
|
+
* manifest: {
|
|
29
|
+
* uuid: "com.example.my-plugin",
|
|
30
|
+
* name: "My Plugin",
|
|
31
|
+
* author: "Me",
|
|
32
|
+
* description: "A plugin",
|
|
33
|
+
* icon: "imgs/plugin-icon",
|
|
34
|
+
* version: "1.0.0.0",
|
|
35
|
+
* },
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
10
38
|
*/
|
|
11
|
-
manifest?:
|
|
39
|
+
manifest?: PluginManifestInfo;
|
|
12
40
|
}
|
|
13
41
|
/**
|
|
14
42
|
* Rollup plugin for Stream Deck React projects.
|
|
@@ -19,12 +47,11 @@ export interface StreamDeckRollupOptions extends StreamDeckTargetOptions {
|
|
|
19
47
|
* - No `configResolved` — dev mode detected via `this.meta.watchMode`
|
|
20
48
|
* - `onLog` suppresses `MODULE_LEVEL_DIRECTIVE` warnings (caused by
|
|
21
49
|
* "use client" directives in React dependencies)
|
|
22
|
-
* - `
|
|
23
|
-
* - `writeBundle`
|
|
24
|
-
* `dirname(outputOptions.file)` (Rollup supports both)
|
|
50
|
+
* - `moduleParsed` extracts defineAction() metadata from each module
|
|
51
|
+
* - `writeBundle` generates manifest.json + copies native bindings
|
|
25
52
|
* - No `closeBundle` restart hook (handled externally)
|
|
26
53
|
*
|
|
27
|
-
* Font inlining and manifest
|
|
28
|
-
* font-inline.ts, and manifest-
|
|
54
|
+
* Font inlining and manifest generation are shared via bundler-shared.ts,
|
|
55
|
+
* font-inline.ts, manifest-gen.ts, and manifest-extract.ts.
|
|
29
56
|
*/
|
|
30
57
|
export declare function streamDeckReact(options?: StreamDeckRollupOptions): Plugin;
|
package/dist/rollup.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { NOOP_DEVTOOLS_CODE, NOOP_DEVTOOLS_ID, TAKUMI_NATIVE_LOADER_CODE, TAKUMI_NATIVE_LOADER_ID, copyNativeBindings, isDevelopmentMode, isLibraryDevtoolsImport, shouldStripDevtools } from "./bundler-shared.js";
|
|
1
|
+
import { NOOP_DEVTOOLS_CODE, NOOP_DEVTOOLS_ID, TAKUMI_NATIVE_LOADER_CODE, TAKUMI_NATIVE_LOADER_ID, copyNativeBindings, deriveCodePath, isDevelopmentMode, isLibraryDevtoolsImport, resolvePluginDir, shouldStripDevtools } from "./bundler-shared.js";
|
|
2
2
|
import { loadFont, resolveFontId } from "./font-inline.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { generateManifestJsonString, validateManifestConfig, validatePluginUUID, writeManifestIfChanged } from "./manifest-gen.js";
|
|
4
|
+
import { extractActionsFromAST, extractedToActionSource } from "./manifest-extract.js";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
5
6
|
//#region src/rollup.ts
|
|
6
7
|
/**
|
|
7
8
|
* Rollup plugin for Stream Deck React projects.
|
|
@@ -12,28 +13,37 @@ import { dirname, resolve } from "node:path";
|
|
|
12
13
|
* - No `configResolved` — dev mode detected via `this.meta.watchMode`
|
|
13
14
|
* - `onLog` suppresses `MODULE_LEVEL_DIRECTIVE` warnings (caused by
|
|
14
15
|
* "use client" directives in React dependencies)
|
|
15
|
-
* - `
|
|
16
|
-
* - `writeBundle`
|
|
17
|
-
* `dirname(outputOptions.file)` (Rollup supports both)
|
|
16
|
+
* - `moduleParsed` extracts defineAction() metadata from each module
|
|
17
|
+
* - `writeBundle` generates manifest.json + copies native bindings
|
|
18
18
|
* - No `closeBundle` restart hook (handled externally)
|
|
19
19
|
*
|
|
20
|
-
* Font inlining and manifest
|
|
21
|
-
* font-inline.ts, and manifest-
|
|
20
|
+
* Font inlining and manifest generation are shared via bundler-shared.ts,
|
|
21
|
+
* font-inline.ts, manifest-gen.ts, and manifest-extract.ts.
|
|
22
22
|
*/
|
|
23
23
|
function streamDeckReact(options = {}) {
|
|
24
|
+
const extractedActions = [];
|
|
24
25
|
return {
|
|
25
26
|
name: "fcannizzaro-streamdeck-react",
|
|
26
27
|
onLog(_level, log) {
|
|
27
28
|
if (log.code === "MODULE_LEVEL_DIRECTIVE") return false;
|
|
28
29
|
},
|
|
29
30
|
buildStart() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (result) {
|
|
34
|
-
this.addWatchFile(result.manifestPath);
|
|
35
|
-
if (result.written) console.log("[@fcannizzaro/streamdeck-react] Generated src/streamdeck-env.d.ts");
|
|
31
|
+
if (options.manifest) {
|
|
32
|
+
const uuidError = validatePluginUUID(options.manifest.uuid);
|
|
33
|
+
if (uuidError) this.warn(`[@fcannizzaro/streamdeck-react] ${uuidError.message}`);
|
|
36
34
|
}
|
|
35
|
+
extractedActions.length = 0;
|
|
36
|
+
},
|
|
37
|
+
moduleParsed(moduleInfo) {
|
|
38
|
+
if (!options.manifest) return;
|
|
39
|
+
if (!moduleInfo.code?.includes("defineAction")) return;
|
|
40
|
+
try {
|
|
41
|
+
const actions = extractActionsFromAST(this.parse(moduleInfo.code));
|
|
42
|
+
for (const action of actions) {
|
|
43
|
+
if (action.info?.disabled) continue;
|
|
44
|
+
extractedActions.push(action);
|
|
45
|
+
}
|
|
46
|
+
} catch {}
|
|
37
47
|
},
|
|
38
48
|
resolveId: {
|
|
39
49
|
order: "pre",
|
|
@@ -56,6 +66,23 @@ function streamDeckReact(options = {}) {
|
|
|
56
66
|
const outDir = outputOptions.file ? dirname(outputOptions.file) : outputOptions.dir;
|
|
57
67
|
if (!outDir) return;
|
|
58
68
|
copyNativeBindings(outDir, isDevelopment, options, (msg) => this.warn(msg));
|
|
69
|
+
if (options.manifest) {
|
|
70
|
+
const pluginDir = resolvePluginDir(outDir);
|
|
71
|
+
if (!pluginDir) {
|
|
72
|
+
this.warn("[@fcannizzaro/streamdeck-react] Could not resolve .sdPlugin directory from output path. Manifest generation skipped.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const codePath = deriveCodePath(outputOptions.file ?? join(outDir, "plugin.mjs"), pluginDir);
|
|
76
|
+
const fullConfig = {
|
|
77
|
+
...options.manifest,
|
|
78
|
+
actions: extractedActions.map(extractedToActionSource)
|
|
79
|
+
};
|
|
80
|
+
const errors = validateManifestConfig(fullConfig, (msg) => this.warn(msg));
|
|
81
|
+
if (errors.length > 0) this.warn(`[@fcannizzaro/streamdeck-react] Manifest validation found ${errors.length} issue(s)`);
|
|
82
|
+
const content = generateManifestJsonString(fullConfig, codePath);
|
|
83
|
+
const manifestPath = join(pluginDir, "manifest.json");
|
|
84
|
+
if (writeManifestIfChanged(manifestPath, content)) console.log(`[@fcannizzaro/streamdeck-react] Generated ${manifestPath}`);
|
|
85
|
+
}
|
|
59
86
|
}
|
|
60
87
|
};
|
|
61
88
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ComponentType, ReactNode } from 'react';
|
|
2
2
|
import { JsonObject, JsonValue } from '@elgato/utils';
|
|
3
3
|
import { AdapterActionHandle, StreamDeckAdapter } from './adapter/types';
|
|
4
|
+
import { ActionManifestInfo, PluginManifestInfo } from './manifest-types';
|
|
4
5
|
/** Controller surface type. */
|
|
5
6
|
export type Controller = "Keypad" | "Encoder";
|
|
6
7
|
/** Grid coordinates for a key or encoder on a device. */
|
|
@@ -81,6 +82,12 @@ export interface PluginConfig {
|
|
|
81
82
|
fonts: FontConfig[];
|
|
82
83
|
actions: ActionDefinition[];
|
|
83
84
|
wrapper?: WrapperComponent;
|
|
85
|
+
/**
|
|
86
|
+
* Plugin manifest metadata. Optional — used for runtime
|
|
87
|
+
* documentation. For manifest generation, provide plugin-level
|
|
88
|
+
* info via the bundler plugin's `manifest` option.
|
|
89
|
+
*/
|
|
90
|
+
info?: PluginManifestInfo;
|
|
84
91
|
/**
|
|
85
92
|
* Takumi renderer backend.
|
|
86
93
|
*
|
|
@@ -111,28 +118,6 @@ export interface PluginConfig {
|
|
|
111
118
|
export interface Plugin {
|
|
112
119
|
connect(): Promise<void>;
|
|
113
120
|
}
|
|
114
|
-
export interface ManifestActions {
|
|
115
|
-
}
|
|
116
|
-
/** Action UUID — a union of manifest UUIDs when available, plain `string` otherwise. */
|
|
117
|
-
export type ActionUUID = [keyof ManifestActions] extends [never] ? string : Extract<keyof ManifestActions, string>;
|
|
118
|
-
type HasController<UUID extends string, C extends string> = UUID extends keyof ManifestActions ? ManifestActions[UUID] extends {
|
|
119
|
-
controllers: readonly (infer Item)[];
|
|
120
|
-
} ? C extends Item ? true : false : false : false;
|
|
121
|
-
type KeySurface<UUID extends string> = HasController<UUID, "Keypad"> extends true ? {
|
|
122
|
-
key: ComponentType;
|
|
123
|
-
} : {
|
|
124
|
-
key?: ComponentType;
|
|
125
|
-
};
|
|
126
|
-
type EncoderSurface<UUID extends string> = HasController<UUID, "Encoder"> extends true ? {
|
|
127
|
-
dial: ComponentType;
|
|
128
|
-
touchStrip?: ComponentType;
|
|
129
|
-
} | {
|
|
130
|
-
dial?: ComponentType;
|
|
131
|
-
touchStrip: ComponentType;
|
|
132
|
-
} : {
|
|
133
|
-
dial?: ComponentType;
|
|
134
|
-
touchStrip?: ComponentType;
|
|
135
|
-
};
|
|
136
121
|
export interface ActionConfig<S extends JsonObject = JsonObject> {
|
|
137
122
|
uuid: string;
|
|
138
123
|
key?: ComponentType;
|
|
@@ -143,19 +128,15 @@ export interface ActionConfig<S extends JsonObject = JsonObject> {
|
|
|
143
128
|
dialLayout?: EncoderLayout;
|
|
144
129
|
wrapper?: WrapperComponent;
|
|
145
130
|
defaultSettings?: Partial<S>;
|
|
131
|
+
/**
|
|
132
|
+
* Action manifest metadata. This is the **primary source** for
|
|
133
|
+
* manifest.json generation — the bundler plugin auto-extracts
|
|
134
|
+
* `info` from each `defineAction()` call at build time.
|
|
135
|
+
*
|
|
136
|
+
* Set `disabled: true` to exclude this action from the manifest.
|
|
137
|
+
*/
|
|
138
|
+
info?: ActionManifestInfo;
|
|
146
139
|
}
|
|
147
|
-
/** Resolved action config shape. When `ManifestActions` is populated (via `streamdeck-env.d.ts`), this becomes a mapped type that iterates over every UUID in the manifest and produces a discriminated union. Each member intersects `KeySurface<UUID>` and `EncoderSurface<UUID>` to enforce controller-specific requirements. When `ManifestActions` is empty, it falls back to the permissive `ActionConfig<S>`. */
|
|
148
|
-
export type ActionConfigInput<S extends JsonObject = JsonObject> = [keyof ManifestActions] extends [
|
|
149
|
-
never
|
|
150
|
-
] ? ActionConfig<S> : {
|
|
151
|
-
[UUID in ActionUUID]: {
|
|
152
|
-
uuid: UUID;
|
|
153
|
-
/** Encoder feedback layout. Defaults to a full-width `pixmap` canvas layout. Custom layouts should include a `pixmap` item keyed as `canvas`. */
|
|
154
|
-
dialLayout?: EncoderLayout;
|
|
155
|
-
wrapper?: WrapperComponent;
|
|
156
|
-
defaultSettings?: Partial<S>;
|
|
157
|
-
} & KeySurface<UUID> & EncoderSurface<UUID>;
|
|
158
|
-
}[ActionUUID];
|
|
159
140
|
export interface ActionDefinition<S extends JsonObject = JsonObject> {
|
|
160
141
|
uuid: string;
|
|
161
142
|
key?: ComponentType;
|
|
@@ -166,6 +147,11 @@ export interface ActionDefinition<S extends JsonObject = JsonObject> {
|
|
|
166
147
|
dialLayout?: EncoderLayout;
|
|
167
148
|
wrapper?: WrapperComponent;
|
|
168
149
|
defaultSettings: Partial<S>;
|
|
150
|
+
/**
|
|
151
|
+
* Action manifest metadata. Carried through from defineAction()
|
|
152
|
+
* for runtime access and manifest generation.
|
|
153
|
+
*/
|
|
154
|
+
info?: ActionManifestInfo;
|
|
169
155
|
}
|
|
170
156
|
export interface DeviceInfo {
|
|
171
157
|
id: string;
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
import { StreamDeckTargetOptions } from './bundler-shared';
|
|
3
|
+
import { PluginManifestInfo } from './manifest-types';
|
|
3
4
|
export type { StreamDeckPlatform, StreamDeckArch, StreamDeckTarget, StreamDeckTargetOptions, TakumiBackend, } from './bundler-shared';
|
|
5
|
+
export type { ManifestActionSource, PluginManifestInfo, ActionManifestInfo, ManifestController, ManifestEncoderInfo, ManifestTriggerDescription, ManifestStateInfo, ManifestOSInfo, ManifestNodejsInfo, ManifestProfileInfo, } from './manifest-types';
|
|
4
6
|
export interface StreamDeckReactOptions extends StreamDeckTargetOptions {
|
|
5
7
|
/**
|
|
6
8
|
* The plugin UUID used to restart the plugin after each build
|
|
7
9
|
* (e.g. `"com.example.react-pokemon"`).
|
|
8
10
|
*
|
|
9
11
|
* When set, the plugin will run `streamdeck restart <uuid>` after
|
|
10
|
-
* each successful build.
|
|
12
|
+
* each successful build. If `manifest` is set, the UUID is
|
|
13
|
+
* auto-derived from `manifest.uuid`.
|
|
11
14
|
*/
|
|
12
15
|
uuid?: string;
|
|
13
16
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* Code-first manifest generation. When a `PluginManifestInfo` object
|
|
18
|
+
* is provided, the plugin generates `manifest.json` in the `.sdPlugin`
|
|
19
|
+
* directory during `writeBundle`.
|
|
16
20
|
*
|
|
17
|
-
*
|
|
21
|
+
* Actions are **auto-extracted** from `defineAction()` calls in the
|
|
22
|
+
* source code — no need to list them here. The plugin scans the
|
|
23
|
+
* module graph during the build and extracts `uuid`, `info`, and
|
|
24
|
+
* component presence from each `defineAction()` call.
|
|
25
|
+
*
|
|
26
|
+
* Actions with `info.disabled: true` are skipped.
|
|
27
|
+
*
|
|
28
|
+
* Auto-derived defaults:
|
|
29
|
+
* - `CodePath` from the bundler output path
|
|
30
|
+
* - `Controllers` from key/dial/touchStrip presence
|
|
31
|
+
* - `OS`, `Nodejs`, `SDKVersion`, `Software` have defaults
|
|
32
|
+
* - `States` default to `[{ Image: icon }]`
|
|
18
33
|
*/
|
|
19
|
-
manifest?:
|
|
34
|
+
manifest?: PluginManifestInfo;
|
|
20
35
|
}
|
|
21
36
|
/**
|
|
22
37
|
* Vite plugin for Stream Deck React projects.
|
|
@@ -24,10 +39,11 @@ export interface StreamDeckReactOptions extends StreamDeckTargetOptions {
|
|
|
24
39
|
* Responsibilities mapped to Vite lifecycle hooks:
|
|
25
40
|
*
|
|
26
41
|
* configResolved → detect dev/production mode, set strip flags
|
|
27
|
-
* buildStart →
|
|
42
|
+
* buildStart → validate plugin UUID format (early check)
|
|
43
|
+
* moduleParsed → extract defineAction() metadata from each module
|
|
28
44
|
* resolveId → redirect devtools imports (production) + font imports
|
|
29
45
|
* load → return noop devtools stub + inline font as base64 Buffer
|
|
30
|
-
* writeBundle → copy native .node bindings
|
|
46
|
+
* writeBundle → copy native .node bindings + generate manifest.json
|
|
31
47
|
* closeBundle → restart Stream Deck plugin (optional, via CLI)
|
|
32
48
|
*
|
|
33
49
|
* Font inlining:
|