@cartanova/qgrid-cli 2.6.7 → 2.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/bundle/dist/application/monit/monit.frame.js +2 -2
  2. package/bundle/dist/application/qgrid/expired-token-reminder.js +45 -15
  3. package/bundle/dist/application/qgrid/oauth.js +1 -1
  4. package/bundle/dist/application/qgrid/qgrid.frame.js +3 -3
  5. package/bundle/dist/application/qgrid/slack-user-map.js +5 -14
  6. package/bundle/dist/application/qgrid/token-death.js +3 -2
  7. package/bundle/dist/application/qgrid/tool-emulation.js +1 -1
  8. package/bundle/dist/application/queries.generated.js +8 -2
  9. package/bundle/dist/application/request-log/request-log.model.js +2 -2
  10. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  11. package/bundle/dist/application/setting/setting.constant.js +226 -0
  12. package/bundle/dist/application/setting/setting.model.js +254 -0
  13. package/bundle/dist/application/setting/setting.store.js +66 -0
  14. package/bundle/dist/application/setting/setting.types.js +51 -0
  15. package/bundle/dist/application/sonamu.generated.js +32 -2
  16. package/bundle/dist/application/sonamu.generated.sso.js +12 -2
  17. package/bundle/dist/application/token/token.model.js +1 -1
  18. package/bundle/dist/i18n/en.js +3 -1
  19. package/bundle/dist/i18n/ko.js +3 -1
  20. package/bundle/dist/i18n/sd.generated.js +9 -1
  21. package/bundle/dist/migrations/20260808194708_create__settings.js +24 -0
  22. package/bundle/dist/sonamu.config.js +8 -2
  23. package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +21 -6
  24. package/bundle/dist/utils/quiet-hours.js +47 -0
  25. package/bundle/dist/utils/slack-notify.js +16 -5
  26. package/bundle/src/application/qgrid/expired-token-reminder.test.ts +147 -2
  27. package/bundle/src/application/qgrid/expired-token-reminder.ts +66 -16
  28. package/bundle/src/application/qgrid/slack-user-map.test.ts +23 -0
  29. package/bundle/src/application/qgrid/slack-user-map.ts +4 -14
  30. package/bundle/src/application/qgrid/token-death.ts +2 -0
  31. package/bundle/src/application/queries.generated.ts +21 -1
  32. package/bundle/src/application/setting/setting.constant.test.ts +109 -0
  33. package/bundle/src/application/setting/setting.constant.ts +250 -0
  34. package/bundle/src/application/setting/setting.entity.json +59 -0
  35. package/bundle/src/application/setting/setting.model.ts +277 -0
  36. package/bundle/src/application/setting/setting.store.test.ts +87 -0
  37. package/bundle/src/application/setting/setting.store.ts +85 -0
  38. package/bundle/src/application/setting/setting.types.ts +53 -0
  39. package/bundle/src/application/sonamu.generated.http +54 -0
  40. package/bundle/src/application/sonamu.generated.sso.ts +21 -0
  41. package/bundle/src/application/sonamu.generated.ts +51 -0
  42. package/bundle/src/i18n/en.ts +2 -0
  43. package/bundle/src/i18n/ko.ts +2 -0
  44. package/bundle/src/i18n/sd.generated.ts +8 -0
  45. package/bundle/src/migrations/20260808194708_create__settings.ts +19 -0
  46. package/bundle/src/sonamu.config.ts +12 -0
  47. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +12 -0
  48. package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +43 -5
  49. package/bundle/src/utils/quiet-hours.ts +79 -0
  50. package/bundle/src/utils/slack-notify.test.ts +171 -20
  51. package/bundle/src/utils/slack-notify.ts +31 -4
  52. package/bundle/web-dist/client/assets/index-DnnliAzf.js +78 -0
  53. package/bundle/web-dist/client/assets/index-rdbxJinT.css +1 -0
  54. package/bundle/web-dist/client/assets/{logs-CUO9Q0UT.js → logs-5gACO5tJ.js} +1 -1
  55. package/bundle/web-dist/client/assets/{monit-Dy7UtqC2.js → monit-DRCc50GU.js} +1 -1
  56. package/bundle/web-dist/client/assets/plus-p4vtg6LN.js +1 -0
  57. package/bundle/web-dist/client/assets/{routes-B6gfQrph.js → routes-DBdI9Ba1.js} +2 -2
  58. package/bundle/web-dist/client/assets/{sd.generated-DYdwSB2I.js → sd.generated-Bwa7rses.js} +1 -1
  59. package/bundle/web-dist/client/assets/services.generated-BzwTuZRP.js +1 -0
  60. package/bundle/web-dist/client/assets/settings-B62_r1i4.js +1 -0
  61. package/bundle/web-dist/client/assets/{show-Bi0QYUVm.js → show-BCRrSc8-.js} +1 -1
  62. package/bundle/web-dist/client/assets/tokens-CDiXKYGf.js +1 -0
  63. package/bundle/web-dist/client/assets/{use-oauth-login-flow-Cx6BlvXM.js → use-oauth-login-flow-Qqg4koSg.js} +1 -1
  64. package/bundle/web-dist/client/index.html +3 -3
  65. package/bundle/web-dist/server/assets/{lazyRouteComponent-BaZaveNc.js → lazyRouteComponent-Ws7I6fL-.js} +2 -1
  66. package/bundle/web-dist/server/assets/{logs-DMOw3SjD.js → logs-C1rxLh8H.js} +4 -4
  67. package/bundle/web-dist/server/assets/{monit-UmcqHroX.js → monit-C8gx9Sar.js} +3 -2
  68. package/bundle/web-dist/server/assets/plus-BISXNqRU.js +19 -0
  69. package/bundle/web-dist/server/assets/react-dom-D7duWOwf.js +462 -0
  70. package/bundle/web-dist/server/assets/{routes-BfoQmYud.js → routes-ZW_Ih5Em.js} +11 -7
  71. package/bundle/web-dist/server/assets/{sd.generated-B0xqnHEo.js → sd.generated-LO-h1_16.js} +13 -461
  72. package/bundle/web-dist/server/assets/{services.generated-DqAKskAS.js → services.generated-CZIChgHV.js} +119 -2
  73. package/bundle/web-dist/server/assets/settings--aoatERH.js +382 -0
  74. package/bundle/web-dist/server/assets/{show-C-oSdzHX.js → show-BY27w9oi.js} +4 -4
  75. package/bundle/web-dist/server/assets/{tokens-Dkd_uXEk.js → tokens-DIObtTuZ.js} +17 -72
  76. package/bundle/web-dist/server/assets/{use-oauth-login-flow-YM1nsd-H.js → use-oauth-login-flow-V3k8PSqQ.js} +2 -2
  77. package/bundle/web-dist/server/entry-server.generated.js +54 -18
  78. package/package.json +1 -1
  79. package/skills/qgrid/references/cli-env-and-server-boot.md +17 -2
  80. package/skills/qgrid/references/openai-codex-runtime.md +1 -1
  81. package/skills/qgrid/references/sonamu-api-web-flow.md +2 -0
  82. package/skills/qgrid/references/token-auth-quota-lifecycle.md +2 -0
  83. package/bundle/web-dist/client/assets/index-B4GlN1IX.css +0 -1
  84. package/bundle/web-dist/client/assets/index-CV_rp3zE.js +0 -78
  85. package/bundle/web-dist/client/assets/services.generated-BsAvotjG.js +0 -1
  86. package/bundle/web-dist/client/assets/tokens-BAuYgBl6.js +0 -1
  87. /package/bundle/web-dist/server/assets/{cost-CSH_t17I.js → cost-DzjfVtUr.js} +0 -0
@@ -1,8 +1,8 @@
1
1
  import { monitLogBuffer } from "./log-buffer.js";
2
- import { resolveOpenAIWorkerPoolConfig } from "../../utils/providers/openai/openai-worker-pool-config.js";
3
- import { QgridDispatcher } from "../qgrid/qgrid.dispatcher.js";
4
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
5
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
4
+ import { resolveOpenAIWorkerPoolConfig } from "../../utils/providers/openai/openai-worker-pool-config.js";
5
+ import { QgridDispatcher } from "../qgrid/qgrid.dispatcher.js";
6
6
  import { BaseFrameClass, DB, api } from "sonamu";
7
7
  //#region src/application/monit/monit.frame.ts
8
8
  /**
@@ -1,3 +1,4 @@
1
+ import { getSetting } from "../setting/setting.store.js";
1
2
  import { SLACK_COLOR, notifySlack } from "../../utils/slack-notify.js";
2
3
  import { TokenModel } from "../token/token.model.js";
3
4
  import { getSlackUserMap, mentionFor } from "./slack-user-map.js";
@@ -17,6 +18,12 @@ import { getLogger } from "@logtape/logtape";
17
18
  */
18
19
  const logger = getLogger(["qgrid", "expired-reminder"]);
19
20
  const MINUTE_MS = 6e4;
21
+ const defaultDeps = {
22
+ findInactive: () => TokenModel.findInactive("A"),
23
+ getSlackUserMap,
24
+ readSetting: getSetting,
25
+ sendSlack: notifySlack
26
+ };
20
27
  /**
21
28
  * 1건이면 제목(subject)에 토큰명이 이미 있으므로 본문에서는 뺀다 — 같은 이름을 두 번 쓰면
22
29
  * 읽는 사람이 다른 정보인 줄 알고 한 번 더 본다. 여러 건이면 제목이 건수라 본문에 남긴다.
@@ -30,31 +37,54 @@ function buildReminderContext(tokens, userMap) {
30
37
  return mention ? `${mention} ${label}` : label;
31
38
  }), "재로그인이 필요합니다"].filter(Boolean).join("\n");
32
39
  }
33
- async function sendReminder(userMap) {
34
- const inactive = await TokenModel.findInactive("A");
35
- if (inactive.length === 0) return;
36
- await notifySlack({
40
+ async function sendReminder(deps, urgent = false) {
41
+ const inactive = await deps.findInactive();
42
+ if (inactive.length === 0) return 0;
43
+ const userMap = deps.getSlackUserMap();
44
+ await deps.sendSlack({
37
45
  title: "세션 만료",
38
46
  subject: inactive.length > 1 ? `${inactive.length}건` : inactive[0].name ?? "unnamed",
39
47
  context: buildReminderContext(inactive, userMap),
40
- color: SLACK_COLOR.bad
48
+ color: SLACK_COLOR.bad,
49
+ urgent
41
50
  });
51
+ return inactive.length;
52
+ }
53
+ /**
54
+ * 화면의 "지금 보내기". 사람이 직접 누른 것이므로 조용 시간·마스터 스위치를 통과시킨다 —
55
+ * 눌렀는데 아무 일도 안 일어나면 버튼이 고장 난 것으로 읽힌다.
56
+ *
57
+ * 보낸 건수를 돌려줘 호출부가 "보낼 대상 없음"과 "보냄"을 구분해 보여준다.
58
+ */
59
+ function sendExpiredTokenReminderNow(deps = defaultDeps) {
60
+ return sendReminder(deps, true);
42
61
  }
43
62
  let timer = null;
63
+ function scheduleExpiredTokenReminder(runNow, deps) {
64
+ stopExpiredTokenReminder();
65
+ if (deps.readSetting("slack.remindersEnabled", "SLACK_REMINDERS_ENABLED") === "false") {
66
+ logger.info("expired token reminder disabled");
67
+ return;
68
+ }
69
+ const minutes = Number(deps.readSetting("slack.expiryReminderMinutes", "SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES") ?? 0);
70
+ if (!Number.isFinite(minutes) || minutes <= 0) return;
71
+ logger.info(`expired token reminder every ${minutes}m (${deps.getSlackUserMap().size} user mappings)`);
72
+ const run = () => sendReminder(deps).catch((e) => logger.warn(`reminder failed: ${e.message}`));
73
+ if (runNow) run();
74
+ timer = setInterval(run, minutes * MINUTE_MS);
75
+ }
44
76
  /**
45
77
  * `SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES` 가 양수일 때만 켜진다. 미설정·0 이면 비활성.
46
78
  *
47
79
  * 인스턴스가 여러 개면 각자 보낸다. 만료 순간 알림과 달리 상태 변화가 없어 DB 로 억제할 수
48
80
  * 없고, 하루 몇 건 수준이라 중복을 감수하는 편이 잠금 장치를 두는 것보다 낫다.
49
81
  */
