@dbx-tools/email 0.6.46 → 0.6.48

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/README.md CHANGED
@@ -7,7 +7,9 @@ outbound email with human approval, sender derivation, SMTP dispatch, and a
7
7
  local outbox mode for development. AppKit ships no first-party email surface,
8
8
  so this is additive rather than an alternative to a native plugin. Browser-safe
9
9
  message/result schemas live in
10
- [`@dbx-tools/shared-email`](../../shared/email).
10
+ [`@dbx-tools/shared-email`](../../shared/email), and the reusable React Email
11
+ presentation lives in
12
+ [`@dbx-tools/shared-email-template`](../../shared/email-template).
11
13
 
12
14
  **Key features:**
13
15
 
@@ -22,8 +24,8 @@ message/result schemas live in
22
24
  configured domain.
23
25
  - Deny-by-default sender policy with exact addresses, domains, domain wildcards,
24
26
  and a named `unrestricted` escape hatch.
25
- - Markdown-to-HTML rendering with a small email layout, inline styles, metadata,
26
- and attachment summaries.
27
+ - React Email rendering with responsive components, matching HTML/plain-text
28
+ alternatives, metadata, attachment summaries, and the dbx-tools brand by default.
27
29
  - Named caps on body length and attachment size, and an `AbortSignal` threaded
28
30
  through every send.
29
31
 
@@ -80,7 +82,7 @@ approval card and compose components.
80
82
  | `senderPolicy` | `"allowlist" \| "unrestricted"` | `EMAIL_SENDER_POLICY`, then `"allowlist"` | How the sender is restricted when `allowedSenders` is empty. |
81
83
  | `allowedSenders` | `string \| string[]` | `EMAIL_ALLOWED_SENDERS` | Permitted `From` patterns: exact addresses, `*@domain`, a bare `domain`, or `*`. |
82
84
  | `outDir` | `string` | `EMAIL_OUTBOX_DIR`, then `<cwd>/tmp` | Directory the outbox writes HTML previews to. |
83
- | `brand` | `EmailBrand` | none | Accent color, font, display name, and header logo inlined into every message. |
85
+ | `brand` | `EmailBrand` | dbx-tools brand | Colors, font, display name, footer, and optional logo applied to every message. |
84
86
 
85
87
  Precedence per field is explicit config, then the environment variable, then the
86
88
  built-in default.
@@ -240,35 +242,41 @@ deployment that only sets `EMAIL_DOMAIN` rejects a `From` on any other domain.
240
242
  Set `senderPolicy: "unrestricted"` to accept any `From` a caller supplies. The
241
243
  effective policy is logged at boot.
242
244
 
243
- ## Render Markdown Email
245
+ ## Render A React Email
244
246
 
245
247
  ```ts
246
248
  import { emailHtml, markdown } from "@dbx-tools/email";
247
249
 
248
- const html = emailHtml.renderEmailHtml({
250
+ const html = await emailHtml.renderEmailHtml({
249
251
  subject: "Incident update",
250
252
  body: "## Status\nResolved.",
251
253
  });
252
254
 
253
- const fragment = markdown.markdownToHtml("## Status\nResolved.");
255
+ const text = await emailHtml.renderEmailText({
256
+ subject: "Incident update",
257
+ body: "## Status\nResolved.",
258
+ });
259
+
260
+ const fragment = await markdown.markdownToHtml("## Status\nResolved.");
254
261
  ```
255
262
 
256
- `renderEmailHtml()` takes a Markdown `body`, renders it, wraps it in the package
257
- layout, and inlines the CSS for mail clients. Pass Markdown, not HTML: the
258
- renderer runs `markdownToHtml()` itself. `markdown.normalizeMarkdown()` trims
259
- common indentation and repairs fenced-text noise, and
260
- `markdown.markdownToHtml()` renders a Markdown fragment on its own.
263
+ `renderEmailHtml()` and `renderEmailText()` render the same shared React Email
264
+ component tree into the two MIME alternatives used by SMTP. The universal
265
+ components live in `@dbx-tools/shared-email-template`, so the browser preview
266
+ and delivered message share typography, content styling, and brand behavior.
267
+ `markdown.normalizeMarkdown()` remains available for compatibility, while
268
+ `markdown.markdownToHtml()` now renders through the shared React Email body.
261
269
 
262
270
  ## Brand The Email
263
271
 
264
- Branding is optional. Pass a `brand` to the plugin (or to `renderEmailHtml`) to
265
- color the layout with an accent, font, and header logo; omit it for the neutral
266
- default palette.
272
+ Every message uses the repository's dbx-tools brand by default. Pass a `brand`
273
+ to the plugin or renderer only when the consuming application needs its own
274
+ identity.
267
275
 
268
276
  ```ts
269
277
  import { brand, plugin } from "@dbx-tools/email";
270
278
 
271
- // The dbx-tools brand, ready to use:
279
+ // Explicitly select the same brand used by default:
272
280
  plugin.email({ brand: brand.defaultEmailBrand });
273
281
 
274
282
  // Or derive from any shared BrandContext:
@@ -286,12 +294,11 @@ plugin.email({
286
294
  });
287
295
  ```
288
296
 
289
- The brand is inlined into every rendered message. The browser UI's `[data-brand]`
290
- CSS bridge can't reach an inbox (mail clients strip `<style>` and ignore `var()`),
291
- so email branding uses inline token values instead. A `logoUrl` renders only when
292
- it is an `http(s):` or `data:` URL - a package-export asset path is dropped rather
293
- than shown as a broken image, so `defaultEmailBrand` applies the brand color and
294
- font but no logo.
297
+ React Email applies the brand through email-safe inline styles. The browser UI's
298
+ `[data-brand]` CSS bridge cannot reach an inbox, so both the delivered document
299
+ and browser preview consume the same `EmailBrand` values directly. A `logoUrl`
300
+ renders when it is an `http(s):`, `data:`, or `cid:` URL; otherwise the branded
301
+ display name becomes the header mark.
295
302
 
296
303
  ## Use The Outbox In Tests
297
304
 
@@ -310,7 +317,7 @@ copied to disk.
310
317
 
311
318
  | Constant | Value | Bounds |
312
319
  | ----------------------------- | ------- | ---------------------------------------- |
313
- | `MAX_BODY_CHARS` | 200,000 | Markdown body length. |
320
+ | `MAX_BODY_CHARS` | 200,000 | Email content length. |
314
321
  | `MAX_ATTACHMENT_BYTES` | 10 MiB | One attachment's decoded inline content. |
315
322
  | `MAX_ATTACHMENTS_TOTAL_BYTES` | 20 MiB | Combined decoded attachment content. |
316
323
  | `MAX_ATTACHMENT_COUNT` | 20 | Attachments on one message. |
@@ -335,9 +342,20 @@ handed to SMTP. The constants and the plugin's interceptor settings live in the
335
342
  `resolveEmailConfig()`.
336
343
  - `defaults` - execution settings for the interceptor chain and the payload caps.
337
344
  - `sender` - sender derivation, allow-list parsing, and sender-option listing.
338
- - `markdown` / `emailHtml` - Markdown normalization/rendering and HTML layout.
345
+ - `emailHtml` - Node rendering adapters over the shared template:
346
+ `renderEmailHtml()`, `renderEmailText()`, and `renderEmail()` for both MIME
347
+ alternatives from one component tree.
348
+ - `markdown` - body-only rendering plus `normalizeMarkdown()`.
339
349
  - `outbox` - local HTML file writer for development and tests.
340
350
  - `brand` - `EmailBrand`, `emailBrandFromContext()`, and `defaultEmailBrand`.
341
351
 
352
+ `brand`, and the components behind `emailHtml`/`markdown`, re-export from
353
+ [`@dbx-tools/shared-email-template`](../../shared/email-template). They exist so
354
+ server code has one import for delivery, and so the Node renderer and a browser
355
+ preview cannot drift apart - not as a second implementation. Style inlining is
356
+ React Email's own; this package runs no separate CSS inliner.
357
+
342
358
  Pair this package with [`@dbx-tools/shared-email`](../../shared/email) when a UI
343
- or tool schema needs to validate the same email payload.
359
+ or tool schema needs to validate the same email payload, and with
360
+ [`@dbx-tools/shared-email-template`](../../shared/email-template) when another
361
+ runtime needs to reuse the presentation components directly.
package/index.ts CHANGED
@@ -12,14 +12,13 @@ export * as plugin from "./src/plugin.ts";
12
12
  export * as sender from "./src/sender.ts";
13
13
  export * as tool from "./src/tool.ts";
14
14
  export * as transport from "./src/transport.ts";
15
- export { defaultEmailBrand } from "./src/brand.ts";
16
- export type { EmailBrand } from "./src/brand.ts";
17
15
  export { DEFAULT_SMTP_PORT, IMPLICIT_TLS_SMTP_PORT, EMAIL_CONFIG_SCHEMA } from "./src/config.ts";
18
16
  export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
19
17
  export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYTES, MAX_ATTACHMENTS_TOTAL_BYTES, MAX_ATTACHMENT_COUNT, MAX_BODY_CHARS, EMAIL_SEND_SETTINGS, EMAIL_VERIFY_SETTINGS, EMAIL_SENDERS_SETTINGS } from "./src/defaults.ts";
20
18
  export type { EmailExecuteConfig, EmailExecutionSettings } from "./src/defaults.ts";
21
19
  export { escapeHtml } from "./src/email-html.ts";
22
20
  export type { EmailHtmlOptions } from "./src/email-html.ts";
21
+ export { normalizeMarkdown } from "./src/markdown.ts";
23
22
  export { EmailPlugin, email } from "./src/plugin.ts";
24
23
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.ts";
25
24
  export type { EmailToolOptions } from "./src/tool.ts";
package/lib/index.d.ts CHANGED
@@ -8,14 +8,13 @@ export * as plugin from "./src/plugin.ts";
8
8
  export * as sender from "./src/sender.ts";
9
9
  export * as tool from "./src/tool.ts";
10
10
  export * as transport from "./src/transport.ts";
11
- export { defaultEmailBrand } from "./src/brand.ts";
12
- export type { EmailBrand } from "./src/brand.ts";
13
11
  export { DEFAULT_SMTP_PORT, IMPLICIT_TLS_SMTP_PORT, EMAIL_CONFIG_SCHEMA } from "./src/config.ts";
14
12
  export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
15
13
  export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYTES, MAX_ATTACHMENTS_TOTAL_BYTES, MAX_ATTACHMENT_COUNT, MAX_BODY_CHARS, EMAIL_SEND_SETTINGS, EMAIL_VERIFY_SETTINGS, EMAIL_SENDERS_SETTINGS } from "./src/defaults.ts";
16
14
  export type { EmailExecuteConfig, EmailExecutionSettings } from "./src/defaults.ts";
17
15
  export { escapeHtml } from "./src/email-html.ts";
18
16
  export type { EmailHtmlOptions } from "./src/email-html.ts";
17
+ export { normalizeMarkdown } from "./src/markdown.ts";
19
18
  export { EmailPlugin, email } from "./src/plugin.ts";
20
19
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.ts";
21
20
  export type { EmailToolOptions } from "./src/tool.ts";
package/lib/index.js CHANGED
@@ -11,10 +11,10 @@ export * as plugin from "./src/plugin.js";
11
11
  export * as sender from "./src/sender.js";
12
12
  export * as tool from "./src/tool.js";
13
13
  export * as transport from "./src/transport.js";
14
- export { defaultEmailBrand } from "./src/brand.js";
15
14
  export { DEFAULT_SMTP_PORT, IMPLICIT_TLS_SMTP_PORT, EMAIL_CONFIG_SCHEMA } from "./src/config.js";
16
15
  export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYTES, MAX_ATTACHMENTS_TOTAL_BYTES, MAX_ATTACHMENT_COUNT, MAX_BODY_CHARS, EMAIL_SEND_SETTINGS, EMAIL_VERIFY_SETTINGS, EMAIL_SENDERS_SETTINGS } from "./src/defaults.js";
17
16
  export { escapeHtml } from "./src/email-html.js";
17
+ export { normalizeMarkdown } from "./src/markdown.js";
18
18
  export { EmailPlugin, email } from "./src/plugin.js";
19
19
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.js";
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVyUCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGVtYWlsSHRtbCBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0ICogYXMgbWFya2Rvd24gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgKiBhcyBvdXRib3ggZnJvbSBcIi4vc3JjL291dGJveC50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHNlbmRlciBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgKiBhcyB0b29sIGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgZGVmYXVsdEVtYWlsQnJhbmQgfSBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxCcmFuZCB9IGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9TTVRQX1BPUlQsIElNUExJQ0lUX1RMU19TTVRQX1BPUlQsIEVNQUlMX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlbmRlclBvbGljeSwgU210cENvbmZpZywgRW1haWxQbHVnaW5Db25maWcsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IEVtYWlsUGx1Z2luLCBlbWFpbCB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB7IFNFTkRfRU1BSUxfREVTQ1JJUFRJT04gfSBmcm9tIFwiLi9zcmMvdG9vbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbFRvb2xPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxFeGVjdXRvciwgRW1haWxSdW50aW1lIH0gZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuIl19
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVyUCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGVtYWlsSHRtbCBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0ICogYXMgbWFya2Rvd24gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgKiBhcyBvdXRib3ggZnJvbSBcIi4vc3JjL291dGJveC50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHNlbmRlciBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgKiBhcyB0b29sIGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9TTVRQX1BPUlQsIElNUExJQ0lUX1RMU19TTVRQX1BPUlQsIEVNQUlMX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlbmRlclBvbGljeSwgU210cENvbmZpZywgRW1haWxQbHVnaW5Db25maWcsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IG5vcm1hbGl6ZU1hcmtkb3duIH0gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgeyBFbWFpbFBsdWdpbiwgZW1haWwgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxUb29sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsRXhlY3V0b3IsIEVtYWlsUnVudGltZSB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
@@ -1,47 +1,10 @@
1
1
  /**
2
- * Optional brand styling for outbound email. {@link EmailBrand} is the
3
- * small, email-safe slice of a brand a message actually needs - an accent
4
- * color, a font stack, a display name, and an optional logo image - and
5
- * {@link emailBrandFromContext} derives it from the portable `BrandContext`
6
- * shared across the UI and libraries.
2
+ * Email brand compatibility exports.
7
3
  *
8
- * Email can't use the `[data-brand]` CSS bridge the browser UI uses (mail
9
- * clients strip `<style>` blocks and ignore `var()`), so branding is applied
10
- * by inlining these values at render time. A logo is only emitted when it's
11
- * a fetchable `http(s):` or `data:` URL - a package-export path (the default
12
- * asset form) can't resolve in an inbox, so it's dropped rather than shown
13
- * as a broken image.
4
+ * The universal brand contract and defaults live with the shared React Email
5
+ * template so Node delivery and browser previews cannot drift.
14
6
  *
15
7
  * @module
16
8
  */
