@uengage.io/platform-sdk 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,7 @@ const { balance, balanceMinor, currency } = await wallet.getBalance();
33
33
  // wallet.debit({ referenceId, amountMinor, service: Services.FLASH_DELIVERY, description }) — idempotent on referenceId
34
34
  // wallet.credit({ ..., reversalOf }) refund capped by that debit; ({ ..., isRefund: true }) uncapped
35
35
  // wallet.listTransactions({...}); wallet.getTransaction(id)
36
+ // wallet.getOverview() — wallet balance or credit line? See Wallet client below.
36
37
  // Legacy-ledger passthroughs, written as top-level ledger fields:
37
38
  // taskId, rto (debit), units, serviceBaseCost, paymentId (credit), updatedBy,
38
39
  // occurredAt — IST 'YYYY-MM-DD HH:mm:ss', dates the CHARGE not the write
@@ -229,6 +230,158 @@ const many = await client.business.bulk([123, 124], { groups: ['profile'] });
229
230
  - The `profile` group (just `name`) is public; other groups need
230
231
  matching `business.<group>:read` capability for the calling service id.
231
232
 
233
+ ## Wallet client
234
+
235
+ `getWallet(...)` is a lightweight handle — no I/O. The wallet is resolved
236
+ server-side on the first operation, so a routing miss surfaces from the
237
+ operation, not from `getWallet()`.
238
+
239
+ ### Which billing model? — start here
240
+
241
+ Prepaid wallets and merchant credit lines coexist, and which one a
242
+ merchant is on decides what a dashboard renders and which calls are even
243
+ legal. `getOverview()` settles it with a discriminated union:
244
+
245
+ ```ts
246
+ const o = await wallet.getOverview();
247
+
248
+ if (o.mode === 'credit') {
249
+ o.creditLine.limit; // { amount, amountMinor } — net of GST
250
+ o.creditLine.band; // 'normal' | 'warning' | 'critical' | 'blocked'
251
+ } else {
252
+ o.balance.balanceMinor; // prepaid: the wallet balance
253
+ }
254
+ ```
255
+
256
+ - `balance` is on **both** arms and means the same thing either way: what
257
+ the merchant can still spend. Available credit on the credit arm.
258
+ - One request for a prepaid merchant, two for a credit one, and never a
259
+ 404 on the happy path — it reads `getBalance().source` rather than
260
+ calling `getCreditLine()` and catching its 404, which would make the
261
+ normal state of a prepaid merchant an error on every page load.
262
+ - A wallet service older than the credit line (no `source`) reads as
263
+ prepaid rather than throwing.
264
+ - **The credit arm needs `wallet.credit:read` on top of
265
+ `wallet.balance:read`.** A token with only the latter gets a
266
+ `WalletApiError` with `status === 403` from the second call — not a
267
+ fallback to `prepaid`, which would render the frozen `wallet_balance`
268
+ these merchants no longer spend from.
269
+ - Not a guaranteed 200: `WalletNotFoundError` (no wallet document for the
270
+ resolved identity) and `UnresolvableWalletError` (routing cannot name
271
+ one) both propagate, because both mean there is nothing to render.
272
+
273
+ ### Credit line
274
+
275
+ The ceiling is per **merchant**, not per wallet, so an outlet's id and its
276
+ parent's id return the same line.
277
+
278
+ ```ts
279
+ const line = await wallet.getCreditLine(); // 404 CreditLineNotFoundError if prepaid
280
+ line.consumed; // net, UNPAID — spans months, not a calendar figure
281
+ line.available; // limit − consumed
282
+ line.estimatedInvoice.total; // exact, from recorded GST — not consumed × 1.18
283
+
284
+ await wallet.setCreditLimit({
285
+ referenceId: 'admin:limit:1200:2026-09-02', // idempotency key
286
+ limitMinor: 10_000_000, // ₹1,00,000, NET of GST; 0 blocks
287
+ onBehalfOf: 'user:4471', // required — the trail names the human
288
+ reason: 'Q3 volume increase',
289
+ // enabled: false → take them off the credit line
290
+ });
291
+
292
+ await wallet.settleInvoice({
293
+ invoiceRef: 'invoice:2026-04:88213', // idempotency key
294
+ netMinor: 500_000, // the NET figure — what frees credit
295
+ gstMinor: 90_000, // recorded, not released
296
+ onBehalfOf: 'user:9',
297
+ });
298
+ await wallet.reverseSettlement({ invoiceRef: '…', onBehalfOf: 'user:9' });
299
+ // Correcting a settled amount: reverse, then settle again with the right
300
+ // figures AND a `reason` — different figures on a reversed invoice
301
+ // release against the merchant's whole outstanding consumption, so the
302
+ // service requires the correction to say what it is correcting.
303
+
304
+ await wallet.listCreditEvents(); // limit changes + settlements, newest first
305
+ await wallet.listCreditEvents({ limit: 200 }); // the service defaults to 50
306
+ await client.wallet.getCreditUtilisation({ band: 'warning' }); // cross-merchant
307
+ ```
308
+
309
+ - **Charges on a credit-line merchant must carry `breakup`** — consumption
310
+ is tracked net of GST, so a missing split is
311
+ `CreditBreakupRequiredError` rather than a guessed rate. `allowNegative`
312
+ is refused (`CreditOverrideRefusedError`): it disables the balance guard
313
+ for migration paths, and on a credit line it would disable the limit.
314
+ - **The merchant pays gross; settlement releases net.** A ₹5,900 invoice
315
+ on ₹5,000 of consumption frees ₹5,000. Passing gross hands back 18% too
316
+ much — and it looks right in a test, since both figures sit on the same
317
+ invoice row.
318
+ - **Setting a limit never touches consumption**, so raising one hands back
319
+ exactly the difference. Lowering below what is consumed blocks charges
320
+ immediately.
321
+ - **`enabled: false` is refused while the merchant owes** —
322
+ `CreditLineHasOutstandingError`, carrying `consumedMinor` so you can say
323
+ how much to settle. Disabling moves them back to a wallet balance, which
324
+ with a balance owed abandons it. To _stop_ a merchant trading use
325
+ `limitMinor: 0`; to move them _off_, settle first.
326
+ - Reusing an idempotency key with **different** figures is
327
+ `CreditIdempotencyConflictError`, not a silent replay. To correct a
328
+ settled amount, reverse it and settle again rather than inventing a new
329
+ ref — a new ref leaves the original settlement standing.
330
+ - **A plain `credit()` is refused** — `CreditTopUpRefusedError`. These
331
+ merchants have no balance to top up: `wallet_balance` is the fiction the
332
+ line replaces and is frozen, so the write would move nothing while
333
+ answering 201. Credit comes back through `settleInvoice`. A genuine
334
+ refund is accepted — send `reversalOf` or `isRefund` and it releases
335
+ what the original charge consumed.
336
+ - `getCreditUtilisation` hangs off the **client**, not a wallet handle: it
337
+ is the one wallet call not scoped to a business.
338
+
339
+ ### Errors
340
+
341
+ All extend `WalletApiError` (`.status`, `.body`).
342
+
343
+ `CreditLimitReachedError` carries `limitMinor` / `consumedMinor` /
344
+ `availableMinor` / `requestedMinor`, and that is the point of it — three
345
+ situations share the code and need different merchant copy:
346
+
347
+ ```ts
348
+ if (e instanceof CreditLimitReachedError) {
349
+ if (e.availableMinor === undefined) {
350
+ // No figures in the response (trimmed or proxied body) — generic
351
+ // copy. Not the same as 0, which is the "used up" sentinel below.
352
+ } else if (e.availableMinor > 0) {
353
+ // Limit NOT used up — this one charge is larger than what is left.
354
+ // A smaller order would go through; do not send them to their KAM.
355
+ }
356
+ // Otherwise the ceiling is reached — which can be unpaid invoices
357
+ // rather than this month's spend. getCreditLine() tells you which.
358
+ }
359
+ ```
360
+
361
+ The figures are optional for that reason: coercing an absent
362
+ `availableMinor` to `0` would silently claim the limit is used up.
363
+
364
+ Also: `CreditLineNotFoundError` (404 — a prepaid merchant, not a
365
+ failure), `CreditBreakupRequiredError`, `CreditOverrideRefusedError`,
366
+ `CreditTopUpRefusedError`, `CreditIdempotencyConflictError`,
367
+ `CreditCorrectionReasonRequiredError` (400 — a reversed invoice is being
368
+ re-settled for different figures; pass `reason`),
369
+ `CreditCurrencyConflictError` and `CreditCurrencyMismatchError` (409 —
370
+ neither is caller-retryable; see their docblocks),
371
+ `SettlementNotFoundError`, plus the
372
+ pre-existing `InsufficientBalanceError`, `OverRefundError`,
373
+ `InvalidReversalError`, `IdempotencyConflictError`,
374
+ `WalletIdentityMismatchError`, `UnresolvableWalletError`,
375
+ `WalletNotFoundError`.
376
+
377
+ ### Money
378
+
379
+ Every figure is `{ amount, amountMinor }`. **Compute in `amountMinor`**
380
+ (integer paise); `amount` is for display. On a ledger row `amount` is
381
+ **gross** and `breakup.subTotalMinor` is what consumed the ceiling —
382
+ `creditMerchantId` present means the row's `balanceBefore`/`balanceAfter`
383
+ are available credit rather than a wallet balance.
384
+
232
385
  ## Auth helpers
233
386
 