50
- function startExpiredTokenReminder() {
51
- const minutes = Number(process.env.SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES ?? 0);
52
- if (!Number.isFinite(minutes) || minutes <= 0) return;
53
- const userMap = getSlackUserMap();
54
- logger.info(`expired token reminder every ${minutes}m (${userMap.size} user mappings)`);
55
- const run = () => sendReminder(userMap).catch((e) => logger.warn(`reminder failed: ${e.message}`));
56
- run();
57
- timer = setInterval(run, minutes * MINUTE_MS);
82
+ function startExpiredTokenReminder(deps = defaultDeps) {
83
+ scheduleExpiredTokenReminder(true, deps);
84
+ }
85
+ /** 설정 변경 시 기존 타이머만 새 주기로 교체한다. 저장 자체가 알림을 보내지는 않는다. */
86
+ function rescheduleExpiredTokenReminder(deps = defaultDeps) {
87
+ scheduleExpiredTokenReminder(false, deps);
58
88
  }
59
89
  function stopExpiredTokenReminder() {
60
90
  if (!timer) return;
@@ -62,6 +92,6 @@ function stopExpiredTokenReminder() {
62
92
  timer = null;
63
93
  }
64
94
  //#endregion
65
- export { buildReminderContext, startExpiredTokenReminder, stopExpiredTokenReminder };
95
+ export { buildReminderContext, rescheduleExpiredTokenReminder, sendExpiredTokenReminderNow, startExpiredTokenReminder, stopExpiredTokenReminder };
66
96
 
67
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwaXJlZC10b2tlbi1yZW1pbmRlci5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvZXhwaXJlZC10b2tlbi1yZW1pbmRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOyEuOyFmCDrp4zro4wg7JWM66a8IOuwmOuztS5cbiAqXG4gKiDrp4zro4wg7Iic6rCE7J2YIOyVjOumvChgdG9rZW4tZGVhdGgudHNgKeydgCDqt7jrlYwg7LGE64SQ7J2EIOuztOyngCDslYrsnLzrqbQg64aT7Lmc64ukLiDsnqzroZzqt7jsnbjsnYAg7IKs656M7J20XG4gKiDtlbTslbwg7ZWY64qUIOydvOydtOudvCDrhpPsuZjrqbQg7Yag7YGw7J20IOqzhOyGjSDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC4g6re4656Y7IScIOyVhOyngSDsnqzroZzqt7jsnbjrkJjsp4Ag7JWK7J2AXG4gKiDthqDtgbDsnYQg6rCZ7J2AIOusuOq1rOuhnCDri6Tsi5wg7JWM66aw64ukIOKAlCDsgqzqsbTsnbQg7ZWY64KY7J2066+A66GcIOyVjOumvOuPhCDtlZwg7KKF66WY64ukLlxuICpcbiAqIOyXrOufrCDthqDtgbDsnbQg66eM66OM64+8IOyeiOycvOuptCDtlZwg66mU7Iuc7KeA7JeQIOuqqOydgOuLpC4g7Yag7YGw66eI64ukIOuplOyLnOyngOulvCDrs7TrgrTrqbQg7LGE64SQ7J20IOyLnOuBhOufrOybjFxuICog7KCV7J6RIOydve2eiOyngCDslYrripTri6QuXG4gKlxuICog67mE7Zmc7ISxIO2GoO2BsOydtCDsl4bsnLzrqbQg67O064K07KeAIOyViuuKlOuLpCDigJQgXCLsnbTsg4Eg7JeG7J2MXCLsnYQg7KO86riw7KCB7Jy866GcIOyVjOumrOuptCDssYTrhJDsnbQg66y0646M7KeE64ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBub3RpZnlTbGFjaywgU0xBQ0tfQ09MT1IgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc2xhY2stbm90aWZ5XCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyBnZXRTbGFja1VzZXJNYXAsIG1lbnRpb25Gb3IgfSBmcm9tIFwiLi9zbGFjay11c2VyLW1hcFwiO1xuXG5jb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJleHBpcmVkLXJlbWluZGVyXCJdKTtcblxuY29uc3QgTUlOVVRFX01TID0gNjBfMDAwO1xuXG4vKipcbiAqIDHqsbTsnbTrqbQg7KCc66qpKHN1YmplY3Qp7JeQIO2GoO2BsOuqheydtCDsnbTrr7gg7J6I7Jy866+A66GcIOuzuOusuOyXkOyEnOuKlCDruoDri6Qg4oCUIOqwmeydgCDsnbTrpoTsnYQg65GQIOuyiCDsk7DrqbRcbiAqIOydveuKlCDsgqzrnozsnbQg64uk66W4IOygleuztOyduCDspIQg7JWM6rOgIO2VnCDrsogg642UIOuzuOuLpC4g7Jes65+sIOqxtOydtOuptCDsoJzrqqnsnbQg6rG07IiY6528IOuzuOusuOyXkCDrgqjquLTri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJlbWluZGVyQ29udGV4dChcbiAgdG9rZW5zOiB7IG5hbWU6IHN0cmluZyB8IG51bGw7IHByb3ZpZGVyOiBzdHJpbmcgfVtdLFxuICB1c2VyTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+LFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc2hvd0xhYmVsID0gdG9rZW5zLmxlbmd0aCA+IDE7XG4gIGNvbnN0IGxpbmVzID0gdG9rZW5zLm1hcCgodG9rZW4pID0+IHtcbiAgICBjb25zdCBtZW50aW9uID0gbWVudGlvbkZvcih0b2tlbi5uYW1lLCB1c2VyTWFwKTtcbiAgICBjb25zdCBsYWJlbCA9IHRva2VuLm5hbWUgPz8gXCJ1bm5hbWVkXCI7XG4gICAgaWYgKCFzaG93TGFiZWwpIHJldHVybiBtZW50aW9uO1xuICAgIHJldHVybiBtZW50aW9uID8gYCR7bWVudGlvbn0gJHtsYWJlbH1gIDogbGFiZWw7XG4gIH0pO1xuICByZXR1cm4gWy4uLmxpbmVzLCBcIuyerOuhnOq3uOyduOydtCDtlYTsmpTtlanri4jri6RcIl0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCJcXG5cIik7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNlbmRSZW1pbmRlcih1c2VyTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGluYWN0aXZlID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kSW5hY3RpdmUoXCJBXCIpO1xuICBpZiAoaW5hY3RpdmUubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgYXdhaXQgbm90aWZ5U2xhY2soe1xuICAgIC8vIOunjOujjCDsiJzqsIQg7JWM66a86rO8IOqwmeydgCDsoJzrqqnsnYQg7JO064ukLiDqsJnsnYAg7IKs6rG07J2066+A66GcIOuLpOuluCDsnbTrpoTsnYQg67aZ7J2066m0IOuzhOqwnCDrrLjsoJzroZwg7J297Z6M64ukLlxuICAgIHRpdGxlOiBcIuyEuOyFmCDrp4zro4xcIixcbiAgICBzdWJqZWN0OiBpbmFjdGl2ZS5sZW5ndGggPiAxID8gYCR7aW5hY3RpdmUubGVuZ3RofeqxtGAgOiAoaW5hY3RpdmVbMF0hLm5hbWUgPz8gXCJ1bm5hbWVkXCIpLFxuICAgIGNvbnRleHQ6IGJ1aWxkUmVtaW5kZXJDb250ZXh0KGluYWN0aXZlLCB1c2VyTWFwKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuYmFkLFxuICB9KTtcbn1cblxubGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBgU0xBQ0tfRVhQSVJZX1JFTUlOREVSX0lOVEVSVkFMX01JTlVURVNgIOqwgCDslpHsiJjsnbwg65WM66eMIOy8nOynhOuLpC4g66+47ISk7KCVwrcwIOydtOuptCDruYTtmZzshLEuXG4gKlxuICog7J247Iqk7YS07Iqk6rCAIOyXrOufrCDqsJzrqbQg6rCB7J6QIOuztOuCuOuLpC4g66eM66OMIOyInOqwhCDslYzrprzqs7wg64us66asIOyDge2DnCDrs4DtmZTqsIAg7JeG7Ja0IERCIOuhnCDslrXsoJztlaAg7IiYXG4gKiDsl4bqs6AsIO2VmOujqCDrqocg6rG0IOyImOykgOydtOudvCDspJHrs7XsnYQg6rCQ7IiY7ZWY64qUIO2OuOydtCDsnqDquIgg7J6l7LmY66W8IOuRkOuKlCDqsoPrs7Tri6Qg64Kr64ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRFeHBpcmVkVG9rZW5SZW1pbmRlcigpOiB2b2lkIHtcbiAgY29uc3QgbWludXRlcyA9IE51bWJlcihwcm9jZXNzLmVudi5TTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFUyA/PyAwKTtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobWludXRlcykgfHwgbWludXRlcyA8PSAwKSByZXR1cm47XG5cbiAgY29uc3QgdXNlck1hcCA9IGdldFNsYWNrVXNlck1hcCgpO1xuICBsb2dnZXIuaW5mbyhgZXhwaXJlZCB0b2tlbiByZW1pbmRlciBldmVyeSAke21pbnV0ZXN9bSAoJHt1c2VyTWFwLnNpemV9IHVzZXIgbWFwcGluZ3MpYCk7XG5cbiAgY29uc3QgcnVuID0gKCkgPT5cbiAgICBzZW5kUmVtaW5kZXIodXNlck1hcCkuY2F0Y2goKGUpID0+IGxvZ2dlci53YXJuKGByZW1pbmRlciBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCkpO1xuXG4gIC8vIOq4sOuPmSDsp4Htm4Tsl5Drj4Qg7ZWcIOuyiCDrs7Trgrjri6QuIOyerOq4sOuPmeydgCDrsLDtj6zrgpgg7J6l7JWgIOuzteq1rCDrlYwg7J287Ja064KY64qU642wLCDqt7gg7Iuc7KCQ7JeQIOydtOuvuFxuICAvLyDrp4zro4zrkJwg7Yag7YGw7J20IOyeiOycvOuptCDssqsg7KO86riw6rCAIOuPjCDrlYzquYzsp4Ag7KGw7Jqp7ZWcIOqyg+ydtCDsnbTsg4HtlZjri6QuXG4gIHZvaWQgcnVuKCk7XG5cbiAgdGltZXIgPSBzZXRJbnRlcnZhbChydW4sIG1pbnV0ZXMgKiBNSU5VVEVfTVMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RvcEV4cGlyZWRUb2tlblJlbWluZGVyKCk6IHZvaWQge1xuICBpZiAoIXRpbWVyKSByZXR1cm47XG4gIGNsZWFySW50ZXJ2YWwodGltZXIpO1xuICB0aW1lciA9IG51bGw7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLE1BQU0sU0FBUyxVQUFVLENBQUMsU0FBUyxrQkFBa0IsQ0FBQztBQUV0RCxNQUFNLFlBQVk7Ozs7O0FBTWxCLFNBQWdCLHFCQUNkLFFBQ0EsU0FDUTtDQUNSLE1BQU0sWUFBWSxPQUFPLFNBQVM7Q0FPbEMsT0FBTyxDQUFDLEdBTk0sT0FBTyxLQUFLLFVBQVU7RUFDbEMsTUFBTSxVQUFVLFdBQVcsTUFBTSxNQUFNLE9BQU87RUFDOUMsTUFBTSxRQUFRLE1BQU0sUUFBUTtFQUM1QixJQUFJLENBQUMsV0FBVyxPQUFPO0VBQ3ZCLE9BQU8sVUFBVSxHQUFHLFFBQVEsR0FBRyxVQUFVO0NBQzNDLENBQ1csR0FBTyxhQUFhLENBQUMsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxDQUFDLEtBQUssSUFBSTtBQUM1RDtBQUVBLGVBQWUsYUFBYSxTQUE2QztDQUN2RSxNQUFNLFdBQVcsTUFBTSxXQUFXLGFBQWEsR0FBRztDQUNsRCxJQUFJLFNBQVMsV0FBVyxHQUFHO0NBRTNCLE1BQU0sWUFBWTtFQUVoQixPQUFPO0VBQ1AsU0FBUyxTQUFTLFNBQVMsSUFBSSxHQUFHLFNBQVMsT0FBTyxLQUFNLFNBQVMsRUFBRSxDQUFFLFFBQVE7RUFDN0UsU0FBUyxxQkFBcUIsVUFBVSxPQUFPO0VBQy9DLE9BQU8sWUFBWTtDQUNyQixDQUFDO0FBQ0g7QUFFQSxJQUFJLFFBQStDOzs7Ozs7O0FBUW5ELFNBQWdCLDRCQUFrQztDQUNoRCxNQUFNLFVBQVUsT0FBTyxRQUFRLElBQUksMENBQTBDLENBQUM7Q0FDOUUsSUFBSSxDQUFDLE9BQU8sU0FBUyxPQUFPLEtBQUssV0FBVyxHQUFHO0NBRS9DLE1BQU0sVUFBVSxnQkFBZ0I7Q0FDaEMsT0FBTyxLQUFLLGdDQUFnQyxRQUFRLEtBQUssUUFBUSxLQUFLLGdCQUFnQjtDQUV0RixNQUFNLFlBQ0osYUFBYSxPQUFPLENBQUMsQ0FBQyxPQUFPLE1BQU0sT0FBTyxLQUFLLG9CQUFxQixFQUFZLFNBQVMsQ0FBQztDQUk1RixBQUFLLElBQUk7Q0FFVCxRQUFRLFlBQVksS0FBSyxVQUFVLFNBQVM7QUFDOUM7QUFFQSxTQUFnQiwyQkFBaUM7Q0FDL0MsSUFBSSxDQUFDLE9BQU87Q0FDWixjQUFjLEtBQUs7Q0FDbkIsUUFBUTtBQUNWIn0=
97
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwaXJlZC10b2tlbi1yZW1pbmRlci5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvZXhwaXJlZC10b2tlbi1yZW1pbmRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOyEuOyFmCDrp4zro4wg7JWM66a8IOuwmOuztS5cbiAqXG4gKiDrp4zro4wg7Iic6rCE7J2YIOyVjOumvChgdG9rZW4tZGVhdGgudHNgKeydgCDqt7jrlYwg7LGE64SQ7J2EIOuztOyngCDslYrsnLzrqbQg64aT7Lmc64ukLiDsnqzroZzqt7jsnbjsnYAg7IKs656M7J20XG4gKiDtlbTslbwg7ZWY64qUIOydvOydtOudvCDrhpPsuZjrqbQg7Yag7YGw7J20IOqzhOyGjSDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC4g6re4656Y7IScIOyVhOyngSDsnqzroZzqt7jsnbjrkJjsp4Ag7JWK7J2AXG4gKiDthqDtgbDsnYQg6rCZ7J2AIOusuOq1rOuhnCDri6Tsi5wg7JWM66aw64ukIOKAlCDsgqzqsbTsnbQg7ZWY64KY7J2066+A66GcIOyVjOumvOuPhCDtlZwg7KKF66WY64ukLlxuICpcbiAqIOyXrOufrCDthqDtgbDsnbQg66eM66OM64+8IOyeiOycvOuptCDtlZwg66mU7Iuc7KeA7JeQIOuqqOydgOuLpC4g7Yag7YGw66eI64ukIOuplOyLnOyngOulvCDrs7TrgrTrqbQg7LGE64SQ7J20IOyLnOuBhOufrOybjFxuICog7KCV7J6RIOydve2eiOyngCDslYrripTri6QuXG4gKlxuICog67mE7Zmc7ISxIO2GoO2BsOydtCDsl4bsnLzrqbQg67O064K07KeAIOyViuuKlOuLpCDigJQgXCLsnbTsg4Eg7JeG7J2MXCLsnYQg7KO86riw7KCB7Jy866GcIOyVjOumrOuptCDssYTrhJDsnbQg66y0646M7KeE64ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBub3RpZnlTbGFjaywgU0xBQ0tfQ09MT1IgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc2xhY2stbm90aWZ5XCI7XG5pbXBvcnQgeyBnZXRTZXR0aW5nIH0gZnJvbSBcIi4uL3NldHRpbmcvc2V0dGluZy5zdG9yZVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwiZXhwaXJlZC1yZW1pbmRlclwiXSk7XG5cbmNvbnN0IE1JTlVURV9NUyA9IDYwXzAwMDtcblxuZXhwb3J0IHR5cGUgRXhwaXJlZFRva2VuUmVtaW5kZXJEZXBzID0ge1xuICBmaW5kSW5hY3RpdmU6ICgpID0+IFByb21pc2U8eyBuYW1lOiBzdHJpbmcgfCBudWxsOyBwcm92aWRlcjogc3RyaW5nIH1bXT47XG4gIGdldFNsYWNrVXNlck1hcDogKCkgPT4gTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgcmVhZFNldHRpbmc6IHR5cGVvZiBnZXRTZXR0aW5nO1xuICBzZW5kU2xhY2s6IHR5cGVvZiBub3RpZnlTbGFjaztcbn07XG5cbmNvbnN0IGRlZmF1bHREZXBzOiBFeHBpcmVkVG9rZW5SZW1pbmRlckRlcHMgPSB7XG4gIGZpbmRJbmFjdGl2ZTogKCkgPT4gVG9rZW5Nb2RlbC5maW5kSW5hY3RpdmUoXCJBXCIpLFxuICBnZXRTbGFja1VzZXJNYXAsXG4gIHJlYWRTZXR0aW5nOiBnZXRTZXR0aW5nLFxuICBzZW5kU2xhY2s6IG5vdGlmeVNsYWNrLFxufTtcblxuLyoqXG4gKiAx6rG07J2066m0IOygnOuqqShzdWJqZWN0KeyXkCDthqDtgbDrqoXsnbQg7J2066+4IOyeiOycvOuvgOuhnCDrs7jrrLjsl5DshJzripQg67qA64ukIOKAlCDqsJnsnYAg7J2066aE7J2EIOuRkCDrsogg7JOw66m0XG4gKiDsnb3ripQg7IKs656M7J20IOuLpOuluCDsoJXrs7Tsnbgg7KSEIOyVjOqzoCDtlZwg67KIIOuNlCDrs7jri6QuIOyXrOufrCDqsbTsnbTrqbQg7KCc66qp7J20IOqxtOyImOudvCDrs7jrrLjsl5Ag64Ko6ri064ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSZW1pbmRlckNvbnRleHQoXG4gIHRva2VuczogeyBuYW1lOiBzdHJpbmcgfCBudWxsOyBwcm92aWRlcjogc3RyaW5nIH1bXSxcbiAgdXNlck1hcDogTWFwPHN0cmluZywgc3RyaW5nPixcbik6IHN0cmluZyB7XG4gIGNvbnN0IHNob3dMYWJlbCA9IHRva2Vucy5sZW5ndGggPiAxO1xuICBjb25zdCBsaW5lcyA9IHRva2Vucy5tYXAoKHRva2VuKSA9PiB7XG4gICAgY29uc3QgbWVudGlvbiA9IG1lbnRpb25Gb3IodG9rZW4ubmFtZSwgdXNlck1hcCk7XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbi5uYW1lID8/IFwidW5uYW1lZFwiO1xuICAgIGlmICghc2hvd0xhYmVsKSByZXR1cm4gbWVudGlvbjtcbiAgICByZXR1cm4gbWVudGlvbiA/IGAke21lbnRpb259ICR7bGFiZWx9YCA6IGxhYmVsO1xuICB9KTtcbiAgcmV0dXJuIFsuLi5saW5lcywgXCLsnqzroZzqt7jsnbjsnbQg7ZWE7JqU7ZWp64uI64ukXCJdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXCIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZW5kUmVtaW5kZXIoZGVwczogRXhwaXJlZFRva2VuUmVtaW5kZXJEZXBzLCB1cmdlbnQgPSBmYWxzZSk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGNvbnN0IGluYWN0aXZlID0gYXdhaXQgZGVwcy5maW5kSW5hY3RpdmUoKTtcbiAgaWYgKGluYWN0aXZlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG5cbiAgY29uc3QgdXNlck1hcCA9IGRlcHMuZ2V0U2xhY2tVc2VyTWFwKCk7XG5cbiAgYXdhaXQgZGVwcy5zZW5kU2xhY2soe1xuICAgIC8vIOunjOujjCDsiJzqsIQg7JWM66a86rO8IOqwmeydgCDsoJzrqqnsnYQg7JO064ukLiDqsJnsnYAg7IKs6rG07J2066+A66GcIOuLpOuluCDsnbTrpoTsnYQg67aZ7J2066m0IOuzhOqwnCDrrLjsoJzroZwg7J297Z6M64ukLlxuICAgIHRpdGxlOiBcIuyEuOyFmCDrp4zro4xcIixcbiAgICBzdWJqZWN0OiBpbmFjdGl2ZS5sZW5ndGggPiAxID8gYCR7aW5hY3RpdmUubGVuZ3RofeqxtGAgOiAoaW5hY3RpdmVbMF0hLm5hbWUgPz8gXCJ1bm5hbWVkXCIpLFxuICAgIGNvbnRleHQ6IGJ1aWxkUmVtaW5kZXJDb250ZXh0KGluYWN0aXZlLCB1c2VyTWFwKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuYmFkLFxuICAgIHVyZ2VudCxcbiAgfSk7XG4gIHJldHVybiBpbmFjdGl2ZS5sZW5ndGg7XG59XG5cbi8qKlxuICog7ZmU66m07J2YIFwi7KeA6riIIOuztOuCtOq4sFwiLiDsgqzrnozsnbQg7KeB7KCRIOuIhOuluCDqsoPsnbTrr4DroZwg7KGw7JqpIOyLnOqwhMK366eI7Iqk7YSwIOyKpOychOy5mOulvCDthrXqs7zsi5ztgqjri6Qg4oCUXG4gKiDriIzroIDripTrjbAg7JWE66y0IOydvOuPhCDslYgg7J287Ja064KY66m0IOuyhO2KvOydtCDqs6DsnqUg64KcIOqyg+ycvOuhnCDsnb3tnozri6QuXG4gKlxuICog67O064K4IOqxtOyImOulvCDrj4zroKTspJgg7Zi47Lac67aA6rCAIFwi67O064K8IOuMgOyDgSDsl4bsnYxcIuqzvCBcIuuztOuDhFwi7J2EIOq1rOu2hO2VtCDrs7Tsl6zspIDri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZW5kRXhwaXJlZFRva2VuUmVtaW5kZXJOb3coXG4gIGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyA9IGRlZmF1bHREZXBzLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIHNlbmRSZW1pbmRlcihkZXBzLCB0cnVlKTtcbn1cblxubGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcblxuZnVuY3Rpb24gc2NoZWR1bGVFeHBpcmVkVG9rZW5SZW1pbmRlcihydW5Ob3c6IGJvb2xlYW4sIGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyk6IHZvaWQge1xuICBzdG9wRXhwaXJlZFRva2VuUmVtaW5kZXIoKTtcblxuICAvLyDso7zquLAg6rCS6rO8IOuzhOqwnOyduCDsiqTsnITsuZjri6QuIOq6vOuPhCDso7zquLDripQg64Ko7JWEIOyeiOyWtCDri6Tsi5wg7LykIOuVjCDqs6DrpbTrjZgg6rCS7J20IOq3uOuMgOuhnOuLpC5cbiAgaWYgKGRlcHMucmVhZFNldHRpbmcoXCJzbGFjay5yZW1pbmRlcnNFbmFibGVkXCIsIFwiU0xBQ0tfUkVNSU5ERVJTX0VOQUJMRURcIikgPT09IFwiZmFsc2VcIikge1xuICAgIGxvZ2dlci5pbmZvKFwiZXhwaXJlZCB0b2tlbiByZW1pbmRlciBkaXNhYmxlZFwiKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBtaW51dGVzID0gTnVtYmVyKFxuICAgIGRlcHMucmVhZFNldHRpbmcoXCJzbGFjay5leHBpcnlSZW1pbmRlck1pbnV0ZXNcIiwgXCJTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU1wiKSA/PyAwLFxuICApO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShtaW51dGVzKSB8fCBtaW51dGVzIDw9IDApIHJldHVybjtcblxuICBsb2dnZXIuaW5mbyhcbiAgICBgZXhwaXJlZCB0b2tlbiByZW1pbmRlciBldmVyeSAke21pbnV0ZXN9bSAoJHtkZXBzLmdldFNsYWNrVXNlck1hcCgpLnNpemV9IHVzZXIgbWFwcGluZ3MpYCxcbiAgKTtcblxuICBjb25zdCBydW4gPSAoKSA9PlxuICAgIHNlbmRSZW1pbmRlcihkZXBzKS5jYXRjaCgoZSkgPT4gbG9nZ2VyLndhcm4oYHJlbWluZGVyIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKSk7XG5cbiAgaWYgKHJ1bk5vdykgdm9pZCBydW4oKTtcbiAgdGltZXIgPSBzZXRJbnRlcnZhbChydW4sIG1pbnV0ZXMgKiBNSU5VVEVfTVMpO1xufVxuXG4vKipcbiAqIGBTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU2Ag6rCAIOyWkeyImOydvCDrlYzrp4wg7Lyc7KeE64ukLiDrr7jshKTsoJXCtzAg7J2066m0IOu5hO2ZnOyEsS5cbiAqXG4gKiDsnbjsiqTthLTsiqTqsIAg7Jes65+sIOqwnOuptCDqsIHsnpAg67O064K464ukLiDrp4zro4wg7Iic6rCEIOyVjOumvOqzvCDri6zrpqwg7IOB7YOcIOuzgO2ZlOqwgCDsl4bslrQgREIg66GcIOyWteygnO2VoCDsiJhcbiAqIOyXhuqzoCwg7ZWY66OoIOuqhyDqsbQg7IiY7KSA7J206528IOykkeuzteydhCDqsJDsiJjtlZjripQg7Y647J20IOyeoOq4iCDsnqXsuZjrpbwg65GQ64qUIOqyg+uztOuLpCDrgqvri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydEV4cGlyZWRUb2tlblJlbWluZGVyKGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyA9IGRlZmF1bHREZXBzKTogdm9pZCB7XG4gIC8vIOq4sOuPmSDsp4Htm4Tsl5Drj4Qg7ZWcIOuyiCDrs7Trgrjri6QuIOyerOq4sOuPmeydgCDrsLDtj6zrgpgg7J6l7JWgIOuzteq1rCDrlYwg7J287Ja064KY64qU642wLCDqt7gg7Iuc7KCQ7JeQIOydtOuvuFxuICAvLyDrp4zro4zrkJwg7Yag7YGw7J20IOyeiOycvOuptCDssqsg7KO86riw6rCAIOuPjCDrlYzquYzsp4Ag7KGw7Jqp7ZWcIOqyg+ydtCDsnbTsg4HtlZjri6QuXG4gIHNjaGVkdWxlRXhwaXJlZFRva2VuUmVtaW5kZXIodHJ1ZSwgZGVwcyk7XG59XG5cbi8qKiDshKTsoJUg67OA6rK9IOyLnCDquLDsobQg7YOA7J2066i466eMIOyDiCDso7zquLDroZwg6rWQ7LK07ZWc64ukLiDsoIDsnqUg7J6Q7LK06rCAIOyVjOumvOydhCDrs7TrgrTsp4DripQg7JWK64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2NoZWR1bGVFeHBpcmVkVG9rZW5SZW1pbmRlcihkZXBzOiBFeHBpcmVkVG9rZW5SZW1pbmRlckRlcHMgPSBkZWZhdWx0RGVwcyk6IHZvaWQge1xuICBzY2hlZHVsZUV4cGlyZWRUb2tlblJlbWluZGVyKGZhbHNlLCBkZXBzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0b3BFeHBpcmVkVG9rZW5SZW1pbmRlcigpOiB2b2lkIHtcbiAgaWYgKCF0aW1lcikgcmV0dXJuO1xuICBjbGVhckludGVydmFsKHRpbWVyKTtcbiAgdGltZXIgPSBudWxsO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsTUFBTSxTQUFTLFVBQVUsQ0FBQyxTQUFTLGtCQUFrQixDQUFDO0FBRXRELE1BQU0sWUFBWTtBQVNsQixNQUFNLGNBQXdDO0NBQzVDLG9CQUFvQixXQUFXLGFBQWEsR0FBRztDQUMvQztDQUNBLGFBQWE7Q0FDYixXQUFXO0FBQ2I7Ozs7O0FBTUEsU0FBZ0IscUJBQ2QsUUFDQSxTQUNRO0NBQ1IsTUFBTSxZQUFZLE9BQU8sU0FBUztDQU9sQyxPQUFPLENBQUMsR0FOTSxPQUFPLEtBQUssVUFBVTtFQUNsQyxNQUFNLFVBQVUsV0FBVyxNQUFNLE1BQU0sT0FBTztFQUM5QyxNQUFNLFFBQVEsTUFBTSxRQUFRO0VBQzVCLElBQUksQ0FBQyxXQUFXLE9BQU87RUFDdkIsT0FBTyxVQUFVLEdBQUcsUUFBUSxHQUFHLFVBQVU7Q0FDM0MsQ0FDVyxHQUFPLGFBQWEsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxJQUFJO0FBQzVEO0FBRUEsZUFBZSxhQUFhLE1BQWdDLFNBQVMsT0FBd0I7Q0FDM0YsTUFBTSxXQUFXLE1BQU0sS0FBSyxhQUFhO0NBQ3pDLElBQUksU0FBUyxXQUFXLEdBQUcsT0FBTztDQUVsQyxNQUFNLFVBQVUsS0FBSyxnQkFBZ0I7Q0FFckMsTUFBTSxLQUFLLFVBQVU7RUFFbkIsT0FBTztFQUNQLFNBQVMsU0FBUyxTQUFTLElBQUksR0FBRyxTQUFTLE9BQU8sS0FBTSxTQUFTLEVBQUUsQ0FBRSxRQUFRO0VBQzdFLFNBQVMscUJBQXFCLFVBQVUsT0FBTztFQUMvQyxPQUFPLFlBQVk7RUFDbkI7Q0FDRixDQUFDO0NBQ0QsT0FBTyxTQUFTO0FBQ2xCOzs7Ozs7O0FBUUEsU0FBZ0IsNEJBQ2QsT0FBaUMsYUFDaEI7Q0FDakIsT0FBTyxhQUFhLE1BQU0sSUFBSTtBQUNoQztBQUVBLElBQUksUUFBK0M7QUFFbkQsU0FBUyw2QkFBNkIsUUFBaUIsTUFBc0M7Q0FDM0YseUJBQXlCO0NBR3pCLElBQUksS0FBSyxZQUFZLDBCQUEwQix5QkFBeUIsTUFBTSxTQUFTO0VBQ3JGLE9BQU8sS0FBSyxpQ0FBaUM7RUFDN0M7Q0FDRjtDQUVBLE1BQU0sVUFBVSxPQUNkLEtBQUssWUFBWSwrQkFBK0Isd0NBQXdDLEtBQUssQ0FDL0Y7Q0FDQSxJQUFJLENBQUMsT0FBTyxTQUFTLE9BQU8sS0FBSyxXQUFXLEdBQUc7Q0FFL0MsT0FBTyxLQUNMLGdDQUFnQyxRQUFRLEtBQUssS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssZ0JBQzNFO0NBRUEsTUFBTSxZQUNKLGFBQWEsSUFBSSxDQUFDLENBQUMsT0FBTyxNQUFNLE9BQU8sS0FBSyxvQkFBcUIsRUFBWSxTQUFTLENBQUM7Q0FFekYsSUFBSSxRQUFRLEFBQUssSUFBSTtDQUNyQixRQUFRLFlBQVksS0FBSyxVQUFVLFNBQVM7QUFDOUM7Ozs7Ozs7QUFRQSxTQUFnQiwwQkFBMEIsT0FBaUMsYUFBbUI7Q0FHNUYsNkJBQTZCLE1BQU0sSUFBSTtBQUN6Qzs7QUFHQSxTQUFnQiwrQkFBK0IsT0FBaUMsYUFBbUI7Q0FDakcsNkJBQTZCLE9BQU8sSUFBSTtBQUMxQztBQUVBLFNBQWdCLDJCQUFpQztDQUMvQyxJQUFJLENBQUMsT0FBTztDQUNaLGNBQWMsS0FBSztDQUNuQixRQUFRO0FBQ1YifQ==
@@ -1,5 +1,5 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
1
  import { getLogger } from "@logtape/logtape";
2
+ import { createHash, randomBytes } from "node:crypto";
3
3
  //#region src/application/qgrid/oauth.ts
4
4
  /**
5
5
  * OAuth 유틸 — Claude Code 소스의 OAuth 플로우 그대로 재현
@@ -1,10 +1,10 @@
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
1
3
  import { getAccessToken, getExpiresAt, getRefreshToken } from "../../utils/providers/common/credentials.js";
2
4
  import { CallerSchemaValidationError } from "../../utils/providers/common/schema-validation.js";
3
5
  import { StreamEvents } from "./qgrid.types.js";
4
6
  import { ToolSchemaCompositionError } from "./tool-emulation-schema.js";
5
7
  import { QgridDispatcher, buildAndValidateStrictOutputSchema } from "./qgrid.dispatcher.js";
6
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
7
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
8
8
  import { TokenModel } from "../token/token.model.js";
9
9
  import { CONSOLE_CALLBACK_URL, RefreshFailedError, buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken } from "./oauth.js";
10
10
  import { MICRO_USD, RequestLogModel } from "../request-log/request-log.model.js";
@@ -12,8 +12,8 @@ import { afterQuery, beforeQuery, finishRunAborted, finishRunWithError } from ".
12
12
  import { TokenCredentials } from "../token/token.types.js";
13
13
  import { deactivateAuthDeadToken, notifyTokenAdded } from "./token-death.js";
14
14
  import { BadRequestException, BaseFrameClass, Sonamu, api, stream } from "sonamu";
15
- import crypto from "node:crypto";
16
15
  import { getLogger } from "@logtape/logtape";
16
+ import crypto from "node:crypto";
17
17
  import { getCacheManagerRef } from "sonamu/cache";
18
18
  //#region src/application/qgrid/qgrid.frame.ts
19
19
  const pendingStreams = /* @__PURE__ */ new Map();
@@ -1,3 +1,4 @@
1
+ import { getSetting } from "../setting/setting.store.js";
1
2
  //#region src/application/qgrid/slack-user-map.ts
2
3
  /**
3
4
  * 토큰 소유자 → Slack 사용자 멘션.
@@ -30,20 +31,10 @@ function mentionFor(tokenName, userMap) {
30
31
  const userId = userMap.get(ownerOf(tokenName));
31
32
  return userId ? `<@${userId}>` : "";
32
33
  }
33
- /**
34
- * 환경변수는 프로세스 수명 동안 고정이라 매번 파싱할 이유가 없다. 사망 알림은 요청 경로에서
35
- * 호출되므로 캐시해 둔다.
36
- */
37
- let cached = null;
38
- function getSlackUserMap() {
39
- cached ??= parseSlackUserMap(process.env.SLACK_USER_MAP);
40
- return cached;
41
- }
42
- /** 테스트에서 env 를 바꿔 끼울 때 쓴다. */
43
- function resetSlackUserMapCache() {
44
- cached = null;
34
+ function getSlackUserMap(readSetting = getSetting) {
35
+ return parseSlackUserMap(readSetting("slack.userMap", "SLACK_USER_MAP"));
45
36
  }
46
37
  //#endregion
47
- export { getSlackUserMap, mentionFor, ownerOf, parseSlackUserMap, resetSlackUserMapCache };
38
+ export { getSlackUserMap, mentionFor, ownerOf, parseSlackUserMap };
48
39
 
49
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stdXNlci1tYXAuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3NsYWNrLXVzZXItbWFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7Yag7YGwIOyGjOycoOyekCDihpIgU2xhY2sg7IKs7Jqp7J6QIOupmOyFmC5cbiAqXG4gKiBTbGFjayDtkZzsi5wg7J2066aE6rO8IO2GoO2BsOuqheydtCDsnpDso7wg7Ja06riL64KYKGhhemXihpJoYXplLmxlZSwgYnllb25nanVu4oaScG90YWRvcykgYHVzZXJzLmxpc3RgXG4gKiDsnpDrj5kg66ek7Lmt7J2AIOyhsOyaqe2eiCDsi6TtjKjtlZzri6QuIOupmOyFmOydtCDruaDsp4DrqbQg7JWM66a87J20IOqwnOyduOyXkOqyjCDri7/sp4Ag7JWK7JWEIOuqqeyggSDsnpDssrTqsIBcbiAqIOyCrOudvOyngOuvgOuhnCBgU0xBQ0tfVVNFUl9NQVBgIOuqheyLnCDrp6TtlZHrp4wg7JO064ukLlxuICpcbiAqIOqzteyaqSDqs4TsoJUoYnlzdWNvLCBkZXYtY29tbW9uIOuTsSnsnYAg66ek7ZWR7JeQIOuEo+yngCDslYrripTri6Qg4oCUIOupmOyFmCDsl4bsnbQg7J2066aE66eMIOuCmOqwgOuKlCDqsoPsnbRcbiAqIOunnuuKlCDrj5nsnpHsnbTri6QuXG4gKi9cblxuLyoqIGDthqDtgbDrqoU6U2xhY2tVc2VySWRgIOuqqeuhneydhCDtjIzsi7HtlZzri6QuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTbGFja1VzZXJNYXAocmF3OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgaWYgKCFyYXcpIHJldHVybiBtYXA7XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiByYXcuc3BsaXQoXCIsXCIpKSB7XG4gICAgY29uc3QgW25hbWUsIHVzZXJJZF0gPSBlbnRyeS5zcGxpdChcIjpcIikubWFwKChzKSA9PiBzLnRyaW0oKSk7XG4gICAgaWYgKG5hbWUgJiYgdXNlcklkKSBtYXAuc2V0KG5hbWUsIHVzZXJJZCk7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn1cblxuLyoqIGBhbnRocm9waWMveWRzYCDihpIgYHlkc2AuIHByb3ZpZGVyIHByZWZpeCDsl4bsnbQg7KCA7J6l65CcIOydtOumhOuPhCDqt7jrjIDroZwg67Cb64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG93bmVyT2YodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHtcbiAgaWYgKCF0b2tlbk5hbWUpIHJldHVybiBcIlwiO1xuICBjb25zdCBzbGFzaCA9IHRva2VuTmFtZS5pbmRleE9mKFwiL1wiKTtcbiAgcmV0dXJuIHNsYXNoID09PSAtMSA/IHRva2VuTmFtZSA6IHRva2VuTmFtZS5zbGljZShzbGFzaCArIDEpO1xufVxuXG4vKiog66ek7ZWR7J20IOyeiOycvOuptCBgPEBVLi4uPmAsIOyXhuycvOuptCDruYgg66y47J6Q7Je0LiDtmLjstpzrtoDqsIAg66mY7IWYIOycoOustOuhnCDrrLjqtazrpbwg6rOg66W464ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lbnRpb25Gb3IodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsLCB1c2VyTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcbiAgY29uc3QgdXNlcklkID0gdXNlck1hcC5nZXQob3duZXJPZih0b2tlbk5hbWUpKTtcbiAgcmV0dXJuIHVzZXJJZCA/IGA8QCR7dXNlcklkfT5gIDogXCJcIjtcbn1cblxuLyoqXG4gKiDtmZjqsr3rs4DsiJjripQg7ZSE66Gc7IS47IqkIOyImOuqhSDrj5nslYgg6rOg7KCV7J206528IOunpOuyiCDtjIzsi7HtlaAg7J207Jyg6rCAIOyXhuuLpC4g7IKs66edIOyVjOumvOydgCDsmpTssq0g6rK966Gc7JeQ7IScXG4gKiDtmLjstpzrkJjrr4DroZwg7LqQ7Iuc7ZW0IOuRlOuLpC5cbiAqL1xubGV0IGNhY2hlZDogTWFwPHN0cmluZywgc3RyaW5nPiB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2xhY2tVc2VyTWFwKCk6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICBjYWNoZWQgPz89IHBhcnNlU2xhY2tVc2VyTWFwKHByb2Nlc3MuZW52LlNMQUNLX1VTRVJfTUFQKTtcbiAgcmV0dXJuIGNhY2hlZDtcbn1cblxuLyoqIO2FjOyKpO2KuOyXkOyEnCBlbnYg66W8IOuwlOq/lCDrgbzsmrgg65WMIOyTtOuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldFNsYWNrVXNlck1hcENhY2hlKCk6IHZvaWQge1xuICBjYWNoZWQgPSBudWxsO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFZQSxTQUFnQixrQkFBa0IsS0FBOEM7Q0FDOUUsTUFBTSxzQkFBTSxJQUFJLElBQW9CO0NBQ3BDLElBQUksQ0FBQyxLQUFLLE9BQU87Q0FFakIsS0FBSyxNQUFNLFNBQVMsSUFBSSxNQUFNLEdBQUcsR0FBRztFQUNsQyxNQUFNLENBQUMsTUFBTSxVQUFVLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLE1BQU0sRUFBRSxLQUFLLENBQUM7RUFDM0QsSUFBSSxRQUFRLFFBQVEsSUFBSSxJQUFJLE1BQU0sTUFBTTtDQUMxQztDQUNBLE9BQU87QUFDVDs7QUFHQSxTQUFnQixRQUFRLFdBQWtDO0NBQ3hELElBQUksQ0FBQyxXQUFXLE9BQU87Q0FDdkIsTUFBTSxRQUFRLFVBQVUsUUFBUSxHQUFHO0NBQ25DLE9BQU8sVUFBVSxLQUFLLFlBQVksVUFBVSxNQUFNLFFBQVEsQ0FBQztBQUM3RDs7QUFHQSxTQUFnQixXQUFXLFdBQTBCLFNBQXNDO0NBQ3pGLE1BQU0sU0FBUyxRQUFRLElBQUksUUFBUSxTQUFTLENBQUM7Q0FDN0MsT0FBTyxTQUFTLEtBQUssT0FBTyxLQUFLO0FBQ25DOzs7OztBQU1BLElBQUksU0FBcUM7QUFFekMsU0FBZ0Isa0JBQXVDO0NBQ3JELFdBQVcsa0JBQWtCLFFBQVEsSUFBSSxjQUFjO0NBQ3ZELE9BQU87QUFDVDs7QUFHQSxTQUFnQix5QkFBK0I7Q0FDN0MsU0FBUztBQUNYIn0=
40
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stdXNlci1tYXAuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3NsYWNrLXVzZXItbWFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7Yag7YGwIOyGjOycoOyekCDihpIgU2xhY2sg7IKs7Jqp7J6QIOupmOyFmC5cbiAqXG4gKiBTbGFjayDtkZzsi5wg7J2066aE6rO8IO2GoO2BsOuqheydtCDsnpDso7wg7Ja06riL64KYKGhhemXihpJoYXplLmxlZSwgYnllb25nanVu4oaScG90YWRvcykgYHVzZXJzLmxpc3RgXG4gKiDsnpDrj5kg66ek7Lmt7J2AIOyhsOyaqe2eiCDsi6TtjKjtlZzri6QuIOupmOyFmOydtCDruaDsp4DrqbQg7JWM66a87J20IOqwnOyduOyXkOqyjCDri7/sp4Ag7JWK7JWEIOuqqeyggSDsnpDssrTqsIBcbiAqIOyCrOudvOyngOuvgOuhnCBgU0xBQ0tfVVNFUl9NQVBgIOuqheyLnCDrp6TtlZHrp4wg7JO064ukLlxuICpcbiAqIOqzteyaqSDqs4TsoJUoYnlzdWNvLCBkZXYtY29tbW9uIOuTsSnsnYAg66ek7ZWR7JeQIOuEo+yngCDslYrripTri6Qg4oCUIOupmOyFmCDsl4bsnbQg7J2066aE66eMIOuCmOqwgOuKlCDqsoPsnbRcbiAqIOunnuuKlCDrj5nsnpHsnbTri6QuXG4gKi9cblxuaW1wb3J0IHsgZ2V0U2V0dGluZyB9IGZyb20gXCIuLi9zZXR0aW5nL3NldHRpbmcuc3RvcmVcIjtcblxuLyoqIGDthqDtgbDrqoU6U2xhY2tVc2VySWRgIOuqqeuhneydhCDtjIzsi7HtlZzri6QuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTbGFja1VzZXJNYXAocmF3OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgaWYgKCFyYXcpIHJldHVybiBtYXA7XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiByYXcuc3BsaXQoXCIsXCIpKSB7XG4gICAgY29uc3QgW25hbWUsIHVzZXJJZF0gPSBlbnRyeS5zcGxpdChcIjpcIikubWFwKChzKSA9PiBzLnRyaW0oKSk7XG4gICAgaWYgKG5hbWUgJiYgdXNlcklkKSBtYXAuc2V0KG5hbWUsIHVzZXJJZCk7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn1cblxuLyoqIGBhbnRocm9waWMveWRzYCDihpIgYHlkc2AuIHByb3ZpZGVyIHByZWZpeCDsl4bsnbQg7KCA7J6l65CcIOydtOumhOuPhCDqt7jrjIDroZwg67Cb64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG93bmVyT2YodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHtcbiAgaWYgKCF0b2tlbk5hbWUpIHJldHVybiBcIlwiO1xuICBjb25zdCBzbGFzaCA9IHRva2VuTmFtZS5pbmRleE9mKFwiL1wiKTtcbiAgcmV0dXJuIHNsYXNoID09PSAtMSA/IHRva2VuTmFtZSA6IHRva2VuTmFtZS5zbGljZShzbGFzaCArIDEpO1xufVxuXG4vKiog66ek7ZWR7J20IOyeiOycvOuptCBgPEBVLi4uPmAsIOyXhuycvOuptCDruYgg66y47J6Q7Je0LiDtmLjstpzrtoDqsIAg66mY7IWYIOycoOustOuhnCDrrLjqtazrpbwg6rOg66W464ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lbnRpb25Gb3IodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsLCB1c2VyTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcbiAgY29uc3QgdXNlcklkID0gdXNlck1hcC5nZXQob3duZXJPZih0b2tlbk5hbWUpKTtcbiAgcmV0dXJuIHVzZXJJZCA/IGA8QCR7dXNlcklkfT5gIDogXCJcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNsYWNrVXNlck1hcChyZWFkU2V0dGluZzogdHlwZW9mIGdldFNldHRpbmcgPSBnZXRTZXR0aW5nKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiBwYXJzZVNsYWNrVXNlck1hcChyZWFkU2V0dGluZyhcInNsYWNrLnVzZXJNYXBcIiwgXCJTTEFDS19VU0VSX01BUFwiKSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFjQSxTQUFnQixrQkFBa0IsS0FBOEM7Q0FDOUUsTUFBTSxzQkFBTSxJQUFJLElBQW9CO0NBQ3BDLElBQUksQ0FBQyxLQUFLLE9BQU87Q0FFakIsS0FBSyxNQUFNLFNBQVMsSUFBSSxNQUFNLEdBQUcsR0FBRztFQUNsQyxNQUFNLENBQUMsTUFBTSxVQUFVLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLE1BQU0sRUFBRSxLQUFLLENBQUM7RUFDM0QsSUFBSSxRQUFRLFFBQVEsSUFBSSxJQUFJLE1BQU0sTUFBTTtDQUMxQztDQUNBLE9BQU87QUFDVDs7QUFHQSxTQUFnQixRQUFRLFdBQWtDO0NBQ3hELElBQUksQ0FBQyxXQUFXLE9BQU87Q0FDdkIsTUFBTSxRQUFRLFVBQVUsUUFBUSxHQUFHO0NBQ25DLE9BQU8sVUFBVSxLQUFLLFlBQVksVUFBVSxNQUFNLFFBQVEsQ0FBQztBQUM3RDs7QUFHQSxTQUFnQixXQUFXLFdBQTBCLFNBQXNDO0NBQ3pGLE1BQU0sU0FBUyxRQUFRLElBQUksUUFBUSxTQUFTLENBQUM7Q0FDN0MsT0FBTyxTQUFTLEtBQUssT0FBTyxLQUFLO0FBQ25DO0FBRUEsU0FBZ0IsZ0JBQWdCLGNBQWlDLFlBQWlDO0NBQ2hHLE9BQU8sa0JBQWtCLFlBQVksaUJBQWlCLGdCQUFnQixDQUFDO0FBQ3pFIn0=
@@ -70,7 +70,8 @@ function notifyLastActiveTokenDying(token, reasonCode) {
70
70
  token.provider,
71
71
  reasonCode
72
72
  ].filter(Boolean).join(" · ") + " · 풀이 비지 않도록 유지 중입니다. 전 토큰이 동시에 실패했다면 client_id 취소나 OAuth 계약 변경을 의심하세요",
73
- color: SLACK_COLOR.bad
73
+ color: SLACK_COLOR.bad,
74
+ urgent: true
74
75
  });
75
76
  }