17
- import { type BrandContext } from "@dbx-tools/shared-core";
18
- /** Email-safe brand values inlined into the message layout at render time. */
19
- export interface EmailBrand {
20
- /** Header-band background and link color. */
21
- accent: string;
22
- /** Text and logo color rendered on the accent band. Defaults to white. */
23
- onAccent?: string;
24
- /** Body font stack. */
25
- fontFamily: string;
26
- /** Product/display name, used as the header text and the logo `alt`. */
27
- name?: string;
28
- /**
29
- * Logo image rendered in the header band. Only an `http(s):` or `data:`
30
- * URL renders; other values (e.g. a package-export path) are ignored,
31
- * since they can't load in a mail client.
32
- */
33
- logoUrl?: string;
34
- }
35
- /**
36
- * Derive the email-safe {@link EmailBrand} from a full brand context: the
37
- * primary color as the accent, the sans font stack, the display name, and
38
- * the dark-surface logo (the header band is dark) when it's a renderable URL.
39
- */
40
- export declare function emailBrandFromContext(context: BrandContext): EmailBrand;
41
- /**
42
- * The dbx-tools brand as an {@link EmailBrand}, ready to pass to the email
43
- * plugin (`email({ brand: defaultEmailBrand })`). Convenience so a consumer
44
- * needs only `@dbx-tools/email`, not the shared brand context, for the
45
- * common case of the default brand.
46
- */
47
- export declare const defaultEmailBrand: EmailBrand;
9
+ export { defaultEmailBrand, emailBrandFromContext, resolveEmailBrand, } from "@dbx-tools/shared-email-template";
10
+ export type { EmailBrand, ResolvedEmailBrand } from "@dbx-tools/shared-email-template";
package/lib/src/brand.js CHANGED
@@ -1,44 +1,10 @@
1
1
  /**
2
- * Optional brand styling for outbound email. {@link EmailBrand} is the
3
- * small, email-safe slice of a brand a message actually needs - an accent
4
- * color, a font stack, a display name, and an optional logo image - and
5
- * {@link emailBrandFromContext} derives it from the portable `BrandContext`
6
- * shared across the UI and libraries.
2
+ * Email brand compatibility exports.
7
3
  *
8
- * Email can't use the `[data-brand]` CSS bridge the browser UI uses (mail
9
- * clients strip `<style>` blocks and ignore `var()`), so branding is applied
10
- * by inlining these values at render time. A logo is only emitted when it's
11
- * a fetchable `http(s):` or `data:` URL - a package-export path (the default
12
- * asset form) can't resolve in an inbox, so it's dropped rather than shown
13
- * as a broken image.
4
+ * The universal brand contract and defaults live with the shared React Email
5
+ * template so Node delivery and browser previews cannot drift.
14
6
  *
15
7
  * @module
16
8
  */
17
- import { brand } from "@dbx-tools/shared-core";
18
- /** Whether `value` is an image reference a mail client can actually load. */
19
- function isRenderableImageUrl(value) {
20
- return typeof value === "string" && /^(?:https?:|data:)/i.test(value);
21
- }
22
- /**
23
- * Derive the email-safe {@link EmailBrand} from a full brand context: the
24
- * primary color as the accent, the sans font stack, the display name, and
25
- * the dark-surface logo (the header band is dark) when it's a renderable URL.
26
- */
27
- export function emailBrandFromContext(context) {
28
- const logo = context.assets.logo.dark ?? context.assets.logo.light;
29
- return {
30
- accent: context.colors.primary,
31
- onAccent: "#ffffff",
32
- fontFamily: context.typography.sans,
33
- name: context.name,
34
- ...(isRenderableImageUrl(logo) ? { logoUrl: logo } : {}),
35
- };
36
- }
37
- /**
38
- * The dbx-tools brand as an {@link EmailBrand}, ready to pass to the email
39
- * plugin (`email({ brand: defaultEmailBrand })`). Convenience so a consumer
40
- * needs only `@dbx-tools/email`, not the shared brand context, for the
41
- * common case of the default brand.
42
- */
43
- export const defaultEmailBrand = emailBrandFromContext(brand.defaultBrandContext);
44
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJhbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnJhbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsT0FBTyxFQUFFLEtBQUssRUFBcUIsTUFBTSx3QkFBd0IsQ0FBQztBQW9CbEUsNkVBQTZFO0FBQzdFLFNBQVMsb0JBQW9CLENBQUMsS0FBeUI7SUFDckQsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUkscUJBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQixDQUFDLE9BQXFCO0lBQ3pELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDbkUsT0FBTztRQUNMLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU87UUFDOUIsUUFBUSxFQUFFLFNBQVM7UUFDbkIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSTtRQUNuQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsR0FBRyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQ3pELENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBZSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3B0aW9uYWwgYnJhbmQgc3R5bGluZyBmb3Igb3V0Ym91bmQgZW1haWwuIHtAbGluayBFbWFpbEJyYW5kfSBpcyB0aGVcbiAqIHNtYWxsLCBlbWFpbC1zYWZlIHNsaWNlIG9mIGEgYnJhbmQgYSBtZXNzYWdlIGFjdHVhbGx5IG5lZWRzIC0gYW4gYWNjZW50XG4gKiBjb2xvciwgYSBmb250IHN0YWNrLCBhIGRpc3BsYXkgbmFtZSwgYW5kIGFuIG9wdGlvbmFsIGxvZ28gaW1hZ2UgLSBhbmRcbiAqIHtAbGluayBlbWFpbEJyYW5kRnJvbUNvbnRleHR9IGRlcml2ZXMgaXQgZnJvbSB0aGUgcG9ydGFibGUgYEJyYW5kQ29udGV4dGBcbiAqIHNoYXJlZCBhY3Jvc3MgdGhlIFVJIGFuZCBsaWJyYXJpZXMuXG4gKlxuICogRW1haWwgY2FuJ3QgdXNlIHRoZSBgW2RhdGEtYnJhbmRdYCBDU1MgYnJpZGdlIHRoZSBicm93c2VyIFVJIHVzZXMgKG1haWxcbiAqIGNsaWVudHMgc3RyaXAgYDxzdHlsZT5gIGJsb2NrcyBhbmQgaWdub3JlIGB2YXIoKWApLCBzbyBicmFuZGluZyBpcyBhcHBsaWVkXG4gKiBieSBpbmxpbmluZyB0aGVzZSB2YWx1ZXMgYXQgcmVuZGVyIHRpbWUuIEEgbG9nbyBpcyBvbmx5IGVtaXR0ZWQgd2hlbiBpdCdzXG4gKiBhIGZldGNoYWJsZSBgaHR0cChzKTpgIG9yIGBkYXRhOmAgVVJMIC0gYSBwYWNrYWdlLWV4cG9ydCBwYXRoICh0aGUgZGVmYXVsdFxuICogYXNzZXQgZm9ybSkgY2FuJ3QgcmVzb2x2ZSBpbiBhbiBpbmJveCwgc28gaXQncyBkcm9wcGVkIHJhdGhlciB0aGFuIHNob3duXG4gKiBhcyBhIGJyb2tlbiBpbWFnZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGJyYW5kLCB0eXBlIEJyYW5kQ29udGV4dCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbi8qKiBFbWFpbC1zYWZlIGJyYW5kIHZhbHVlcyBpbmxpbmVkIGludG8gdGhlIG1lc3NhZ2UgbGF5b3V0IGF0IHJlbmRlciB0aW1lLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWFpbEJyYW5kIHtcbiAgLyoqIEhlYWRlci1iYW5kIGJhY2tncm91bmQgYW5kIGxpbmsgY29sb3IuICovXG4gIGFjY2VudDogc3RyaW5nO1xuICAvKiogVGV4dCBhbmQgbG9nbyBjb2xvciByZW5kZXJlZCBvbiB0aGUgYWNjZW50IGJhbmQuIERlZmF1bHRzIHRvIHdoaXRlLiAqL1xuICBvbkFjY2VudD86IHN0cmluZztcbiAgLyoqIEJvZHkgZm9udCBzdGFjay4gKi9cbiAgZm9udEZhbWlseTogc3RyaW5nO1xuICAvKiogUHJvZHVjdC9kaXNwbGF5IG5hbWUsIHVzZWQgYXMgdGhlIGhlYWRlciB0ZXh0IGFuZCB0aGUgbG9nbyBgYWx0YC4gKi9cbiAgbmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIExvZ28gaW1hZ2UgcmVuZGVyZWQgaW4gdGhlIGhlYWRlciBiYW5kLiBPbmx5IGFuIGBodHRwKHMpOmAgb3IgYGRhdGE6YFxuICAgKiBVUkwgcmVuZGVyczsgb3RoZXIgdmFsdWVzIChlLmcuIGEgcGFja2FnZS1leHBvcnQgcGF0aCkgYXJlIGlnbm9yZWQsXG4gICAqIHNpbmNlIHRoZXkgY2FuJ3QgbG9hZCBpbiBhIG1haWwgY2xpZW50LlxuICAgKi9cbiAgbG9nb1VybD86IHN0cmluZztcbn1cblxuLyoqIFdoZXRoZXIgYHZhbHVlYCBpcyBhbiBpbWFnZSByZWZlcmVuY2UgYSBtYWlsIGNsaWVudCBjYW4gYWN0dWFsbHkgbG9hZC4gKi9cbmZ1bmN0aW9uIGlzUmVuZGVyYWJsZUltYWdlVXJsKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB2YWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIC9eKD86aHR0cHM/OnxkYXRhOikvaS50ZXN0KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBEZXJpdmUgdGhlIGVtYWlsLXNhZmUge0BsaW5rIEVtYWlsQnJhbmR9IGZyb20gYSBmdWxsIGJyYW5kIGNvbnRleHQ6IHRoZVxuICogcHJpbWFyeSBjb2xvciBhcyB0aGUgYWNjZW50LCB0aGUgc2FucyBmb250IHN0YWNrLCB0aGUgZGlzcGxheSBuYW1lLCBhbmRcbiAqIHRoZSBkYXJrLXN1cmZhY2UgbG9nbyAodGhlIGhlYWRlciBiYW5kIGlzIGRhcmspIHdoZW4gaXQncyBhIHJlbmRlcmFibGUgVVJMLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1haWxCcmFuZEZyb21Db250ZXh0KGNvbnRleHQ6IEJyYW5kQ29udGV4dCk6IEVtYWlsQnJhbmQge1xuICBjb25zdCBsb2dvID0gY29udGV4dC5hc3NldHMubG9nby5kYXJrID8/IGNvbnRleHQuYXNzZXRzLmxvZ28ubGlnaHQ7XG4gIHJldHVybiB7XG4gICAgYWNjZW50OiBjb250ZXh0LmNvbG9ycy5wcmltYXJ5LFxuICAgIG9uQWNjZW50OiBcIiNmZmZmZmZcIixcbiAgICBmb250RmFtaWx5OiBjb250ZXh0LnR5cG9ncmFwaHkuc2FucyxcbiAgICBuYW1lOiBjb250ZXh0Lm5hbWUsXG4gICAgLi4uKGlzUmVuZGVyYWJsZUltYWdlVXJsKGxvZ28pID8geyBsb2dvVXJsOiBsb2dvIH0gOiB7fSksXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGRieC10b29scyBicmFuZCBhcyBhbiB7QGxpbmsgRW1haWxCcmFuZH0sIHJlYWR5IHRvIHBhc3MgdG8gdGhlIGVtYWlsXG4gKiBwbHVnaW4gKGBlbWFpbCh7IGJyYW5kOiBkZWZhdWx0RW1haWxCcmFuZCB9KWApLiBDb252ZW5pZW5jZSBzbyBhIGNvbnN1bWVyXG4gKiBuZWVkcyBvbmx5IGBAZGJ4LXRvb2xzL2VtYWlsYCwgbm90IHRoZSBzaGFyZWQgYnJhbmQgY29udGV4dCwgZm9yIHRoZVxuICogY29tbW9uIGNhc2Ugb2YgdGhlIGRlZmF1bHQgYnJhbmQuXG4gKi9cbmV4cG9ydCBjb25zdCBkZWZhdWx0RW1haWxCcmFuZDogRW1haWxCcmFuZCA9IGVtYWlsQnJhbmRGcm9tQ29udGV4dChicmFuZC5kZWZhdWx0QnJhbmRDb250ZXh0KTtcbiJdfQ==
9
+ export { defaultEmailBrand, emailBrandFromContext, resolveEmailBrand, } from "@dbx-tools/shared-email-template";
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJhbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnJhbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFDTCxpQkFBaUIsRUFDakIscUJBQXFCLEVBQ3JCLGlCQUFpQixHQUNsQixNQUFNLGtDQUFrQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFbWFpbCBicmFuZCBjb21wYXRpYmlsaXR5IGV4cG9ydHMuXG4gKlxuICogVGhlIHVuaXZlcnNhbCBicmFuZCBjb250cmFjdCBhbmQgZGVmYXVsdHMgbGl2ZSB3aXRoIHRoZSBzaGFyZWQgUmVhY3QgRW1haWxcbiAqIHRlbXBsYXRlIHNvIE5vZGUgZGVsaXZlcnkgYW5kIGJyb3dzZXIgcHJldmlld3MgY2Fubm90IGRyaWZ0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuZXhwb3J0IHtcbiAgZGVmYXVsdEVtYWlsQnJhbmQsXG4gIGVtYWlsQnJhbmRGcm9tQ29udGV4dCxcbiAgcmVzb2x2ZUVtYWlsQnJhbmQsXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbC10ZW1wbGF0ZVwiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEJyYW5kLCBSZXNvbHZlZEVtYWlsQnJhbmQgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtZW1haWwtdGVtcGxhdGVcIjtcbiJdfQ==
@@ -1,6 +1,6 @@
1
1
  import { type BasePluginConfig } from "@databricks/appkit";
2
2
  import type { JSONSchema7 } from "json-schema";
3
- import type { EmailBrand } from "./brand.ts";
3
+ import { type EmailBrand } from "./brand.ts";
4
4
  /** SMTP submission port used when none is configured. */
5
5
  export declare const DEFAULT_SMTP_PORT = 587;
6
6
  /** SMTP port that implies a TLS-on-connect socket rather than STARTTLS. */
@@ -75,10 +75,9 @@ export interface EmailPluginConfig extends BasePluginConfig {
75
75
  */
76
76
  senderPolicy?: SenderPolicy;
77
77
  /**
78
- * Optional brand styling (accent, font, header logo) applied to the
79
- * rendered HTML of every message. Omit for the neutral default layout.
80
- * Pass {@link emailBrandFromContext} to derive it from a shared
81
- * `BrandContext`.
78
+ * Optional brand styling applied to every rendered message. Omit to use the
79
+ * repository's dbx-tools brand. Pass {@link emailBrandFromContext} to derive
80
+ * a custom value from a shared `BrandContext`.
82
81
  */
83
82
  brand?: EmailBrand;
84
83
  }
@@ -97,8 +96,8 @@ interface ResolvedSender {
97
96
  allowedSenders: string[];
98
97
  /** The restriction mode the allow-list was resolved under. */
99
98
  senderPolicy: SenderPolicy;
100
- /** Brand styling applied to rendered HTML; absent for the default layout. */
101
- brand?: EmailBrand;
99
+ /** Brand styling applied to rendered HTML. */
100
+ brand: EmailBrand;
102
101
  }
103
102
  /** Resolved config for real SMTP delivery. */