234
387
  ```ts
@@ -1,2 +1,2 @@
1
1
  export { upsell, createUpsellClient, UpsellApiError, type UpsellClient, type UpsellClientOptions, type UpsellEnv, } from './client';
2
- export type { Cart, CartItem, Channel, KnownLayout, LadderRung, Layout, Placement, PlacementDeleteInput, PlacementDisplay, PlacementRecord, PlacementScope, PlacementUpsertInput, PlacementsQuery, ReasonCode, StrategyParams, SuggestionsInput, SuggestionsResult, Tenant, Touchpoint, UpsellEvent, UpsellEventType, UpsellEventsInput, UpsellItem, UpsellStrategy, } from './schema';
2
+ export type { Cart, CartItem, Channel, ItemSource, KnownLayout, LadderRung, Layout, Placement, PlacementDeleteInput, PlacementDisplay, PlacementRecord, PlacementScope, PlacementUpsertInput, PlacementsQuery, ReasonCode, StrategyParams, SuggestionsInput, SuggestionsResult, Tenant, Touchpoint, UpsellEvent, UpsellEventType, UpsellEventsInput, UpsellItem, UpsellStrategy, } from './schema';
@@ -5,4 +5,4 @@ var client_1 = require("./client");
5
5
  Object.defineProperty(exports, "upsell", { enumerable: true, get: function () { return client_1.upsell; } });
6
6
  Object.defineProperty(exports, "createUpsellClient", { enumerable: true, get: function () { return client_1.createUpsellClient; } });
7
7
  Object.defineProperty(exports, "UpsellApiError", { enumerable: true, get: function () { return client_1.UpsellApiError; } });
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXBzZWxsL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQU9rQjtBQU5oQixnR0FBQSxNQUFNLE9BQUE7QUFDTiw0R0FBQSxrQkFBa0IsT0FBQTtBQUNsQix3R0FBQSxjQUFjLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge1xuICB1cHNlbGwsXG4gIGNyZWF0ZVVwc2VsbENsaWVudCxcbiAgVXBzZWxsQXBpRXJyb3IsXG4gIHR5cGUgVXBzZWxsQ2xpZW50LFxuICB0eXBlIFVwc2VsbENsaWVudE9wdGlvbnMsXG4gIHR5cGUgVXBzZWxsRW52LFxufSBmcm9tICcuL2NsaWVudCc7XG5leHBvcnQgdHlwZSB7XG4gIENhcnQsXG4gIENhcnRJdGVtLFxuICBDaGFubmVsLFxuICBLbm93bkxheW91dCxcbiAgTGFkZGVyUnVuZyxcbiAgTGF5b3V0LFxuICBQbGFjZW1lbnQsXG4gIFBsYWNlbWVudERlbGV0ZUlucHV0LFxuICBQbGFjZW1lbnREaXNwbGF5LFxuICBQbGFjZW1lbnRSZWNvcmQsXG4gIFBsYWNlbWVudFNjb3BlLFxuICBQbGFjZW1lbnRVcHNlcnRJbnB1dCxcbiAgUGxhY2VtZW50c1F1ZXJ5LFxuICBSZWFzb25Db2RlLFxuICBTdHJhdGVneVBhcmFtcyxcbiAgU3VnZ2VzdGlvbnNJbnB1dCxcbiAgU3VnZ2VzdGlvbnNSZXN1bHQsXG4gIFRlbmFudCxcbiAgVG91Y2hwb2ludCxcbiAgVXBzZWxsRXZlbnQsXG4gIFVwc2VsbEV2ZW50VHlwZSxcbiAgVXBzZWxsRXZlbnRzSW5wdXQsXG4gIFVwc2VsbEl0ZW0sXG4gIFVwc2VsbFN0cmF0ZWd5LFxufSBmcm9tICcuL3NjaGVtYSc7XG4iXX0=
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXBzZWxsL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQU9rQjtBQU5oQixnR0FBQSxNQUFNLE9BQUE7QUFDTiw0R0FBQSxrQkFBa0IsT0FBQTtBQUNsQix3R0FBQSxjQUFjLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge1xuICB1cHNlbGwsXG4gIGNyZWF0ZVVwc2VsbENsaWVudCxcbiAgVXBzZWxsQXBpRXJyb3IsXG4gIHR5cGUgVXBzZWxsQ2xpZW50LFxuICB0eXBlIFVwc2VsbENsaWVudE9wdGlvbnMsXG4gIHR5cGUgVXBzZWxsRW52LFxufSBmcm9tICcuL2NsaWVudCc7XG5leHBvcnQgdHlwZSB7XG4gIENhcnQsXG4gIENhcnRJdGVtLFxuICBDaGFubmVsLFxuICBJdGVtU291cmNlLFxuICBLbm93bkxheW91dCxcbiAgTGFkZGVyUnVuZyxcbiAgTGF5b3V0LFxuICBQbGFjZW1lbnQsXG4gIFBsYWNlbWVudERlbGV0ZUlucHV0LFxuICBQbGFjZW1lbnREaXNwbGF5LFxuICBQbGFjZW1lbnRSZWNvcmQsXG4gIFBsYWNlbWVudFNjb3BlLFxuICBQbGFjZW1lbnRVcHNlcnRJbnB1dCxcbiAgUGxhY2VtZW50c1F1ZXJ5LFxuICBSZWFzb25Db2RlLFxuICBTdHJhdGVneVBhcmFtcyxcbiAgU3VnZ2VzdGlvbnNJbnB1dCxcbiAgU3VnZ2VzdGlvbnNSZXN1bHQsXG4gIFRlbmFudCxcbiAgVG91Y2hwb2ludCxcbiAgVXBzZWxsRXZlbnQsXG4gIFVwc2VsbEV2ZW50VHlwZSxcbiAgVXBzZWxsRXZlbnRzSW5wdXQsXG4gIFVwc2VsbEl0ZW0sXG4gIFVwc2VsbFN0cmF0ZWd5LFxufSBmcm9tICcuL3NjaGVtYSc7XG4iXX0=
@@ -23,9 +23,28 @@ export type KnownLayout = 'carousel_2up' | 'horizontal_carousel' | 'grid_2xn_mod
23
23
  export type Layout = KnownLayout | (string & {});
24
24
  /** Why an item was recommended. Channels render these in customer language. */
25
25
  export type ReasonCode = 'popular_now' | 'completes_meal' | 'often_ordered_together' | 'your_usual' | 'chefs_pick';
26
+ /**
27
+ * Which layer produced an item.
28
+ *
29
+ * Separate from `reasonCode` on purpose: `reasonCode` is customer-facing
30
+ * copy the channel renders ("Popular right now"), so overloading it with
31
+ * provenance would change the customer's visible label whenever the
32
+ * source changed.
33
+ *
34
+ * algorithm — scored by the engine, priority pins included
35
+ * merchant_list — the merchant's own list replaced the algorithm
36
+ * fallback — topped up from the backup list, safety rules only
37
+ */
38
+ export type ItemSource = 'algorithm' | 'merchant_list' | 'fallback';
26
39
  /** Which rung of the resolution ladder answered the request. */
27
40
  export type LadderRung = 'full_engine' | 'band_relaxation' | 'popularity_floor' | 'backup_suggestions' | 'empty_degraded';
28
- export type UpsellStrategy = 'menu-order-popularity' | 'legacy-catalog-sample';
41
+ export type UpsellStrategy = 'menu-order-popularity' | 'legacy-catalog-sample'
42
+ /**
43
+ * The merchant's own list replaces the algorithm at this placement.
44
+ * Requires `strategyParams.merchantListItemSlugs`; an empty list falls
45
+ * back to `menu-order-popularity` rather than serving nothing.
46
+ */
47
+ | 'merchant-list';
29
48
  export interface PlacementDisplay {
30
49
  title: string;
31
50
  /** Requested count. Touchpoint policy may cap it lower — see `meta.maxItems`. */
@@ -96,6 +115,16 @@ export interface UpsellItem {
96
115
  veg: number | null;
97
116
  brandId: number | null;
98
117
  reasonCode: ReasonCode;
118
+ /**
119
+ * Which layer produced this item.
120
+ *
121
+ * Optional on purpose, and it stays optional. The service always sets
122
+ * it, but an SDK is routinely newer than the deployment it talks to —
123
+ * typing it as required would let TypeScript promise a string that is
124
+ * `undefined` at runtime against any service older than the release
125
+ * that added it. Narrow it yourself if you have pinned both.
126
+ */
127
+ source?: ItemSource;
99
128
  }
100
129
  export interface SuggestionsResult {
101
130
  placement: string;
@@ -105,8 +134,21 @@ export interface SuggestionsResult {
105
134
  enabled: boolean;
106
135
  strategy: UpsellStrategy;
107
136
  configVersion: string;
108
- /** Which ladder rung produced these items. */
137
+ /**
138
+ * The step that PRIMARILY answered — the first one to contribute.
139
+ *
140
+ * Since the ladder became a fill loop, several steps can contribute
141
+ * to one response; `rung` names the one that answered first, so a
142
+ * healthy card that merely topped up its last slot does not read as
143
+ * fully degraded. Read `steps` for how far down it went.
144
+ */
109
145
  rung: LadderRung;
146
+ /**
147
+ * Every step that contributed at least one item, in the order they
148
+ * ran. Optional for the same reason as `UpsellItem.source`: an older
149
+ * service does not send it.
150
+ */
151
+ steps?: LadderRung[];
110
152
  /** Effective cap applied: min(display.maxItems, touchpoint policy). */
111
153
  maxItems: number;
112
154
  /** How long the client may reuse this response, in seconds. */
@@ -124,8 +166,25 @@ export interface StrategyParams {
124
166
  neverSuggestItemSlugs?: string[];
125
167
  /** "My Priority Items" — occupy reserved slots ahead of scored items. */
126
168
  priorityItemSlugs?: string[];
127
- /** "Backup Suggestions" — 2-6 items, served when everything else is empty. */
169
+ /**
170
+ * "Backup Suggestions" — up to 6 items. Skips the price band (the band
171
+ * is usually what emptied the pool) but still respects stock, cart,
172
+ * exclusions, diet and `maxPrice`. It TOPS UP a short list rather than
173
+ * only firing when everything else returned nothing, so one scored
174
+ * item plus two backup items is a valid response.
175
+ */
128
176
  backupItemSlugs?: string[];
177
+ /**
178
+ * The merchant's own list for this placement, up to 12 items. Only read
179
+ * when `strategy` is `merchant-list`.
180
+ *
181
+ * Distinct from `includedItemSlugs`, which is a FILTER over the whole
182
+ * menu — items still get ranked by the strategy and still report as
183
+ * `source: 'algorithm'`. This REPLACES the pool, rotates within it so a
184
+ * 10-item list on a 3-slot card shows all ten over time, and reports as
185
+ * `source: 'merchant_list'`.
186
+ */
187
+ merchantListItemSlugs?: string[];
129
188
  excludeCartItems?: boolean;
130
189
  maxPrice?: number;
131
190
  }
@@ -187,6 +246,12 @@ export interface PlacementsQuery {
187
246
  export type UpsellEventType = 'shown' | 'added' | 'ignored';
188
247
  export interface UpsellEvent {
189
248
  type: UpsellEventType;
249
+ /**
250
+ * Echo the item's `source`. This is what makes "is my list performing
251
+ * better than your algorithm?" answerable — attach rate is only
252
+ * comparable by layer if the layer is recorded on the event.
253
+ */
254
+ source?: ItemSource;
190
255
  itemId: number;
191
256
  reasonCode?: ReasonCode;
192
257
  /** ISO-8601. Defaults to server receive time when omitted. */
@@ -9,4 +9,4 @@
9
9
  * admin methods.
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Vwc2VsbC9zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7OztHQVFHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUeXBlIHN1cmZhY2UgZm9yIHRoZSBwbGF0Zm9ybSBVcHNlbGwgQVBJLlxuICpcbiAqIFR3byBjb25zdW1lci1mYWNpbmcgY2FsbHM6IGBwbGFjZW1lbnRzKC4uLilgICh3aGljaCB1cHNlbGwgc3VyZmFjZXMgYVxuICogY2hhbm5lbCBzaG91bGQgcmVuZGVyIGZvciBhIHRlbmFudCkgYW5kIGBzdWdnZXN0KC4uLilgIChpdGVtcyBmb3Igb25lXG4gKiBwbGFjZW1lbnQgZ2l2ZW4gdGhlIGxpdmUgY2FydCkuIGByZXBvcnRFdmVudHMoLi4uKWAgZmVlZHMgYXR0YWNoLXJhdGVcbiAqIHRlbGVtZXRyeS4gUGxhY2VtZW50IGNvbmZpZyBpcyBtYW5hZ2VkIHZpYSB0aGUgc2VydmljZS1hY3Rvci1vbmx5XG4gKiBhZG1pbiBtZXRob2RzLlxuICovXG5cbmV4cG9ydCB0eXBlIENoYW5uZWwgPSAnbW9iaWxlX2FwcCcgfCAna2lvc2snIHwgJ3doaXRlbGFiZWxfd2ViJyB8ICd3aGF0c2FwcCcgfCAndm9pY2UnO1xuXG4vKipcbiAqIEEgbW9tZW50IGluIHRoZSBjdXN0b21lciBqb3VybmV5IOKAlCB0aGUgdW5pdCBvZiBwbGF0Zm9ybSBwb2xpY3lcbiAqIChwcmljZSBiYW5kLCBtYXggaXRlbXMsIGFuZCBsYXRlciB0aGUgc2lnbmFsIHdlaWdodCBwcm9maWxlKS4gQVxuICogcGxhY2VtZW50IGlzIGEgY2hhbm5lbCdzIGpvdXJuZXkgbGFiZWwgcG9pbnRpbmcgYXQgb25lIG9mIHRoZXNlLlxuICovXG5leHBvcnQgdHlwZSBUb3VjaHBvaW50ID1cbiAgfCAnaG9tZSdcbiAgfCAnbWVudV9icm93c2luZydcbiAgfCAnbWVudV9jb21wb3NpbmcnXG4gIHwgJ3NlYXJjaF9ub19yZXN1bHQnXG4gIHwgJ2NhcnQnXG4gIHwgJ3ByZV9jaGVja291dCdcbiAgfCAncG9zdF9vcmRlcic7XG5cbi8qKlxuICogUmVuZGVyaW5nIGhpbnQsIG93bmVkIGJ5IHRoZSBjaGFubmVsIGZyb250ZW5kIOKAlCB0aGUgcGxhdGZvcm0gbmV2ZXJcbiAqIGludGVycHJldHMgaXQuIEtub3duIHZhbHVlcyBhcmUgbGlzdGVkIGZvciBlZGl0b3IgY29tcGxldGlvbiwgYnV0IGFueVxuICogbG93ZXJjYXNlIGlkZW50aWZpZXIgaXMgdmFsaWQgc28gbmV3IGxheW91dHMgbmVlZCBubyBTREsgcmVsZWFzZS5cbiAqL1xuZXhwb3J0IHR5cGUgS25vd25MYXlvdXQgPVxuICB8ICdjYXJvdXNlbF8ydXAnXG4gIHwgJ2hvcml6b250YWxfY2Fyb3VzZWwnXG4gIHwgJ2dyaWRfMnhuX21vZGFsJ1xuICB8ICdjYXJvdXNlbF8xdXAnXG4gIHwgJ3ZlcnRpY2FsX2xpc3QnXG4gIHwgJ2dyaWRfM3huJ1xuICB8ICdjb21wYWN0X2xpc3QnXG4gIHwgJ2hlcm9fYmFubmVyJztcblxuZXhwb3J0IHR5cGUgTGF5b3V0ID0gS25vd25MYXlvdXQgfCAoc3RyaW5nICYge30pO1xuXG4vKiogV2h5IGFuIGl0ZW0gd2FzIHJlY29tbWVuZGVkLiBDaGFubmVscyByZW5kZXIgdGhlc2UgaW4gY3VzdG9tZXIgbGFuZ3VhZ2UuICovXG5leHBvcnQgdHlwZSBSZWFzb25Db2RlID1cbiAgfCAncG9wdWxhcl9ub3cnXG4gIHwgJ2NvbXBsZXRlc19tZWFsJ1xuICB8ICdvZnRlbl9vcmRlcmVkX3RvZ2V0aGVyJ1xuICB8ICd5b3VyX3VzdWFsJ1xuICB8ICdjaGVmc19waWNrJztcblxuLyoqIFdoaWNoIHJ1bmcgb2YgdGhlIHJlc29sdXRpb24gbGFkZGVyIGFuc3dlcmVkIHRoZSByZXF1ZXN0LiAqL1xuZXhwb3J0IHR5cGUgTGFkZGVyUnVuZyA9XG4gIHwgJ2Z1bGxfZW5naW5lJ1xuICB8ICdiYW5kX3JlbGF4YXRpb24nXG4gIHwgJ3BvcHVsYXJpdHlfZmxvb3InXG4gIHwgJ2JhY2t1cF9zdWdnZXN0aW9ucydcbiAgfCAnZW1wdHlfZGVncmFkZWQnO1xuXG5leHBvcnQgdHlwZSBVcHNlbGxTdHJhdGVneSA9ICdtZW51LW9yZGVyLXBvcHVsYXJpdHknIHwgJ2xlZ2FjeS1jYXRhbG9nLXNhbXBsZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50RGlzcGxheSB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIC8qKiBSZXF1ZXN0ZWQgY291bnQuIFRvdWNocG9pbnQgcG9saWN5IG1heSBjYXAgaXQgbG93ZXIg4oCUIHNlZSBgbWV0YS5tYXhJdGVtc2AuICovXG4gIG1heEl0ZW1zOiBudW1iZXI7XG4gIGxheW91dDogTGF5b3V0O1xufVxuXG4vKiogUmVzb2x2ZWQgcHVibGljIHBsYWNlbWVudCAoYnVzaW5lc3Mgb3ZlcnJpZGUgPiBicmFuZCA+IHBsYXRmb3JtIGRlZmF1bHQpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnQge1xuICBrZXk6IHN0cmluZztcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAgdG91Y2hwb2ludDogVG91Y2hwb2ludDtcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgZGlzcGxheTogUGxhY2VtZW50RGlzcGxheTtcbiAgY29uZmlnVmVyc2lvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbmFudCB7XG4gIHBhcmVudElkOiBudW1iZXI7XG4gIGJ1c2luZXNzSWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYXJ0SXRlbSB7XG4gIGl0ZW1JZDogbnVtYmVyO1xuICBxdHk6IG51bWJlcjtcbiAgdW5pdFByaWNlOiBudW1iZXI7XG4gIC8qKiBPcHRpb25hbDsgbGV0cyB0aGUgZGlldGFyeSBnYXRlIGFuZCBjYXRlZ29yeSBuby1yZXBlYXQgc2VlIGNhcnQgY29udGVudHMuICovXG4gIGl0ZW1TbHVnPzogc3RyaW5nO1xuICBzZWN0aW9uTmFtZT86IHN0cmluZztcbiAgLyoqIExlZ2FjeSB2ZWdOb252ZWdCb3RoIGZsYWc6IDEgdmVnLCAyIG5vbi12ZWcsIDMgYm90aC9lZ2cuICovXG4gIHZlZz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYXJ0IHtcbiAgaXRlbXM6IENhcnRJdGVtW107XG4gIHN1YnRvdGFsOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VnZ2VzdGlvbnNJbnB1dCB7XG4gIGNoYW5uZWw6IENoYW5uZWw7XG4gIHBsYWNlbWVudDogc3RyaW5nO1xuICB0ZW5hbnQ6IFRlbmFudDtcbiAgY29udGV4dDoge1xuICAgIGNhcnQ6IENhcnQ7XG4gICAgZnVsZmlsbWVudE1vZGU/OiAnZGVsaXZlcnknIHwgJ3BpY2t1cCcgfCAnZGluZV9pbic7XG4gICAgLyoqXG4gICAgICogT3B0aW9uYWw7IHVudXNlZCBieSB0aGUgdjEgc2NvcmVycy4gSW4gdGhlIGNvbnRyYWN0IGZyb20gZGF5IG9uZVxuICAgICAqIHNvIHBlcnNvbmFsaXphdGlvbiBsYW5kcyB3aXRob3V0IGEgYnJlYWsuIGBpZGAgTVVTVCBiZSB0aGUgb3BhcXVlXG4gICAgICogcGxhdGZvcm0gY3VzdG9tZXIgaWQsIG5ldmVyIGEgbW9iaWxlIG51bWJlci5cbiAgICAgKi9cbiAgICBjdXN0b21lcj86IHsgaWQ6IHN0cmluZyB9O1xuICAgIC8qKlxuICAgICAqIE9wdGlvbmFsOyBub3QgeWV0IGFjdGVkIG9uLiBJbXByZXNzaW9uIGZhdGlndWUgaXMgc2Vzc2lvbi1zY29wZWRcbiAgICAgKiBhbmQgc2hhcmVkIGFjcm9zcyB0b3VjaHBvaW50cyDigJQgc2VuZCBpdCBub3cgc28gY2hhbm5lbHNcbiAgICAgKiBpbnN0cnVtZW50IG9uY2UgcmF0aGVyIHRoYW4gdHdpY2UuXG4gICAgICovXG4gICAgc2Vzc2lvbklkPzogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2VsbEl0ZW0ge1xuICBpdGVtSWQ6IG51bWJlcjtcbiAgaXRlbU5hbWU6IHN0cmluZztcbiAgaXRlbVNsdWc6IHN0cmluZyB8IG51bGw7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmcgfCBudWxsO1xuICBzZWN0aW9uSWQ6IG51bWJlciB8IG51bGw7XG4gIHNlY3Rpb25OYW1lOiBzdHJpbmcgfCBudWxsO1xuICAvKiogU2VsbGluZyBwcmljZSAoSU5SKS4gKi9cbiAgcHJpY2U6IG51bWJlcjtcbiAgaW1hZ2U6IHN0cmluZyB8IG51bGw7XG4gIC8qKiBSYXcgbGVnYWN5IGB2ZWdOb252ZWdCb3RoYCBmbGFnLCBwYXNzZWQgdGhyb3VnaCB1bnRyYW5zbGF0ZWQuICovXG4gIHZlZzogbnVtYmVyIHwgbnVsbDtcbiAgYnJhbmRJZDogbnVtYmVyIHwgbnVsbDtcbiAgcmVhc29uQ29kZTogUmVhc29uQ29kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdWdnZXN0aW9uc1Jlc3VsdCB7XG4gIHBsYWNlbWVudDogc3RyaW5nO1xuICB0b3VjaHBvaW50OiBUb3VjaHBvaW50O1xuICBpdGVtczogVXBzZWxsSXRlbVtdO1xuICBtZXRhOiB7XG4gICAgZW5hYmxlZDogYm9vbGVhbjtcbiAgICBzdHJhdGVneTogVXBzZWxsU3RyYXRlZ3k7XG4gICAgY29uZmlnVmVyc2lvbjogc3RyaW5nO1xuICAgIC8qKiBXaGljaCBsYWRkZXIgcnVuZyBwcm9kdWNlZCB0aGVzZSBpdGVtcy4gKi9cbiAgICBydW5nOiBMYWRkZXJSdW5nO1xuICAgIC8qKiBFZmZlY3RpdmUgY2FwIGFwcGxpZWQ6IG1pbihkaXNwbGF5Lm1heEl0ZW1zLCB0b3VjaHBvaW50IHBvbGljeSkuICovXG4gICAgbWF4SXRlbXM6IG51bWJlcjtcbiAgICAvKiogSG93IGxvbmcgdGhlIGNsaWVudCBtYXkgcmV1c2UgdGhpcyByZXNwb25zZSwgaW4gc2Vjb25kcy4gKi9cbiAgICB0dGxTZWNvbmRzOiBudW1iZXI7XG4gICAgLyoqIFRydWUgd2hlbiB0aGUgY2FuZGlkYXRlIHNvdXJjZSBmYWlsZWQgYW5kIHRoZSBzZXJ2aWNlIGRlZ3JhZGVkIHRvIGVtcHR5LiAqL1xuICAgIGRlZ3JhZGVkPzogYm9vbGVhbjtcbiAgfTtcbn1cblxuLyoqIE1lcmNoYW50LWNvbnRyb2xsZWQgc2VsZWN0aW9uIGlucHV0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyYXRlZ3lQYXJhbXMge1xuICBpbmNsdWRlZEl0ZW1TbHVncz86IHN0cmluZ1tdO1xuICBpbmNsdWRlZFNlY3Rpb25zPzogc3RyaW5nW107XG4gIGV4Y2x1ZGVkU2VjdGlvbnM/OiBzdHJpbmdbXTtcbiAgLyoqIFwiTmV2ZXIgU3VnZ2VzdCBUaGVzZVwiIOKAlCBhYnNvbHV0ZSwgb3ZlcnJpZGVzIHRoZSBwcmlvcml0eSBsaXN0LiAqL1xuICBuZXZlclN1Z2dlc3RJdGVtU2x1Z3M/OiBzdHJpbmdbXTtcbiAgLyoqIFwiTXkgUHJpb3JpdHkgSXRlbXNcIiDigJQgb2NjdXB5IHJlc2VydmVkIHNsb3RzIGFoZWFkIG9mIHNjb3JlZCBpdGVtcy4gKi9cbiAgcHJpb3JpdHlJdGVtU2x1Z3M/OiBzdHJpbmdbXTtcbiAgLyoqIFwiQmFja3VwIFN1Z2dlc3Rpb25zXCIg4oCUIDItNiBpdGVtcywgc2VydmVkIHdoZW4gZXZlcnl0aGluZyBlbHNlIGlzIGVtcHR5LiAqL1xuICBiYWNrdXBJdGVtU2x1Z3M/OiBzdHJpbmdbXTtcbiAgZXhjbHVkZUNhcnRJdGVtcz86IGJvb2xlYW47XG4gIG1heFByaWNlPzogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBQbGFjZW1lbnRTY29wZSA9ICdkZWZhdWx0JyB8ICd0ZW5hbnQnIHwgJ2J1c2luZXNzJztcblxuLyoqIFJhdyBhZG1pbi1wbGFuZSBjb25maWcgcm93IChubyBwcmVjZWRlbmNlIG1lcmdlIGFwcGxpZWQpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRSZWNvcmQge1xuICBzY29wZTogUGxhY2VtZW50U2NvcGU7XG4gIHBhcmVudElkPzogbnVtYmVyO1xuICBidXNpbmVzc0lkPzogbnVtYmVyO1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBrZXk6IHN0cmluZztcbiAgdG91Y2hwb2ludDogVG91Y2hwb2ludDtcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgZGlzcGxheTogUGxhY2VtZW50RGlzcGxheTtcbiAgc3RyYXRlZ3k6IFVwc2VsbFN0cmF0ZWd5O1xuICBzdHJhdGVneVBhcmFtczogU3RyYXRlZ3lQYXJhbXM7XG4gIGNvbmZpZ1ZlcnNpb246IHN0cmluZztcbiAgdXBkYXRlZEF0OiBzdHJpbmc7XG4gIHVwZGF0ZWRCeTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFkbWluIHVwc2VydC4gU2NvcGUgaXMgZGVyaXZlZDogbm8gcGFyZW50SWQg4oaSIHBsYXRmb3JtIGRlZmF1bHQ7XG4gKiBwYXJlbnRJZCBvbmx5IOKGkiBicmFuZCByb3c7IHBhcmVudElkICsgYnVzaW5lc3NJZCDihpIgYnVzaW5lc3Mgb3ZlcnJpZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50VXBzZXJ0SW5wdXQge1xuICBwYXJlbnRJZD86IG51bWJlcjtcbiAgYnVzaW5lc3NJZD86IG51bWJlcjtcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAga2V5OiBzdHJpbmc7XG4gIHRvdWNocG9pbnQ6IFRvdWNocG9pbnQ7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGRpc3BsYXk6IFBsYWNlbWVudERpc3BsYXk7XG4gIHN0cmF0ZWd5PzogVXBzZWxsU3RyYXRlZ3k7XG4gIHN0cmF0ZWd5UGFyYW1zPzogU3RyYXRlZ3lQYXJhbXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50RGVsZXRlSW5wdXQge1xuICBwYXJlbnRJZD86IG51bWJlcjtcbiAgYnVzaW5lc3NJZD86IG51bWJlcjtcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAga2V5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSZXF1aXJlZCBieSB0aGUgc2VydmVyIHdoZW4gYHBhcmVudElkYCBpcyBvbWl0dGVkLCBiZWNhdXNlIHRoYXQgY2FsbFxuICAgKiB0YXJnZXRzIHRoZSBQTEFURk9STSBERUZBVUxUIHJvdyBhbmQgc28gcmVtb3ZlcyB0aGUgcGxhY2VtZW50IGZvclxuICAgKiBldmVyeSB0ZW5hbnQgdGhhdCBoYXMgbm90IG92ZXJyaWRkZW4gaXQuIFdpdGhvdXQgdGhpcyB0aGUgc2VydmVyXG4gICAqIHJlamVjdHMgdGhlIHJlcXVlc3Qgd2l0aCA0MDAgcmF0aGVyIHRoYW4gZ3Vlc3NpbmcgdGhhdCBhIG1pc3NpbmdcbiAgICogcGFyZW50SWQgd2FzIGRlbGliZXJhdGUuXG4gICAqXG4gICAqIERlbGliZXJhdGVseSBub3QgZGVmYXVsdGVkIHRvIGB0cnVlYCBoZXJlOiB0aGUgd2hvbGUgcG9pbnQgb2YgdGhlXG4gICAqIGZsYWcgaXMgdGhhdCBkZWxldGluZyBhIGRlZmF1bHQgbXVzdCBiZSBzdGF0ZWQsIG5vdCBpbmZlcnJlZCBmcm9tXG4gICAqIHRoZSBzaGFwZSBvZiB0aGUgY2FsbC5cbiAgICovXG4gIGNvbmZpcm1EZWxldGVEZWZhdWx0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRzUXVlcnkge1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBwYXJlbnRJZDogbnVtYmVyO1xuICBidXNpbmVzc0lkOiBudW1iZXI7XG59XG5cbi8vIOKUgOKUgOKUgCBBdHRhY2gtcmF0ZSB0ZWxlbWV0cnkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCB0eXBlIFVwc2VsbEV2ZW50VHlwZSA9ICdzaG93bicgfCAnYWRkZWQnIHwgJ2lnbm9yZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2VsbEV2ZW50IHtcbiAgdHlwZTogVXBzZWxsRXZlbnRUeXBlO1xuICBpdGVtSWQ6IG51bWJlcjtcbiAgcmVhc29uQ29kZT86IFJlYXNvbkNvZGU7XG4gIC8qKiBJU08tODYwMS4gRGVmYXVsdHMgdG8gc2VydmVyIHJlY2VpdmUgdGltZSB3aGVuIG9taXR0ZWQuICovXG4gIG9jY3VycmVkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBzZWxsRXZlbnRzSW5wdXQge1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBwbGFjZW1lbnQ6IHN0cmluZztcbiAgdGVuYW50OiBUZW5hbnQ7XG4gIHNlc3Npb25JZD86IHN0cmluZztcbiAgLyoqIEVjaG8gYG1ldGEuY29uZmlnVmVyc2lvbmAgZnJvbSB0aGUgcmVzcG9uc2UgYmVpbmcgcmVwb3J0ZWQgb24uICovXG4gIGNvbmZpZ1ZlcnNpb24/OiBzdHJpbmc7XG4gIGV2ZW50czogVXBzZWxsRXZlbnRbXTtcbn1cbiJdfQ==
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Vwc2VsbC9zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7OztHQVFHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUeXBlIHN1cmZhY2UgZm9yIHRoZSBwbGF0Zm9ybSBVcHNlbGwgQVBJLlxuICpcbiAqIFR3byBjb25zdW1lci1mYWNpbmcgY2FsbHM6IGBwbGFjZW1lbnRzKC4uLilgICh3aGljaCB1cHNlbGwgc3VyZmFjZXMgYVxuICogY2hhbm5lbCBzaG91bGQgcmVuZGVyIGZvciBhIHRlbmFudCkgYW5kIGBzdWdnZXN0KC4uLilgIChpdGVtcyBmb3Igb25lXG4gKiBwbGFjZW1lbnQgZ2l2ZW4gdGhlIGxpdmUgY2FydCkuIGByZXBvcnRFdmVudHMoLi4uKWAgZmVlZHMgYXR0YWNoLXJhdGVcbiAqIHRlbGVtZXRyeS4gUGxhY2VtZW50IGNvbmZpZyBpcyBtYW5hZ2VkIHZpYSB0aGUgc2VydmljZS1hY3Rvci1vbmx5XG4gKiBhZG1pbiBtZXRob2RzLlxuICovXG5cbmV4cG9ydCB0eXBlIENoYW5uZWwgPSAnbW9iaWxlX2FwcCcgfCAna2lvc2snIHwgJ3doaXRlbGFiZWxfd2ViJyB8ICd3aGF0c2FwcCcgfCAndm9pY2UnO1xuXG4vKipcbiAqIEEgbW9tZW50IGluIHRoZSBjdXN0b21lciBqb3VybmV5IOKAlCB0aGUgdW5pdCBvZiBwbGF0Zm9ybSBwb2xpY3lcbiAqIChwcmljZSBiYW5kLCBtYXggaXRlbXMsIGFuZCBsYXRlciB0aGUgc2lnbmFsIHdlaWdodCBwcm9maWxlKS4gQVxuICogcGxhY2VtZW50IGlzIGEgY2hhbm5lbCdzIGpvdXJuZXkgbGFiZWwgcG9pbnRpbmcgYXQgb25lIG9mIHRoZXNlLlxuICovXG5leHBvcnQgdHlwZSBUb3VjaHBvaW50ID1cbiAgfCAnaG9tZSdcbiAgfCAnbWVudV9icm93c2luZydcbiAgfCAnbWVudV9jb21wb3NpbmcnXG4gIHwgJ3NlYXJjaF9ub19yZXN1bHQnXG4gIHwgJ2NhcnQnXG4gIHwgJ3ByZV9jaGVja291dCdcbiAgfCAncG9zdF9vcmRlcic7XG5cbi8qKlxuICogUmVuZGVyaW5nIGhpbnQsIG93bmVkIGJ5IHRoZSBjaGFubmVsIGZyb250ZW5kIOKAlCB0aGUgcGxhdGZvcm0gbmV2ZXJcbiAqIGludGVycHJldHMgaXQuIEtub3duIHZhbHVlcyBhcmUgbGlzdGVkIGZvciBlZGl0b3IgY29tcGxldGlvbiwgYnV0IGFueVxuICogbG93ZXJjYXNlIGlkZW50aWZpZXIgaXMgdmFsaWQgc28gbmV3IGxheW91dHMgbmVlZCBubyBTREsgcmVsZWFzZS5cbiAqL1xuZXhwb3J0IHR5cGUgS25vd25MYXlvdXQgPVxuICB8ICdjYXJvdXNlbF8ydXAnXG4gIHwgJ2hvcml6b250YWxfY2Fyb3VzZWwnXG4gIHwgJ2dyaWRfMnhuX21vZGFsJ1xuICB8ICdjYXJvdXNlbF8xdXAnXG4gIHwgJ3ZlcnRpY2FsX2xpc3QnXG4gIHwgJ2dyaWRfM3huJ1xuICB8ICdjb21wYWN0X2xpc3QnXG4gIHwgJ2hlcm9fYmFubmVyJztcblxuZXhwb3J0IHR5cGUgTGF5b3V0ID0gS25vd25MYXlvdXQgfCAoc3RyaW5nICYge30pO1xuXG4vKiogV2h5IGFuIGl0ZW0gd2FzIHJlY29tbWVuZGVkLiBDaGFubmVscyByZW5kZXIgdGhlc2UgaW4gY3VzdG9tZXIgbGFuZ3VhZ2UuICovXG5leHBvcnQgdHlwZSBSZWFzb25Db2RlID1cbiAgfCAncG9wdWxhcl9ub3cnXG4gIHwgJ2NvbXBsZXRlc19tZWFsJ1xuICB8ICdvZnRlbl9vcmRlcmVkX3RvZ2V0aGVyJ1xuICB8ICd5b3VyX3VzdWFsJ1xuICB8ICdjaGVmc19waWNrJztcblxuLyoqXG4gKiBXaGljaCBsYXllciBwcm9kdWNlZCBhbiBpdGVtLlxuICpcbiAqIFNlcGFyYXRlIGZyb20gYHJlYXNvbkNvZGVgIG9uIHB1cnBvc2U6IGByZWFzb25Db2RlYCBpcyBjdXN0b21lci1mYWNpbmdcbiAqIGNvcHkgdGhlIGNoYW5uZWwgcmVuZGVycyAoXCJQb3B1bGFyIHJpZ2h0IG5vd1wiKSwgc28gb3ZlcmxvYWRpbmcgaXQgd2l0aFxuICogcHJvdmVuYW5jZSB3b3VsZCBjaGFuZ2UgdGhlIGN1c3RvbWVyJ3MgdmlzaWJsZSBsYWJlbCB3aGVuZXZlciB0aGVcbiAqIHNvdXJjZSBjaGFuZ2VkLlxuICpcbiAqICAgYWxnb3JpdGhtICAgICDigJQgc2NvcmVkIGJ5IHRoZSBlbmdpbmUsIHByaW9yaXR5IHBpbnMgaW5jbHVkZWRcbiAqICAgbWVyY2hhbnRfbGlzdCDigJQgdGhlIG1lcmNoYW50J3Mgb3duIGxpc3QgcmVwbGFjZWQgdGhlIGFsZ29yaXRobVxuICogICBmYWxsYmFjayAgICAgIOKAlCB0b3BwZWQgdXAgZnJvbSB0aGUgYmFja3VwIGxpc3QsIHNhZmV0eSBydWxlcyBvbmx5XG4gKi9cbmV4cG9ydCB0eXBlIEl0ZW1Tb3VyY2UgPSAnYWxnb3JpdGhtJyB8ICdtZXJjaGFudF9saXN0JyB8ICdmYWxsYmFjayc7XG5cbi8qKiBXaGljaCBydW5nIG9mIHRoZSByZXNvbHV0aW9uIGxhZGRlciBhbnN3ZXJlZCB0aGUgcmVxdWVzdC4gKi9cbmV4cG9ydCB0eXBlIExhZGRlclJ1bmcgPVxuICB8ICdmdWxsX2VuZ2luZSdcbiAgfCAnYmFuZF9yZWxheGF0aW9uJ1xuICB8ICdwb3B1bGFyaXR5X2Zsb29yJ1xuICB8ICdiYWNrdXBfc3VnZ2VzdGlvbnMnXG4gIHwgJ2VtcHR5X2RlZ3JhZGVkJztcblxuZXhwb3J0IHR5cGUgVXBzZWxsU3RyYXRlZ3kgPVxuICB8ICdtZW51LW9yZGVyLXBvcHVsYXJpdHknXG4gIHwgJ2xlZ2FjeS1jYXRhbG9nLXNhbXBsZSdcbiAgLyoqXG4gICAqIFRoZSBtZXJjaGFudCdzIG93biBsaXN0IHJlcGxhY2VzIHRoZSBhbGdvcml0aG0gYXQgdGhpcyBwbGFjZW1lbnQuXG4gICAqIFJlcXVpcmVzIGBzdHJhdGVneVBhcmFtcy5tZXJjaGFudExpc3RJdGVtU2x1Z3NgOyBhbiBlbXB0eSBsaXN0IGZhbGxzXG4gICAqIGJhY2sgdG8gYG1lbnUtb3JkZXItcG9wdWxhcml0eWAgcmF0aGVyIHRoYW4gc2VydmluZyBub3RoaW5nLlxuICAgKi9cbiAgfCAnbWVyY2hhbnQtbGlzdCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50RGlzcGxheSB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIC8qKiBSZXF1ZXN0ZWQgY291bnQuIFRvdWNocG9pbnQgcG9saWN5IG1heSBjYXAgaXQgbG93ZXIg4oCUIHNlZSBgbWV0YS5tYXhJdGVtc2AuICovXG4gIG1heEl0ZW1zOiBudW1iZXI7XG4gIGxheW91dDogTGF5b3V0O1xufVxuXG4vKiogUmVzb2x2ZWQgcHVibGljIHBsYWNlbWVudCAoYnVzaW5lc3Mgb3ZlcnJpZGUgPiBicmFuZCA+IHBsYXRmb3JtIGRlZmF1bHQpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnQge1xuICBrZXk6IHN0cmluZztcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAgdG91Y2hwb2ludDogVG91Y2hwb2ludDtcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgZGlzcGxheTogUGxhY2VtZW50RGlzcGxheTtcbiAgY29uZmlnVmVyc2lvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbmFudCB7XG4gIHBhcmVudElkOiBudW1iZXI7XG4gIGJ1c2luZXNzSWQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYXJ0SXRlbSB7XG4gIGl0ZW1JZDogbnVtYmVyO1xuICBxdHk6IG51bWJlcjtcbiAgdW5pdFByaWNlOiBudW1iZXI7XG4gIC8qKiBPcHRpb25hbDsgbGV0cyB0aGUgZGlldGFyeSBnYXRlIGFuZCBjYXRlZ29yeSBuby1yZXBlYXQgc2VlIGNhcnQgY29udGVudHMuICovXG4gIGl0ZW1TbHVnPzogc3RyaW5nO1xuICBzZWN0aW9uTmFtZT86IHN0cmluZztcbiAgLyoqIExlZ2FjeSB2ZWdOb252ZWdCb3RoIGZsYWc6IDEgdmVnLCAyIG5vbi12ZWcsIDMgYm90aC9lZ2cuICovXG4gIHZlZz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDYXJ0IHtcbiAgaXRlbXM6IENhcnRJdGVtW107XG4gIHN1YnRvdGFsOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VnZ2VzdGlvbnNJbnB1dCB7XG4gIGNoYW5uZWw6IENoYW5uZWw7XG4gIHBsYWNlbWVudDogc3RyaW5nO1xuICB0ZW5hbnQ6IFRlbmFudDtcbiAgY29udGV4dDoge1xuICAgIGNhcnQ6IENhcnQ7XG4gICAgZnVsZmlsbWVudE1vZGU/OiAnZGVsaXZlcnknIHwgJ3BpY2t1cCcgfCAnZGluZV9pbic7XG4gICAgLyoqXG4gICAgICogT3B0aW9uYWw7IHVudXNlZCBieSB0aGUgdjEgc2NvcmVycy4gSW4gdGhlIGNvbnRyYWN0IGZyb20gZGF5IG9uZVxuICAgICAqIHNvIHBlcnNvbmFsaXphdGlvbiBsYW5kcyB3aXRob3V0IGEgYnJlYWsuIGBpZGAgTVVTVCBiZSB0aGUgb3BhcXVlXG4gICAgICogcGxhdGZvcm0gY3VzdG9tZXIgaWQsIG5ldmVyIGEgbW9iaWxlIG51bWJlci5cbiAgICAgKi9cbiAgICBjdXN0b21lcj86IHsgaWQ6IHN0cmluZyB9O1xuICAgIC8qKlxuICAgICAqIE9wdGlvbmFsOyBub3QgeWV0IGFjdGVkIG9uLiBJbXByZXNzaW9uIGZhdGlndWUgaXMgc2Vzc2lvbi1zY29wZWRcbiAgICAgKiBhbmQgc2hhcmVkIGFjcm9zcyB0b3VjaHBvaW50cyDigJQgc2VuZCBpdCBub3cgc28gY2hhbm5lbHNcbiAgICAgKiBpbnN0cnVtZW50IG9uY2UgcmF0aGVyIHRoYW4gdHdpY2UuXG4gICAgICovXG4gICAgc2Vzc2lvbklkPzogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2VsbEl0ZW0ge1xuICBpdGVtSWQ6IG51bWJlcjtcbiAgaXRlbU5hbWU6IHN0cmluZztcbiAgaXRlbVNsdWc6IHN0cmluZyB8IG51bGw7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmcgfCBudWxsO1xuICBzZWN0aW9uSWQ6IG51bWJlciB8IG51bGw7XG4gIHNlY3Rpb25OYW1lOiBzdHJpbmcgfCBudWxsO1xuICAvKiogU2VsbGluZyBwcmljZSAoSU5SKS4gKi9cbiAgcHJpY2U6IG51bWJlcjtcbiAgaW1hZ2U6IHN0cmluZyB8IG51bGw7XG4gIC8qKiBSYXcgbGVnYWN5IGB2ZWdOb252ZWdCb3RoYCBmbGFnLCBwYXNzZWQgdGhyb3VnaCB1bnRyYW5zbGF0ZWQuICovXG4gIHZlZzogbnVtYmVyIHwgbnVsbDtcbiAgYnJhbmRJZDogbnVtYmVyIHwgbnVsbDtcbiAgcmVhc29uQ29kZTogUmVhc29uQ29kZTtcbiAgLyoqXG4gICAqIFdoaWNoIGxheWVyIHByb2R1Y2VkIHRoaXMgaXRlbS5cbiAgICpcbiAgICogT3B0aW9uYWwgb24gcHVycG9zZSwgYW5kIGl0IHN0YXlzIG9wdGlvbmFsLiBUaGUgc2VydmljZSBhbHdheXMgc2V0c1xuICAgKiBpdCwgYnV0IGFuIFNESyBpcyByb3V0aW5lbHkgbmV3ZXIgdGhhbiB0aGUgZGVwbG95bWVudCBpdCB0YWxrcyB0byDigJRcbiAgICogdHlwaW5nIGl0IGFzIHJlcXVpcmVkIHdvdWxkIGxldCBUeXBlU2NyaXB0IHByb21pc2UgYSBzdHJpbmcgdGhhdCBpc1xuICAgKiBgdW5kZWZpbmVkYCBhdCBydW50aW1lIGFnYWluc3QgYW55IHNlcnZpY2Ugb2xkZXIgdGhhbiB0aGUgcmVsZWFzZVxuICAgKiB0aGF0IGFkZGVkIGl0LiBOYXJyb3cgaXQgeW91cnNlbGYgaWYgeW91IGhhdmUgcGlubmVkIGJvdGguXG4gICAqL1xuICBzb3VyY2U/OiBJdGVtU291cmNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN1Z2dlc3Rpb25zUmVzdWx0IHtcbiAgcGxhY2VtZW50OiBzdHJpbmc7XG4gIHRvdWNocG9pbnQ6IFRvdWNocG9pbnQ7XG4gIGl0ZW1zOiBVcHNlbGxJdGVtW107XG4gIG1ldGE6IHtcbiAgICBlbmFibGVkOiBib29sZWFuO1xuICAgIHN0cmF0ZWd5OiBVcHNlbGxTdHJhdGVneTtcbiAgICBjb25maWdWZXJzaW9uOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIHN0ZXAgdGhhdCBQUklNQVJJTFkgYW5zd2VyZWQg4oCUIHRoZSBmaXJzdCBvbmUgdG8gY29udHJpYnV0ZS5cbiAgICAgKlxuICAgICAqIFNpbmNlIHRoZSBsYWRkZXIgYmVjYW1lIGEgZmlsbCBsb29wLCBzZXZlcmFsIHN0ZXBzIGNhbiBjb250cmlidXRlXG4gICAgICogdG8gb25lIHJlc3BvbnNlOyBgcnVuZ2AgbmFtZXMgdGhlIG9uZSB0aGF0IGFuc3dlcmVkIGZpcnN0LCBzbyBhXG4gICAgICogaGVhbHRoeSBjYXJkIHRoYXQgbWVyZWx5IHRvcHBlZCB1cCBpdHMgbGFzdCBzbG90IGRvZXMgbm90IHJlYWQgYXNcbiAgICAgKiBmdWxseSBkZWdyYWRlZC4gUmVhZCBgc3RlcHNgIGZvciBob3cgZmFyIGRvd24gaXQgd2VudC5cbiAgICAgKi9cbiAgICBydW5nOiBMYWRkZXJSdW5nO1xuICAgIC8qKlxuICAgICAqIEV2ZXJ5IHN0ZXAgdGhhdCBjb250cmlidXRlZCBhdCBsZWFzdCBvbmUgaXRlbSwgaW4gdGhlIG9yZGVyIHRoZXlcbiAgICAgKiByYW4uIE9wdGlvbmFsIGZvciB0aGUgc2FtZSByZWFzb24gYXMgYFVwc2VsbEl0ZW0uc291cmNlYDogYW4gb2xkZXJcbiAgICAgKiBzZXJ2aWNlIGRvZXMgbm90IHNlbmQgaXQuXG4gICAgICovXG4gICAgc3RlcHM/OiBMYWRkZXJSdW5nW107XG4gICAgLyoqIEVmZmVjdGl2ZSBjYXAgYXBwbGllZDogbWluKGRpc3BsYXkubWF4SXRlbXMsIHRvdWNocG9pbnQgcG9saWN5KS4gKi9cbiAgICBtYXhJdGVtczogbnVtYmVyO1xuICAgIC8qKiBIb3cgbG9uZyB0aGUgY2xpZW50IG1heSByZXVzZSB0aGlzIHJlc3BvbnNlLCBpbiBzZWNvbmRzLiAqL1xuICAgIHR0bFNlY29uZHM6IG51bWJlcjtcbiAgICAvKiogVHJ1ZSB3aGVuIHRoZSBjYW5kaWRhdGUgc291cmNlIGZhaWxlZCBhbmQgdGhlIHNlcnZpY2UgZGVncmFkZWQgdG8gZW1wdHkuICovXG4gICAgZGVncmFkZWQ/OiBib29sZWFuO1xuICB9O1xufVxuXG4vKiogTWVyY2hhbnQtY29udHJvbGxlZCBzZWxlY3Rpb24gaW5wdXRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJhdGVneVBhcmFtcyB7XG4gIGluY2x1ZGVkSXRlbVNsdWdzPzogc3RyaW5nW107XG4gIGluY2x1ZGVkU2VjdGlvbnM/OiBzdHJpbmdbXTtcbiAgZXhjbHVkZWRTZWN0aW9ucz86IHN0cmluZ1tdO1xuICAvKiogXCJOZXZlciBTdWdnZXN0IFRoZXNlXCIg4oCUIGFic29sdXRlLCBvdmVycmlkZXMgdGhlIHByaW9yaXR5IGxpc3QuICovXG4gIG5ldmVyU3VnZ2VzdEl0ZW1TbHVncz86IHN0cmluZ1tdO1xuICAvKiogXCJNeSBQcmlvcml0eSBJdGVtc1wiIOKAlCBvY2N1cHkgcmVzZXJ2ZWQgc2xvdHMgYWhlYWQgb2Ygc2NvcmVkIGl0ZW1zLiAqL1xuICBwcmlvcml0eUl0ZW1TbHVncz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogXCJCYWNrdXAgU3VnZ2VzdGlvbnNcIiDigJQgdXAgdG8gNiBpdGVtcy4gU2tpcHMgdGhlIHByaWNlIGJhbmQgKHRoZSBiYW5kXG4gICAqIGlzIHVzdWFsbHkgd2hhdCBlbXB0aWVkIHRoZSBwb29sKSBidXQgc3RpbGwgcmVzcGVjdHMgc3RvY2ssIGNhcnQsXG4gICAqIGV4Y2x1c2lvbnMsIGRpZXQgYW5kIGBtYXhQcmljZWAuIEl0IFRPUFMgVVAgYSBzaG9ydCBsaXN0IHJhdGhlciB0aGFuXG4gICAqIG9ubHkgZmlyaW5nIHdoZW4gZXZlcnl0aGluZyBlbHNlIHJldHVybmVkIG5vdGhpbmcsIHNvIG9uZSBzY29yZWRcbiAgICogaXRlbSBwbHVzIHR3byBiYWNrdXAgaXRlbXMgaXMgYSB2YWxpZCByZXNwb25zZS5cbiAgICovXG4gIGJhY2t1cEl0ZW1TbHVncz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogVGhlIG1lcmNoYW50J3Mgb3duIGxpc3QgZm9yIHRoaXMgcGxhY2VtZW50LCB1cCB0byAxMiBpdGVtcy4gT25seSByZWFkXG4gICAqIHdoZW4gYHN0cmF0ZWd5YCBpcyBgbWVyY2hhbnQtbGlzdGAuXG4gICAqXG4gICAqIERpc3RpbmN0IGZyb20gYGluY2x1ZGVkSXRlbVNsdWdzYCwgd2hpY2ggaXMgYSBGSUxURVIgb3ZlciB0aGUgd2hvbGVcbiAgICogbWVudSDigJQgaXRlbXMgc3RpbGwgZ2V0IHJhbmtlZCBieSB0aGUgc3RyYXRlZ3kgYW5kIHN0aWxsIHJlcG9ydCBhc1xuICAgKiBgc291cmNlOiAnYWxnb3JpdGhtJ2AuIFRoaXMgUkVQTEFDRVMgdGhlIHBvb2wsIHJvdGF0ZXMgd2l0aGluIGl0IHNvIGFcbiAgICogMTAtaXRlbSBsaXN0IG9uIGEgMy1zbG90IGNhcmQgc2hvd3MgYWxsIHRlbiBvdmVyIHRpbWUsIGFuZCByZXBvcnRzIGFzXG4gICAqIGBzb3VyY2U6ICdtZXJjaGFudF9saXN0J2AuXG4gICAqL1xuICBtZXJjaGFudExpc3RJdGVtU2x1Z3M/OiBzdHJpbmdbXTtcbiAgZXhjbHVkZUNhcnRJdGVtcz86IGJvb2xlYW47XG4gIG1heFByaWNlPzogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBQbGFjZW1lbnRTY29wZSA9ICdkZWZhdWx0JyB8ICd0ZW5hbnQnIHwgJ2J1c2luZXNzJztcblxuLyoqIFJhdyBhZG1pbi1wbGFuZSBjb25maWcgcm93IChubyBwcmVjZWRlbmNlIG1lcmdlIGFwcGxpZWQpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRSZWNvcmQge1xuICBzY29wZTogUGxhY2VtZW50U2NvcGU7XG4gIHBhcmVudElkPzogbnVtYmVyO1xuICBidXNpbmVzc0lkPzogbnVtYmVyO1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBrZXk6IHN0cmluZztcbiAgdG91Y2hwb2ludDogVG91Y2hwb2ludDtcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgZGlzcGxheTogUGxhY2VtZW50RGlzcGxheTtcbiAgc3RyYXRlZ3k6IFVwc2VsbFN0cmF0ZWd5O1xuICBzdHJhdGVneVBhcmFtczogU3RyYXRlZ3lQYXJhbXM7XG4gIGNvbmZpZ1ZlcnNpb246IHN0cmluZztcbiAgdXBkYXRlZEF0OiBzdHJpbmc7XG4gIHVwZGF0ZWRCeTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFkbWluIHVwc2VydC4gU2NvcGUgaXMgZGVyaXZlZDogbm8gcGFyZW50SWQg4oaSIHBsYXRmb3JtIGRlZmF1bHQ7XG4gKiBwYXJlbnRJZCBvbmx5IOKGkiBicmFuZCByb3c7IHBhcmVudElkICsgYnVzaW5lc3NJZCDihpIgYnVzaW5lc3Mgb3ZlcnJpZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50VXBzZXJ0SW5wdXQge1xuICBwYXJlbnRJZD86IG51bWJlcjtcbiAgYnVzaW5lc3NJZD86IG51bWJlcjtcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAga2V5OiBzdHJpbmc7XG4gIHRvdWNocG9pbnQ6IFRvdWNocG9pbnQ7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGRpc3BsYXk6IFBsYWNlbWVudERpc3BsYXk7XG4gIHN0cmF0ZWd5PzogVXBzZWxsU3RyYXRlZ3k7XG4gIHN0cmF0ZWd5UGFyYW1zPzogU3RyYXRlZ3lQYXJhbXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGxhY2VtZW50RGVsZXRlSW5wdXQge1xuICBwYXJlbnRJZD86IG51bWJlcjtcbiAgYnVzaW5lc3NJZD86IG51bWJlcjtcbiAgY2hhbm5lbDogQ2hhbm5lbDtcbiAga2V5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSZXF1aXJlZCBieSB0aGUgc2VydmVyIHdoZW4gYHBhcmVudElkYCBpcyBvbWl0dGVkLCBiZWNhdXNlIHRoYXQgY2FsbFxuICAgKiB0YXJnZXRzIHRoZSBQTEFURk9STSBERUZBVUxUIHJvdyBhbmQgc28gcmVtb3ZlcyB0aGUgcGxhY2VtZW50IGZvclxuICAgKiBldmVyeSB0ZW5hbnQgdGhhdCBoYXMgbm90IG92ZXJyaWRkZW4gaXQuIFdpdGhvdXQgdGhpcyB0aGUgc2VydmVyXG4gICAqIHJlamVjdHMgdGhlIHJlcXVlc3Qgd2l0aCA0MDAgcmF0aGVyIHRoYW4gZ3Vlc3NpbmcgdGhhdCBhIG1pc3NpbmdcbiAgICogcGFyZW50SWQgd2FzIGRlbGliZXJhdGUuXG4gICAqXG4gICAqIERlbGliZXJhdGVseSBub3QgZGVmYXVsdGVkIHRvIGB0cnVlYCBoZXJlOiB0aGUgd2hvbGUgcG9pbnQgb2YgdGhlXG4gICAqIGZsYWcgaXMgdGhhdCBkZWxldGluZyBhIGRlZmF1bHQgbXVzdCBiZSBzdGF0ZWQsIG5vdCBpbmZlcnJlZCBmcm9tXG4gICAqIHRoZSBzaGFwZSBvZiB0aGUgY2FsbC5cbiAgICovXG4gIGNvbmZpcm1EZWxldGVEZWZhdWx0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbGFjZW1lbnRzUXVlcnkge1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBwYXJlbnRJZDogbnVtYmVyO1xuICBidXNpbmVzc0lkOiBudW1iZXI7XG59XG5cbi8vIOKUgOKUgOKUgCBBdHRhY2gtcmF0ZSB0ZWxlbWV0cnkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmV4cG9ydCB0eXBlIFVwc2VsbEV2ZW50VHlwZSA9ICdzaG93bicgfCAnYWRkZWQnIHwgJ2lnbm9yZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2VsbEV2ZW50IHtcbiAgdHlwZTogVXBzZWxsRXZlbnRUeXBlO1xuICAvKipcbiAgICogRWNobyB0aGUgaXRlbSdzIGBzb3VyY2VgLiBUaGlzIGlzIHdoYXQgbWFrZXMgXCJpcyBteSBsaXN0IHBlcmZvcm1pbmdcbiAgICogYmV0dGVyIHRoYW4geW91ciBhbGdvcml0aG0/XCIgYW5zd2VyYWJsZSDigJQgYXR0YWNoIHJhdGUgaXMgb25seVxuICAgKiBjb21wYXJhYmxlIGJ5IGxheWVyIGlmIHRoZSBsYXllciBpcyByZWNvcmRlZCBvbiB0aGUgZXZlbnQuXG4gICAqL1xuICBzb3VyY2U/OiBJdGVtU291cmNlO1xuICBpdGVtSWQ6IG51bWJlcjtcbiAgcmVhc29uQ29kZT86IFJlYXNvbkNvZGU7XG4gIC8qKiBJU08tODYwMS4gRGVmYXVsdHMgdG8gc2VydmVyIHJlY2VpdmUgdGltZSB3aGVuIG9taXR0ZWQuICovXG4gIG9jY3VycmVkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBzZWxsRXZlbnRzSW5wdXQge1xuICBjaGFubmVsOiBDaGFubmVsO1xuICBwbGFjZW1lbnQ6IHN0cmluZztcbiAgdGVuYW50OiBUZW5hbnQ7XG4gIHNlc3Npb25JZD86IHN0cmluZztcbiAgLyoqIEVjaG8gYG1ldGEuY29uZmlnVmVyc2lvbmAgZnJvbSB0aGUgcmVzcG9uc2UgYmVpbmcgcmVwb3J0ZWQgb24uICovXG4gIGNvbmZpZ1ZlcnNpb24/OiBzdHJpbmc7XG4gIGV2ZW50czogVXBzZWxsRXZlbnRbXTtcbn1cbiJdfQ==
package/dist/version.d.ts CHANGED
@@ -13,4 +13,4 @@
13
13
  * namespace suite, so a later split or trim of one namespace cannot take
14
14
  * the release guard with it.
15
15
  */
16
- export declare const SDK_VERSION = "2.2.0";
16
+ export declare const SDK_VERSION = "2.4.0";
package/dist/version.js CHANGED
@@ -16,5 +16,5 @@ exports.SDK_VERSION = void 0;
16
16
  * namespace suite, so a later split or trim of one namespace cannot take
17
17
  * the release guard with it.
18
18
  */
19
- exports.SDK_VERSION = '2.2.0';
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ1UsUUFBQSxXQUFXLEdBQUcsT0FBTyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYW51YWxseS1tYWludGFpbmVkIHZlcnNpb24gc3RyaW5nIHN1cmZhY2VkIHZpYSB0aGUgYFVzZXItQWdlbnRgXG4gKiBoZWFkZXIuIEtlcHQgaW4gc3luYyB3aXRoIGBwYWNrYWdlLmpzb25gIGJ5IGhhbmQgYmVjYXVzZSBwdWxsaW5nIHRoZVxuICogdmFsdWUgZnJvbSBwYWNrYWdlLmpzb24gYXQgcnVudGltZSB3b3VsZCByZXF1aXJlIGVpdGhlciBhIEpTT04gaW1wb3J0XG4gKiAoVFMgbGliIHNldHRpbmdzIGRlcGVuZGVudCkgb3IgYSBidWlsZC10aW1lIHJlcGxhY2VtZW50LCBhbmQgdGhlXG4gKiBjb3N0IG9mIG9uZSBidW1wLWluLXR3by1wbGFjZXMgcGVyIHJlbGVhc2UgaXMgc21hbGwuXG4gKlxuICogVGhhdCBjb3N0IHdhcyB1bmRlcmVzdGltYXRlZCBvbmNlOiB0aGUgcHVibGlzaCBqb2IgdmVyaWZpZXNcbiAqIHBhY2thZ2UuanNvbiBhZ2FpbnN0IHRoZSByZWxlYXNlIHRhZyBidXQgbmV2ZXIgcmVhZHMgdGhpcyBmaWxlLCBzbyB0aGVcbiAqIHR3byBkcmlmdGVkIGFuZCAxLjAuMCBzaGlwcGVkIHJlcG9ydGluZyAwLjkuMS4gQSB0ZXN0IG5vdyBwaW5zIHRoZW1cbiAqIHRvZ2V0aGVyIChgdGVzdC92ZXJzaW9uLnRlc3QudHNgKSwgc28gZm9yZ2V0dGluZyB0aGlzIGJ1bXAgZmFpbHMgdGhlXG4gKiBidWlsZCBpbnN0ZWFkIG9mIHRoZSBVc2VyLUFnZW50LiBJdCBsaXZlcyBhdCB0aGUgdG9wIGxldmVsLCBub3QgdW5kZXIgYVxuICogbmFtZXNwYWNlIHN1aXRlLCBzbyBhIGxhdGVyIHNwbGl0IG9yIHRyaW0gb2Ygb25lIG5hbWVzcGFjZSBjYW5ub3QgdGFrZVxuICogdGhlIHJlbGVhc2UgZ3VhcmQgd2l0aCBpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNES19WRVJTSU9OID0gJzIuMi4wJztcbiJdfQ==
19
+ exports.SDK_VERSION = '2.4.0';
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ1UsUUFBQSxXQUFXLEdBQUcsT0FBTyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYW51YWxseS1tYWludGFpbmVkIHZlcnNpb24gc3RyaW5nIHN1cmZhY2VkIHZpYSB0aGUgYFVzZXItQWdlbnRgXG4gKiBoZWFkZXIuIEtlcHQgaW4gc3luYyB3aXRoIGBwYWNrYWdlLmpzb25gIGJ5IGhhbmQgYmVjYXVzZSBwdWxsaW5nIHRoZVxuICogdmFsdWUgZnJvbSBwYWNrYWdlLmpzb24gYXQgcnVudGltZSB3b3VsZCByZXF1aXJlIGVpdGhlciBhIEpTT04gaW1wb3J0XG4gKiAoVFMgbGliIHNldHRpbmdzIGRlcGVuZGVudCkgb3IgYSBidWlsZC10aW1lIHJlcGxhY2VtZW50LCBhbmQgdGhlXG4gKiBjb3N0IG9mIG9uZSBidW1wLWluLXR3by1wbGFjZXMgcGVyIHJlbGVhc2UgaXMgc21hbGwuXG4gKlxuICogVGhhdCBjb3N0IHdhcyB1bmRlcmVzdGltYXRlZCBvbmNlOiB0aGUgcHVibGlzaCBqb2IgdmVyaWZpZXNcbiAqIHBhY2thZ2UuanNvbiBhZ2FpbnN0IHRoZSByZWxlYXNlIHRhZyBidXQgbmV2ZXIgcmVhZHMgdGhpcyBmaWxlLCBzbyB0aGVcbiAqIHR3byBkcmlmdGVkIGFuZCAxLjAuMCBzaGlwcGVkIHJlcG9ydGluZyAwLjkuMS4gQSB0ZXN0IG5vdyBwaW5zIHRoZW1cbiAqIHRvZ2V0aGVyIChgdGVzdC92ZXJzaW9uLnRlc3QudHNgKSwgc28gZm9yZ2V0dGluZyB0aGlzIGJ1bXAgZmFpbHMgdGhlXG4gKiBidWlsZCBpbnN0ZWFkIG9mIHRoZSBVc2VyLUFnZW50LiBJdCBsaXZlcyBhdCB0aGUgdG9wIGxldmVsLCBub3QgdW5kZXIgYVxuICogbmFtZXNwYWNlIHN1aXRlLCBzbyBhIGxhdGVyIHNwbGl0IG9yIHRyaW0gb2Ygb25lIG5hbWVzcGFjZSBjYW5ub3QgdGFrZVxuICogdGhlIHJlbGVhc2UgZ3VhcmQgd2l0aCBpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNES19WRVJTSU9OID0gJzIuNC4wJztcbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  import { type PlatformAuth, type PlatformAuthInput, type PlatformConfigInput } from '../config';
2
- import type { CreditInput, Currency, DebitInput, GetWalletOptions, ListTransactionsFilter, TransactionPage, TransactionResult, WalletBalance, WalletInstance, WalletTransaction } from './schema';
2
+ import type { CreditEvent, CreditInput, CreditLine, CreditUtilisationFilter, CreditUtilisationPage, Currency, DebitInput, GetWalletOptions, ListCreditEventsFilter, ListTransactionsFilter, ReverseSettlementInput, SetCreditLimitInput, SetCreditLimitResult, SettleInvoiceInput, SettleInvoiceResult, TransactionPage, TransactionResult, WalletBalance, WalletInstance, WalletOverview, WalletTransaction } from './schema';
3
3
  /**
4
4
  * A handle to one business wallet. Cheap to create — `getWallet(...)`
5
5
  * does no I/O. The wallet is resolved server-side on the first
@@ -7,6 +7,23 @@ import type { CreditInput, Currency, DebitInput, GetWalletOptions, ListTransacti
7
7
  * surface from the operation, not from `getWallet()`.
8
8
  */
9
9
  export interface Wallet {
10
+ /**
11
+ * WHICH MODEL IS THIS MERCHANT ON — call this first.
12
+ *
13
+ * Returns a discriminated union on `mode`, so a dashboard settles
14
+ * "wallet balance or credit line?" from a value rather than by
15
+ * catching a 404, and TypeScript narrows the rest for you:
16
+ *
17
+ * ```ts
18
+ * const o = await wallet.getOverview();
19
+ * if (o.mode === 'credit') renderCreditWidget(o.creditLine);
20
+ * else renderWalletPanel(o.balance);
21
+ * ```
22
+ *
23
+ * One request for a prepaid merchant, two for a credit one, and never
24
+ * a 404 on the happy path — see the implementation for why that order.
25
+ */
26
+ getOverview(): Promise<WalletOverview>;
10
27
  /** GET /v1/wallet/balance — resolves the wallet and returns its balance + currency. */
11
28
  getBalance(): Promise<WalletBalance>;
12
29
  /** GET /v1/wallet/instance — wallet identity + currency, without the balance. */
@@ -29,6 +46,39 @@ export interface Wallet {
29
46
  listTransactions(filter?: ListTransactionsFilter): Promise<TransactionPage>;
30
47
  /** GET /v1/wallet/transactions/:id — scoped to this wallet. */
31
48
  getTransaction(id: string): Promise<WalletTransaction>;
49
+ /**
50
+ * GET /v1/wallet/credit — everything the merchant widget renders.
51
+ * Throws `CreditLineNotFoundError` (404) when the merchant is not on
52
+ * the credit line, which is the normal state for a prepaid merchant.
53
+ * Requires `wallet.credit:read`.
54
+ */
55
+ getCreditLine(): Promise<CreditLine>;
56
+ /**
57
+ * GET /v1/wallet/credit/events — the limit-change and settlement
58
+ * trail, newest first. Requires `wallet.credit:read`.
59
+ *
60
+ * Pass a `limit` to widen the page: the service defaults to 50, which
61
+ * a merchant on the line for a year will have outgrown.
62
+ */
63
+ listCreditEvents(filter?: ListCreditEventsFilter): Promise<CreditEvent[]>;
64
+ /**
65
+ * PUT /v1/wallet/credit/limit — set the limit, creating the credit
66
+ * line on first use. Consumption is never touched, so raising a limit
67
+ * hands back exactly the difference. Requires `wallet.credit:write`.
68
+ */
69
+ setCreditLimit(input: SetCreditLimitInput): Promise<SetCreditLimitResult>;
70
+ /**
71
+ * POST /v1/wallet/credit/settlements — release the credit an invoice
72
+ * was holding, on payment IN FULL. Releases the invoice's net figure;
73
+ * see `SettleInvoiceInput.netMinor`. Requires `wallet.credit:settle`.
74
+ */
75
+ settleInvoice(input: SettleInvoiceInput): Promise<SettleInvoiceResult>;
76
+ /**
77
+ * POST /v1/wallet/credit/settlements/reversal — undo a settlement
78
+ * recorded in error, re-holding exactly what it released. Requires
79
+ * `wallet.credit:settle`.
80
+ */
81
+ reverseSettlement(input: ReverseSettlementInput): Promise<SettleInvoiceResult>;
32
82
  }
33
83
  export interface WalletClient {
34
84
  config(input: PlatformConfigInput): WalletClient;
@@ -39,6 +89,16 @@ export interface WalletClient {
39
89
  * `wallet.*` scope for the operations on the returned handle.
40
90
  */
41
91
  getWallet(opts: GetWalletOptions): Wallet;
92
+ /**
93
+ * GET /v1/wallet/credit/utilisation — every merchant on the credit
94
+ * line, most-utilised first.
95
+ *
96
+ * On the client rather than on a wallet handle because it is the one
97
+ * wallet operation that is not scoped to a business, and it carries
98
+ * its own capability (`wallet.credit:list`) for the same reason: it is
99
+ * a materially broader grant than reading one merchant's line.
100
+ */
101
+ getCreditUtilisation(filter?: CreditUtilisationFilter): Promise<CreditUtilisationPage>;
42
102
  }
43
103
  export declare class WalletApiError extends Error {
44
104
  readonly status: number;
@@ -79,4 +139,148 @@ export declare class UnresolvableWalletError extends WalletApiError {
79
139
  export declare class WalletNotFoundError extends WalletApiError {
80
140
  constructor(body: string);
81
141
  }
142
+ /**
143
+ * The charge would exceed the merchant's credit limit; nothing was moved
144
+ * (HTTP 409).
145
+ *
146
+ * Distinct from `InsufficientBalanceError` because the merchant's next
147
+ * step is different — settle an invoice or talk to their account
148
+ * manager, not top up. The figures also separate two cases that share
149
+ * this error and need different copy:
150
+ *
151
+ * - `availableMinor === 0` — the limit is used up.
152
+ * - `availableMinor > 0` — this one charge is larger than what is
153
+ * left, which can happen at any utilisation. Telling that merchant
154
+ * their "credit limit is reached" would be wrong.
155
+ * - `availableMinor === undefined` — the response carried no figures
156
+ * (a trimmed or proxied body). Fall back to generic copy; do not
157
+ * read it as zero, which is the sentinel above.
158
+ *
159
+ * And a third the fields cannot distinguish on their own: consumption
160
+ * spans months, so a merchant can be at their ceiling purely because
161
+ * older invoices are unpaid. `getCreditLine()` tells you which.
162
+ */
163
+ export declare class CreditLimitReachedError extends WalletApiError {
164
+ readonly limitMinor?: number;
165
+ readonly consumedMinor?: number;
166
+ readonly availableMinor?: number;
167
+ readonly requestedMinor?: number;
168
+ constructor(figures: {
169
+ limitMinor?: number;
170
+ consumedMinor?: number;
171
+ availableMinor?: number;
172
+ requestedMinor?: number;
173
+ }, body: string);
174
+ }
175
+ /**
176
+ * A charge on a credit-line merchant arrived without its GST split
177
+ * (HTTP 400).
178
+ *
179
+ * Consumption is tracked net of GST, so `breakup` is required rather
180
+ * than a rate being inferred. If you hit this, the caller is sending
181
+ * gross-only amounts and needs to send `breakup` — the same split it
182
+ * almost certainly already computes.
183
+ */
184
+ export declare class CreditBreakupRequiredError extends WalletApiError {
185
+ constructor(body: string);
186
+ }
187
+ /** `allowNegative` was passed for a credit-line merchant (HTTP 400). */
188
+ export declare class CreditOverrideRefusedError extends WalletApiError {
189
+ constructor(body: string);
190
+ }
191
+ /**
192
+ * A re-settlement changed an invoice's figures without saying why
193
+ * (HTTP 400).
194
+ *
195
+ * Re-settling a REVERSED invoice with different figures is how a settled
196
+ * amount is corrected, so the service does not refuse it the way it
197
+ * refuses a conflicting first settlement. But it releases against the
198
+ * merchant's whole outstanding consumption rather than the invoice's own
199
+ * amount, so a mistyped figure can hand back far more than the invoice
200
+ * held — and a deliberate correction can say what it is correcting where
201
+ * a replayed webhook cannot. Pass `reason` and retry. Re-settling with
202
+ * the SAME figures needs none.
203
+ */
204
+ export declare class CreditCorrectionReasonRequiredError extends WalletApiError {
205
+ /** What the invoice was previously settled for, in minor units. */
206
+ readonly previousNetMinor: number | undefined;
207
+ constructor(
208
+ /** What the invoice was previously settled for, in minor units. */
209
+ previousNetMinor: number | undefined, body: string);
210
+ }
211
+ /**
212
+ * A limit change named a currency the credit line is not denominated in
213
+ * (HTTP 409).
214
+ *
215
+ * The line's currency is fixed when it is created, because it sets the
216
+ * exponent every stored figure is already scaled by — changing it would
217
+ * re-denominate the limit and the consumption without touching either
218
+ * number. Re-denominating a live line is a migration, not a field
219
+ * update, so this is not something a caller can retry past: send the
220
+ * currency the line already carries.
221
+ */
222
+ export declare class CreditCurrencyConflictError extends WalletApiError {
223
+ readonly storedCurrency: string | undefined;
224
+ readonly requestedCurrency: string | undefined;
225
+ constructor(storedCurrency: string | undefined, requestedCurrency: string | undefined, body: string);
226
+ }
227
+ /**
228
+ * The merchant's credit line and the wallet the charge routed to are in
229
+ * different currencies (HTTP 409).
230
+ *
231
+ * `amountMinor` and `breakup` carry no currency of their own — they are
232
+ * read with the exponent of the resolved wallet — so when the two
233
+ * disagree there is no reading of them that is right for both, and the
234
+ * service refuses rather than mis-scaling by a factor of ten or a
235
+ * hundred. Not caller-fixable: it means the merchant's routing and their
236
+ * credit line disagree, which is an ops/data problem.
237
+ */
238
+ export declare class CreditCurrencyMismatchError extends WalletApiError {
239
+ constructor(body: string);
240
+ }
241
+ /**
242
+ * A plain top-up was sent for a credit-line merchant (HTTP 400).
243
+ *
244
+ * These merchants have no balance to top up: `wallet_balance` is the
245
+ * fiction the credit line replaces and is deliberately frozen, so the
246
+ * write would move nothing while appearing to succeed. Credit is handed
247
+ * back by settling an invoice (`settleInvoice`), never by crediting the
248
+ * wallet. A genuine refund is accepted — send it as `reversalOf` or
249
+ * `isRefund` and it releases the credit the original charge consumed.
250
+ */
251
+ export declare class CreditTopUpRefusedError extends WalletApiError {
252
+ constructor(body: string);
253
+ }
254
+ /**
255
+ * The merchant is not on the credit line (HTTP 404).
256
+ *
257
+ * The normal state for a prepaid merchant, so a widget should treat it
258
+ * as "show the wallet balance instead", not as an error.
259
+ */
260
+ export declare class CreditLineNotFoundError extends WalletApiError {
261
+ constructor(body: string);
262
+ }
263
+ /**
264
+ * `enabled: false` was refused because the merchant still owes for the
265
+ * credit line (HTTP 409).
266
+ *
267
+ * Disabling moves a merchant back to a wallet balance, and doing that
268
+ * with consumption outstanding abandons it. Show `consumedMinor` and
269
+ * tell the operator to settle first — or, if the intent was to stop the
270
+ * merchant trading rather than to move them off the model, set
271
+ * `limitMinor: 0`, which blocks every charge and keeps the balance.
272
+ */
273
+ export declare class CreditLineHasOutstandingError extends WalletApiError {
274
+ readonly consumedMinor: number;
275
+ readonly gstAccruedMinor: number;
276
+ constructor(consumedMinor: number, gstAccruedMinor: number, body: string);
277
+ }
278
+ /** A limit `referenceId` or an invoice was reused for different figures (HTTP 409). */
279
+ export declare class CreditIdempotencyConflictError extends WalletApiError {
280
+ constructor(body: string);
281
+ }
282
+ /** No settlement to reverse for that invoice (HTTP 404). */
283
+ export declare class SettlementNotFoundError extends WalletApiError {
284
+ constructor(body: string);
285
+ }
82
286
  export declare function createWalletClient(input?: PlatformConfigInput): WalletClient;