76
77
  /** 로그인이 완료돼 토큰이 저장됐을 때. 신규·재로그인을 가리지 않는다. */
@@ -90,4 +91,4 @@ function notifyTokenAdded(name, provider) {
90
91
  //#endregion
91
92
  export { deactivateAuthDeadToken, notifyTokenAdded };
92
93
 
93
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tZGVhdGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rva2VuLWRlYXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7IS47IWYIOunjOujjChhdXRoLWRlYWQpIO2GoO2BsOydmCDrnbzsmrDtjIUg7KCc7Jm4IOyngOygkC5cbiAqXG4gKiByZWZyZXNoIOqwgCDsnqzroZzqt7jsnbgg7Jm4IOuzteq1rCDrtojqsIDtlZwg7Iuk7Yyo66W8IOuwmO2ZmO2VnCDsiJzqsITsl5Drp4wg7Zi47Lac65Cc64ukLiDruYTtmZzshLHtmZTripRcbiAqIGBhY3RpdmU9dHJ1ZWAg7KGw6rG067aAIOqwseyLoCAx7ZqM7J206rOgLCDqt7gg6rCx7Iug7J2EIOydtOq4tCDtlITroZzshLjsiqTrp4wgU2xhY2sg7JWM66a87J2EIOuztOuCuOuLpCDigJRcbiAqIOqzteycoCBEQiDrpbwg7JOw64qUIOyduOyKpO2EtOyKpOqwgCDrqofsnbTrk6Ag7IKs6rG064u5IOyVjOumvOydgCAx6rG07J2064ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBnZXRSZWZyZXNoVG9rZW4gfSBmcm9tIFwiLi4vLi4vdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHsgbm90aWZ5U2xhY2ssIFNMQUNLX0NPTE9SIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3NsYWNrLW5vdGlmeVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9rZW4tZGVhdGhcIl0pO1xuXG50eXBlIERlYWRUb2tlblJlZiA9IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwcm92aWRlcjogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gdXNlZFJlZnJlc2hUb2tlbiDsi6TtjKjtlZwg7JqU7LKt7J20IOyLpOygnOuhnCDsgqzsmqntlZwgcmVmcmVzaCB0b2tlbi5cbiAqICAgcmVmcmVzaCB0b2tlbiDsnYAg7ZqM7KCEIOyggOyepeuQmOuvgOuhnCwg7J2066+4IO2ajOyghOuQnCDsmJsg7Yag7YGw7Jy866GcIOuKpuqyjCDrj4TssKntlZwg7J6s7Iuc64+E6rCAXG4gKiAgIDQwMCDsnYQg67Cb64qUIOqyg+ydgCDsoJXsg4Eg66CI7J207Iqk64ukLiBEQiDsnZgg7ZiE7J6sIOqwkuqzvCDri6TrpbTrqbQg7IKs66ed7Jy866GcIOuztOyngCDslYrripTri6QuXG4gKiBAcGFyYW0gcmVhc29uQ29kZSBgcHJvdmlkZXI6Y29kZWAg7ZiV7YOc7J2YIOuCtOu2gCDsvZTrk5wuIHByb3ZpZGVyIOydkeuLtSDrs7jrrLjsl5DripQg6rOE7KCVIOydtOuplOydvOydtOuCmFxuICogICDthqDtgbAg7KGw6rCB7J20IOyEnuydvCDsiJgg7J6I7Ja0IHJhdyDrqZTsi5zsp4Drpbwg6re464yA66GcIOyVjOumvOyXkCDsi6Psp4Ag7JWK64qU64ukLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVhY3RpdmF0ZUF1dGhEZWFkVG9rZW4oXG4gIHRva2VuOiBEZWFkVG9rZW5SZWYsXG4gIHVzZWRSZWZyZXNoVG9rZW46IHN0cmluZyxcbiAgcmVhc29uQ29kZTogc3RyaW5nLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQ6IHRva2VuLmlkIH0pO1xuICBpZiAoIWN1cnJlbnQpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBjdXJyZW50UmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGN1cnJlbnQuY3JlZGVudGlhbHMpO1xuICBpZiAoY3VycmVudFJlZnJlc2hUb2tlbiAmJiBjdXJyZW50UmVmcmVzaFRva2VuICE9PSB1c2VkUmVmcmVzaFRva2VuKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgc2tpcHBpbmcgYXV0aC1kZWF0aCBmb3IgJHt0b2tlbi5uYW1lfShpZD0ke3Rva2VuLmlkfSk6IHJlZnJlc2ggdG9rZW4gcm90YXRlZCBzaW5jZSB0aGlzIGF0dGVtcHRgLFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgeyBkZWFjdGl2YXRlZCwga2VwdEFzTGFzdEFjdGl2ZSB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5kZWFjdGl2YXRlSWZBY3RpdmUodG9rZW4uaWQpO1xuICBpZiAoIWRlYWN0aXZhdGVkKSB7XG4gICAgaWYgKGtlcHRBc0xhc3RBY3RpdmUpIG5vdGlmeUxhc3RBY3RpdmVUb2tlbkR5aW5nKHRva2VuLCByZWFzb25Db2RlKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsb2dnZXIud2FybihgdG9rZW4gZGVhY3RpdmF0ZWQgKGF1dGggZGVhZCk6ICR7dG9rZW4ubmFtZX0oaWQ9JHt0b2tlbi5pZH0pIHJlYXNvbj0ke3JlYXNvbkNvZGV9YCk7XG4gIC8vIOunjOujjCDsp4Htm4TqsIAg7J6s66Gc6re47J247ZWY6riwIOqwgOyepSDsoovsnYAg7YOA7J2067CN7J2064ukLiDshozsnKDsnpDrpbwg66mY7IWY7ZW0IOq3uCDsiJzqsIQg64u57IKs7J6Q7JeQ6rKMXG4gIC8vIOq9guuKlOuLpCDigJQg64uk7J207KCc7Iqk7Yq466W8IOq4sOuLpOumrOuptCDri6TsnYwg7KO86riw6rmM7KeAIO2GoO2BsOydtCDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC5cbiAgY29uc3QgbWVudGlvbiA9IG1lbnRpb25Gb3IodG9rZW4ubmFtZSwgZ2V0U2xhY2tVc2VyTWFwKCkpO1xuICB2b2lkIG5vdGlmeVNsYWNrKHtcbiAgICB0aXRsZTogXCLshLjshZgg66eM66OMXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OiBbbWVudGlvbiwgdG9rZW4ucHJvdmlkZXIsIHJlYXNvbkNvZGUsIFwi7J6s66Gc6re47J247J20IO2VhOyalO2VqeuLiOuLpFwiXVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmpvaW4oXCIgwrcgXCIpLFxuICAgIGNvbG9yOiBTTEFDS19DT0xPUi5iYWQsXG4gIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDrp4jsp4Drp4kg7Zmc7ISxIO2GoO2BsOydtCDso73sl4jsnYQg65WM7J2YIOyVjOumvCDsv6jri6TsmrQuXG4gKlxuICog7J20IOqyveyasCDthqDtgbDsnYAg67mE7Zmc7ISx7ZmU65CY7KeAIOyViuqzoCDsgrTslYTrgqjsnLzrr4DroZwsIOuSpOuUsOultOuKlCDsmpTssq3rp4jri6Qg6rCZ7J2AIOyLpO2MqOulvCDrsJjrs7XtlbRcbiAqIOyVjOumvOydtCDtj63so7ztlZzri6QuIOu5hO2ZnOyEse2ZlCDshLHqs7Ug6rK966Gc6rCAIOyhsOqxtOu2gCBVUERBVEUg66GcIOykkeuzteydhCDrp4nripQg6rKD6rO8IOuLrOumrCDsl6zquLDsl5RcbiAqIOyDge2DnCDrs4DtmZTqsIAg7JeG7Ja0IERCIOuhnCDslrXsoJztlaAg7IiYIOyXhuuLpCDigJQgcHJvdmlkZXIg64uo7JyE66GcIOyLnOqwhCDssL3snYQg65GU64ukLlxuICovXG5jb25zdCBMQVNUX0FDVElWRV9BTEVSVF9DT09MRE9XTl9NUyA9IDMwICogNjAgKiAxMDAwO1xuY29uc3QgbGFzdEFjdGl2ZUFsZXJ0QXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5mdW5jdGlvbiBub3RpZnlMYXN0QWN0aXZlVG9rZW5EeWluZyh0b2tlbjogRGVhZFRva2VuUmVmLCByZWFzb25Db2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcHJldmlvdXMgPSBsYXN0QWN0aXZlQWxlcnRBdC5nZXQodG9rZW4ucHJvdmlkZXIpO1xuICBpZiAocHJldmlvdXMgIT09IHVuZGVmaW5lZCAmJiBub3cgLSBwcmV2aW91cyA8IExBU1RfQUNUSVZFX0FMRVJUX0NPT0xET1dOX01TKSByZXR1cm47XG4gIGxhc3RBY3RpdmVBbGVydEF0LnNldCh0b2tlbi5wcm92aWRlciwgbm93KTtcblxuICBjb25zdCBtZW50aW9uID0gbWVudGlvbkZvcih0b2tlbi5uYW1lLCBnZXRTbGFja1VzZXJNYXAoKSk7XG4gIHZvaWQgbm90aWZ5U2xhY2soe1xuICAgIHRpdGxlOiBcIuuniOyngOuniSDthqDtgbAg7IKs66edXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OlxuICAgICAgW21lbnRpb24sIHRva2VuLnByb3ZpZGVyLCByZWFzb25Db2RlXS5maWx0ZXIoQm9vbGVhbikuam9pbihcIiDCtyBcIikgK1xuICAgICAgYCDCtyDtkoDsnbQg67mE7KeAIOyViuuPhOuhnSDsnKDsp4Ag7KSR7J6F64uI64ukLiBgICtcbiAgICAgIGDsoIQg7Yag7YGw7J20IOuPmeyLnOyXkCDsi6TtjKjtlojri6TrqbQgY2xpZW50X2lkIOy3qOyGjOuCmCBPQXV0aCDqs4Tslb0g67OA6rK97J2EIOydmOyLrO2VmOyEuOyalGAsXG4gICAgY29sb3I6IFNMQUNLX0NPTE9SLmJhZCxcbiAgfSk7XG59XG5cbi8qKiDroZzqt7jsnbjsnbQg7JmE66OM64+8IO2GoO2BsOydtCDsoIDsnqXrkJDsnYQg65WMLiDsi6Dqt5zCt+yerOuhnOq3uOyduOydhCDqsIDrpqzsp4Ag7JWK64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdGlmeVRva2VuQWRkZWQobmFtZTogc3RyaW5nLCBwcm92aWRlcjogc3RyaW5nKTogdm9pZCB7XG4gIGxvZ2dlci5pbmZvKGB0b2tlbiBhZGRlZDogJHtuYW1lfSAoJHtwcm92aWRlcn0pYCk7XG4gIGNvbnN0IG1lbnRpb24gPSBtZW50aW9uRm9yKG5hbWUsIGdldFNsYWNrVXNlck1hcCgpKTtcbiAgdm9pZCBub3RpZnlTbGFjayh7XG4gICAgdGl0bGU6IFwi7Yag7YGwIOy2lOqwgFwiLFxuICAgIHN1YmplY3Q6IG5hbWUsXG4gICAgY29udGV4dDogW21lbnRpb24sIHByb3ZpZGVyLCBcIuyalOyyrSDsspjrpqzsl5Ag7IKs7Jqp65Cp64uI64ukXCJdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiIMK3IFwiKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuZ29vZCxcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFjQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsYUFBYSxDQUFDOzs7Ozs7OztBQWVqRCxlQUFzQix3QkFDcEIsT0FDQSxrQkFDQSxZQUNrQjtDQUNsQixNQUFNLFVBQVUsTUFBTSxXQUFXLFFBQVEsS0FBSyxFQUFFLElBQUksTUFBTSxHQUFHLENBQUM7Q0FDOUQsSUFBSSxDQUFDLFNBQVMsT0FBTztDQUVyQixNQUFNLHNCQUFzQixnQkFBZ0IsUUFBUSxXQUFXO0NBQy9ELElBQUksdUJBQXVCLHdCQUF3QixrQkFBa0I7RUFDbkUsT0FBTyxLQUNMLDJCQUEyQixNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsNENBQ3ZEO0VBQ0EsT0FBTztDQUNUO0NBRUEsTUFBTSxFQUFFLGFBQWEscUJBQXFCLE1BQU0sV0FBVyxtQkFBbUIsTUFBTSxFQUFFO0NBQ3RGLElBQUksQ0FBQyxhQUFhO0VBQ2hCLElBQUksa0JBQWtCLDJCQUEyQixPQUFPLFVBQVU7RUFDbEUsT0FBTztDQUNUO0NBRUEsT0FBTyxLQUFLLGtDQUFrQyxNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsV0FBVyxZQUFZO0NBRy9GLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FBUztHQUFDO0dBQVMsTUFBTTtHQUFVO0dBQVk7RUFBYSxDQUFDLENBQzFELE9BQU8sT0FBTyxDQUFDLENBQ2YsS0FBSyxLQUFLO0VBQ2IsT0FBTyxZQUFZO0NBQ3JCLENBQUM7Q0FDRCxPQUFPO0FBQ1Q7Ozs7Ozs7O0FBU0EsTUFBTSxnQ0FBZ0MsT0FBVTtBQUNoRCxNQUFNLG9DQUFvQixJQUFJLElBQW9CO0FBRWxELFNBQVMsMkJBQTJCLE9BQXFCLFlBQTBCO0NBQ2pGLE1BQU0sTUFBTSxLQUFLLElBQUk7Q0FDckIsTUFBTSxXQUFXLGtCQUFrQixJQUFJLE1BQU0sUUFBUTtDQUNyRCxJQUFJLGFBQWEsVUFBYSxNQUFNLFdBQVcsK0JBQStCO0NBQzlFLGtCQUFrQixJQUFJLE1BQU0sVUFBVSxHQUFHO0NBRXpDLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FDRTtHQUFDO0dBQVMsTUFBTTtHQUFVO0VBQVUsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLElBQ2hFO0VBRUYsT0FBTyxZQUFZO0NBQ3JCLENBQUM7QUFDSDs7QUFHQSxTQUFnQixpQkFBaUIsTUFBYyxVQUF3QjtDQUNyRSxPQUFPLEtBQUssZ0JBQWdCLEtBQUssSUFBSSxTQUFTLEVBQUU7Q0FFaEQsQUFBSyxZQUFZO0VBQ2YsT0FBTztFQUNQLFNBQVM7RUFDVCxTQUFTO0dBSkssV0FBVyxNQUFNLGdCQUFnQixDQUlyQztHQUFTO0dBQVU7RUFBYyxDQUFDLENBQUMsT0FBTyxPQUFPLENBQUMsQ0FBQyxLQUFLLEtBQUs7RUFDdkUsT0FBTyxZQUFZO0NBQ3JCLENBQUM7QUFDSCJ9
94
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tZGVhdGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rva2VuLWRlYXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7IS47IWYIOunjOujjChhdXRoLWRlYWQpIO2GoO2BsOydmCDrnbzsmrDtjIUg7KCc7Jm4IOyngOygkC5cbiAqXG4gKiByZWZyZXNoIOqwgCDsnqzroZzqt7jsnbgg7Jm4IOuzteq1rCDrtojqsIDtlZwg7Iuk7Yyo66W8IOuwmO2ZmO2VnCDsiJzqsITsl5Drp4wg7Zi47Lac65Cc64ukLiDruYTtmZzshLHtmZTripRcbiAqIGBhY3RpdmU9dHJ1ZWAg7KGw6rG067aAIOqwseyLoCAx7ZqM7J206rOgLCDqt7gg6rCx7Iug7J2EIOydtOq4tCDtlITroZzshLjsiqTrp4wgU2xhY2sg7JWM66a87J2EIOuztOuCuOuLpCDigJRcbiAqIOqzteycoCBEQiDrpbwg7JOw64qUIOyduOyKpO2EtOyKpOqwgCDrqofsnbTrk6Ag7IKs6rG064u5IOyVjOumvOydgCAx6rG07J2064ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBnZXRSZWZyZXNoVG9rZW4gfSBmcm9tIFwiLi4vLi4vdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHsgbm90aWZ5U2xhY2ssIFNMQUNLX0NPTE9SIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3NsYWNrLW5vdGlmeVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9rZW4tZGVhdGhcIl0pO1xuXG50eXBlIERlYWRUb2tlblJlZiA9IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwcm92aWRlcjogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gdXNlZFJlZnJlc2hUb2tlbiDsi6TtjKjtlZwg7JqU7LKt7J20IOyLpOygnOuhnCDsgqzsmqntlZwgcmVmcmVzaCB0b2tlbi5cbiAqICAgcmVmcmVzaCB0b2tlbiDsnYAg7ZqM7KCEIOyggOyepeuQmOuvgOuhnCwg7J2066+4IO2ajOyghOuQnCDsmJsg7Yag7YGw7Jy866GcIOuKpuqyjCDrj4TssKntlZwg7J6s7Iuc64+E6rCAXG4gKiAgIDQwMCDsnYQg67Cb64qUIOqyg+ydgCDsoJXsg4Eg66CI7J207Iqk64ukLiBEQiDsnZgg7ZiE7J6sIOqwkuqzvCDri6TrpbTrqbQg7IKs66ed7Jy866GcIOuztOyngCDslYrripTri6QuXG4gKiBAcGFyYW0gcmVhc29uQ29kZSBgcHJvdmlkZXI6Y29kZWAg7ZiV7YOc7J2YIOuCtOu2gCDsvZTrk5wuIHByb3ZpZGVyIOydkeuLtSDrs7jrrLjsl5DripQg6rOE7KCVIOydtOuplOydvOydtOuCmFxuICogICDthqDtgbAg7KGw6rCB7J20IOyEnuydvCDsiJgg7J6I7Ja0IHJhdyDrqZTsi5zsp4Drpbwg6re464yA66GcIOyVjOumvOyXkCDsi6Psp4Ag7JWK64qU64ukLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVhY3RpdmF0ZUF1dGhEZWFkVG9rZW4oXG4gIHRva2VuOiBEZWFkVG9rZW5SZWYsXG4gIHVzZWRSZWZyZXNoVG9rZW46IHN0cmluZyxcbiAgcmVhc29uQ29kZTogc3RyaW5nLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQ6IHRva2VuLmlkIH0pO1xuICBpZiAoIWN1cnJlbnQpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBjdXJyZW50UmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGN1cnJlbnQuY3JlZGVudGlhbHMpO1xuICBpZiAoY3VycmVudFJlZnJlc2hUb2tlbiAmJiBjdXJyZW50UmVmcmVzaFRva2VuICE9PSB1c2VkUmVmcmVzaFRva2VuKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgc2tpcHBpbmcgYXV0aC1kZWF0aCBmb3IgJHt0b2tlbi5uYW1lfShpZD0ke3Rva2VuLmlkfSk6IHJlZnJlc2ggdG9rZW4gcm90YXRlZCBzaW5jZSB0aGlzIGF0dGVtcHRgLFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgeyBkZWFjdGl2YXRlZCwga2VwdEFzTGFzdEFjdGl2ZSB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5kZWFjdGl2YXRlSWZBY3RpdmUodG9rZW4uaWQpO1xuICBpZiAoIWRlYWN0aXZhdGVkKSB7XG4gICAgaWYgKGtlcHRBc0xhc3RBY3RpdmUpIG5vdGlmeUxhc3RBY3RpdmVUb2tlbkR5aW5nKHRva2VuLCByZWFzb25Db2RlKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsb2dnZXIud2FybihgdG9rZW4gZGVhY3RpdmF0ZWQgKGF1dGggZGVhZCk6ICR7dG9rZW4ubmFtZX0oaWQ9JHt0b2tlbi5pZH0pIHJlYXNvbj0ke3JlYXNvbkNvZGV9YCk7XG4gIC8vIOunjOujjCDsp4Htm4TqsIAg7J6s66Gc6re47J247ZWY6riwIOqwgOyepSDsoovsnYAg7YOA7J2067CN7J2064ukLiDshozsnKDsnpDrpbwg66mY7IWY7ZW0IOq3uCDsiJzqsIQg64u57IKs7J6Q7JeQ6rKMXG4gIC8vIOq9guuKlOuLpCDigJQg64uk7J207KCc7Iqk7Yq466W8IOq4sOuLpOumrOuptCDri6TsnYwg7KO86riw6rmM7KeAIO2GoO2BsOydtCDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC5cbiAgY29uc3QgbWVudGlvbiA9IG1lbnRpb25Gb3IodG9rZW4ubmFtZSwgZ2V0U2xhY2tVc2VyTWFwKCkpO1xuICB2b2lkIG5vdGlmeVNsYWNrKHtcbiAgICB0aXRsZTogXCLshLjshZgg66eM66OMXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OiBbbWVudGlvbiwgdG9rZW4ucHJvdmlkZXIsIHJlYXNvbkNvZGUsIFwi7J6s66Gc6re47J247J20IO2VhOyalO2VqeuLiOuLpFwiXVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmpvaW4oXCIgwrcgXCIpLFxuICAgIGNvbG9yOiBTTEFDS19DT0xPUi5iYWQsXG4gIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDrp4jsp4Drp4kg7Zmc7ISxIO2GoO2BsOydtCDso73sl4jsnYQg65WM7J2YIOyVjOumvCDsv6jri6TsmrQuXG4gKlxuICog7J20IOqyveyasCDthqDtgbDsnYAg67mE7Zmc7ISx7ZmU65CY7KeAIOyViuqzoCDsgrTslYTrgqjsnLzrr4DroZwsIOuSpOuUsOultOuKlCDsmpTssq3rp4jri6Qg6rCZ7J2AIOyLpO2MqOulvCDrsJjrs7XtlbRcbiAqIOyVjOumvOydtCDtj63so7ztlZzri6QuIOu5hO2ZnOyEse2ZlCDshLHqs7Ug6rK966Gc6rCAIOyhsOqxtOu2gCBVUERBVEUg66GcIOykkeuzteydhCDrp4nripQg6rKD6rO8IOuLrOumrCDsl6zquLDsl5RcbiAqIOyDge2DnCDrs4DtmZTqsIAg7JeG7Ja0IERCIOuhnCDslrXsoJztlaAg7IiYIOyXhuuLpCDigJQgcHJvdmlkZXIg64uo7JyE66GcIOyLnOqwhCDssL3snYQg65GU64ukLlxuICovXG5jb25zdCBMQVNUX0FDVElWRV9BTEVSVF9DT09MRE9XTl9NUyA9IDMwICogNjAgKiAxMDAwO1xuY29uc3QgbGFzdEFjdGl2ZUFsZXJ0QXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5mdW5jdGlvbiBub3RpZnlMYXN0QWN0aXZlVG9rZW5EeWluZyh0b2tlbjogRGVhZFRva2VuUmVmLCByZWFzb25Db2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcHJldmlvdXMgPSBsYXN0QWN0aXZlQWxlcnRBdC5nZXQodG9rZW4ucHJvdmlkZXIpO1xuICBpZiAocHJldmlvdXMgIT09IHVuZGVmaW5lZCAmJiBub3cgLSBwcmV2aW91cyA8IExBU1RfQUNUSVZFX0FMRVJUX0NPT0xET1dOX01TKSByZXR1cm47XG4gIGxhc3RBY3RpdmVBbGVydEF0LnNldCh0b2tlbi5wcm92aWRlciwgbm93KTtcblxuICBjb25zdCBtZW50aW9uID0gbWVudGlvbkZvcih0b2tlbi5uYW1lLCBnZXRTbGFja1VzZXJNYXAoKSk7XG4gIHZvaWQgbm90aWZ5U2xhY2soe1xuICAgIHRpdGxlOiBcIuuniOyngOuniSDthqDtgbAg7IKs66edXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OlxuICAgICAgW21lbnRpb24sIHRva2VuLnByb3ZpZGVyLCByZWFzb25Db2RlXS5maWx0ZXIoQm9vbGVhbikuam9pbihcIiDCtyBcIikgK1xuICAgICAgYCDCtyDtkoDsnbQg67mE7KeAIOyViuuPhOuhnSDsnKDsp4Ag7KSR7J6F64uI64ukLiBgICtcbiAgICAgIGDsoIQg7Yag7YGw7J20IOuPmeyLnOyXkCDsi6TtjKjtlojri6TrqbQgY2xpZW50X2lkIOy3qOyGjOuCmCBPQXV0aCDqs4Tslb0g67OA6rK97J2EIOydmOyLrO2VmOyEuOyalGAsXG4gICAgY29sb3I6IFNMQUNLX0NPTE9SLmJhZCxcbiAgICAvLyBwcm92aWRlciDsoITssrTqsIAg7KO97JeI64uk64qUIOyLoO2YuOuLpC4g7KGw7JqpIOyLnOqwhOyXkCDrrLvtnojrqbQg64uk7J2MIOq3vOustOydvOq5jOyngCDshJzruYTsiqTqsIAg66mI7LaY64ukLlxuICAgIHVyZ2VudDogdHJ1ZSxcbiAgfSk7XG59XG5cbi8qKiDroZzqt7jsnbjsnbQg7JmE66OM64+8IO2GoO2BsOydtCDsoIDsnqXrkJDsnYQg65WMLiDsi6Dqt5zCt+yerOuhnOq3uOyduOydhCDqsIDrpqzsp4Ag7JWK64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdGlmeVRva2VuQWRkZWQobmFtZTogc3RyaW5nLCBwcm92aWRlcjogc3RyaW5nKTogdm9pZCB7XG4gIGxvZ2dlci5pbmZvKGB0b2tlbiBhZGRlZDogJHtuYW1lfSAoJHtwcm92aWRlcn0pYCk7XG4gIGNvbnN0IG1lbnRpb24gPSBtZW50aW9uRm9yKG5hbWUsIGdldFNsYWNrVXNlck1hcCgpKTtcbiAgdm9pZCBub3RpZnlTbGFjayh7XG4gICAgdGl0bGU6IFwi7Yag7YGwIOy2lOqwgFwiLFxuICAgIHN1YmplY3Q6IG5hbWUsXG4gICAgY29udGV4dDogW21lbnRpb24sIHByb3ZpZGVyLCBcIuyalOyyrSDsspjrpqzsl5Ag7IKs7Jqp65Cp64uI64ukXCJdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiIMK3IFwiKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuZ29vZCxcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFjQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsYUFBYSxDQUFDOzs7Ozs7OztBQWVqRCxlQUFzQix3QkFDcEIsT0FDQSxrQkFDQSxZQUNrQjtDQUNsQixNQUFNLFVBQVUsTUFBTSxXQUFXLFFBQVEsS0FBSyxFQUFFLElBQUksTUFBTSxHQUFHLENBQUM7Q0FDOUQsSUFBSSxDQUFDLFNBQVMsT0FBTztDQUVyQixNQUFNLHNCQUFzQixnQkFBZ0IsUUFBUSxXQUFXO0NBQy9ELElBQUksdUJBQXVCLHdCQUF3QixrQkFBa0I7RUFDbkUsT0FBTyxLQUNMLDJCQUEyQixNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsNENBQ3ZEO0VBQ0EsT0FBTztDQUNUO0NBRUEsTUFBTSxFQUFFLGFBQWEscUJBQXFCLE1BQU0sV0FBVyxtQkFBbUIsTUFBTSxFQUFFO0NBQ3RGLElBQUksQ0FBQyxhQUFhO0VBQ2hCLElBQUksa0JBQWtCLDJCQUEyQixPQUFPLFVBQVU7RUFDbEUsT0FBTztDQUNUO0NBRUEsT0FBTyxLQUFLLGtDQUFrQyxNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsV0FBVyxZQUFZO0NBRy9GLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FBUztHQUFDO0dBQVMsTUFBTTtHQUFVO0dBQVk7RUFBYSxDQUFDLENBQzFELE9BQU8sT0FBTyxDQUFDLENBQ2YsS0FBSyxLQUFLO0VBQ2IsT0FBTyxZQUFZO0NBQ3JCLENBQUM7Q0FDRCxPQUFPO0FBQ1Q7Ozs7Ozs7O0FBU0EsTUFBTSxnQ0FBZ0MsT0FBVTtBQUNoRCxNQUFNLG9DQUFvQixJQUFJLElBQW9CO0FBRWxELFNBQVMsMkJBQTJCLE9BQXFCLFlBQTBCO0NBQ2pGLE1BQU0sTUFBTSxLQUFLLElBQUk7Q0FDckIsTUFBTSxXQUFXLGtCQUFrQixJQUFJLE1BQU0sUUFBUTtDQUNyRCxJQUFJLGFBQWEsVUFBYSxNQUFNLFdBQVcsK0JBQStCO0NBQzlFLGtCQUFrQixJQUFJLE1BQU0sVUFBVSxHQUFHO0NBRXpDLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FDRTtHQUFDO0dBQVMsTUFBTTtHQUFVO0VBQVUsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLElBQ2hFO0VBRUYsT0FBTyxZQUFZO0VBRW5CLFFBQVE7Q0FDVixDQUFDO0FBQ0g7O0FBR0EsU0FBZ0IsaUJBQWlCLE1BQWMsVUFBd0I7Q0FDckUsT0FBTyxLQUFLLGdCQUFnQixLQUFLLElBQUksU0FBUyxFQUFFO0NBRWhELEFBQUssWUFBWTtFQUNmLE9BQU87RUFDUCxTQUFTO0VBQ1QsU0FBUztHQUpLLFdBQVcsTUFBTSxnQkFBZ0IsQ0FJckM7R0FBUztHQUFVO0VBQWMsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLO0VBQ3ZFLE9BQU8sWUFBWTtDQUNyQixDQUFDO0FBQ0gifQ==
@@ -1,6 +1,6 @@
1
+ import { getLogger } from "@logtape/logtape";
1
2
  import { Buffer } from "node:buffer";
2
3
  import { z } from "zod";
3
- import { getLogger } from "@logtape/logtape";
4
4
  //#region src/application/qgrid/tool-emulation.ts
5
5
  const STRUCTURED_ENVELOPE_LIMITS = {
6
6
  maxUtf8Bytes: 512 * 1024,
@@ -13,6 +13,12 @@ let TokenService;
13
13
  _TokenService.getToken = (subset, id) => createSSRQuery("TokenModel", "findById", [subset, id], ["Token", "getToken"]);
14
14
  _TokenService.getTokens = (subset, rawParams) => createSSRQuery("TokenModel", "findMany", [subset, rawParams], ["Token", "getTokens"]);
15
15
  })(TokenService || (TokenService = {}));