104
103
  export interface ResolvedSmtpConfig extends ResolvedSender {
package/lib/src/config.js CHANGED
@@ -25,7 +25,8 @@
25
25
  */
26
26
  import { resolve } from "node:path";
27
27
  import { ConfigurationError, ValidationError } from "@databricks/appkit";
28
- import { object } from "@dbx-tools/shared-core";
28
+ import { env, object } from "@dbx-tools/shared-core";
29
+ import { defaultEmailBrand } from "./brand.js";
29
30
  import { parseAllowedSenders } from "./sender.js";
30
31
  /** SMTP submission port used when none is configured. */
31
32
  export const DEFAULT_SMTP_PORT = 587;
@@ -79,7 +80,7 @@ export const EMAIL_CONFIG_SCHEMA = {
79
80
  },
80
81
  brand: {
81
82
  type: "object",
82
- description: "Brand styling inlined into every rendered message. Omit for the neutral default layout.",
83
+ description: "Brand styling applied to every React Email message. Omit to use the dbx-tools brand.",
83
84
  properties: {
84
85
  accent: {
85
86
  type: "string",
@@ -101,6 +102,13 @@ export const EMAIL_CONFIG_SCHEMA = {
101
102
  type: "string",
102
103
  description: "Logo image for the header band. Only an http(s): or data: URL renders; other values are dropped because a mail client cannot load them.",
103
104
  },
105
+ background: { type: "string", description: "Inbox canvas color." },
106
+ surface: { type: "string", description: "Message-card color." },
107
+ foreground: { type: "string", description: "Primary text color." },
108
+ muted: { type: "string", description: "Secondary text color." },
109
+ border: { type: "string", description: "Border and divider color." },
110
+ tagline: { type: "string", description: "Footer product line." },
111
+ website: { type: "string", description: "Optional footer website URL." },
104
112
  },
105
113
  required: ["accent", "fontFamily"],
106
114
  },
@@ -108,13 +116,11 @@ export const EMAIL_CONFIG_SCHEMA = {
108
116
  };
109
117
  /** Parse the `SMTP_SECURE` env / config flag, defaulting by port. */
110
118
  function resolveSecure(flag, port) {
111
- if (typeof flag === "boolean")
112
- return flag;
113
- return object.toBoolean(process.env.SMTP_SECURE) ?? port === IMPLICIT_TLS_SMTP_PORT;
119
+ return env.boolean(flag, "SMTP_SECURE") ?? port === IMPLICIT_TLS_SMTP_PORT;
114
120
  }
115
121
  /** Parse the `EMAIL_SENDER_POLICY` env / config value, defaulting to deny-by-default. */
116
122
  function resolveSenderPolicy(policy) {
117
- const raw = policy ?? process.env.EMAIL_SENDER_POLICY?.trim().toLowerCase();
123
+ const raw = policy ?? env.text("EMAIL_SENDER_POLICY")?.toLowerCase();
118
124
  if (raw === "unrestricted")
119
125
  return "unrestricted";
120
126
  if (raw === undefined || raw === "" || raw === "allowlist")
@@ -138,7 +144,7 @@ function impliedSenderPatterns(domain, from) {
138
144
  }
139
145
  /** Whether `EMAIL_OUTBOX_MODE` explicitly opts into the file/outbox fallback. */
140
146
  function isOutboxModeEnabled() {
141
- return object.toBoolean(process.env.EMAIL_OUTBOX_MODE) ?? false;
147
+ return env.boolean(undefined, "EMAIL_OUTBOX_MODE") ?? false;
142
148
  }
143
149
  const SMTP_REQUIRED_FIELDS = ["SMTP_HOST", "SMTP_USER", "SMTP_PASSWORD"];
144
150
  /** List env keys for SMTP fields that are unset in the resolved credential set. */
@@ -166,22 +172,22 @@ function missingSmtpFields(host, user, pass) {
166
172
  */
167
173
  export function resolveEmailConfig(config = {}) {
168
174
  const smtp = config.smtp ?? {};
169
- const host = smtp.host ?? process.env.SMTP_HOST;
170
- const user = smtp.user ?? process.env.SMTP_USER;
171
- const pass = smtp.password ?? process.env.SMTP_PASSWORD;
172
- const domain = config.domain ?? process.env.EMAIL_DOMAIN;
173
- const from = config.from ?? process.env.EMAIL_FROM;
175
+ const host = env.string(smtp.host, "SMTP_HOST") ?? undefined;
176
+ const user = env.string(smtp.user, "SMTP_USER") ?? undefined;
177
+ const pass = env.string(smtp.password, "SMTP_PASSWORD") ?? undefined;
178
+ const domain = env.string(config.domain, "EMAIL_DOMAIN") ?? undefined;
179
+ const from = env.string(config.from, "EMAIL_FROM") ?? undefined;
174
180
  const senderPolicy = resolveSenderPolicy(config.senderPolicy);
175
- const configuredSenders = parseAllowedSenders(config.allowedSenders ?? process.env.EMAIL_ALLOWED_SENDERS);
181
+ const configuredSenders = parseAllowedSenders(config.allowedSenders ?? env.text("EMAIL_ALLOWED_SENDERS") ?? undefined);
176
182
  const allowedSenders = configuredSenders.length > 0 || senderPolicy === "unrestricted"
177
183
  ? configuredSenders
178
184
  : impliedSenderPatterns(domain, from);
179
185
  const sender = {
180
- ...(domain ? { domain } : {}),
181
- ...(from ? { from } : {}),
186
+ ...object.optional("domain", domain),
187
+ ...object.optional("from", from),
182
188
  allowedSenders,
183
189
  senderPolicy,
184
- ...(config.brand ? { brand: config.brand } : {}),
190
+ brand: config.brand ?? defaultEmailBrand,
185
191
  };
186
192
  const hasAllSmtp = Boolean(host && user && pass);
187
193
  const hasAnySmtp = Boolean(host || user || pass);
@@ -192,8 +198,7 @@ export function resolveEmailConfig(config = {}) {
192
198
  if (!domain && !from) {
193
199
  throw ConfigurationError.resourceNotFound("Email sender source", "Set EMAIL_DOMAIN to derive <user-local-part>@<domain>, or EMAIL_FROM for a fixed address.");
194
200
  }
195
- const portRaw = smtp.port ?? Number(process.env.SMTP_PORT);
196
- const port = Number.isFinite(portRaw) && portRaw ? Number(portRaw) : DEFAULT_SMTP_PORT;
201
+ const port = env.positiveInt(smtp.port, "SMTP_PORT", DEFAULT_SMTP_PORT);
197
202
  return {
198
203
  mode: "smtp",
199
204
  host: host,
@@ -206,7 +211,7 @@ export function resolveEmailConfig(config = {}) {
206
211
  if (!isOutboxModeEnabled()) {
207
212
  throw ConfigurationError.invalidConnection("SMTP", `Set ${SMTP_REQUIRED_FIELDS.join(", ")}, or EMAIL_OUTBOX_MODE=1 to write messages to a local outbox instead.`);
208
213
  }
209
- const outDir = resolve(config.outDir ?? process.env.EMAIL_OUTBOX_DIR ?? resolve(process.cwd(), "tmp"));
214
+ const outDir = resolve(env.string(config.outDir, "EMAIL_OUTBOX_DIR") ?? resolve(process.cwd(), "tmp"));
210
215
  return { mode: "file", outDir, ...sender };
211
216
  }
212
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQ2hHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUdoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbEQseURBQXlEO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUVyQywyRUFBMkU7QUFDM0UsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBd0gxQywrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQWdCO0lBQzlDLElBQUksRUFBRSxRQUFRO0lBQ2QsVUFBVSxFQUFFO1FBQ1YsSUFBSSxFQUFFO1lBQ0osSUFBSSxFQUFFLFFBQVE7WUFDZCxXQUFXLEVBQUUsMERBQTBEO1lBQ3ZFLFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxtQ0FBbUMsRUFBRTtnQkFDMUUsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSw2Q0FBNkMsaUJBQWlCLEdBQUc7aUJBQy9FO2dCQUNELE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsU0FBUztvQkFDZixXQUFXLEVBQUUsNkRBQTZELHNCQUFzQixHQUFHO2lCQUNwRztnQkFDRCxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxpQ0FBaUMsRUFBRTtnQkFDeEUsUUFBUSxFQUFFO29CQUNSLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSwrQ0FBK0M7aUJBQzdEO2FBQ0Y7U0FDRjtRQUNELE1BQU0sRUFBRTtZQUNOLElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUNULGlHQUFpRztTQUNwRztRQUNELElBQUksRUFBRTtZQUNKLElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUFFLDZFQUE2RTtTQUMzRjtRQUNELE1BQU0sRUFBRTtZQUNOLElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUNULG1IQUFtSDtTQUN0SDtRQUNELGNBQWMsRUFBRTtZQUNkLElBQUksRUFBRSxPQUFPO1lBQ2IsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUN6QixXQUFXLEVBQ1QscVBBQXFQO1NBQ3hQO1FBQ0QsWUFBWSxFQUFFO1lBQ1osSUFBSSxFQUFFLFFBQVE7WUFDZCxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsY0FBYyxDQUFDO1lBQ25DLFdBQVcsRUFDVCx3TEFBd0w7U0FDM0w7UUFDRCxLQUFLLEVBQUU7WUFDTCxJQUFJLEVBQUUsUUFBUTtZQUNkLFdBQVcsRUFDVCx5RkFBeUY7WUFDM0YsVUFBVSxFQUFFO2dCQUNWLE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsOERBQThEO2lCQUM1RTtnQkFDRCxRQUFRLEVBQUU7b0JBQ1IsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHFFQUFxRTtpQkFDbkY7Z0JBQ0QsVUFBVSxFQUFFO29CQUNWLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSx1RUFBdUU7aUJBQ3JGO2dCQUNELElBQUksRUFBRTtvQkFDSixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsdUVBQXVFO2lCQUNyRjtnQkFDRCxPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUNULHlJQUF5STtpQkFDNUk7YUFDRjtZQUNELFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUM7U0FDbkM7S0FDRjtDQUNGLENBQUM7QUFFRixxRUFBcUU7QUFDckUsU0FBUyxhQUFhLENBQUMsSUFBeUIsRUFBRSxJQUFZO0lBQzVELElBQUksT0FBTyxJQUFJLEtBQUssU0FBUztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzNDLE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksS0FBSyxzQkFBc0IsQ0FBQztBQUN0RixDQUFDO0FBRUQseUZBQXlGO0FBQ3pGLFNBQVMsbUJBQW1CLENBQUMsTUFBZ0M7SUFDM0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDNUUsSUFBSSxHQUFHLEtBQUssY0FBYztRQUFFLE9BQU8sY0FBYyxDQUFDO0lBQ2xELElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLEdBQUcsS0FBSyxXQUFXO1FBQUUsT0FBTyxXQUFXLENBQUM7SUFDL0UsTUFBTSxlQUFlLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxHQUFHLEVBQUUsK0JBQStCLENBQUMsQ0FBQztBQUMzRixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyxxQkFBcUIsQ0FBQyxNQUEwQixFQUFFLElBQXdCO0lBQ2pGLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUM5QixJQUFJLElBQUk7UUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELElBQUksTUFBTTtRQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUM7QUFFRCxpRkFBaUY7QUFDakYsU0FBUyxtQkFBbUI7SUFDMUIsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsSUFBSSxLQUFLLENBQUM7QUFDbEUsQ0FBQztBQUVELE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBVSxDQUFDO0FBRWxGLG1GQUFtRjtBQUNuRixTQUFTLGlCQUFpQixDQUN4QixJQUF3QixFQUN4QixJQUF3QixFQUN4QixJQUF3QjtJQUV4QixNQUFNLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFVLENBQUM7SUFDM0MsT0FBTyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsU0FBNEIsRUFBRTtJQUMvRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO0lBQ2hELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7SUFDaEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztJQUN4RCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO0lBQ3pELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7SUFDbkQsTUFBTSxZQUFZLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzlELE1BQU0saUJBQWlCLEdBQUcsbUJBQW1CLENBQzNDLE1BQU0sQ0FBQyxjQUFjLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FDM0QsQ0FBQztJQUNGLE1BQU0sY0FBYyxHQUNsQixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFlBQVksS0FBSyxjQUFjO1FBQzdELENBQUMsQ0FBQyxpQkFBaUI7UUFDbkIsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxQyxNQUFNLE1BQU0sR0FBbUI7UUFDN0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzdCLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN6QixjQUFjO1FBQ2QsWUFBWTtRQUNaLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNqRCxDQUFDO0lBRUYsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLENBQUM7SUFDakQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLENBQUM7SUFFakQsSUFBSSxVQUFVLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM5QixNQUFNLGVBQWUsQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3JCLE1BQU0sa0JBQWtCLENBQUMsZ0JBQWdCLENBQ3ZDLHFCQUFxQixFQUNyQiwyRkFBMkYsQ0FDNUYsQ0FBQztRQUNKLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDO1FBQ3ZGLE9BQU87WUFDTCxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRSxJQUFLO1lBQ1gsSUFBSTtZQUNKLE1BQU0sRUFBRSxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7WUFDeEMsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUssRUFBRSxJQUFJLEVBQUUsSUFBSyxFQUFFO1lBQ2xDLEdBQUcsTUFBTTtTQUNWLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEVBQUUsQ0FBQztRQUMzQixNQUFNLGtCQUFrQixDQUFDLGlCQUFpQixDQUN4QyxNQUFNLEVBQ04sT0FBTyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHVFQUF1RSxDQUM5RyxDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FDcEIsTUFBTSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQy9FLENBQUM7SUFDRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTTVRQIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBlbWFpbCBwbHVnaW46IHRoZSB0eXBlZFxuICoge0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnfSAodGhlIHBsdWdpbidzIHNsaWNlIG9mIEFwcEtpdCBjb25maWcpLCB0aGVcbiAqIEpTT04gU2NoZW1hIHRoZSBtYW5pZmVzdCBwdWJsaXNoZXMgZm9yIGl0LCBhbmQge0BsaW5rIHJlc29sdmVFbWFpbENvbmZpZ31cbiAqIHdoaWNoIGxheWVycyB0aGF0IGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzIGludG8gdGhlIGNvbmNyZXRlXG4gKiB7QGxpbmsgUmVzb2x2ZWRFbWFpbENvbmZpZ30gdGhlIHJ1bnRpbWUgbmVlZHMuXG4gKlxuICogVHdvIG1vZGVzIGZhbGwgb3V0IG9mIHRoZSByZXNvbHV0aW9uLiBXaGVuIFNNVFAgY3JlZGVudGlhbHMgKGhvc3QgK1xuICogdXNlciArIHBhc3N3b3JkKSBhcmUgYWxsIHByZXNlbnQgaXQgcmVzb2x2ZXMgdG8gYG1vZGU6IFwic210cFwiYCBhbmRcbiAqIG1haWwgaXMgc2VudCBmb3IgcmVhbC4gV2hlbiB0aGV5IGFyZSBhYnNlbnQgYW5kIGBFTUFJTF9PVVRCT1hfTU9ERWBcbiAqIGlzIGV4cGxpY2l0bHkgZW5hYmxlZCBpdCByZXNvbHZlcyB0byBgbW9kZTogXCJmaWxlXCJgIChhbiBcIm91dGJveFwiKVxuICogYW5kIGVhY2ggbWVzc2FnZSBpcyB3cml0dGVuIHRvIGRpc2sgYXMgSFRNTCBpbnN0ZWFkIG9mIHNlbnQuIEFueVxuICogcGFydGlhbCBTTVRQIGNvbmZpZ3VyYXRpb24gb3IgYSBzZW5kIGF0dGVtcHQgd2l0aCBubyBjcmVkZW50aWFscyBhbmRcbiAqIG5vIG91dGJveCBvcHQtaW4gdGhyb3dzLlxuICpcbiAqIFByZWNlZGVuY2UgcGVyIGZpZWxkOiBleHBsaWNpdCBwbHVnaW4gY29uZmlnIHdpbnMsIHRoZW4gdGhlIG1hdGNoaW5nXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZS4gRW52IG5hbWVzIGFyZSB1bnByZWZpeGVkIGJlY2F1c2UgdGhlIGFwcCB0YWxrc1xuICogdG8gYSBzaW5nbGUgU01UUCBzZXJ2ZXIgKGUuZy4gU01UUDJHTyk6IGBTTVRQX0hPU1RgLCBgU01UUF9QT1JUYCxcbiAqIGBTTVRQX1NFQ1VSRWAsIGBTTVRQX1VTRVJgLCBgU01UUF9QQVNTV09SRGAsIHBsdXMgYEVNQUlMX0RPTUFJTmAgZm9yXG4gKiB0aGUgZGVyaXZlZCBzZW5kZXIncyBkb21haW4sIGBFTUFJTF9GUk9NYCBmb3IgYW4gZXhwbGljaXQgb3ZlcnJpZGUsXG4gKiBgRU1BSUxfU0VOREVSX1BPTElDWWAgZm9yIHRoZSBzZW5kZXIgcmVzdHJpY3Rpb24gbW9kZSwgYW5kXG4gKiBgRU1BSUxfT1VUQk9YX0RJUmAgZm9yIHRoZSBvdXRib3ggZGlyZWN0b3J5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25FcnJvciwgVmFsaWRhdGlvbkVycm9yLCB0eXBlIEJhc2VQbHVnaW5Db25maWcgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBvYmplY3QgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBKU09OU2NoZW1hNyB9IGZyb20gXCJqc29uLXNjaGVtYVwiO1xuaW1wb3J0IHR5cGUgeyBFbWFpbEJyYW5kIH0gZnJvbSBcIi4vYnJhbmQudHNcIjtcbmltcG9ydCB7IHBhcnNlQWxsb3dlZFNlbmRlcnMgfSBmcm9tIFwiLi9zZW5kZXIudHNcIjtcblxuLyoqIFNNVFAgc3VibWlzc2lvbiBwb3J0IHVzZWQgd2hlbiBub25lIGlzIGNvbmZpZ3VyZWQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TTVRQX1BPUlQgPSA1ODc7XG5cbi8qKiBTTVRQIHBvcnQgdGhhdCBpbXBsaWVzIGEgVExTLW9uLWNvbm5lY3Qgc29ja2V0IHJhdGhlciB0aGFuIFNUQVJUVExTLiAqL1xuZXhwb3J0IGNvbnN0IElNUExJQ0lUX1RMU19TTVRQX1BPUlQgPSA0NjU7XG5cbi8qKlxuICogSG93IHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcyBpcyByZXN0cmljdGVkLlxuICpcbiAqIGBcImFsbG93bGlzdFwiYCBpcyB0aGUgZGVmYXVsdCBhbmQgdGhlIGRlbnktYnktZGVmYXVsdCBwb3N0dXJlOiBhIHNlbmQgaXNcbiAqIHBlcm1pdHRlZCBvbmx5IGZyb20gYW4gYWRkcmVzcyB0aGUgY29uZmlndXJhdGlvbiBuYW1lcywgZWl0aGVyIHRocm91Z2hcbiAqIHtAbGluayBFbWFpbFBsdWdpbkNvbmZpZy5hbGxvd2VkU2VuZGVyc30gb3IsIHdoZW4gdGhhdCBpcyBlbXB0eSwgdGhyb3VnaFxuICogdGhlIGNvbmZpZ3VyZWQgc2VuZGVyIHNvdXJjZSAoe0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnLmZyb219IGFzIGFuIGV4YWN0XG4gKiBhZGRyZXNzLCB7QGxpbmsgRW1haWxQbHVnaW5Db25maWcuZG9tYWlufSBhcyBhIGAqQGRvbWFpbmAgd2lsZGNhcmQpLlxuICpcbiAqIGBcInVucmVzdHJpY3RlZFwiYCBpcyB0aGUgZXhwbGljaXQgb3B0LW91dDogYW55IGBGcm9tYCBhIGNhbGxlciBzdXBwbGllcyBpc1xuICogYWNjZXB0ZWQuIE9ubHkgcmVhY2ggZm9yIGl0IHdoZW4gYW4gdXBzdHJlYW0gc3lzdGVtIGFscmVhZHkgdmV0cyB0aGVcbiAqIHNlbmRlci5cbiAqL1xuZXhwb3J0IHR5cGUgU2VuZGVyUG9saWN5ID0gXCJhbGxvd2xpc3RcIiB8IFwidW5yZXN0cmljdGVkXCI7XG5cbi8qKiBTTVRQIGNvbm5lY3Rpb24gKyBjcmVkZW50aWFscy4gQWxsIGZpZWxkcyBmYWxsIGJhY2sgdG8gZW52IHdoZW4gdW5zZXQuICovXG5leHBvcnQgaW50ZXJmYWNlIFNtdHBDb25maWcge1xuICAvKiogU01UUCBzZXJ2ZXIgaG9zdG5hbWUgKGBTTVRQX0hPU1RgKS4gKi9cbiAgaG9zdD86IHN0cmluZztcbiAgLyoqIFNNVFAgc2VydmVyIHBvcnQgKGBTTVRQX1BPUlRgKS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfU01UUF9QT1JUfS4gKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFVzZSBhIFRMUy1vbi1jb25uZWN0IHNvY2tldCAoYFNNVFBfU0VDVVJFYCkuIERlZmF1bHRzIHRvXG4gICAqIGBwb3J0ID09PSBgIHtAbGluayBJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5cbiAgICovXG4gIHNlY3VyZT86IGJvb2xlYW47XG4gIC8qKiBTTVRQIGF1dGggdXNlcm5hbWUgKGBTTVRQX1VTRVJgKS4gKi9cbiAgdXNlcj86IHN0cmluZztcbiAgLyoqIFNNVFAgYXV0aCBwYXNzd29yZCAvIEFQSSBrZXkgKGBTTVRQX1BBU1NXT1JEYCkuICovXG4gIHBhc3N3b3JkPzogc3RyaW5nO1xufVxuXG4vKiogQXBwS2l0IGNvbmZpZyBhY2NlcHRlZCBieSB0aGUgZW1haWwgcGx1Z2luLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWFpbFBsdWdpbkNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICAvKiogU01UUCBjb25uZWN0aW9uICsgY3JlZGVudGlhbHMuIE9taXQgdG8gcnVuIGluIGZpbGUvb3V0Ym94IG1vZGUuICovXG4gIHNtdHA/OiBTbXRwQ29uZmlnO1xuICAvKipcbiAgICogRG9tYWluIHVzZWQgdG8gYnVpbGQgdGhlIHNlbmRlciBhZGRyZXNzIGZyb20gdGhlIG9uLWJlaGFsZi1vZiB1c2VyXG4gICAqIChgPGxvY2FsLXBhcnQ+QDxkb21haW4+YCkuIEZhbGxzIGJhY2sgdG8gYEVNQUlMX0RPTUFJTmAuIFJlcXVpcmVkIGluXG4gICAqIFNNVFAgbW9kZSB1bmxlc3Mge0BsaW5rIGZyb219IGlzIHNldDsgb3B0aW9uYWwgaW4gZmlsZSBtb2RlICh0aGVcbiAgICogb3V0Ym94IGZhbGxzIGJhY2sgdG8gdGhlIHVzZXIncyBvd24gZW1haWwgYWRkcmVzcykuXG4gICAqL1xuICBkb21haW4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBgRnJvbWAgYWRkcmVzcy4gV2hlbiBzZXQsIHRoZSBzZW5kZXIgaXMgdXNlZCB2ZXJiYXRpbSBhbmRcbiAgICogdGhlIHBlci11c2VyIGRlcml2YXRpb24gaXMgc2tpcHBlZC4gRmFsbHMgYmFjayB0byBgRU1BSUxfRlJPTWAuXG4gICAqL1xuICBmcm9tPzogc3RyaW5nO1xuICAvKipcbiAgICogRGlyZWN0b3J5IGZvciB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suIEZhbGxzIGJhY2sgdG9cbiAgICogYEVNQUlMX09VVEJPWF9ESVJgLCB0aGVuIGA8Y3dkPi90bXBgLiBPbmx5IHVzZWQgd2hlbiBTTVRQXG4gICAqIGNyZWRlbnRpYWxzIGFyZSBhYnNlbnQuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbGxvdy1saXN0IHJlc3RyaWN0aW5nIHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcy4gRWFjaCBlbnRyeSBpcyBhblxuICAgKiBleGFjdCBhZGRyZXNzIChgdXNlckBkb21haW4uY29tYCksIGEgZG9tYWluIHdpbGRjYXJkIChgKkBkb21haW4uY29tYFxuICAgKiBvciB0aGUgYmFyZSBgZG9tYWluLmNvbWAsIG1hdGNoaW5nIGFueSBsb2NhbCBwYXJ0IG9uIHRoYXQgZG9tYWluKSwgb3JcbiAgICogYCpgIChhbnkpLiBBIHJlc29sdmVkIC8gY2hvc2VuIHNlbmRlciB0aGF0IG1hdGNoZXMgbm8gZW50cnkgaXNcbiAgICogcmVqZWN0ZWQgYXQgc2VuZCB0aW1lLiBBY2NlcHRzIGEgYHN0cmluZ1tdYCBvciBhIHNpbmdsZSBjb21tYS0gL1xuICAgKiB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBzdHJpbmc7IGZhbGxzIGJhY2sgdG8gYEVNQUlMX0FMTE9XRURfU0VOREVSU2AuXG4gICAqIFdoZW4gZW1wdHksIHRoZSB7QGxpbmsgc2VuZGVyUG9saWN5fSBkZWNpZGVzIHdoYXQgaXMgcGVybWl0dGVkLlxuICAgKi9cbiAgYWxsb3dlZFNlbmRlcnM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEhvdyB0aGUgc2VuZGVyIGFkZHJlc3MgaXMgcmVzdHJpY3RlZCB3aGVuIHtAbGluayBhbGxvd2VkU2VuZGVyc30gaXNcbiAgICogZW1wdHkgKGBFTUFJTF9TRU5ERVJfUE9MSUNZYCkuIERlZmF1bHRzIHRvIGBcImFsbG93bGlzdFwiYCwgd2hpY2hcbiAgICogbmFycm93cyBzZW5kcyB0byB0aGUgY29uZmlndXJlZCBzZW5kZXIgc291cmNlLiBTZWVcbiAgICoge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gICAqL1xuICBzZW5kZXJQb2xpY3k/OiBTZW5kZXJQb2xpY3k7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBicmFuZCBzdHlsaW5nIChhY2NlbnQsIGZvbnQsIGhlYWRlciBsb2dvKSBhcHBsaWVkIHRvIHRoZVxuICAgKiByZW5kZXJlZCBIVE1MIG9mIGV2ZXJ5IG1lc3NhZ2UuIE9taXQgZm9yIHRoZSBuZXV0cmFsIGRlZmF1bHQgbGF5b3V0LlxuICAgKiBQYXNzIHtAbGluayBlbWFpbEJyYW5kRnJvbUNvbnRleHR9IHRvIGRlcml2ZSBpdCBmcm9tIGEgc2hhcmVkXG4gICAqIGBCcmFuZENvbnRleHRgLlxuICAgKi9cbiAgYnJhbmQ/OiBFbWFpbEJyYW5kO1xufVxuXG4vKiogQ29uZmlnIHNoYXJlZCBieSBib3RoIHJlc29sdmVkIG1vZGVzLiAqL1xuaW50ZXJmYWNlIFJlc29sdmVkU2VuZGVyIHtcbiAgLyoqIFNlbmRlciBkb21haW47IHByZXNlbnQgd2hlbmV2ZXIge0BsaW5rIGZyb219IGlzIGFic2VudC4gKi9cbiAgZG9tYWluPzogc3RyaW5nO1xuICAvKiogRXhwbGljaXQgc2VuZGVyIG92ZXJyaWRlOyBwcmVzZW50IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uICovXG4gIGZyb20/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFZmZlY3RpdmUgc2VuZGVyIGFsbG93LWxpc3Q6IHRoZSBjb25maWd1cmVkIHBhdHRlcm5zIHdoZW4gYW55IHdlcmVcbiAgICogZ2l2ZW4sIGVsc2UgdGhlIHBhdHRlcm5zIGltcGxpZWQgYnkgdGhlIHNlbmRlciBzb3VyY2UgdW5kZXIgYW5cbiAgICogYFwiYWxsb3dsaXN0XCJgIHBvbGljeS4gRW1wdHkgbWVhbnMgdW5lbmZvcmNlYWJsZSAoYW4gYFwidW5yZXN0cmljdGVkXCJgXG4gICAqIHBvbGljeSwgb3IgYW4gb3V0Ym94IHdpdGggbm8gc2VuZGVyIHNvdXJjZSB0byBuYXJyb3cgdG8pLlxuICAgKi9cbiAgYWxsb3dlZFNlbmRlcnM6IHN0cmluZ1tdO1xuICAvKiogVGhlIHJlc3RyaWN0aW9uIG1vZGUgdGhlIGFsbG93LWxpc3Qgd2FzIHJlc29sdmVkIHVuZGVyLiAqL1xuICBzZW5kZXJQb2xpY3k6IFNlbmRlclBvbGljeTtcbiAgLyoqIEJyYW5kIHN0eWxpbmcgYXBwbGllZCB0byByZW5kZXJlZCBIVE1MOyBhYnNlbnQgZm9yIHRoZSBkZWZhdWx0IGxheW91dC4gKi9cbiAgYnJhbmQ/OiBFbWFpbEJyYW5kO1xufVxuXG4vKiogUmVzb2x2ZWQgY29uZmlnIGZvciByZWFsIFNNVFAgZGVsaXZlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkU210cENvbmZpZyBleHRlbmRzIFJlc29sdmVkU2VuZGVyIHtcbiAgbW9kZTogXCJzbXRwXCI7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xuICBzZWN1cmU6IGJvb2xlYW47XG4gIGF1dGg6IHsgdXNlcjogc3RyaW5nOyBwYXNzOiBzdHJpbmcgfTtcbn1cblxuLyoqIFJlc29sdmVkIGNvbmZpZyBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIChubyBTTVRQIGNyZWRlbnRpYWxzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRGaWxlQ29uZmlnIGV4dGVuZHMgUmVzb2x2ZWRTZW5kZXIge1xuICBtb2RlOiBcImZpbGVcIjtcbiAgLyoqIEFic29sdXRlIGRpcmVjdG9yeSBtZXNzYWdlcyBhcmUgd3JpdHRlbiB1bmRlci4gKi9cbiAgb3V0RGlyOiBzdHJpbmc7XG59XG5cbi8qKiBDb25jcmV0ZSwgdmFsaWRhdGVkIGNvbmZpZyB0aGUgcnVudGltZSBkaXNwYXRjaGVzIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZEVtYWlsQ29uZmlnID0gUmVzb2x2ZWRTbXRwQ29uZmlnIHwgUmVzb2x2ZWRGaWxlQ29uZmlnO1xuXG4vKiogSlNPTiBTY2hlbWEgcHVibGlzaGVkIG9uIHRoZSBtYW5pZmVzdCdzIGBjb25maWcuc2NoZW1hYC4gKi9cbmV4cG9ydCBjb25zdCBFTUFJTF9DT05GSUdfU0NIRU1BOiBKU09OU2NoZW1hNyA9IHtcbiAgdHlwZTogXCJvYmplY3RcIixcbiAgcHJvcGVydGllczoge1xuICAgIHNtdHA6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJTTVRQIGNvbm5lY3Rpb24gYW5kIGNyZWRlbnRpYWxzIChlbnYgZmFsbGJhY2tzOiBTTVRQXyopLlwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBob3N0OiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgc2VydmVyIGhvc3RuYW1lIChTTVRQX0hPU1QpLlwiIH0sXG4gICAgICAgIHBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgU01UUCBzZXJ2ZXIgcG9ydCAoU01UUF9QT1JUKS4gRGVmYXVsdHMgdG8gJHtERUZBVUxUX1NNVFBfUE9SVH0uYCxcbiAgICAgICAgfSxcbiAgICAgICAgc2VjdXJlOiB7XG4gICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGBUTFMtb24tY29ubmVjdCBzb2NrZXQgKFNNVFBfU0VDVVJFKS4gRGVmYXVsdHMgdG8gcG9ydCA9PT0gJHtJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5gLFxuICAgICAgICB9LFxuICAgICAgICB1c2VyOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgYXV0aCB1c2VybmFtZSAoU01UUF9VU0VSKS5cIiB9LFxuICAgICAgICBwYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiU01UUCBhdXRoIHBhc3N3b3JkIC8gQVBJIGtleSAoU01UUF9QQVNTV09SRCkuXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgZG9tYWluOiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRG9tYWluIGZvciB0aGUgZGVyaXZlZCBzZW5kZXIgYWRkcmVzcyAoPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4pLiBGYWxscyBiYWNrIHRvIEVNQUlMX0RPTUFJTi5cIixcbiAgICB9LFxuICAgIGZyb206IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBsaWNpdCBGcm9tIGFkZHJlc3M7IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uIEZhbGxzIGJhY2sgdG8gRU1BSUxfRlJPTS5cIixcbiAgICB9LFxuICAgIG91dERpcjoge1xuICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkRpcmVjdG9yeSBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIHdoZW4gU01UUCBpcyB1bmNvbmZpZ3VyZWQuIEZhbGxzIGJhY2sgdG8gRU1BSUxfT1VUQk9YX0RJUiwgdGhlbiA8Y3dkPi90bXAuXCIsXG4gICAgfSxcbiAgICBhbGxvd2VkU2VuZGVyczoge1xuICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgaXRlbXM6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdy1saXN0IG9mIHBlcm1pdHRlZCBzZW5kZXIgKEZyb20pIHBhdHRlcm5zOiBleGFjdCBhZGRyZXNzZXMgKFwidXNlckBkb21haW4uY29tXCIpLCBkb21haW4gd2lsZGNhcmRzIChcIipAZG9tYWluLmNvbVwiKSwgb3IgXCIqXCIuIEFsc28gYWNjZXB0cyBhIGNvbW1hL3NwYWNlLXNlcGFyYXRlZCBzdHJpbmcuIEZhbGxzIGJhY2sgdG8gRU1BSUxfQUxMT1dFRF9TRU5ERVJTLiBXaGVuIGVtcHR5LCBzZW5kZXJQb2xpY3kgZGVjaWRlcy4nLFxuICAgIH0sXG4gICAgc2VuZGVyUG9saWN5OiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZW51bTogW1wiYWxsb3dsaXN0XCIsIFwidW5yZXN0cmljdGVkXCJdLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdIb3cgdGhlIHNlbmRlciBpcyByZXN0cmljdGVkIHdoZW4gYWxsb3dlZFNlbmRlcnMgaXMgZW1wdHkgKEVNQUlMX1NFTkRFUl9QT0xJQ1kpLiBcImFsbG93bGlzdFwiIChkZWZhdWx0KSBuYXJyb3dzIHNlbmRzIHRvIHRoZSBjb25maWd1cmVkIHNlbmRlciBzb3VyY2U7IFwidW5yZXN0cmljdGVkXCIgYWNjZXB0cyBhbnkgRnJvbS4nLFxuICAgIH0sXG4gICAgYnJhbmQ6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJCcmFuZCBzdHlsaW5nIGlubGluZWQgaW50byBldmVyeSByZW5kZXJlZCBtZXNzYWdlLiBPbWl0IGZvciB0aGUgbmV1dHJhbCBkZWZhdWx0IGxheW91dC5cIixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWNjZW50OiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0hlYWRlci1iYW5kIGJhY2tncm91bmQgYW5kIGJvZHkgbGluayBjb2xvciAoZS5nLiBcIiNGRjM2MjFcIikuJyxcbiAgICAgICAgfSxcbiAgICAgICAgb25BY2NlbnQ6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHQgYW5kIGxvZ28gY29sb3IgcmVuZGVyZWQgb24gdGhlIGFjY2VudCBiYW5kLiBEZWZhdWx0cyB0byB3aGl0ZS5cIixcbiAgICAgICAgfSxcbiAgICAgICAgZm9udEZhbWlseToge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdCb2R5IGZvbnQgc3RhY2sgKGUuZy4gXCJJbnRlciwgdWktc2Fucy1zZXJpZiwgc3lzdGVtLXVpLCBzYW5zLXNlcmlmXCIpLicsXG4gICAgICAgIH0sXG4gICAgICAgIG5hbWU6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3QgLyBkaXNwbGF5IG5hbWUgdXNlZCBhcyB0aGUgaGVhZGVyIHRleHQgYW5kIHRoZSBsb2dvIGFsdCB0ZXh0LlwiLFxuICAgICAgICB9LFxuICAgICAgICBsb2dvVXJsOiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiTG9nbyBpbWFnZSBmb3IgdGhlIGhlYWRlciBiYW5kLiBPbmx5IGFuIGh0dHAocyk6IG9yIGRhdGE6IFVSTCByZW5kZXJzOyBvdGhlciB2YWx1ZXMgYXJlIGRyb3BwZWQgYmVjYXVzZSBhIG1haWwgY2xpZW50IGNhbm5vdCBsb2FkIHRoZW0uXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFtcImFjY2VudFwiLCBcImZvbnRGYW1pbHlcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKiBQYXJzZSB0aGUgYFNNVFBfU0VDVVJFYCBlbnYgLyBjb25maWcgZmxhZywgZGVmYXVsdGluZyBieSBwb3J0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNlY3VyZShmbGFnOiBib29sZWFuIHwgdW5kZWZpbmVkLCBwb3J0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgaWYgKHR5cGVvZiBmbGFnID09PSBcImJvb2xlYW5cIikgcmV0dXJuIGZsYWc7XG4gIHJldHVybiBvYmplY3QudG9Cb29sZWFuKHByb2Nlc3MuZW52LlNNVFBfU0VDVVJFKSA/PyBwb3J0ID09PSBJTVBMSUNJVF9UTFNfU01UUF9QT1JUO1xufVxuXG4vKiogUGFyc2UgdGhlIGBFTUFJTF9TRU5ERVJfUE9MSUNZYCBlbnYgLyBjb25maWcgdmFsdWUsIGRlZmF1bHRpbmcgdG8gZGVueS1ieS1kZWZhdWx0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNlbmRlclBvbGljeShwb2xpY3k6IFNlbmRlclBvbGljeSB8IHVuZGVmaW5lZCk6IFNlbmRlclBvbGljeSB7XG4gIGNvbnN0IHJhdyA9IHBvbGljeSA/PyBwcm9jZXNzLmVudi5FTUFJTF9TRU5ERVJfUE9MSUNZPy50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgaWYgKHJhdyA9PT0gXCJ1bnJlc3RyaWN0ZWRcIikgcmV0dXJuIFwidW5yZXN0cmljdGVkXCI7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09IFwiXCIgfHwgcmF3ID09PSBcImFsbG93bGlzdFwiKSByZXR1cm4gXCJhbGxvd2xpc3RcIjtcbiAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLmludmFsaWRWYWx1ZShcInNlbmRlclBvbGljeVwiLCByYXcsICdcImFsbG93bGlzdFwiIG9yIFwidW5yZXN0cmljdGVkXCInKTtcbn1cblxuLyoqXG4gKiBFZmZlY3RpdmUgYWxsb3ctbGlzdCBmb3IgYW4gYFwiYWxsb3dsaXN0XCJgIHBvbGljeSB3aXRoIG5vIGV4cGxpY2l0IHBhdHRlcm5zOlxuICogdGhlIHNlbmRlciBzb3VyY2UgaXRzZWxmLCBzbyBhIGNvbmZpZ3VyZWQgZG9tYWluIG9yIGZpeGVkIGFkZHJlc3MgaXMgdGhlXG4gKiBib3VuZGFyeSByYXRoZXIgdGhhbiBcImFueXRoaW5nIGdvZXNcIi4gWWllbGRzIG5vdGhpbmcgd2hlbiBuZWl0aGVyIGlzIHNldCxcbiAqIHdoaWNoIG9ubHkgaGFwcGVucyBpbiBvdXRib3ggbW9kZSAod2hlcmUgdGhlIHNlbmRlciBmYWxscyBiYWNrIHRvIHRoZVxuICogb24tYmVoYWxmLW9mIHVzZXIncyBvd24gYWRkcmVzcyBhbmQgY2Fubm90IGJlIGVudW1lcmF0ZWQgdXAgZnJvbnQpLlxuICovXG5mdW5jdGlvbiBpbXBsaWVkU2VuZGVyUGF0dGVybnMoZG9tYWluOiBzdHJpbmcgfCB1bmRlZmluZWQsIGZyb206IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcGF0dGVybnM6IHN0cmluZ1tdID0gW107XG4gIGlmIChmcm9tKSBwYXR0ZXJucy5wdXNoKGZyb20udHJpbSgpLnRvTG93ZXJDYXNlKCkpO1xuICBpZiAoZG9tYWluKSBwYXR0ZXJucy5wdXNoKGAqQCR7ZG9tYWluLnRyaW0oKS50b0xvd2VyQ2FzZSgpfWApO1xuICByZXR1cm4gcGF0dGVybnM7XG59XG5cbi8qKiBXaGV0aGVyIGBFTUFJTF9PVVRCT1hfTU9ERWAgZXhwbGljaXRseSBvcHRzIGludG8gdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrLiAqL1xuZnVuY3Rpb24gaXNPdXRib3hNb2RlRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnYuRU1BSUxfT1VUQk9YX01PREUpID8/IGZhbHNlO1xufVxuXG5jb25zdCBTTVRQX1JFUVVJUkVEX0ZJRUxEUyA9IFtcIlNNVFBfSE9TVFwiLCBcIlNNVFBfVVNFUlwiLCBcIlNNVFBfUEFTU1dPUkRcIl0gYXMgY29uc3Q7XG5cbi8qKiBMaXN0IGVudiBrZXlzIGZvciBTTVRQIGZpZWxkcyB0aGF0IGFyZSB1bnNldCBpbiB0aGUgcmVzb2x2ZWQgY3JlZGVudGlhbCBzZXQuICovXG5mdW5jdGlvbiBtaXNzaW5nU210cEZpZWxkcyhcbiAgaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB1c2VyOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgdmFsdWVzID0gW2hvc3QsIHVzZXIsIHBhc3NdIGFzIGNvbnN0O1xuICByZXR1cm4gU01UUF9SRVFVSVJFRF9GSUVMRFMuZmlsdGVyKChfLCBpbmRleCkgPT4gIXZhbHVlc1tpbmRleF0pO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcGx1Z2luIGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzLlxuICpcbiAqIFdoZW4gU01UUCBob3N0ICsgdXNlciArIHBhc3N3b3JkIGFyZSBhbGwgcHJlc2VudCwgcmV0dXJucyBgbW9kZTpcbiAqIFwic210cFwiYCBmb3IgcmVhbCBkZWxpdmVyeSAoYW5kIHRocm93cyBpZiBubyBzZW5kZXIgc291cmNlIC0gZG9tYWluIG9yXG4gKiBmcm9tIC0gaXMgY29uZmlndXJlZCwgc2luY2UgU01UUCBjYW4ndCBkZXJpdmUgb25lIGZyb20gbm90aGluZykuXG4gKiBXaGVuIGFsbCB0aHJlZSBhcmUgYWJzZW50IGFuZCBgRU1BSUxfT1VUQk9YX01PREVgIGlzIGVuYWJsZWQsIHJldHVybnNcbiAqIGBtb2RlOiBcImZpbGVcImAgc28gdGhlIHJ1bnRpbWUgd3JpdGVzIG1lc3NhZ2VzIHRvIHRoZSBvdXRib3ggZGlyZWN0b3J5XG4gKiBmb3IgbG9jYWwgdGVzdGluZzsgaW4gdGhhdCBtb2RlIGEgc2VuZGVyIHNvdXJjZSBpcyBvcHRpb25hbCAodGhlXG4gKiBvdXRib3ggZmFsbHMgYmFjayB0byB0aGUgT0JPIHVzZXIncyBvd24gYWRkcmVzcykuIFBhcnRpYWwgU01UUFxuICogY29uZmlndXJhdGlvbiBvciBhIHNlbmQgd2l0aCBubyBjcmVkZW50aWFscyBhbmQgbm8gb3V0Ym94IG9wdC1pblxuICogdGhyb3dzLlxuICpcbiAqIFRoZSBzZW5kZXIgYWxsb3ctbGlzdCBpcyByZXNvbHZlZCBoZXJlIHRvbzogdW5kZXIgdGhlIGRlZmF1bHRcbiAqIGBcImFsbG93bGlzdFwiYCBwb2xpY3kgYW4gZW1wdHkgbGlzdCBpcyBmaWxsZWQgaW4gZnJvbSB0aGUgc2VuZGVyIHNvdXJjZSxcbiAqIHNvIGEgZGVwbG95bWVudCB0aGF0IG9ubHkgc2V0cyBgRU1BSUxfRE9NQUlOYCBzdGlsbCByZWplY3RzIGEgYEZyb21gIG9uXG4gKiBhbnkgb3RoZXIgZG9tYWluLiBTZWUge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1haWxDb25maWcoY29uZmlnOiBFbWFpbFBsdWdpbkNvbmZpZyA9IHt9KTogUmVzb2x2ZWRFbWFpbENvbmZpZyB7XG4gIGNvbnN0IHNtdHAgPSBjb25maWcuc210cCA/PyB7fTtcbiAgY29uc3QgaG9zdCA9IHNtdHAuaG9zdCA/PyBwcm9jZXNzLmVudi5TTVRQX0hPU1Q7XG4gIGNvbnN0IHVzZXIgPSBzbXRwLnVzZXIgPz8gcHJvY2Vzcy5lbnYuU01UUF9VU0VSO1xuICBjb25zdCBwYXNzID0gc210cC5wYXNzd29yZCA/PyBwcm9jZXNzLmVudi5TTVRQX1BBU1NXT1JEO1xuICBjb25zdCBkb21haW4gPSBjb25maWcuZG9tYWluID8/IHByb2Nlc3MuZW52LkVNQUlMX0RPTUFJTjtcbiAgY29uc3QgZnJvbSA9IGNvbmZpZy5mcm9tID8/IHByb2Nlc3MuZW52LkVNQUlMX0ZST007XG4gIGNvbnN0IHNlbmRlclBvbGljeSA9IHJlc29sdmVTZW5kZXJQb2xpY3koY29uZmlnLnNlbmRlclBvbGljeSk7XG4gIGNvbnN0IGNvbmZpZ3VyZWRTZW5kZXJzID0gcGFyc2VBbGxvd2VkU2VuZGVycyhcbiAgICBjb25maWcuYWxsb3dlZFNlbmRlcnMgPz8gcHJvY2Vzcy5lbnYuRU1BSUxfQUxMT1dFRF9TRU5ERVJTLFxuICApO1xuICBjb25zdCBhbGxvd2VkU2VuZGVycyA9XG4gICAgY29uZmlndXJlZFNlbmRlcnMubGVuZ3RoID4gMCB8fCBzZW5kZXJQb2xpY3kgPT09IFwidW5yZXN0cmljdGVkXCJcbiAgICAgID8gY29uZmlndXJlZFNlbmRlcnNcbiAgICAgIDogaW1wbGllZFNlbmRlclBhdHRlcm5zKGRvbWFpbiwgZnJvbSk7XG4gIGNvbnN0IHNlbmRlcjogUmVzb2x2ZWRTZW5kZXIgPSB7XG4gICAgLi4uKGRvbWFpbiA/IHsgZG9tYWluIH0gOiB7fSksXG4gICAgLi4uKGZyb20gPyB7IGZyb20gfSA6IHt9KSxcbiAgICBhbGxvd2VkU2VuZGVycyxcbiAgICBzZW5kZXJQb2xpY3ksXG4gICAgLi4uKGNvbmZpZy5icmFuZCA/IHsgYnJhbmQ6IGNvbmZpZy5icmFuZCB9IDoge30pLFxuICB9O1xuXG4gIGNvbnN0IGhhc0FsbFNtdHAgPSBCb29sZWFuKGhvc3QgJiYgdXNlciAmJiBwYXNzKTtcbiAgY29uc3QgaGFzQW55U210cCA9IEJvb2xlYW4oaG9zdCB8fCB1c2VyIHx8IHBhc3MpO1xuXG4gIGlmIChoYXNBbnlTbXRwICYmICFoYXNBbGxTbXRwKSB7XG4gICAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLm1pc3NpbmdFbnZWYXJzKG1pc3NpbmdTbXRwRmllbGRzKGhvc3QsIHVzZXIsIHBhc3MpKTtcbiAgfVxuXG4gIGlmIChoYXNBbGxTbXRwKSB7XG4gICAgaWYgKCFkb21haW4gJiYgIWZyb20pIHtcbiAgICAgIHRocm93IENvbmZpZ3VyYXRpb25FcnJvci5yZXNvdXJjZU5vdEZvdW5kKFxuICAgICAgICBcIkVtYWlsIHNlbmRlciBzb3VyY2VcIixcbiAgICAgICAgXCJTZXQgRU1BSUxfRE9NQUlOIHRvIGRlcml2ZSA8dXNlci1sb2NhbC1wYXJ0PkA8ZG9tYWluPiwgb3IgRU1BSUxfRlJPTSBmb3IgYSBmaXhlZCBhZGRyZXNzLlwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcG9ydFJhdyA9IHNtdHAucG9ydCA/PyBOdW1iZXIocHJvY2Vzcy5lbnYuU01UUF9QT1JUKTtcbiAgICBjb25zdCBwb3J0ID0gTnVtYmVyLmlzRmluaXRlKHBvcnRSYXcpICYmIHBvcnRSYXcgPyBOdW1iZXIocG9ydFJhdykgOiBERUZBVUxUX1NNVFBfUE9SVDtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kZTogXCJzbXRwXCIsXG4gICAgICBob3N0OiBob3N0ISxcbiAgICAgIHBvcnQsXG4gICAgICBzZWN1cmU6IHJlc29sdmVTZWN1cmUoc210cC5zZWN1cmUsIHBvcnQpLFxuICAgICAgYXV0aDogeyB1c2VyOiB1c2VyISwgcGFzczogcGFzcyEgfSxcbiAgICAgIC4uLnNlbmRlcixcbiAgICB9O1xuICB9XG5cbiAgaWYgKCFpc091dGJveE1vZGVFbmFibGVkKCkpIHtcbiAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IuaW52YWxpZENvbm5lY3Rpb24oXG4gICAgICBcIlNNVFBcIixcbiAgICAgIGBTZXQgJHtTTVRQX1JFUVVJUkVEX0ZJRUxEUy5qb2luKFwiLCBcIil9LCBvciBFTUFJTF9PVVRCT1hfTU9ERT0xIHRvIHdyaXRlIG1lc3NhZ2VzIHRvIGEgbG9jYWwgb3V0Ym94IGluc3RlYWQuYCxcbiAgICApO1xuICB9XG5cbiAgY29uc3Qgb3V0RGlyID0gcmVzb2x2ZShcbiAgICBjb25maWcub3V0RGlyID8/IHByb2Nlc3MuZW52LkVNQUlMX09VVEJPWF9ESVIgPz8gcmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcInRtcFwiKSxcbiAgKTtcbiAgcmV0dXJuIHsgbW9kZTogXCJmaWxlXCIsIG91dERpciwgLi4uc2VuZGVyIH07XG59XG4iXX0=
217
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQ2hHLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFckQsT0FBTyxFQUFFLGlCQUFpQixFQUFtQixNQUFNLFlBQVksQ0FBQztBQUNoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbEQseURBQXlEO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUVyQywyRUFBMkU7QUFDM0UsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBdUgxQywrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQWdCO0lBQzlDLElBQUksRUFBRSxRQUFRO0lBQ2QsVUFBVSxFQUFFO1FBQ1YsSUFBSSxFQUFFO1lBQ0osSUFBSSxFQUFFLFFBQVE7WUFDZCxXQUFXLEVBQUUsMERBQTBEO1lBQ3ZFLFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxtQ0FBbUMsRUFBRTtnQkFDMUUsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSw2Q0FBNkMsaUJBQWlCLEdBQUc7aUJBQy9FO2dCQUNELE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsU0FBUztvQkFDZixXQUFXLEVBQUUsNkRBQTZELHNCQUFzQixHQUFHO2lCQUNwRztnQkFDRCxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFB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RUFBdUUsQ0FDOUcsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQ3BCLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQy9FLENBQUM7SUFDRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTTVRQIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBlbWFpbCBwbHVnaW46IHRoZSB0eXBlZFxuICoge0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnfSAodGhlIHBsdWdpbidzIHNsaWNlIG9mIEFwcEtpdCBjb25maWcpLCB0aGVcbiAqIEpTT04gU2NoZW1hIHRoZSBtYW5pZmVzdCBwdWJsaXNoZXMgZm9yIGl0LCBhbmQge0BsaW5rIHJlc29sdmVFbWFpbENvbmZpZ31cbiAqIHdoaWNoIGxheWVycyB0aGF0IGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzIGludG8gdGhlIGNvbmNyZXRlXG4gKiB7QGxpbmsgUmVzb2x2ZWRFbWFpbENvbmZpZ30gdGhlIHJ1bnRpbWUgbmVlZHMuXG4gKlxuICogVHdvIG1vZGVzIGZhbGwgb3V0IG9mIHRoZSByZXNvbHV0aW9uLiBXaGVuIFNNVFAgY3JlZGVudGlhbHMgKGhvc3QgK1xuICogdXNlciArIHBhc3N3b3JkKSBhcmUgYWxsIHByZXNlbnQgaXQgcmVzb2x2ZXMgdG8gYG1vZGU6IFwic210cFwiYCBhbmRcbiAqIG1haWwgaXMgc2VudCBmb3IgcmVhbC4gV2hlbiB0aGV5IGFyZSBhYnNlbnQgYW5kIGBFTUFJTF9PVVRCT1hfTU9ERWBcbiAqIGlzIGV4cGxpY2l0bHkgZW5hYmxlZCBpdCByZXNvbHZlcyB0byBgbW9kZTogXCJmaWxlXCJgIChhbiBcIm91dGJveFwiKVxuICogYW5kIGVhY2ggbWVzc2FnZSBpcyB3cml0dGVuIHRvIGRpc2sgYXMgSFRNTCBpbnN0ZWFkIG9mIHNlbnQuIEFueVxuICogcGFydGlhbCBTTVRQIGNvbmZpZ3VyYXRpb24gb3IgYSBzZW5kIGF0dGVtcHQgd2l0aCBubyBjcmVkZW50aWFscyBhbmRcbiAqIG5vIG91dGJveCBvcHQtaW4gdGhyb3dzLlxuICpcbiAqIFByZWNlZGVuY2UgcGVyIGZpZWxkOiBleHBsaWNpdCBwbHVnaW4gY29uZmlnIHdpbnMsIHRoZW4gdGhlIG1hdGNoaW5nXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZS4gRW52IG5hbWVzIGFyZSB1bnByZWZpeGVkIGJlY2F1c2UgdGhlIGFwcCB0YWxrc1xuICogdG8gYSBzaW5nbGUgU01UUCBzZXJ2ZXIgKGUuZy4gU01UUDJHTyk6IGBTTVRQX0hPU1RgLCBgU01UUF9QT1JUYCxcbiAqIGBTTVRQX1NFQ1VSRWAsIGBTTVRQX1VTRVJgLCBgU01UUF9QQVNTV09SRGAsIHBsdXMgYEVNQUlMX0RPTUFJTmAgZm9yXG4gKiB0aGUgZGVyaXZlZCBzZW5kZXIncyBkb21haW4sIGBFTUFJTF9GUk9NYCBmb3IgYW4gZXhwbGljaXQgb3ZlcnJpZGUsXG4gKiBgRU1BSUxfU0VOREVSX1BPTElDWWAgZm9yIHRoZSBzZW5kZXIgcmVzdHJpY3Rpb24gbW9kZSwgYW5kXG4gKiBgRU1BSUxfT1VUQk9YX0RJUmAgZm9yIHRoZSBvdXRib3ggZGlyZWN0b3J5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25FcnJvciwgVmFsaWRhdGlvbkVycm9yLCB0eXBlIEJhc2VQbHVnaW5Db25maWcgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBlbnYsIG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IEpTT05TY2hlbWE3IH0gZnJvbSBcImpzb24tc2NoZW1hXCI7XG5pbXBvcnQgeyBkZWZhdWx0RW1haWxCcmFuZCwgdHlwZSBFbWFpbEJyYW5kIH0gZnJvbSBcIi4vYnJhbmQudHNcIjtcbmltcG9ydCB7IHBhcnNlQWxsb3dlZFNlbmRlcnMgfSBmcm9tIFwiLi9zZW5kZXIudHNcIjtcblxuLyoqIFNNVFAgc3VibWlzc2lvbiBwb3J0IHVzZWQgd2hlbiBub25lIGlzIGNvbmZpZ3VyZWQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TTVRQX1BPUlQgPSA1ODc7XG5cbi8qKiBTTVRQIHBvcnQgdGhhdCBpbXBsaWVzIGEgVExTLW9uLWNvbm5lY3Qgc29ja2V0IHJhdGhlciB0aGFuIFNUQVJUVExTLiAqL1xuZXhwb3J0IGNvbnN0IElNUExJQ0lUX1RMU19TTVRQX1BPUlQgPSA0NjU7XG5cbi8qKlxuICogSG93IHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcyBpcyByZXN0cmljdGVkLlxuICpcbiAqIGBcImFsbG93bGlzdFwiYCBpcyB0aGUgZGVmYXVsdCBhbmQgdGhlIGRlbnktYnktZGVmYXVsdCBwb3N0dXJlOiBhIHNlbmQgaXNcbiAqIHBlcm1pdHRlZCBvbmx5IGZyb20gYW4gYWRkcmVzcyB0aGUgY29uZmlndXJhdGlvbiBuYW1lcywgZWl0aGVyIHRocm91Z2hcbiAqIHtAbGluayBFbWFpbFBsdWdpbkNvbmZpZy5hbGxvd2VkU2VuZGVyc30gb3IsIHdoZW4gdGhhdCBpcyBlbXB0eSwgdGhyb3VnaFxuICogdGhlIGNvbmZpZ3VyZWQgc2VuZGVyIHNvdXJjZSAoe0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnLmZyb219IGFzIGFuIGV4YWN0XG4gKiBhZGRyZXNzLCB7QGxpbmsgRW1haWxQbHVnaW5Db25maWcuZG9tYWlufSBhcyBhIGAqQGRvbWFpbmAgd2lsZGNhcmQpLlxuICpcbiAqIGBcInVucmVzdHJpY3RlZFwiYCBpcyB0aGUgZXhwbGljaXQgb3B0LW91dDogYW55IGBGcm9tYCBhIGNhbGxlciBzdXBwbGllcyBpc1xuICogYWNjZXB0ZWQuIE9ubHkgcmVhY2ggZm9yIGl0IHdoZW4gYW4gdXBzdHJlYW0gc3lzdGVtIGFscmVhZHkgdmV0cyB0aGVcbiAqIHNlbmRlci5cbiAqL1xuZXhwb3J0IHR5cGUgU2VuZGVyUG9saWN5ID0gXCJhbGxvd2xpc3RcIiB8IFwidW5yZXN0cmljdGVkXCI7XG5cbi8qKiBTTVRQIGNvbm5lY3Rpb24gKyBjcmVkZW50aWFscy4gQWxsIGZpZWxkcyBmYWxsIGJhY2sgdG8gZW52IHdoZW4gdW5zZXQuICovXG5leHBvcnQgaW50ZXJmYWNlIFNtdHBDb25maWcge1xuICAvKiogU01UUCBzZXJ2ZXIgaG9zdG5hbWUgKGBTTVRQX0hPU1RgKS4gKi9cbiAgaG9zdD86IHN0cmluZztcbiAgLyoqIFNNVFAgc2VydmVyIHBvcnQgKGBTTVRQX1BPUlRgKS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfU01UUF9QT1JUfS4gKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFVzZSBhIFRMUy1vbi1jb25uZWN0IHNvY2tldCAoYFNNVFBfU0VDVVJFYCkuIERlZmF1bHRzIHRvXG4gICAqIGBwb3J0ID09PSBgIHtAbGluayBJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5cbiAgICovXG4gIHNlY3VyZT86IGJvb2xlYW47XG4gIC8qKiBTTVRQIGF1dGggdXNlcm5hbWUgKGBTTVRQX1VTRVJgKS4gKi9cbiAgdXNlcj86IHN0cmluZztcbiAgLyoqIFNNVFAgYXV0aCBwYXNzd29yZCAvIEFQSSBrZXkgKGBTTVRQX1BBU1NXT1JEYCkuICovXG4gIHBhc3N3b3JkPzogc3RyaW5nO1xufVxuXG4vKiogQXBwS2l0IGNvbmZpZyBhY2NlcHRlZCBieSB0aGUgZW1haWwgcGx1Z2luLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWFpbFBsdWdpbkNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICAvKiogU01UUCBjb25uZWN0aW9uICsgY3JlZGVudGlhbHMuIE9taXQgdG8gcnVuIGluIGZpbGUvb3V0Ym94IG1vZGUuICovXG4gIHNtdHA/OiBTbXRwQ29uZmlnO1xuICAvKipcbiAgICogRG9tYWluIHVzZWQgdG8gYnVpbGQgdGhlIHNlbmRlciBhZGRyZXNzIGZyb20gdGhlIG9uLWJlaGFsZi1vZiB1c2VyXG4gICAqIChgPGxvY2FsLXBhcnQ+QDxkb21haW4+YCkuIEZhbGxzIGJhY2sgdG8gYEVNQUlMX0RPTUFJTmAuIFJlcXVpcmVkIGluXG4gICAqIFNNVFAgbW9kZSB1bmxlc3Mge0BsaW5rIGZyb219IGlzIHNldDsgb3B0aW9uYWwgaW4gZmlsZSBtb2RlICh0aGVcbiAgICogb3V0Ym94IGZhbGxzIGJhY2sgdG8gdGhlIHVzZXIncyBvd24gZW1haWwgYWRkcmVzcykuXG4gICAqL1xuICBkb21haW4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBgRnJvbWAgYWRkcmVzcy4gV2hlbiBzZXQsIHRoZSBzZW5kZXIgaXMgdXNlZCB2ZXJiYXRpbSBhbmRcbiAgICogdGhlIHBlci11c2VyIGRlcml2YXRpb24gaXMgc2tpcHBlZC4gRmFsbHMgYmFjayB0byBgRU1BSUxfRlJPTWAuXG4gICAqL1xuICBmcm9tPzogc3RyaW5nO1xuICAvKipcbiAgICogRGlyZWN0b3J5IGZvciB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suIEZhbGxzIGJhY2sgdG9cbiAgICogYEVNQUlMX09VVEJPWF9ESVJgLCB0aGVuIGA8Y3dkPi90bXBgLiBPbmx5IHVzZWQgd2hlbiBTTVRQXG4gICAqIGNyZWRlbnRpYWxzIGFyZSBhYnNlbnQuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbGxvdy1saXN0IHJlc3RyaWN0aW5nIHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcy4gRWFjaCBlbnRyeSBpcyBhblxuICAgKiBleGFjdCBhZGRyZXNzIChgdXNlckBkb21haW4uY29tYCksIGEgZG9tYWluIHdpbGRjYXJkIChgKkBkb21haW4uY29tYFxuICAgKiBvciB0aGUgYmFyZSBgZG9tYWluLmNvbWAsIG1hdGNoaW5nIGFueSBsb2NhbCBwYXJ0IG9uIHRoYXQgZG9tYWluKSwgb3JcbiAgICogYCpgIChhbnkpLiBBIHJlc29sdmVkIC8gY2hvc2VuIHNlbmRlciB0aGF0IG1hdGNoZXMgbm8gZW50cnkgaXNcbiAgICogcmVqZWN0ZWQgYXQgc2VuZCB0aW1lLiBBY2NlcHRzIGEgYHN0cmluZ1tdYCBvciBhIHNpbmdsZSBjb21tYS0gL1xuICAgKiB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBzdHJpbmc7IGZhbGxzIGJhY2sgdG8gYEVNQUlMX0FMTE9XRURfU0VOREVSU2AuXG4gICAqIFdoZW4gZW1wdHksIHRoZSB7QGxpbmsgc2VuZGVyUG9saWN5fSBkZWNpZGVzIHdoYXQgaXMgcGVybWl0dGVkLlxuICAgKi9cbiAgYWxsb3dlZFNlbmRlcnM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEhvdyB0aGUgc2VuZGVyIGFkZHJlc3MgaXMgcmVzdHJpY3RlZCB3aGVuIHtAbGluayBhbGxvd2VkU2VuZGVyc30gaXNcbiAgICogZW1wdHkgKGBFTUFJTF9TRU5ERVJfUE9MSUNZYCkuIERlZmF1bHRzIHRvIGBcImFsbG93bGlzdFwiYCwgd2hpY2hcbiAgICogbmFycm93cyBzZW5kcyB0byB0aGUgY29uZmlndXJlZCBzZW5kZXIgc291cmNlLiBTZWVcbiAgICoge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gICAqL1xuICBzZW5kZXJQb2xpY3k/OiBTZW5kZXJQb2xpY3k7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBicmFuZCBzdHlsaW5nIGFwcGxpZWQgdG8gZXZlcnkgcmVuZGVyZWQgbWVzc2FnZS4gT21pdCB0byB1c2UgdGhlXG4gICAqIHJlcG9zaXRvcnkncyBkYngtdG9vbHMgYnJhbmQuIFBhc3Mge0BsaW5rIGVtYWlsQnJhbmRGcm9tQ29udGV4dH0gdG8gZGVyaXZlXG4gICAqIGEgY3VzdG9tIHZhbHVlIGZyb20gYSBzaGFyZWQgYEJyYW5kQ29udGV4dGAuXG4gICAqL1xuICBicmFuZD86IEVtYWlsQnJhbmQ7XG59XG5cbi8qKiBDb25maWcgc2hhcmVkIGJ5IGJvdGggcmVzb2x2ZWQgbW9kZXMuICovXG5pbnRlcmZhY2UgUmVzb2x2ZWRTZW5kZXIge1xuICAvKiogU2VuZGVyIGRvbWFpbjsgcHJlc2VudCB3aGVuZXZlciB7QGxpbmsgZnJvbX0gaXMgYWJzZW50LiAqL1xuICBkb21haW4/OiBzdHJpbmc7XG4gIC8qKiBFeHBsaWNpdCBzZW5kZXIgb3ZlcnJpZGU7IHByZXNlbnQgc2tpcHMgcGVyLXVzZXIgZGVyaXZhdGlvbi4gKi9cbiAgZnJvbT86IHN0cmluZztcbiAgLyoqXG4gICAqIEVmZmVjdGl2ZSBzZW5kZXIgYWxsb3ctbGlzdDogdGhlIGNvbmZpZ3VyZWQgcGF0dGVybnMgd2hlbiBhbnkgd2VyZVxuICAgKiBnaXZlbiwgZWxzZSB0aGUgcGF0dGVybnMgaW1wbGllZCBieSB0aGUgc2VuZGVyIHNvdXJjZSB1bmRlciBhblxuICAgKiBgXCJhbGxvd2xpc3RcImAgcG9saWN5LiBFbXB0eSBtZWFucyB1bmVuZm9yY2VhYmxlIChhbiBgXCJ1bnJlc3RyaWN0ZWRcImBcbiAgICogcG9saWN5LCBvciBhbiBvdXRib3ggd2l0aCBubyBzZW5kZXIgc291cmNlIHRvIG5hcnJvdyB0bykuXG4gICAqL1xuICBhbGxvd2VkU2VuZGVyczogc3RyaW5nW107XG4gIC8qKiBUaGUgcmVzdHJpY3Rpb24gbW9kZSB0aGUgYWxsb3ctbGlzdCB3YXMgcmVzb2x2ZWQgdW5kZXIuICovXG4gIHNlbmRlclBvbGljeTogU2VuZGVyUG9saWN5O1xuICAvKiogQnJhbmQgc3R5bGluZyBhcHBsaWVkIHRvIHJlbmRlcmVkIEhUTUwuICovXG4gIGJyYW5kOiBFbWFpbEJyYW5kO1xufVxuXG4vKiogUmVzb2x2ZWQgY29uZmlnIGZvciByZWFsIFNNVFAgZGVsaXZlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkU210cENvbmZpZyBleHRlbmRzIFJlc29sdmVkU2VuZGVyIHtcbiAgbW9kZTogXCJzbXRwXCI7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xuICBzZWN1cmU6IGJvb2xlYW47XG4gIGF1dGg6IHsgdXNlcjogc3RyaW5nOyBwYXNzOiBzdHJpbmcgfTtcbn1cblxuLyoqIFJlc29sdmVkIGNvbmZpZyBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIChubyBTTVRQIGNyZWRlbnRpYWxzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRGaWxlQ29uZmlnIGV4dGVuZHMgUmVzb2x2ZWRTZW5kZXIge1xuICBtb2RlOiBcImZpbGVcIjtcbiAgLyoqIEFic29sdXRlIGRpcmVjdG9yeSBtZXNzYWdlcyBhcmUgd3JpdHRlbiB1bmRlci4gKi9cbiAgb3V0RGlyOiBzdHJpbmc7XG59XG5cbi8qKiBDb25jcmV0ZSwgdmFsaWRhdGVkIGNvbmZpZyB0aGUgcnVudGltZSBkaXNwYXRjaGVzIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZEVtYWlsQ29uZmlnID0gUmVzb2x2ZWRTbXRwQ29uZmlnIHwgUmVzb2x2ZWRGaWxlQ29uZmlnO1xuXG4vKiogSlNPTiBTY2hlbWEgcHVibGlzaGVkIG9uIHRoZSBtYW5pZmVzdCdzIGBjb25maWcuc2NoZW1hYC4gKi9cbmV4cG9ydCBjb25zdCBFTUFJTF9DT05GSUdfU0NIRU1BOiBKU09OU2NoZW1hNyA9IHtcbiAgdHlwZTogXCJvYmplY3RcIixcbiAgcHJvcGVydGllczoge1xuICAgIHNtdHA6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJTTVRQIGNvbm5lY3Rpb24gYW5kIGNyZWRlbnRpYWxzIChlbnYgZmFsbGJhY2tzOiBTTVRQXyopLlwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBob3N0OiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgc2VydmVyIGhvc3RuYW1lIChTTVRQX0hPU1QpLlwiIH0sXG4gICAgICAgIHBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgU01UUCBzZXJ2ZXIgcG9ydCAoU01UUF9QT1JUKS4gRGVmYXVsdHMgdG8gJHtERUZBVUxUX1NNVFBfUE9SVH0uYCxcbiAgICAgICAgfSxcbiAgICAgICAgc2VjdXJlOiB7XG4gICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGBUTFMtb24tY29ubmVjdCBzb2NrZXQgKFNNVFBfU0VDVVJFKS4gRGVmYXVsdHMgdG8gcG9ydCA9PT0gJHtJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5gLFxuICAgICAgICB9LFxuICAgICAgICB1c2VyOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgYXV0aCB1c2VybmFtZSAoU01UUF9VU0VSKS5cIiB9LFxuICAgICAgICBwYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiU01UUCBhdXRoIHBhc3N3b3JkIC8gQVBJIGtleSAoU01UUF9QQVNTV09SRCkuXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgZG9tYWluOiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRG9tYWluIGZvciB0aGUgZGVyaXZlZCBzZW5kZXIgYWRkcmVzcyAoPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4pLiBGYWxscyBiYWNrIHRvIEVNQUlMX0RPTUFJTi5cIixcbiAgICB9LFxuICAgIGZyb206IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBsaWNpdCBGcm9tIGFkZHJlc3M7IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uIEZhbGxzIGJhY2sgdG8gRU1BSUxfRlJPTS5cIixcbiAgICB9LFxuICAgIG91dERpcjoge1xuICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkRpcmVjdG9yeSBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIHdoZW4gU01UUCBpcyB1bmNvbmZpZ3VyZWQuIEZhbGxzIGJhY2sgdG8gRU1BSUxfT1VUQk9YX0RJUiwgdGhlbiA8Y3dkPi90bXAuXCIsXG4gICAgfSxcbiAgICBhbGxvd2VkU2VuZGVyczoge1xuICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgaXRlbXM6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdy1saXN0IG9mIHBlcm1pdHRlZCBzZW5kZXIgKEZyb20pIHBhdHRlcm5zOiBleGFjdCBhZGRyZXNzZXMgKFwidXNlckBkb21haW4uY29tXCIpLCBkb21haW4gd2lsZGNhcmRzIChcIipAZG9tYWluLmNvbVwiKSwgb3IgXCIqXCIuIEFsc28gYWNjZXB0cyBhIGNvbW1hL3NwYWNlLXNlcGFyYXRlZCBzdHJpbmcuIEZhbGxzIGJhY2sgdG8gRU1BSUxfQUxMT1dFRF9TRU5ERVJTLiBXaGVuIGVtcHR5LCBzZW5kZXJQb2xpY3kgZGVjaWRlcy4nLFxuICAgIH0sXG4gICAgc2VuZGVyUG9saWN5OiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZW51bTogW1wiYWxsb3dsaXN0XCIsIFwidW5yZXN0cmljdGVkXCJdLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdIb3cgdGhlIHNlbmRlciBpcyByZXN0cmljdGVkIHdoZW4gYWxsb3dlZFNlbmRlcnMgaXMgZW1wdHkgKEVNQUlMX1NFTkRFUl9QT0xJQ1kpLiBcImFsbG93bGlzdFwiIChkZWZhdWx0KSBuYXJyb3dzIHNlbmRzIHRvIHRoZSBjb25maWd1cmVkIHNlbmRlciBzb3VyY2U7IFwidW5yZXN0cmljdGVkXCIgYWNjZXB0cyBhbnkgRnJvbS4nLFxuICAgIH0sXG4gICAgYnJhbmQ6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJCcmFuZCBzdHlsaW5nIGFwcGxpZWQgdG8gZXZlcnkgUmVhY3QgRW1haWwgbWVzc2FnZS4gT21pdCB0byB1c2UgdGhlIGRieC10b29scyBicmFuZC5cIixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWNjZW50OiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0hlYWRlci1iYW5kIGJhY2tncm91bmQgYW5kIGJvZHkgbGluayBjb2xvciAoZS5nLiBcIiNGRjM2MjFcIikuJyxcbiAgICAgICAgfSxcbiAgICAgICAgb25BY2NlbnQ6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHQgYW5kIGxvZ28gY29sb3IgcmVuZGVyZWQgb24gdGhlIGFjY2VudCBiYW5kLiBEZWZhdWx0cyB0byB3aGl0ZS5cIixcbiAgICAgICAgfSxcbiAgICAgICAgZm9udEZhbWlseToge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdCb2R5IGZvbnQgc3RhY2sgKGUuZy4gXCJJbnRlciwgdWktc2Fucy1zZXJpZiwgc3lzdGVtLXVpLCBzYW5zLXNlcmlmXCIpLicsXG4gICAgICAgIH0sXG4gICAgICAgIG5hbWU6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3QgLyBkaXNwbGF5IG5hbWUgdXNlZCBhcyB0aGUgaGVhZGVyIHRleHQgYW5kIHRoZSBsb2dvIGFsdCB0ZXh0LlwiLFxuICAgICAgICB9LFxuICAgICAgICBsb2dvVXJsOiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiTG9nbyBpbWFnZSBmb3IgdGhlIGhlYWRlciBiYW5kLiBPbmx5IGFuIGh0dHAocyk6IG9yIGRhdGE6IFVSTCByZW5kZXJzOyBvdGhlciB2YWx1ZXMgYXJlIGRyb3BwZWQgYmVjYXVzZSBhIG1haWwgY2xpZW50IGNhbm5vdCBsb2FkIHRoZW0uXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2tncm91bmQ6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiSW5ib3ggY2FudmFzIGNvbG9yLlwiIH0sXG4gICAgICAgIHN1cmZhY2U6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiTWVzc2FnZS1jYXJkIGNvbG9yLlwiIH0sXG4gICAgICAgIGZvcmVncm91bmQ6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiUHJpbWFyeSB0ZXh0IGNvbG9yLlwiIH0sXG4gICAgICAgIG11dGVkOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNlY29uZGFyeSB0ZXh0IGNvbG9yLlwiIH0sXG4gICAgICAgIGJvcmRlcjogeyB0eXBlOiBcInN0cmluZ1wiLCBkZXNjcmlwdGlvbjogXCJCb3JkZXIgYW5kIGRpdmlkZXIgY29sb3IuXCIgfSxcbiAgICAgICAgdGFnbGluZTogeyB0eXBlOiBcInN0cmluZ1wiLCBkZXNjcmlwdGlvbjogXCJGb290ZXIgcHJvZHVjdCBsaW5lLlwiIH0sXG4gICAgICAgIHdlYnNpdGU6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiT3B0aW9uYWwgZm9vdGVyIHdlYnNpdGUgVVJMLlwiIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFtcImFjY2VudFwiLCBcImZvbnRGYW1pbHlcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKiBQYXJzZSB0aGUgYFNNVFBfU0VDVVJFYCBlbnYgLyBjb25maWcgZmxhZywgZGVmYXVsdGluZyBieSBwb3J0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNlY3VyZShmbGFnOiBib29sZWFuIHwgdW5kZWZpbmVkLCBwb3J0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGVudi5ib29sZWFuKGZsYWcsIFwiU01UUF9TRUNVUkVcIikgPz8gcG9ydCA9PT0gSU1QTElDSVRfVExTX1NNVFBfUE9SVDtcbn1cblxuLyoqIFBhcnNlIHRoZSBgRU1BSUxfU0VOREVSX1BPTElDWWAgZW52IC8gY29uZmlnIHZhbHVlLCBkZWZhdWx0aW5nIHRvIGRlbnktYnktZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVTZW5kZXJQb2xpY3kocG9saWN5OiBTZW5kZXJQb2xpY3kgfCB1bmRlZmluZWQpOiBTZW5kZXJQb2xpY3kge1xuICBjb25zdCByYXcgPSBwb2xpY3kgPz8gZW52LnRleHQoXCJFTUFJTF9TRU5ERVJfUE9MSUNZXCIpPy50b0xvd2VyQ2FzZSgpO1xuICBpZiAocmF3ID09PSBcInVucmVzdHJpY3RlZFwiKSByZXR1cm4gXCJ1bnJlc3RyaWN0ZWRcIjtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gXCJcIiB8fCByYXcgPT09IFwiYWxsb3dsaXN0XCIpIHJldHVybiBcImFsbG93bGlzdFwiO1xuICB0aHJvdyBWYWxpZGF0aW9uRXJyb3IuaW52YWxpZFZhbHVlKFwic2VuZGVyUG9saWN5XCIsIHJhdywgJ1wiYWxsb3dsaXN0XCIgb3IgXCJ1bnJlc3RyaWN0ZWRcIicpO1xufVxuXG4vKipcbiAqIEVmZmVjdGl2ZSBhbGxvdy1saXN0IGZvciBhbiBgXCJhbGxvd2xpc3RcImAgcG9saWN5IHdpdGggbm8gZXhwbGljaXQgcGF0dGVybnM6XG4gKiB0aGUgc2VuZGVyIHNvdXJjZSBpdHNlbGYsIHNvIGEgY29uZmlndXJlZCBkb21haW4gb3IgZml4ZWQgYWRkcmVzcyBpcyB0aGVcbiAqIGJvdW5kYXJ5IHJhdGhlciB0aGFuIFwiYW55dGhpbmcgZ29lc1wiLiBZaWVsZHMgbm90aGluZyB3aGVuIG5laXRoZXIgaXMgc2V0LFxuICogd2hpY2ggb25seSBoYXBwZW5zIGluIG91dGJveCBtb2RlICh3aGVyZSB0aGUgc2VuZGVyIGZhbGxzIGJhY2sgdG8gdGhlXG4gKiBvbi1iZWhhbGYtb2YgdXNlcidzIG93biBhZGRyZXNzIGFuZCBjYW5ub3QgYmUgZW51bWVyYXRlZCB1cCBmcm9udCkuXG4gKi9cbmZ1bmN0aW9uIGltcGxpZWRTZW5kZXJQYXR0ZXJucyhkb21haW46IHN0cmluZyB8IHVuZGVmaW5lZCwgZnJvbTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nW10ge1xuICBjb25zdCBwYXR0ZXJuczogc3RyaW5nW10gPSBbXTtcbiAgaWYgKGZyb20pIHBhdHRlcm5zLnB1c2goZnJvbS50cmltKCkudG9Mb3dlckNhc2UoKSk7XG4gIGlmIChkb21haW4pIHBhdHRlcm5zLnB1c2goYCpAJHtkb21haW4udHJpbSgpLnRvTG93ZXJDYXNlKCl9YCk7XG4gIHJldHVybiBwYXR0ZXJucztcbn1cblxuLyoqIFdoZXRoZXIgYEVNQUlMX09VVEJPWF9NT0RFYCBleHBsaWNpdGx5IG9wdHMgaW50byB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suICovXG5mdW5jdGlvbiBpc091dGJveE1vZGVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZW52LmJvb2xlYW4odW5kZWZpbmVkLCBcIkVNQUlMX09VVEJPWF9NT0RFXCIpID8/IGZhbHNlO1xufVxuXG5jb25zdCBTTVRQX1JFUVVJUkVEX0ZJRUxEUyA9IFtcIlNNVFBfSE9TVFwiLCBcIlNNVFBfVVNFUlwiLCBcIlNNVFBfUEFTU1dPUkRcIl0gYXMgY29uc3Q7XG5cbi8qKiBMaXN0IGVudiBrZXlzIGZvciBTTVRQIGZpZWxkcyB0aGF0IGFyZSB1bnNldCBpbiB0aGUgcmVzb2x2ZWQgY3JlZGVudGlhbCBzZXQuICovXG5mdW5jdGlvbiBtaXNzaW5nU210cEZpZWxkcyhcbiAgaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB1c2VyOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgdmFsdWVzID0gW2hvc3QsIHVzZXIsIHBhc3NdIGFzIGNvbnN0O1xuICByZXR1cm4gU01UUF9SRVFVSVJFRF9GSUVMRFMuZmlsdGVyKChfLCBpbmRleCkgPT4gIXZhbHVlc1tpbmRleF0pO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcGx1Z2luIGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzLlxuICpcbiAqIFdoZW4gU01UUCBob3N0ICsgdXNlciArIHBhc3N3b3JkIGFyZSBhbGwgcHJlc2VudCwgcmV0dXJucyBgbW9kZTpcbiAqIFwic210cFwiYCBmb3IgcmVhbCBkZWxpdmVyeSAoYW5kIHRocm93cyBpZiBubyBzZW5kZXIgc291cmNlIC0gZG9tYWluIG9yXG4gKiBmcm9tIC0gaXMgY29uZmlndXJlZCwgc2luY2UgU01UUCBjYW4ndCBkZXJpdmUgb25lIGZyb20gbm90aGluZykuXG4gKiBXaGVuIGFsbCB0aHJlZSBhcmUgYWJzZW50IGFuZCBgRU1BSUxfT1VUQk9YX01PREVgIGlzIGVuYWJsZWQsIHJldHVybnNcbiAqIGBtb2RlOiBcImZpbGVcImAgc28gdGhlIHJ1bnRpbWUgd3JpdGVzIG1lc3NhZ2VzIHRvIHRoZSBvdXRib3ggZGlyZWN0b3J5XG4gKiBmb3IgbG9jYWwgdGVzdGluZzsgaW4gdGhhdCBtb2RlIGEgc2VuZGVyIHNvdXJjZSBpcyBvcHRpb25hbCAodGhlXG4gKiBvdXRib3ggZmFsbHMgYmFjayB0byB0aGUgT0JPIHVzZXIncyBvd24gYWRkcmVzcykuIFBhcnRpYWwgU01UUFxuICogY29uZmlndXJhdGlvbiBvciBhIHNlbmQgd2l0aCBubyBjcmVkZW50aWFscyBhbmQgbm8gb3V0Ym94IG9wdC1pblxuICogdGhyb3dzLlxuICpcbiAqIFRoZSBzZW5kZXIgYWxsb3ctbGlzdCBpcyByZXNvbHZlZCBoZXJlIHRvbzogdW5kZXIgdGhlIGRlZmF1bHRcbiAqIGBcImFsbG93bGlzdFwiYCBwb2xpY3kgYW4gZW1wdHkgbGlzdCBpcyBmaWxsZWQgaW4gZnJvbSB0aGUgc2VuZGVyIHNvdXJjZSxcbiAqIHNvIGEgZGVwbG95bWVudCB0aGF0IG9ubHkgc2V0cyBgRU1BSUxfRE9NQUlOYCBzdGlsbCByZWplY3RzIGEgYEZyb21gIG9uXG4gKiBhbnkgb3RoZXIgZG9tYWluLiBTZWUge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1haWxDb25maWcoY29uZmlnOiBFbWFpbFBsdWdpbkNvbmZpZyA9IHt9KTogUmVzb2x2ZWRFbWFpbENvbmZpZyB7XG4gIGNvbnN0IHNtdHAgPSBjb25maWcuc210cCA/PyB7fTtcbiAgY29uc3QgaG9zdCA9IGVudi5zdHJpbmcoc210cC5ob3N0LCBcIlNNVFBfSE9TVFwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHVzZXIgPSBlbnYuc3RyaW5nKHNtdHAudXNlciwgXCJTTVRQX1VTRVJcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBwYXNzID0gZW52LnN0cmluZyhzbXRwLnBhc3N3b3JkLCBcIlNNVFBfUEFTU1dPUkRcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBkb21haW4gPSBlbnYuc3RyaW5nKGNvbmZpZy5kb21haW4sIFwiRU1BSUxfRE9NQUlOXCIpID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgZnJvbSA9IGVudi5zdHJpbmcoY29uZmlnLmZyb20sIFwiRU1BSUxfRlJPTVwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHNlbmRlclBvbGljeSA9IHJlc29sdmVTZW5kZXJQb2xpY3koY29uZmlnLnNlbmRlclBvbGljeSk7XG4gIGNvbnN0IGNvbmZpZ3VyZWRTZW5kZXJzID0gcGFyc2VBbGxvd2VkU2VuZGVycyhcbiAgICBjb25maWcuYWxsb3dlZFNlbmRlcnMgPz8gZW52LnRleHQoXCJFTUFJTF9BTExPV0VEX1NFTkRFUlNcIikgPz8gdW5kZWZpbmVkLFxuICApO1xuICBjb25zdCBhbGxvd2VkU2VuZGVycyA9XG4gICAgY29uZmlndXJlZFNlbmRlcnMubGVuZ3RoID4gMCB8fCBzZW5kZXJQb2xpY3kgPT09IFwidW5yZXN0cmljdGVkXCJcbiAgICAgID8gY29uZmlndXJlZFNlbmRlcnNcbiAgICAgIDogaW1wbGllZFNlbmRlclBhdHRlcm5zKGRvbWFpbiwgZnJvbSk7XG4gIGNvbnN0IHNlbmRlcjogUmVzb2x2ZWRTZW5kZXIgPSB7XG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZG9tYWluXCIsIGRvbWFpbiksXG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZnJvbVwiLCBmcm9tKSxcbiAgICBhbGxvd2VkU2VuZGVycyxcbiAgICBzZW5kZXJQb2xpY3ksXG4gICAgYnJhbmQ6IGNvbmZpZy5icmFuZCA/PyBkZWZhdWx0RW1haWxCcmFuZCxcbiAgfTtcblxuICBjb25zdCBoYXNBbGxTbXRwID0gQm9vbGVhbihob3N0ICYmIHVzZXIgJiYgcGFzcyk7XG4gIGNvbnN0IGhhc0FueVNtdHAgPSBCb29sZWFuKGhvc3QgfHwgdXNlciB8fCBwYXNzKTtcblxuICBpZiAoaGFzQW55U210cCAmJiAhaGFzQWxsU210cCkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5taXNzaW5nRW52VmFycyhtaXNzaW5nU210cEZpZWxkcyhob3N0LCB1c2VyLCBwYXNzKSk7XG4gIH1cblxuICBpZiAoaGFzQWxsU210cCkge1xuICAgIGlmICghZG9tYWluICYmICFmcm9tKSB7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IucmVzb3VyY2VOb3RGb3VuZChcbiAgICAgICAgXCJFbWFpbCBzZW5kZXIgc291cmNlXCIsXG4gICAgICAgIFwiU2V0IEVNQUlMX0RPTUFJTiB0byBkZXJpdmUgPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4sIG9yIEVNQUlMX0ZST00gZm9yIGEgZml4ZWQgYWRkcmVzcy5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSBlbnYucG9zaXRpdmVJbnQoc210cC5wb3J0LCBcIlNNVFBfUE9SVFwiLCBERUZBVUxUX1NNVFBfUE9SVCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGU6IFwic210cFwiLFxuICAgICAgaG9zdDogaG9zdCEsXG4gICAgICBwb3J0LFxuICAgICAgc2VjdXJlOiByZXNvbHZlU2VjdXJlKHNtdHAuc2VjdXJlLCBwb3J0KSxcbiAgICAgIGF1dGg6IHsgdXNlcjogdXNlciEsIHBhc3M6IHBhc3MhIH0sXG4gICAgICAuLi5zZW5kZXIsXG4gICAgfTtcbiAgfVxuXG4gIGlmICghaXNPdXRib3hNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgQ29uZmlndXJhdGlvbkVycm9yLmludmFsaWRDb25uZWN0aW9uKFxuICAgICAgXCJTTVRQXCIsXG4gICAgICBgU2V0ICR7U01UUF9SRVFVSVJFRF9GSUVMRFMuam9pbihcIiwgXCIpfSwgb3IgRU1BSUxfT1VUQk9YX01PREU9MSB0byB3cml0ZSBtZXNzYWdlcyB0byBhIGxvY2FsIG91dGJveCBpbnN0ZWFkLmAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG91dERpciA9IHJlc29sdmUoXG4gICAgZW52LnN0cmluZyhjb25maWcub3V0RGlyLCBcIkVNQUlMX09VVEJPWF9ESVJcIikgPz8gcmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcInRtcFwiKSxcbiAgKTtcbiAgcmV0dXJuIHsgbW9kZTogXCJmaWxlXCIsIG91dERpciwgLi4uc2VuZGVyIH07XG59XG4iXX0=
@@ -50,7 +50,7 @@ export declare const MAX_ATTACHMENT_BYTES = 10485760;
50
50
  export declare const MAX_ATTACHMENTS_TOTAL_BYTES = 20971520;
51
51
  /** Largest number of attachments accepted on one message. */
52
52
  export declare const MAX_ATTACHMENT_COUNT = 20;
53
- /** Largest markdown body accepted, in characters. */
53
+ /** Largest email body accepted, in characters. */
54
54
  export declare const MAX_BODY_CHARS = 200000;
55
55
  /** Execution settings for a send (SMTP dispatch or an outbox write). */
56
56
  export declare const EMAIL_SEND_SETTINGS: EmailExecutionSettings;