16
+ let SettingService;
17
+ (function(_SettingService) {
18
+ _SettingService.getSetting = (subset, id) => createSSRQuery("SettingModel", "findById", [subset, id], ["Setting", "getSetting"]);
19
+ _SettingService.getSettings = (subset, rawParams) => createSSRQuery("SettingModel", "findMany", [subset, rawParams], ["Setting", "getSettings"]);
20
+ _SettingService.getSettingList = () => createSSRQuery("SettingModel", "listSettings", [], ["Setting", "getSettingList"]);
21
+ })(SettingService || (SettingService = {}));
16
22
  let RequestLogStepService;
17
23
  (function(_RequestLogStepService) {
18
24
  _RequestLogStepService.getRequestLogStep = (subset, id) => createSSRQuery("RequestLogStepModel", "findById", [subset, id], ["RequestLogStep", "getRequestLogStep"]);
@@ -38,6 +44,6 @@ let MonitService;
38
44
  _MonitService.monitInfo = () => createSSRQuery("MonitFrame", "monitInfo", [], ["Monit", "monitInfo"]);
39
45
  })(MonitService || (MonitService = {}));
40
46
  //#endregion
41
- export { MonitService, QgridService, RequestLogService, RequestLogStepService, TokenService };
47
+ export { MonitService, QgridService, RequestLogService, RequestLogStepService, SettingService, TokenService };
42
48
 
43
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5nZW5lcmF0ZWQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3F1ZXJpZXMuZ2VuZXJhdGVkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGdlbmVyYXRlZFxuICog7KeB7KCRIOyImOygle2VmOyngCDrp4jshLjsmpQuXG4gKi9cblxuLyogb3hsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHR5cGUgeyBTU1JRdWVyeSB9IGZyb20gXCJzb25hbXUvc3NyXCI7XG5cbi8vIFNTUlF1ZXJ5IO2XrO2NvCDtlajsiJhcbmZ1bmN0aW9uIGNyZWF0ZVNTUlF1ZXJ5KFxuICBtb2RlbE5hbWU6IHN0cmluZyxcbiAgbWV0aG9kTmFtZTogc3RyaW5nLFxuICBwYXJhbXM6IGFueVtdLFxuICBzZXJ2aWNlS2V5OiBbc3RyaW5nLCBzdHJpbmddLFxuKTogU1NSUXVlcnkge1xuICByZXR1cm4geyBtb2RlbE5hbWUsIG1ldGhvZE5hbWUsIHBhcmFtcywgc2VydmljZUtleSwgX19icmFuZDogXCJTU1JRdWVyeVwiIH0gYXMgU1NSUXVlcnk7XG59XG5cbmltcG9ydCB7IFJlcXVlc3RMb2dTdGVwTGlzdFBhcmFtcyB9IGZyb20gXCIuL3JlcXVlc3QtbG9nLXN0ZXAvcmVxdWVzdC1sb2ctc3RlcC50eXBlc1wiO1xuaW1wb3J0IHsgUmVxdWVzdExvZ0xpc3RQYXJhbXMgfSBmcm9tIFwiLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy50eXBlc1wiO1xuaW1wb3J0IHsgVG9rZW5TdWJzZXRLZXksIFJlcXVlc3RMb2dTdGVwU3Vic2V0S2V5LCBSZXF1ZXN0TG9nU3Vic2V0S2V5IH0gZnJvbSBcIi4vc29uYW11LmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgVG9rZW5MaXN0UGFyYW1zIH0gZnJvbSBcIi4vdG9rZW4vdG9rZW4udHlwZXNcIjtcblxuZXhwb3J0IG5hbWVzcGFjZSBUb2tlblNlcnZpY2Uge1xuICBleHBvcnQgY29uc3QgZ2V0VG9rZW4gPSA8VCBleHRlbmRzIFRva2VuU3Vic2V0S2V5PihzdWJzZXQ6IFQsIGlkOiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiVG9rZW5Nb2RlbFwiLCBcImZpbmRCeUlkXCIsIFtzdWJzZXQsIGlkXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlblwiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFRva2VucyA9IDxUIGV4dGVuZHMgVG9rZW5TdWJzZXRLZXksIExQIGV4dGVuZHMgVG9rZW5MaXN0UGFyYW1zPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJUb2tlbk1vZGVsXCIsIFwiZmluZE1hbnlcIiwgW3N1YnNldCwgcmF3UGFyYW1zXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlbnNcIl0pO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFJlcXVlc3RMb2dTdGVwU2VydmljZSB7XG4gIGV4cG9ydCBjb25zdCBnZXRSZXF1ZXN0TG9nU3RlcCA9IDxUIGV4dGVuZHMgUmVxdWVzdExvZ1N0ZXBTdWJzZXRLZXk+KFxuICAgIHN1YnNldDogVCxcbiAgICBpZDogbnVtYmVyLFxuICApOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFxuICAgICAgXCJSZXF1ZXN0TG9nU3RlcE1vZGVsXCIsXG4gICAgICBcImZpbmRCeUlkXCIsXG4gICAgICBbc3Vic2V0LCBpZF0sXG4gICAgICBbXCJSZXF1ZXN0TG9nU3RlcFwiLCBcImdldFJlcXVlc3RMb2dTdGVwXCJdLFxuICAgICk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2dTdGVwcyA9IDxcbiAgICBUIGV4dGVuZHMgUmVxdWVzdExvZ1N0ZXBTdWJzZXRLZXksXG4gICAgTFAgZXh0ZW5kcyBSZXF1ZXN0TG9nU3RlcExpc3RQYXJhbXMsXG4gID4oXG4gICAgc3Vic2V0OiBULFxuICAgIHJhd1BhcmFtcz86IExQLFxuICApOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFxuICAgICAgXCJSZXF1ZXN0TG9nU3RlcE1vZGVsXCIsXG4gICAgICBcImZpbmRNYW55XCIsXG4gICAgICBbc3Vic2V0LCByYXdQYXJhbXNdLFxuICAgICAgW1wiUmVxdWVzdExvZ1N0ZXBcIiwgXCJnZXRSZXF1ZXN0TG9nU3RlcHNcIl0sXG4gICAgKTtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBSZXF1ZXN0TG9nU2VydmljZSB7XG4gIGV4cG9ydCBjb25zdCBnZXRSZXF1ZXN0TG9nID0gPFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3Vic2V0S2V5PihzdWJzZXQ6IFQsIGlkOiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUmVxdWVzdExvZ01vZGVsXCIsIFwiZmluZEJ5SWRcIiwgW3N1YnNldCwgaWRdLCBbXCJSZXF1ZXN0TG9nXCIsIFwiZ2V0UmVxdWVzdExvZ1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2dzID0gPFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3Vic2V0S2V5LCBMUCBleHRlbmRzIFJlcXVlc3RMb2dMaXN0UGFyYW1zPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXG4gICAgICBcIlJlcXVlc3RMb2dNb2RlbFwiLFxuICAgICAgXCJmaW5kTWFueVwiLFxuICAgICAgW3N1YnNldCwgcmF3UGFyYW1zXSxcbiAgICAgIFtcIlJlcXVlc3RMb2dcIiwgXCJnZXRSZXF1ZXN0TG9nc1wiXSxcbiAgICApO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFFncmlkU2VydmljZSB7XG4gIGV4cG9ydCBjb25zdCBzdGF0cyA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcInN0YXRzXCIsIFtdLCBbXCJRZ3JpZFwiLCBcInN0YXRzXCJdKTtcblxuICBleHBvcnQgY29uc3QgdG90YWxDb3N0ID0gKHBhcmFtcz86IFJlcXVlc3RMb2dMaXN0UGFyYW1zKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJ0b3RhbENvc3RcIiwgW3BhcmFtc10sIFtcIlFncmlkXCIsIFwidG90YWxDb3N0XCJdKTtcblxuICBleHBvcnQgY29uc3QgcHJvamVjdE5hbWVzID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJRZ3JpZEZyYW1lXCIsIFwicHJvamVjdE5hbWVzXCIsIFtdLCBbXCJRZ3JpZFwiLCBcInByb2plY3ROYW1lc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IG1vZGVsTmFtZXMgPSAoKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJtb2RlbE5hbWVzXCIsIFtdLCBbXCJRZ3JpZFwiLCBcIm1vZGVsTmFtZXNcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCB1c2FnZSA9ICh0b2tlbklkPzogbnVtYmVyKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJ1c2FnZVwiLCBbdG9rZW5JZF0sIFtcIlFncmlkXCIsIFwidXNhZ2VcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCBoZWFsdGggPSAoKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJoZWFsdGhcIiwgW10sIFtcIlFncmlkXCIsIFwiaGVhbHRoXCJdKTtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBNb25pdFNlcnZpY2Uge1xuICBleHBvcnQgY29uc3QgbW9uaXRMb2dzID0gKGN1cnNvcj86IG51bWJlcik6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJNb25pdEZyYW1lXCIsIFwibW9uaXRMb2dzXCIsIFtjdXJzb3JdLCBbXCJNb25pdFwiLCBcIm1vbml0TG9nc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IG1vbml0SW5mbyA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiTW9uaXRGcmFtZVwiLCBcIm1vbml0SW5mb1wiLCBbXSwgW1wiTW9uaXRcIiwgXCJtb25pdEluZm9cIl0pO1xufVxuIl0sIm1hcHBpbmdzIjoiO0FBVUEsU0FBUyxlQUNQLFdBQ0EsWUFDQSxRQUNBLFlBQ1U7Q0FDVixPQUFPO0VBQUU7RUFBVztFQUFZO0VBQVE7RUFBWSxTQUFTO0NBQVc7QUFDMUU7QUFPTyxJQUFVO0NBQVYsU0FBQSxlQUFBO0NBQ1EsY0FBQSxZQUFzQyxRQUFXLE9BQzVELGVBQWUsY0FBYyxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxTQUFTLFVBQVUsQ0FBQztDQUVqRSxjQUFBLGFBQ1gsUUFDQSxjQUVBLGVBQWUsY0FBYyxZQUFZLENBQUMsUUFBUSxTQUFTLEdBQUcsQ0FBQyxTQUFTLFdBQVcsQ0FBQztBQUN2RixFQUFBLENBQUEsaUJBQUEsZUFBQSxDQUFBLEVBQUQ7QUFFTyxJQUFVO0NBQVYsU0FBQSx3QkFBQTtDQUNRLHVCQUFBLHFCQUNYLFFBQ0EsT0FFQSxlQUNFLHVCQUNBLFlBQ0EsQ0FBQyxRQUFRLEVBQUUsR0FDWCxDQUFDLGtCQUFrQixtQkFBbUIsQ0FDeEM7Q0FFVyx1QkFBQSxzQkFJWCxRQUNBLGNBRUEsZUFDRSx1QkFDQSxZQUNBLENBQUMsUUFBUSxTQUFTLEdBQ2xCLENBQUMsa0JBQWtCLG9CQUFvQixDQUN6QztBQUNILEVBQUEsQ0FBQSwwQkFBQSx3QkFBQSxDQUFBLEVBQUQ7QUFFTyxJQUFVO0NBQVYsU0FBQSxvQkFBQTtDQUNRLG1CQUFBLGlCQUFnRCxRQUFXLE9BQ3RFLGVBQWUsbUJBQW1CLFlBQVksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLGNBQWMsZUFBZSxDQUFDO0NBRWhGLG1CQUFBLGtCQUNYLFFBQ0EsY0FFQSxlQUNFLG1CQUNBLFlBQ0EsQ0FBQyxRQUFRLFNBQVMsR0FDbEIsQ0FBQyxjQUFjLGdCQUFnQixDQUNqQztBQUNILEVBQUEsQ0FBQSxzQkFBQSxvQkFBQSxDQUFBLEVBQUQ7QUFFTyxJQUFVO0NBQVYsU0FBQSxlQUFBO0NBQ1EsY0FBQSxjQUNYLGVBQWUsY0FBYyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsT0FBTyxDQUFDO0NBRWpELGNBQUEsYUFBYSxXQUN4QixlQUFlLGNBQWMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLFNBQVMsV0FBVyxDQUFDO0NBRS9ELGNBQUEscUJBQ1gsZUFBZSxjQUFjLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxTQUFTLGNBQWMsQ0FBQztDQUUvRCxjQUFBLG1CQUNYLGVBQWUsY0FBYyxjQUFjLENBQUMsR0FBRyxDQUFDLFNBQVMsWUFBWSxDQUFDO0NBRTNELGNBQUEsU0FBUyxZQUNwQixlQUFlLGNBQWMsU0FBUyxDQUFDLE9BQU8sR0FBRyxDQUFDLFNBQVMsT0FBTyxDQUFDO0NBRXhELGNBQUEsZUFDWCxlQUFlLGNBQWMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLFFBQVEsQ0FBQztBQUNqRSxFQUFBLENBQUEsaUJBQUEsZUFBQSxDQUFBLEVBQUQ7QUFFTyxJQUFVO0NBQVYsU0FBQSxlQUFBO0NBQ1EsY0FBQSxhQUFhLFdBQ3hCLGVBQWUsY0FBYyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsU0FBUyxXQUFXLENBQUM7Q0FFL0QsY0FBQSxrQkFDWCxlQUFlLGNBQWMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxTQUFTLFdBQVcsQ0FBQztBQUN2RSxFQUFBLENBQUEsaUJBQUEsZUFBQSxDQUFBLEVBQUQifQ==
49
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5nZW5lcmF0ZWQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3F1ZXJpZXMuZ2VuZXJhdGVkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGdlbmVyYXRlZFxuICog7KeB7KCRIOyImOygle2VmOyngCDrp4jshLjsmpQuXG4gKi9cblxuLyogb3hsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHR5cGUgeyBTU1JRdWVyeSB9IGZyb20gXCJzb25hbXUvc3NyXCI7XG5cbi8vIFNTUlF1ZXJ5IO2XrO2NvCDtlajsiJhcbmZ1bmN0aW9uIGNyZWF0ZVNTUlF1ZXJ5KFxuICBtb2RlbE5hbWU6IHN0cmluZyxcbiAgbWV0aG9kTmFtZTogc3RyaW5nLFxuICBwYXJhbXM6IGFueVtdLFxuICBzZXJ2aWNlS2V5OiBbc3RyaW5nLCBzdHJpbmddLFxuKTogU1NSUXVlcnkge1xuICByZXR1cm4geyBtb2RlbE5hbWUsIG1ldGhvZE5hbWUsIHBhcmFtcywgc2VydmljZUtleSwgX19icmFuZDogXCJTU1JRdWVyeVwiIH0gYXMgU1NSUXVlcnk7XG59XG5cbmltcG9ydCB7IFJlcXVlc3RMb2dTdGVwTGlzdFBhcmFtcyB9IGZyb20gXCIuL3JlcXVlc3QtbG9nLXN0ZXAvcmVxdWVzdC1sb2ctc3RlcC50eXBlc1wiO1xuaW1wb3J0IHsgUmVxdWVzdExvZ0xpc3RQYXJhbXMgfSBmcm9tIFwiLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy50eXBlc1wiO1xuaW1wb3J0IHsgU2V0dGluZ0xpc3RQYXJhbXMgfSBmcm9tIFwiLi9zZXR0aW5nL3NldHRpbmcudHlwZXNcIjtcbmltcG9ydCB7XG4gIFRva2VuU3Vic2V0S2V5LFxuICBTZXR0aW5nU3Vic2V0S2V5LFxuICBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleSxcbiAgUmVxdWVzdExvZ1N1YnNldEtleSxcbn0gZnJvbSBcIi4vc29uYW11LmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgVG9rZW5MaXN0UGFyYW1zIH0gZnJvbSBcIi4vdG9rZW4vdG9rZW4udHlwZXNcIjtcblxuZXhwb3J0IG5hbWVzcGFjZSBUb2tlblNlcnZpY2Uge1xuICBleHBvcnQgY29uc3QgZ2V0VG9rZW4gPSA8VCBleHRlbmRzIFRva2VuU3Vic2V0S2V5PihzdWJzZXQ6IFQsIGlkOiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiVG9rZW5Nb2RlbFwiLCBcImZpbmRCeUlkXCIsIFtzdWJzZXQsIGlkXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlblwiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFRva2VucyA9IDxUIGV4dGVuZHMgVG9rZW5TdWJzZXRLZXksIExQIGV4dGVuZHMgVG9rZW5MaXN0UGFyYW1zPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJUb2tlbk1vZGVsXCIsIFwiZmluZE1hbnlcIiwgW3N1YnNldCwgcmF3UGFyYW1zXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlbnNcIl0pO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFNldHRpbmdTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFNldHRpbmcgPSA8VCBleHRlbmRzIFNldHRpbmdTdWJzZXRLZXk+KHN1YnNldDogVCwgaWQ6IG51bWJlcik6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJTZXR0aW5nTW9kZWxcIiwgXCJmaW5kQnlJZFwiLCBbc3Vic2V0LCBpZF0sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nXCJdKTtcblxuICBleHBvcnQgY29uc3QgZ2V0U2V0dGluZ3MgPSA8VCBleHRlbmRzIFNldHRpbmdTdWJzZXRLZXksIExQIGV4dGVuZHMgU2V0dGluZ0xpc3RQYXJhbXM+KFxuICAgIHN1YnNldDogVCxcbiAgICByYXdQYXJhbXM/OiBMUCxcbiAgKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlNldHRpbmdNb2RlbFwiLCBcImZpbmRNYW55XCIsIFtzdWJzZXQsIHJhd1BhcmFtc10sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFNldHRpbmdMaXN0ID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJTZXR0aW5nTW9kZWxcIiwgXCJsaXN0U2V0dGluZ3NcIiwgW10sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nTGlzdFwiXSk7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgUmVxdWVzdExvZ1N0ZXBTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2dTdGVwID0gPFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleT4oXG4gICAgc3Vic2V0OiBULFxuICAgIGlkOiBudW1iZXIsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXG4gICAgICBcIlJlcXVlc3RMb2dTdGVwTW9kZWxcIixcbiAgICAgIFwiZmluZEJ5SWRcIixcbiAgICAgIFtzdWJzZXQsIGlkXSxcbiAgICAgIFtcIlJlcXVlc3RMb2dTdGVwXCIsIFwiZ2V0UmVxdWVzdExvZ1N0ZXBcIl0sXG4gICAgKTtcblxuICBleHBvcnQgY29uc3QgZ2V0UmVxdWVzdExvZ1N0ZXBzID0gPFxuICAgIFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleSxcbiAgICBMUCBleHRlbmRzIFJlcXVlc3RMb2dTdGVwTGlzdFBhcmFtcyxcbiAgPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXG4gICAgICBcIlJlcXVlc3RMb2dTdGVwTW9kZWxcIixcbiAgICAgIFwiZmluZE1hbnlcIixcbiAgICAgIFtzdWJzZXQsIHJhd1BhcmFtc10sXG4gICAgICBbXCJSZXF1ZXN0TG9nU3RlcFwiLCBcImdldFJlcXVlc3RMb2dTdGVwc1wiXSxcbiAgICApO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFJlcXVlc3RMb2dTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2cgPSA8VCBleHRlbmRzIFJlcXVlc3RMb2dTdWJzZXRLZXk+KHN1YnNldDogVCwgaWQ6IG51bWJlcik6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJSZXF1ZXN0TG9nTW9kZWxcIiwgXCJmaW5kQnlJZFwiLCBbc3Vic2V0LCBpZF0sIFtcIlJlcXVlc3RMb2dcIiwgXCJnZXRSZXF1ZXN0TG9nXCJdKTtcblxuICBleHBvcnQgY29uc3QgZ2V0UmVxdWVzdExvZ3MgPSA8VCBleHRlbmRzIFJlcXVlc3RMb2dTdWJzZXRLZXksIExQIGV4dGVuZHMgUmVxdWVzdExvZ0xpc3RQYXJhbXM+KFxuICAgIHN1YnNldDogVCxcbiAgICByYXdQYXJhbXM/OiBMUCxcbiAgKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcbiAgICAgIFwiUmVxdWVzdExvZ01vZGVsXCIsXG4gICAgICBcImZpbmRNYW55XCIsXG4gICAgICBbc3Vic2V0LCByYXdQYXJhbXNdLFxuICAgICAgW1wiUmVxdWVzdExvZ1wiLCBcImdldFJlcXVlc3RMb2dzXCJdLFxuICAgICk7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgUWdyaWRTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IHN0YXRzID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJRZ3JpZEZyYW1lXCIsIFwic3RhdHNcIiwgW10sIFtcIlFncmlkXCIsIFwic3RhdHNcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCB0b3RhbENvc3QgPSAocGFyYW1zPzogUmVxdWVzdExvZ0xpc3RQYXJhbXMpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcInRvdGFsQ29zdFwiLCBbcGFyYW1zXSwgW1wiUWdyaWRcIiwgXCJ0b3RhbENvc3RcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCBwcm9qZWN0TmFtZXMgPSAoKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJwcm9qZWN0TmFtZXNcIiwgW10sIFtcIlFncmlkXCIsIFwicHJvamVjdE5hbWVzXCJdKTtcblxuICBleHBvcnQgY29uc3QgbW9kZWxOYW1lcyA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcIm1vZGVsTmFtZXNcIiwgW10sIFtcIlFncmlkXCIsIFwibW9kZWxOYW1lc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IHVzYWdlID0gKHRva2VuSWQ/OiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcInVzYWdlXCIsIFt0b2tlbklkXSwgW1wiUWdyaWRcIiwgXCJ1c2FnZVwiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGhlYWx0aCA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcImhlYWx0aFwiLCBbXSwgW1wiUWdyaWRcIiwgXCJoZWFsdGhcIl0pO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1vbml0U2VydmljZSB7XG4gIGV4cG9ydCBjb25zdCBtb25pdExvZ3MgPSAoY3Vyc29yPzogbnVtYmVyKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIk1vbml0RnJhbWVcIiwgXCJtb25pdExvZ3NcIiwgW2N1cnNvcl0sIFtcIk1vbml0XCIsIFwibW9uaXRMb2dzXCJdKTtcblxuICBleHBvcnQgY29uc3QgbW9uaXRJbmZvID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJNb25pdEZyYW1lXCIsIFwibW9uaXRJbmZvXCIsIFtdLCBbXCJNb25pdFwiLCBcIm1vbml0SW5mb1wiXSk7XG59XG4iXSwibWFwcGluZ3MiOiI7QUFVQSxTQUFTLGVBQ1AsV0FDQSxZQUNBLFFBQ0EsWUFDVTtDQUNWLE9BQU87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
@@ -1,8 +1,8 @@
1
1
  import { SD } from "../../i18n/sd.generated.js";
2
- import { calculateCostUsd } from "../../utils/providers/common/model-cost.js";
2
+ import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso.js";
3
3
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
4
4
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
5
- import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso.js";
5
+ import { calculateCostUsd } from "../../utils/providers/common/model-cost.js";
6
6
  import { BadRequestException, BaseModelClass, NotFoundException, Puri, api, asArray, transactional } from "sonamu";
7
7
  //#region src/application/request-log/request-log.model.ts
8
8
  const MICRO_USD = 1e6;
@@ -1,7 +1,7 @@
1
1
  import { SD } from "../../i18n/sd.generated.js";
2
+ import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
2
3
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
3
4
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
4
- import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
5
5
  import { BadRequestException, BaseModelClass, NotFoundException, api, asArray, exhaustive } from "sonamu";
6
6
  //#region src/application/request-log-step/request-log-step.model.ts
7
7
  var RequestLogStepModelClass = class extends BaseModelClass {
@@ -0,0 +1,226 @@
1
+ //#region src/application/setting/setting.constant.ts
2
+ /** 64 GiB 운영 호스트에서 세 자리 오입력을 막는 설정 상한. 안전을 보장하는 값은 아니다. */
3
+ const MAX_OPENAI_ESTIMATED_RSS_GIB = 32;
4
+ const MAX_OPENAI_MIN_HOST_AVAILABLE_GIB = 64;
5
+ const SETTING_DEFS = [
6
+ {
7
+ key: "openai.autoscale",
8
+ fallback: "true",
9
+ group: "openai",
10
+ envKey: "QGRID_OPENAI_AUTOSCALE",
11
+ label: "OpenAI 워커 오토스케일",
12
+ kind: "boolean",
13
+ applies: "restart",
14
+ help: "끄면 워커 수가 최소값으로 고정됩니다"
15
+ },
16
+ {
17
+ key: "openai.minWorkersPerToken",
18
+ fallback: "1",
19
+ group: "openai",
20
+ envKey: "QGRID_OPENAI_MIN_WORKERS_PER_TOKEN",
21
+ label: "토큰당 최소 워커",
22
+ kind: "integer",
23
+ applies: "restart",
24
+ min: 1,
25
+ max: 20
26
+ },
27
+ {
28
+ key: "openai.maxWorkersPerToken",
29
+ fallback: "3",
30
+ group: "openai",
31
+ envKey: "QGRID_OPENAI_MAX_WORKERS_PER_TOKEN",
32
+ label: "토큰당 최대 워커",
33
+ kind: "integer",
34
+ applies: "restart",
35
+ min: 1,
36
+ max: 20,
37
+ help: "오토스케일이 꺼져 있으면 무시됩니다"
38
+ },
39
+ {
40
+ key: "openai.maxEstimatedRssGiB",
41
+ fallback: "16",
42
+ group: "openai",
43
+ envKey: "QGRID_OPENAI_MAX_ESTIMATED_RSS_GIB",
44
+ label: "워커 메모리 상한 (GiB)",
45
+ kind: "number",
46
+ applies: "restart",
47
+ min: 1,
48
+ max: 32,
49
+ help: "이 추정치를 넘기면 워커를 더 늘리지 않습니다. 올릴수록 OOM 위험이 커지며 상한은 오입력 방지용입니다"
50
+ },
51
+ {
52
+ key: "openai.minHostAvailableGiB",
53
+ fallback: "20",
54
+ group: "openai",
55
+ envKey: "QGRID_OPENAI_MIN_HOST_AVAILABLE_GIB",
56
+ label: "호스트 여유 메모리 하한 (GiB)",
57
+ kind: "number",
58
+ applies: "restart",
59
+ min: 0,
60
+ max: 64,
61
+ help: "호스트 여유가 이 값 아래면 스케일업을 멈춥니다. 확장을 끄려면 오토스케일을 끄세요"
62
+ },
63
+ {
64
+ key: "slack.enabled",
65
+ fallback: "true",
66
+ group: "slack",
67
+ envKey: "SLACK_ENABLED",
68
+ label: "Slack 알림",
69
+ kind: "boolean",
70
+ applies: "immediate",
71
+ help: "연휴처럼 규칙으로 잡을 수 없는 기간에 끕니다. 서비스 정지급 장애 알림은 꺼도 전달됩니다"
72
+ },
73
+ {
74
+ key: "slack.remindersEnabled",
75
+ fallback: "true",
76
+ group: "slack",
77
+ envKey: "SLACK_REMINDERS_ENABLED",
78
+ label: "만료 알림 반복",
79
+ kind: "boolean",
80
+ applies: "immediate",
81
+ help: "끄면 반복만 멈추고 만료 순간의 알림은 그대로 갑니다"
82
+ },
83
+ {
84
+ key: "slack.expiryReminderMinutes",
85
+ fallback: "60",
86
+ group: "slack",
87
+ envKey: "SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES",
88
+ label: "반복 주기",
89
+ kind: "preset",
90
+ applies: "immediate",
91
+ presets: [
92
+ 10,
93
+ 30,
94
+ 60,
95
+ 180
96
+ ],
97
+ help: "재로그인이 필요한 토큰이 남아 있는 동안 이 주기로 다시 알립니다"
98
+ },
99
+ {
100
+ key: "slack.quietFromHour",
101
+ fallback: "20",
102
+ group: "slack",
103
+ envKey: "SLACK_QUIET_FROM_HOUR",
104
+ label: "조용 시간 시작",
105
+ kind: "integer",
106
+ applies: "immediate",
107
+ min: 0,
108
+ max: 23,
109
+ help: "이 시각부터 알리지 않습니다 (한국 시간)"
110
+ },
111
+ {
112
+ key: "slack.quietUntilHour",
113
+ fallback: "8",
114
+ group: "slack",
115
+ envKey: "SLACK_QUIET_UNTIL_HOUR",
116
+ label: "조용 시간 종료",
117
+ kind: "integer",
118
+ applies: "immediate",
119
+ min: 0,
120
+ max: 23,
121
+ help: "이 시각부터 다시 알립니다. 시작보다 빠르면 자정을 넘는 구간이 됩니다"
122
+ },
123
+ {
124
+ key: "slack.notifyOnWeekends",
125
+ fallback: "false",
126
+ group: "slack",
127
+ envKey: "SLACK_NOTIFY_ON_WEEKENDS",
128
+ label: "주말에도 알림",
129
+ kind: "boolean",
130
+ applies: "immediate",
131
+ help: "켜면 주말에도 위의 조용 시간 규칙만 적용됩니다"
132
+ },
133
+ {
134
+ key: "slack.channelId",
135
+ fallback: "",
136
+ group: "slackConnection",
137
+ envKey: "SLACK_CHANNEL_ID",
138
+ label: "Slack 채널 ID",
139
+ kind: "string",
140
+ applies: "immediate",
141
+ help: "사용자 ID(U...)를 넣으면 그 사람 DM 으로 갑니다"
142
+ },
143
+ {
144
+ key: "slack.userMap",
145
+ fallback: "",
146
+ group: "slackConnection",
147
+ envKey: "SLACK_USER_MAP",
148
+ label: "Slack 사용자 매핑",
149
+ kind: "string",
150
+ applies: "immediate",
151
+ help: "토큰명:SlackUserId 를 쉼표로. 공용 계정은 넣지 않습니다"
152
+ },
153
+ {
154
+ key: "slack.botToken",
155
+ fallback: "",
156
+ group: "slackConnection",
157
+ envKey: "SLACK_BOT_TOKEN",
158
+ label: "Slack 봇 토큰",
159
+ kind: "secret",
160
+ applies: "immediate"
161
+ }
162
+ ];
163
+ function findSettingDef(key) {
164
+ return SETTING_DEFS.find((d) => d.key === key);
165
+ }
166
+ /** 저장 전 검증. 잘못된 값이 들어가면 런타임에서 조용히 기본값으로 떨어져 원인을 찾기 어렵다. */
167
+ function validateSettingValue(def, raw) {
168
+ const trimmed = raw.trim();
169
+ if (def.kind === "boolean") {
170
+ if (!["true", "false"].includes(trimmed)) return {
171
+ ok: false,
172
+ error: "true 또는 false"
173
+ };
174
+ return {
175
+ ok: true,
176
+ value: trimmed
177
+ };
178
+ }
179
+ if (def.kind === "preset") {
180
+ const parsed = Number(trimmed);
181
+ if (!def.presets?.includes(parsed)) return {
182
+ ok: false,
183
+ error: `${def.presets?.join(", ") ?? ""} 중 하나여야 합니다`
184
+ };
185
+ return {
186
+ ok: true,
187
+ value: String(parsed)
188
+ };
189
+ }
190
+ if (def.kind === "integer" || def.kind === "number") {
191
+ const parsed = Number(trimmed);
192
+ if (!Number.isFinite(parsed)) return {
193
+ ok: false,
194
+ error: "숫자를 입력하세요"
195
+ };
196
+ if (def.kind === "integer" && !Number.isInteger(parsed)) return {
197
+ ok: false,
198
+ error: "정수를 입력하세요"
199
+ };
200
+ if (def.min !== void 0 && parsed < def.min) return {
201
+ ok: false,
202
+ error: `${def.min} 이상이어야 합니다`
203
+ };
204
+ if (def.max !== void 0 && parsed > def.max) return {
205
+ ok: false,
206
+ error: `${def.max} 이하여야 합니다`
207
+ };
208
+ return {
209
+ ok: true,
210
+ value: String(parsed)
211
+ };
212
+ }
213
+ return {
214
+ ok: true,
215
+ value: trimmed
216
+ };
217
+ }
218
+ /** 화면에 그대로 내려보내면 안 되는 값. 앞뒤만 남긴다. */
219
+ function maskSecret(value) {
220
+ if (value.length <= 12) return "***";
221
+ return `${value.slice(0, 8)}...${value.slice(-4)}`;
222
+ }
223
+ //#endregion
224
+ export { MAX_OPENAI_ESTIMATED_RSS_GIB, MAX_OPENAI_MIN_HOST_AVAILABLE_GIB, SETTING_DEFS, findSettingDef, maskSecret, validateSettingValue };
225
+
226
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZy5jb25zdGFudC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vc2V0dGluZy9zZXR0aW5nLmNvbnN0YW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog6rSA66asIOqwgOuKpe2VnCDrn7Dtg4DsnoQg7ISk7KCVIOuqqeuhnS5cbiAqXG4gKiDtgqTCt2VudiDsnbTrpoTCt+2DgOyehcK36rKA7Kad7J2EIO2VnCDqs7Psl5Ag66qo7JWEIEFQSSDsmYAgVUkg6rCAIOqwmeydgCDsoJXsnZjrpbwg67O464ukLiDsl6zquLAg7JeG64qUIGVudiDripRcbiAqIO2ZlOuptOyXkOyEnCDrsJTqv4Ag7IiYIOyXhuuLpCDigJQgREIg7KCR7IaNIOygleuztOuCmCDtj6ztirjsspjrn7wg7ISc67KE6rCAIOucqOq4sCDsoITsl5Ag7ZWE7JqU7ZWcIOqwkuuTpOydtOuLpC5cbiAqXG4gKiBgc2V0dGluZ3NgIO2FjOydtOu4lOydgCBgKGtleSwgdmFsdWUpYCDrrLjsnpDsl7Qg7IyN66eMIOuLtOuKlCDqt7jrpofsnbTrnbwoYHNldHRpbmcuZW50aXR5Lmpzb25gKSxcbiAqIFwi7J20IO2CpOqwgCDsoJXsiJjsnbjsp4DCt+uylOychOqwgCDslrzrp4jsnbjsp4DCt+2ZlOuptOyXkCDrrZDrnbzqs6Ag7JO47KeAXCLrpbwg64u07J2EIOqzs+ydtCDrlLDroZwg7ZWE7JqU7ZWY64ukLlxuICog6re4IOuplO2DgOuNsOydtO2EsOqwgCDsl6zquLAg7J6I64ukIOKAlCBEQiDsiqTtgqTrp4jqsIAg7JWE64uI6528IOyVseydtCDslYTripQg7IOB7IiYIOuqqeuhneydtOuLpC5cbiAqL1xuXG5leHBvcnQgdHlwZSBTZXR0aW5nS2luZCA9IFwiYm9vbGVhblwiIHwgXCJpbnRlZ2VyXCIgfCBcIm51bWJlclwiIHwgXCJzdHJpbmdcIiB8IFwic2VjcmV0XCIgfCBcInByZXNldFwiO1xuXG4vKipcbiAqIO2ZlOuptOyXkOyEnCDrrLbslrQg67O07Jes7KSEIOuLqOychC4g7Y+J7Y+J7ZWY6rKMIOuCmOyXtO2VmOuptCDslrTrlJTrpbwg67SQ7JW8IO2VoOyngCDslYwg7IiYIOyXhuuLpC5cbiAqXG4gKiBTbGFjayDsnYAgXCLslrjsoJwg67O064K86rmMXCIoc2xhY2sp7JmAIFwi7Ja065SU66GcIOuztOuCvOq5jFwiKHNsYWNrQ29ubmVjdGlvbinrpbwg64KY64iI64ukIOKAlCDslZ7snYAg7Jq07JiBXG4gKiDspJEg7J6Q7KO8IOunjOyngOqzoCDrkqTripQg7ZWcIOuyiCDrp57stpTrqbQg64Gd7J206528IOyImOuqheydtCDri6TrpbTri6QuXG4gKi9cbmV4cG9ydCB0eXBlIFNldHRpbmdHcm91cCA9IFwib3BlbmFpXCIgfCBcInNsYWNrXCIgfCBcInNsYWNrQ29ubmVjdGlvblwiO1xuXG5leHBvcnQgdHlwZSBTZXR0aW5nRGVmID0ge1xuICBrZXk6IHN0cmluZztcbiAgZ3JvdXA6IFNldHRpbmdHcm91cDtcbiAgZW52S2V5OiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGtpbmQ6IFNldHRpbmdLaW5kO1xuICAvKiog7KCB7JqpIOyLnOygkC4g7JuM7LukIOyEpOygleydgCBkaXNwYXRjaGVyIOyDneyEseyekOyXkOyEnCDtlZwg67KI66eMIOydve2YgCDsnqzsi5zsnpHsnbQg7ZWE7JqU7ZWY64ukLiAqL1xuICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiIHwgXCJyZXN0YXJ0XCI7XG4gIG1pbj86IG51bWJlcjtcbiAgbWF4PzogbnVtYmVyO1xuICAvKiogYHByZXNldGAg7KKF66WY7JeQ7IScIOqzoOulvCDsiJgg7J6I64qUIOqwki4g7J20IOuqqeuhnSDrsJbsnZgg6rCS7J2AIOyggOyepeuQmOyngCDslYrripTri6QuICovXG4gIHByZXNldHM/OiBudW1iZXJbXTtcbiAgLyoqXG4gICAqIOyggOyepeqwkuuPhCBlbnYg64+EIOyXhuydhCDrlYwg7Iuk7KCc66GcIOyggeyaqeuQmOuKlCDqsJIuIO2ZlOuptOydhCDruYTsm4zrkZDrqbQgXCLshKTsoJUg7JWIIOuQqFwi7Jy866GcIOydve2eiOyngOunjFxuICAgKiDsi6TsoJzroZzripQg7J20IOqwkuydtCDrj4zqs6Ag7J6I64ukIOKAlCDshozruYTsspjsnZgg6riw67O46rCS6rO8IOuwmOuTnOyLnCDqsJnslYTslbwg7ZWc64ukLlxuICAgKi9cbiAgZmFsbGJhY2s6IHN0cmluZztcbiAgaGVscD86IHN0cmluZztcbn07XG5cbi8qKiA2NCBHaUIg7Jq07JiBIO2YuOyKpO2KuOyXkOyEnCDshLgg7J6Q66asIOyYpOyeheugpeydhCDrp4nripQg7ISk7KCVIOyDge2VnC4g7JWI7KCE7J2EIOuztOyepe2VmOuKlCDqsJLsnYAg7JWE64uI64ukLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9PUEVOQUlfRVNUSU1BVEVEX1JTU19HSUIgPSAzMjtcbmV4cG9ydCBjb25zdCBNQVhfT1BFTkFJX01JTl9IT1NUX0FWQUlMQUJMRV9HSUIgPSA2NDtcblxuZXhwb3J0IGNvbnN0IFNFVFRJTkdfREVGUzogU2V0dGluZ0RlZltdID0gW1xuICB7XG4gICAga2V5OiBcIm9wZW5haS5hdXRvc2NhbGVcIixcbiAgICBmYWxsYmFjazogXCJ0cnVlXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9BVVRPU0NBTEVcIixcbiAgICBsYWJlbDogXCJPcGVuQUkg7JuM7LukIOyYpO2GoOyKpOy8gOydvFwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIGhlbHA6IFwi64GE66m0IOybjOy7pCDsiJjqsIAg7LWc7IaM6rCS7Jy866GcIOqzoOygleuQqeuLiOuLpFwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcIm9wZW5haS5taW5Xb3JrZXJzUGVyVG9rZW5cIixcbiAgICBmYWxsYmFjazogXCIxXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NSU5fV09SS0VSU19QRVJfVE9LRU5cIixcbiAgICBsYWJlbDogXCLthqDtgbDri7kg7LWc7IaMIOybjOy7pFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IDIwLFxuICB9LFxuICB7XG4gICAga2V5OiBcIm9wZW5haS5tYXhXb3JrZXJzUGVyVG9rZW5cIixcbiAgICBmYWxsYmFjazogXCIzXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NQVhfV09SS0VSU19QRVJfVE9LRU5cIixcbiAgICBsYWJlbDogXCLthqDtgbDri7kg7LWc64yAIOybjOy7pFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IDIwLFxuICAgIGhlbHA6IFwi7Jik7Yag7Iqk7LyA7J287J20IOq6vOyguCDsnojsnLzrqbQg66y07Iuc65Cp64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwib3BlbmFpLm1heEVzdGltYXRlZFJzc0dpQlwiLFxuICAgIGZhbGxiYWNrOiBcIjE2XCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NQVhfRVNUSU1BVEVEX1JTU19HSUJcIixcbiAgICBsYWJlbDogXCLsm4zsu6Qg66mU66qo66asIOyDge2VnCAoR2lCKVwiLFxuICAgIGtpbmQ6IFwibnVtYmVyXCIsXG4gICAgYXBwbGllczogXCJyZXN0YXJ0XCIsXG4gICAgbWluOiAxLFxuICAgIG1heDogTUFYX09QRU5BSV9FU1RJTUFURURfUlNTX0dJQixcbiAgICBoZWxwOiBcIuydtCDstpTsoJXsuZjrpbwg64SY6riw66m0IOybjOy7pOulvCDrjZQg64qY66as7KeAIOyViuyKteuLiOuLpC4g7Jis66a07IiY66GdIE9PTSDsnITtl5jsnbQg7Luk7KeA66mwIOyDge2VnOydgCDsmKTsnoXroKUg67Cp7KeA7Jqp7J6F64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwib3BlbmFpLm1pbkhvc3RBdmFpbGFibGVHaUJcIixcbiAgICBmYWxsYmFjazogXCIyMFwiLFxuICAgIGdyb3VwOiBcIm9wZW5haVwiLFxuICAgIGVudktleTogXCJRR1JJRF9PUEVOQUlfTUlOX0hPU1RfQVZBSUxBQkxFX0dJQlwiLFxuICAgIGxhYmVsOiBcIu2YuOyKpO2KuCDsl6zsnKAg66mU66qo66asIO2VmO2VnCAoR2lCKVwiLFxuICAgIGtpbmQ6IFwibnVtYmVyXCIsXG4gICAgYXBwbGllczogXCJyZXN0YXJ0XCIsXG4gICAgbWluOiAwLFxuICAgIG1heDogTUFYX09QRU5BSV9NSU5fSE9TVF9BVkFJTEFCTEVfR0lCLFxuICAgIGhlbHA6IFwi7Zi47Iqk7Yq4IOyXrOycoOqwgCDsnbQg6rCSIOyVhOuemOuptCDsiqTsvIDsnbzsl4XsnYQg66mI7Lal64uI64ukLiDtmZXsnqXsnYQg64GE66Ck66m0IOyYpO2GoOyKpOy8gOydvOydhCDrgYTshLjsmpRcIixcbiAgfSxcbiAge1xuICAgIGtleTogXCJzbGFjay5lbmFibGVkXCIsXG4gICAgZmFsbGJhY2s6IFwidHJ1ZVwiLFxuICAgIGdyb3VwOiBcInNsYWNrXCIsXG4gICAgZW52S2V5OiBcIlNMQUNLX0VOQUJMRURcIixcbiAgICBsYWJlbDogXCJTbGFjayDslYzrprxcIixcbiAgICBraW5kOiBcImJvb2xlYW5cIixcbiAgICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiLFxuICAgIGhlbHA6IFwi7Jew7Zy07LKY65+8IOq3nOy5meycvOuhnCDsnqHsnYQg7IiYIOyXhuuKlCDquLDqsITsl5Ag64GV64uI64ukLiDshJzruYTsiqQg7KCV7KeA6riJIOyepeyVoCDslYzrprzsnYAg6rq864+EIOyghOuLrOuQqeuLiOuLpFwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcInNsYWNrLnJlbWluZGVyc0VuYWJsZWRcIixcbiAgICBmYWxsYmFjazogXCJ0cnVlXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfUkVNSU5ERVJTX0VOQUJMRURcIixcbiAgICBsYWJlbDogXCLrp4zro4wg7JWM66a8IOuwmOuztVwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLrgYTrqbQg67CY67O166eMIOupiOy2lOqzoCDrp4zro4wg7Iic6rCE7J2YIOyVjOumvOydgCDqt7jrjIDroZwg6rCR64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2suZXhwaXJ5UmVtaW5kZXJNaW51dGVzXCIsXG4gICAgZmFsbGJhY2s6IFwiNjBcIixcbiAgICBncm91cDogXCJzbGFja1wiLFxuICAgIGVudktleTogXCJTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU1wiLFxuICAgIGxhYmVsOiBcIuuwmOuztSDso7zquLBcIixcbiAgICBraW5kOiBcInByZXNldFwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgLy8g7J6Q7JygIOyeheugpSDrjIDsi6Ag6rOg7KCVIOyEoO2DneyngOulvCDsk7Tri6Qg4oCUIFwi7Ja866eI64KYIOyekOyjvCDsnqzstIntlaDquYxcIuudvOyEnCAx67aEIOuLqOychCDsoJXrsIDrj4TqsIBcbiAgICAvLyDsnZjrr7gg7JeG6rOgLCDsnpjrqrsg64Sj7Jy866m0IOyxhOuEkOydtCDsi5zrgYTrn6zsm4zsp4Tri6QuIOuBhOuKlCDqsoPsnYAgcmVtaW5kZXJzRW5hYmxlZCDqsIAg66eh64qU64ukLlxuICAgIHByZXNldHM6IFsxMCwgMzAsIDYwLCAxODBdLFxuICAgIGhlbHA6IFwi7J6s66Gc6re47J247J20IO2VhOyalO2VnCDthqDtgbDsnbQg64Ko7JWEIOyeiOuKlCDrj5nslYgg7J20IOyjvOq4sOuhnCDri6Tsi5wg7JWM66a964uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2sucXVpZXRGcm9tSG91clwiLFxuICAgIGZhbGxiYWNrOiBcIjIwXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfUVVJRVRfRlJPTV9IT1VSXCIsXG4gICAgbGFiZWw6IFwi7KGw7JqpIOyLnOqwhCDsi5zsnpFcIixcbiAgICBraW5kOiBcImludGVnZXJcIixcbiAgICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiLFxuICAgIG1pbjogMCxcbiAgICBtYXg6IDIzLFxuICAgIGhlbHA6IFwi7J20IOyLnOqwgeu2gO2EsCDslYzrpqzsp4Ag7JWK7Iq164uI64ukICjtlZzqta0g7Iuc6rCEKVwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcInNsYWNrLnF1aWV0VW50aWxIb3VyXCIsXG4gICAgZmFsbGJhY2s6IFwiOFwiLFxuICAgIGdyb3VwOiBcInNsYWNrXCIsXG4gICAgZW52S2V5OiBcIlNMQUNLX1FVSUVUX1VOVElMX0hPVVJcIixcbiAgICBsYWJlbDogXCLsobDsmqkg7Iuc6rCEIOyiheujjFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgbWluOiAwLFxuICAgIG1heDogMjMsXG4gICAgaGVscDogXCLsnbQg7Iuc6rCB67aA7YSwIOuLpOyLnCDslYzrpr3ri4jri6QuIOyLnOyekeuztOuLpCDruaDrpbTrqbQg7J6Q7KCV7J2EIOuEmOuKlCDqtazqsITsnbQg65Cp64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2subm90aWZ5T25XZWVrZW5kc1wiLFxuICAgIGZhbGxiYWNrOiBcImZhbHNlXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfTk9USUZZX09OX1dFRUtFTkRTXCIsXG4gICAgbGFiZWw6IFwi7KO866eQ7JeQ64+EIOyVjOumvFwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLsvJzrqbQg7KO866eQ7JeQ64+EIOychOydmCDsobDsmqkg7Iuc6rCEIOq3nOy5meunjCDsoIHsmqnrkKnri4jri6RcIixcbiAgfSxcbiAge1xuICAgIGtleTogXCJzbGFjay5jaGFubmVsSWRcIixcbiAgICBmYWxsYmFjazogXCJcIixcbiAgICBncm91cDogXCJzbGFja0Nvbm5lY3Rpb25cIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfQ0hBTk5FTF9JRFwiLFxuICAgIGxhYmVsOiBcIlNsYWNrIOyxhOuEkCBJRFwiLFxuICAgIGtpbmQ6IFwic3RyaW5nXCIsXG4gICAgYXBwbGllczogXCJpbW1lZGlhdGVcIixcbiAgICBoZWxwOiBcIuyCrOyaqeyekCBJRChVLi4uKeulvCDrhKPsnLzrqbQg6re4IOyCrOuejCBETSDsnLzroZwg6rCR64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2sudXNlck1hcFwiLFxuICAgIGZhbGxiYWNrOiBcIlwiLFxuICAgIGdyb3VwOiBcInNsYWNrQ29ubmVjdGlvblwiLFxuICAgIGVudktleTogXCJTTEFDS19VU0VSX01BUFwiLFxuICAgIGxhYmVsOiBcIlNsYWNrIOyCrOyaqeyekCDrp6TtlZFcIixcbiAgICBraW5kOiBcInN0cmluZ1wiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLthqDtgbDrqoU6U2xhY2tVc2VySWQg66W8IOyJvO2RnOuhnC4g6rO17JqpIOqzhOygleydgCDrhKPsp4Ag7JWK7Iq164uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2suYm90VG9rZW5cIixcbiAgICBmYWxsYmFjazogXCJcIixcbiAgICBncm91cDogXCJzbGFja0Nvbm5lY3Rpb25cIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfQk9UX1RPS0VOXCIsXG4gICAgbGFiZWw6IFwiU2xhY2sg67SHIO2GoO2BsFwiLFxuICAgIGtpbmQ6IFwic2VjcmV0XCIsXG4gICAgYXBwbGllczogXCJpbW1lZGlhdGVcIixcbiAgfSxcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kU2V0dGluZ0RlZihrZXk6IHN0cmluZyk6IFNldHRpbmdEZWYgfCB1bmRlZmluZWQge1xuICByZXR1cm4gU0VUVElOR19ERUZTLmZpbmQoKGQpID0+IGQua2V5ID09PSBrZXkpO1xufVxuXG4vKiog7KCA7J6lIOyghCDqsoDspp0uIOyemOuqu+uQnCDqsJLsnbQg65Ok7Ja06rCA66m0IOufsO2DgOyehOyXkOyEnCDsobDsmqntnogg6riw67O46rCS7Jy866GcIOuWqOyWtOyguCDsm5DsnbjsnYQg7LC+6riwIOyWtOugteuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVNldHRpbmdWYWx1ZShcbiAgZGVmOiBTZXR0aW5nRGVmLFxuICByYXc6IHN0cmluZyxcbik6IHsgb2s6IHRydWU7IHZhbHVlOiBzdHJpbmcgfSB8IHsgb2s6IGZhbHNlOyBlcnJvcjogc3RyaW5nIH0ge1xuICBjb25zdCB0cmltbWVkID0gcmF3LnRyaW0oKTtcblxuICBpZiAoZGVmLmtpbmQgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgaWYgKCFbXCJ0cnVlXCIsIFwiZmFsc2VcIl0uaW5jbHVkZXModHJpbW1lZCkpIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IFwidHJ1ZSDrmJDripQgZmFsc2VcIiB9O1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCB2YWx1ZTogdHJpbW1lZCB9O1xuICB9XG5cbiAgaWYgKGRlZi5raW5kID09PSBcInByZXNldFwiKSB7XG4gICAgLy8g7ZmU66m07J2AIOuyhO2KvOunjCDso7zsp4Drp4wgQVBJIOuKlCDslYTrrLQg6rCS7J2064KYIOuwm+ydhCDsiJgg7J6I64ukLiDrqqnroZ0g67CW7J2YIOqwkuydtCDrk6TslrTsmKTrqbRcbiAgICAvLyDtmZTrqbTsl5DshJwg7JWE66y0IOuyhO2KvOuPhCDshKDtg53rj7wg67O07J207KeAIOyViuyVhCBcIuyZnCDslYgg67CU64CM7KeAXCLqsIAg65Cc64ukLlxuICAgIGNvbnN0IHBhcnNlZCA9IE51bWJlcih0cmltbWVkKTtcbiAgICBpZiAoIWRlZi5wcmVzZXRzPy5pbmNsdWRlcyhwYXJzZWQpKSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBgJHtkZWYucHJlc2V0cz8uam9pbihcIiwgXCIpID8/IFwiXCJ9IOykkSDtlZjrgpjsl6zslbwg7ZWp64uI64ukYCB9O1xuICAgIH1cbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdmFsdWU6IFN0cmluZyhwYXJzZWQpIH07XG4gIH1cblxuICBpZiAoZGVmLmtpbmQgPT09IFwiaW50ZWdlclwiIHx8IGRlZi5raW5kID09PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHRyaW1tZWQpO1xuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHBhcnNlZCkpIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IFwi7Iir7J6Q66W8IOyeheugpe2VmOyEuOyalFwiIH07XG4gICAgaWYgKGRlZi5raW5kID09PSBcImludGVnZXJcIiAmJiAhTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpKSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBcIuygleyImOulvCDsnoXroKXtlZjshLjsmpRcIiB9O1xuICAgIH1cbiAgICBpZiAoZGVmLm1pbiAhPT0gdW5kZWZpbmVkICYmIHBhcnNlZCA8IGRlZi5taW4pIHtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IGAke2RlZi5taW59IOydtOyDgeydtOyWtOyVvCDtlanri4jri6RgIH07XG4gICAgfVxuICAgIGlmIChkZWYubWF4ICE9PSB1bmRlZmluZWQgJiYgcGFyc2VkID4gZGVmLm1heCkge1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogYCR7ZGVmLm1heH0g7J207ZWY7Jes7JW8IO2VqeuLiOuLpGAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgb2s6IHRydWUsIHZhbHVlOiBTdHJpbmcocGFyc2VkKSB9O1xuICB9XG5cbiAgcmV0dXJuIHsgb2s6IHRydWUsIHZhbHVlOiB0cmltbWVkIH07XG59XG5cbi8qKiDtmZTrqbTsl5Ag6re464yA66GcIOuCtOugpOuztOuCtOuptCDslYgg65CY64qUIOqwki4g7JWe65Kk66eMIOuCqOq4tOuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXNrU2VjcmV0KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAodmFsdWUubGVuZ3RoIDw9IDEyKSByZXR1cm4gXCIqKipcIjtcbiAgcmV0dXJuIGAke3ZhbHVlLnNsaWNlKDAsIDgpfS4uLiR7dmFsdWUuc2xpY2UoLTQpfWA7XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBMENBLE1BQWEsK0JBQStCO0FBQzVDLE1BQWEsb0NBQW9DO0FBRWpELE1BQWEsZUFBNkI7Q0FDeEM7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsTUFBTTtDQUNSO0NBQ0E7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsS0FBSztFQUNMLEtBQUs7Q0FDUDtDQUNBO0VBQ0UsS0FBSztFQUNMLFVBQVU7RUFDVixPQUFPO0VBQ1AsUUFBUTtFQUNSLE9BQU87RUFDUCxNQUFNO0VBQ04sU0FBUztFQUNULEtBQUs7RUFDTCxLQUFLO0VBQ0wsTUFBTTtDQUNSO0NBQ0E7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsS0FBSztFQUNMLEtBQUE7RUFDQSxNQUFNO0NBQ1I7Q0FDQTtFQUNFLEtBQUs7RUFDTCxVQUFVO0VBQ1YsT0FBTztFQUNQLFFBQVE7RUFDUixPQUFPO0VBQ1AsTUFBTTtFQUNOLFNBQVM7RUFDVCxLQUFLO0VBQ0wsS0FBQTtFQUNBLE1BQU07Q0FDUjtDQUNBO0VBQ0UsS0FBSztFQUNMLFVBQVU7RUFDVixPQUFP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