@adonis-agora/flags 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +15 -2
  4. package/dist/assets/spa/assets/index-DdmFo7xr.js +12 -0
  5. package/dist/assets/spa/assets/index-DdmFo7xr.js.map +1 -0
  6. package/dist/assets/spa/assets/index-DhkcP3Cw.css +2 -0
  7. package/dist/assets/spa/index.html +26 -0
  8. package/dist/commands/flags_list.d.ts +9 -0
  9. package/dist/commands/flags_list.d.ts.map +1 -0
  10. package/dist/commands/flags_list.js +51 -0
  11. package/dist/commands/flags_list.js.map +1 -0
  12. package/dist/commands/flags_ops.d.ts +60 -0
  13. package/dist/commands/flags_ops.d.ts.map +1 -0
  14. package/dist/commands/flags_ops.js +253 -0
  15. package/dist/commands/flags_ops.js.map +1 -0
  16. package/dist/commands/flags_refs.d.ts +15 -0
  17. package/dist/commands/flags_refs.d.ts.map +1 -0
  18. package/dist/commands/flags_refs.js +90 -0
  19. package/dist/commands/flags_refs.js.map +1 -0
  20. package/dist/commands/flags_set.d.ts +19 -0
  21. package/dist/commands/flags_set.d.ts.map +1 -0
  22. package/dist/commands/flags_set.js +97 -0
  23. package/dist/commands/flags_set.js.map +1 -0
  24. package/dist/commands/flags_types.d.ts +18 -0
  25. package/dist/commands/flags_types.d.ts.map +1 -0
  26. package/dist/commands/flags_types.js +94 -0
  27. package/dist/commands/flags_types.js.map +1 -0
  28. package/dist/commands/flags_work.d.ts +16 -0
  29. package/dist/commands/flags_work.d.ts.map +1 -0
  30. package/dist/commands/flags_work.js +71 -0
  31. package/dist/commands/flags_work.js.map +1 -0
  32. package/dist/commands/main.d.ts +15 -0
  33. package/dist/commands/main.d.ts.map +1 -0
  34. package/dist/commands/main.js +30 -0
  35. package/dist/commands/main.js.map +1 -0
  36. package/dist/commands/shared.d.ts +21 -0
  37. package/dist/commands/shared.d.ts.map +1 -0
  38. package/dist/commands/shared.js +70 -0
  39. package/dist/commands/shared.js.map +1 -0
  40. package/dist/configure.d.ts +11 -0
  41. package/dist/configure.d.ts.map +1 -0
  42. package/dist/configure.js +32 -0
  43. package/dist/configure.js.map +1 -0
  44. package/dist/providers/dashboard_provider.d.ts +65 -0
  45. package/dist/providers/dashboard_provider.d.ts.map +1 -0
  46. package/dist/providers/dashboard_provider.js +340 -0
  47. package/dist/providers/dashboard_provider.js.map +1 -0
  48. package/dist/providers/flags_provider.d.ts +30 -0
  49. package/dist/providers/flags_provider.d.ts.map +1 -0
  50. package/dist/providers/flags_provider.js +184 -0
  51. package/dist/providers/flags_provider.js.map +1 -0
  52. package/dist/services/main.d.ts +17 -0
  53. package/dist/services/main.d.ts.map +1 -0
  54. package/dist/services/main.js +20 -0
  55. package/dist/services/main.js.map +1 -0
  56. package/dist/src/admin.d.ts +189 -0
  57. package/dist/src/admin.d.ts.map +1 -0
  58. package/dist/src/admin.js +539 -0
  59. package/dist/src/admin.js.map +1 -0
  60. package/dist/src/analytics/backend.d.ts +18 -0
  61. package/dist/src/analytics/backend.d.ts.map +1 -0
  62. package/dist/src/analytics/backend.js +25 -0
  63. package/dist/src/analytics/backend.js.map +1 -0
  64. package/dist/src/analytics/clickhouse_backend.d.ts +16 -0
  65. package/dist/src/analytics/clickhouse_backend.d.ts.map +1 -0
  66. package/dist/src/analytics/clickhouse_backend.js +48 -0
  67. package/dist/src/analytics/clickhouse_backend.js.map +1 -0
  68. package/dist/src/analytics/duckdb.d.ts +39 -0
  69. package/dist/src/analytics/duckdb.d.ts.map +1 -0
  70. package/dist/src/analytics/duckdb.js +117 -0
  71. package/dist/src/analytics/duckdb.js.map +1 -0
  72. package/dist/src/analytics/lucid_backend.d.ts +16 -0
  73. package/dist/src/analytics/lucid_backend.d.ts.map +1 -0
  74. package/dist/src/analytics/lucid_backend.js +45 -0
  75. package/dist/src/analytics/lucid_backend.js.map +1 -0
  76. package/dist/src/analytics/metrics.d.ts +50 -0
  77. package/dist/src/analytics/metrics.d.ts.map +1 -0
  78. package/dist/src/analytics/metrics.js +42 -0
  79. package/dist/src/analytics/metrics.js.map +1 -0
  80. package/dist/src/analytics/results.d.ts +80 -0
  81. package/dist/src/analytics/results.d.ts.map +1 -0
  82. package/dist/src/analytics/results.js +143 -0
  83. package/dist/src/analytics/results.js.map +1 -0
  84. package/dist/src/dashboard/access_denied_page.d.ts +100 -0
  85. package/dist/src/dashboard/access_denied_page.d.ts.map +1 -0
  86. package/dist/src/dashboard/access_denied_page.js +262 -0
  87. package/dist/src/dashboard/access_denied_page.js.map +1 -0
  88. package/dist/src/dashboard/actor.d.ts +12 -0
  89. package/dist/src/dashboard/actor.d.ts.map +1 -0
  90. package/dist/src/dashboard/actor.js +33 -0
  91. package/dist/src/dashboard/actor.js.map +1 -0
  92. package/dist/src/dashboard/authorize_decision.d.ts +48 -0
  93. package/dist/src/dashboard/authorize_decision.d.ts.map +1 -0
  94. package/dist/src/dashboard/authorize_decision.js +44 -0
  95. package/dist/src/dashboard/authorize_decision.js.map +1 -0
  96. package/dist/src/dashboard/console_authorize.d.ts +77 -0
  97. package/dist/src/dashboard/console_authorize.d.ts.map +1 -0
  98. package/dist/src/dashboard/console_authorize.js +104 -0
  99. package/dist/src/dashboard/console_authorize.js.map +1 -0
  100. package/dist/src/dashboard/define_config.d.ts +71 -0
  101. package/dist/src/dashboard/define_config.d.ts.map +1 -0
  102. package/dist/src/dashboard/define_config.js +18 -0
  103. package/dist/src/dashboard/define_config.js.map +1 -0
  104. package/dist/src/dashboard/handlers.d.ts +172 -0
  105. package/dist/src/dashboard/handlers.d.ts.map +1 -0
  106. package/dist/src/dashboard/handlers.js +949 -0
  107. package/dist/src/dashboard/handlers.js.map +1 -0
  108. package/dist/src/dashboard/index.d.ts +15 -0
  109. package/dist/src/dashboard/index.d.ts.map +1 -0
  110. package/dist/src/dashboard/index.js +10 -0
  111. package/dist/src/dashboard/index.js.map +1 -0
  112. package/dist/src/dashboard/shape.d.ts +12 -0
  113. package/dist/src/dashboard/shape.d.ts.map +1 -0
  114. package/dist/src/dashboard/shape.js +232 -0
  115. package/dist/src/dashboard/shape.js.map +1 -0
  116. package/dist/src/dashboard/spa.d.ts +34 -0
  117. package/dist/src/dashboard/spa.d.ts.map +1 -0
  118. package/dist/src/dashboard/spa.js +50 -0
  119. package/dist/src/dashboard/spa.js.map +1 -0
  120. package/dist/src/declare.d.ts +85 -0
  121. package/dist/src/declare.d.ts.map +1 -0
  122. package/dist/src/declare.js +62 -0
  123. package/dist/src/declare.js.map +1 -0
  124. package/dist/src/define_config.d.ts +256 -0
  125. package/dist/src/define_config.d.ts.map +1 -0
  126. package/dist/src/define_config.js +90 -0
  127. package/dist/src/define_config.js.map +1 -0
  128. package/dist/src/durable.d.ts +29 -0
  129. package/dist/src/durable.d.ts.map +1 -0
  130. package/dist/src/durable.js +55 -0
  131. package/dist/src/durable.js.map +1 -0
  132. package/dist/src/enrichers.d.ts +51 -0
  133. package/dist/src/enrichers.d.ts.map +1 -0
  134. package/dist/src/enrichers.js +105 -0
  135. package/dist/src/enrichers.js.map +1 -0
  136. package/dist/src/events/buffer.d.ts +38 -0
  137. package/dist/src/events/buffer.d.ts.map +1 -0
  138. package/dist/src/events/buffer.js +86 -0
  139. package/dist/src/events/buffer.js.map +1 -0
  140. package/dist/src/events/event.d.ts +42 -0
  141. package/dist/src/events/event.d.ts.map +1 -0
  142. package/dist/src/events/event.js +82 -0
  143. package/dist/src/events/event.js.map +1 -0
  144. package/dist/src/http/browser.d.ts +33 -0
  145. package/dist/src/http/browser.d.ts.map +1 -0
  146. package/dist/src/http/browser.js +81 -0
  147. package/dist/src/http/browser.js.map +1 -0
  148. package/dist/src/http/browser_api.d.ts +48 -0
  149. package/dist/src/http/browser_api.d.ts.map +1 -0
  150. package/dist/src/http/browser_api.js +273 -0
  151. package/dist/src/http/browser_api.js.map +1 -0
  152. package/dist/src/http/browser_tokens.d.ts +27 -0
  153. package/dist/src/http/browser_tokens.d.ts.map +1 -0
  154. package/dist/src/http/browser_tokens.js +48 -0
  155. package/dist/src/http/browser_tokens.js.map +1 -0
  156. package/dist/src/http/control_plane.d.ts +58 -0
  157. package/dist/src/http/control_plane.d.ts.map +1 -0
  158. package/dist/src/http/control_plane.js +318 -0
  159. package/dist/src/http/control_plane.js.map +1 -0
  160. package/dist/src/http/csrf.d.ts +22 -0
  161. package/dist/src/http/csrf.d.ts.map +1 -0
  162. package/dist/src/http/csrf.js +24 -0
  163. package/dist/src/http/csrf.js.map +1 -0
  164. package/dist/src/http/edge_tag.d.ts +55 -0
  165. package/dist/src/http/edge_tag.d.ts.map +1 -0
  166. package/dist/src/http/edge_tag.js +45 -0
  167. package/dist/src/http/edge_tag.js.map +1 -0
  168. package/dist/src/http/flag_middleware.d.ts +27 -0
  169. package/dist/src/http/flag_middleware.d.ts.map +1 -0
  170. package/dist/src/http/flag_middleware.js +30 -0
  171. package/dist/src/http/flag_middleware.js.map +1 -0
  172. package/dist/src/http/flags_middleware.d.ts +20 -0
  173. package/dist/src/http/flags_middleware.d.ts.map +1 -0
  174. package/dist/src/http/flags_middleware.js +20 -0
  175. package/dist/src/http/flags_middleware.js.map +1 -0
  176. package/dist/src/http/subject_resolver.d.ts +45 -0
  177. package/dist/src/http/subject_resolver.d.ts.map +1 -0
  178. package/dist/src/http/subject_resolver.js +93 -0
  179. package/dist/src/http/subject_resolver.js.map +1 -0
  180. package/dist/src/identity.d.ts +82 -0
  181. package/dist/src/identity.d.ts.map +1 -0
  182. package/dist/src/identity.js +100 -0
  183. package/dist/src/identity.js.map +1 -0
  184. package/dist/src/index.d.ts +41 -0
  185. package/dist/src/index.d.ts.map +1 -0
  186. package/dist/src/index.js +34 -0
  187. package/dist/src/index.js.map +1 -0
  188. package/dist/src/manager.d.ts +154 -0
  189. package/dist/src/manager.d.ts.map +1 -0
  190. package/dist/src/manager.js +333 -0
  191. package/dist/src/manager.js.map +1 -0
  192. package/dist/src/openfeature/provider.d.ts +36 -0
  193. package/dist/src/openfeature/provider.d.ts.map +1 -0
  194. package/dist/src/openfeature/provider.js +82 -0
  195. package/dist/src/openfeature/provider.js.map +1 -0
  196. package/dist/src/relay/relay.d.ts +36 -0
  197. package/dist/src/relay/relay.d.ts.map +1 -0
  198. package/dist/src/relay/relay.js +73 -0
  199. package/dist/src/relay/relay.js.map +1 -0
  200. package/dist/src/relay/results_cache.d.ts +20 -0
  201. package/dist/src/relay/results_cache.d.ts.map +1 -0
  202. package/dist/src/relay/results_cache.js +31 -0
  203. package/dist/src/relay/results_cache.js.map +1 -0
  204. package/dist/src/relay/worker.d.ts +66 -0
  205. package/dist/src/relay/worker.d.ts.map +1 -0
  206. package/dist/src/relay/worker.js +177 -0
  207. package/dist/src/relay/worker.js.map +1 -0
  208. package/dist/src/ruleset_source.d.ts +73 -0
  209. package/dist/src/ruleset_source.d.ts.map +1 -0
  210. package/dist/src/ruleset_source.js +128 -0
  211. package/dist/src/ruleset_source.js.map +1 -0
  212. package/dist/src/runtime.d.ts +70 -0
  213. package/dist/src/runtime.d.ts.map +1 -0
  214. package/dist/src/runtime.js +301 -0
  215. package/dist/src/runtime.js.map +1 -0
  216. package/dist/src/schema.d.ts +39 -0
  217. package/dist/src/schema.d.ts.map +1 -0
  218. package/dist/src/schema.js +311 -0
  219. package/dist/src/schema.js.map +1 -0
  220. package/dist/src/services/accessor.d.ts +5 -0
  221. package/dist/src/services/accessor.d.ts.map +1 -0
  222. package/dist/src/services/accessor.js +20 -0
  223. package/dist/src/services/accessor.js.map +1 -0
  224. package/dist/src/sinks/clickhouse.d.ts +41 -0
  225. package/dist/src/sinks/clickhouse.d.ts.map +1 -0
  226. package/dist/src/sinks/clickhouse.js +117 -0
  227. package/dist/src/sinks/clickhouse.js.map +1 -0
  228. package/dist/src/sinks/lucid_sink.d.ts +25 -0
  229. package/dist/src/sinks/lucid_sink.d.ts.map +1 -0
  230. package/dist/src/sinks/lucid_sink.js +87 -0
  231. package/dist/src/sinks/lucid_sink.js.map +1 -0
  232. package/dist/src/sinks/parquet_sink.d.ts +41 -0
  233. package/dist/src/sinks/parquet_sink.d.ts.map +1 -0
  234. package/dist/src/sinks/parquet_sink.js +140 -0
  235. package/dist/src/sinks/parquet_sink.js.map +1 -0
  236. package/dist/src/sinks/posthog_sink.d.ts +29 -0
  237. package/dist/src/sinks/posthog_sink.d.ts.map +1 -0
  238. package/dist/src/sinks/posthog_sink.js +65 -0
  239. package/dist/src/sinks/posthog_sink.js.map +1 -0
  240. package/dist/src/sinks/sink.d.ts +36 -0
  241. package/dist/src/sinks/sink.d.ts.map +1 -0
  242. package/dist/src/sinks/sink.js +36 -0
  243. package/dist/src/sinks/sink.js.map +1 -0
  244. package/dist/src/sql.d.ts +33 -0
  245. package/dist/src/sql.d.ts.map +1 -0
  246. package/dist/src/sql.js +66 -0
  247. package/dist/src/sql.js.map +1 -0
  248. package/dist/src/stores/lucid_store.d.ts +55 -0
  249. package/dist/src/stores/lucid_store.d.ts.map +1 -0
  250. package/dist/src/stores/lucid_store.js +412 -0
  251. package/dist/src/stores/lucid_store.js.map +1 -0
  252. package/dist/src/stores/memory_store.d.ts +38 -0
  253. package/dist/src/stores/memory_store.d.ts.map +1 -0
  254. package/dist/src/stores/memory_store.js +166 -0
  255. package/dist/src/stores/memory_store.js.map +1 -0
  256. package/dist/src/stores/store.d.ts +166 -0
  257. package/dist/src/stores/store.d.ts.map +1 -0
  258. package/dist/src/stores/store.js +67 -0
  259. package/dist/src/stores/store.js.map +1 -0
  260. package/dist/src/subject.d.ts +25 -0
  261. package/dist/src/subject.d.ts.map +1 -0
  262. package/dist/src/subject.js +30 -0
  263. package/dist/src/subject.js.map +1 -0
  264. package/dist/src/testing/index.d.ts +31 -0
  265. package/dist/src/testing/index.d.ts.map +1 -0
  266. package/dist/src/testing/index.js +60 -0
  267. package/dist/src/testing/index.js.map +1 -0
  268. package/dist/src/topology/browser_token.d.ts +48 -0
  269. package/dist/src/topology/browser_token.d.ts.map +1 -0
  270. package/dist/src/topology/browser_token.js +128 -0
  271. package/dist/src/topology/browser_token.js.map +1 -0
  272. package/dist/src/topology/remote_source.d.ts +39 -0
  273. package/dist/src/topology/remote_source.d.ts.map +1 -0
  274. package/dist/src/topology/remote_source.js +184 -0
  275. package/dist/src/topology/remote_source.js.map +1 -0
  276. package/dist/src/topology/token.d.ts +36 -0
  277. package/dist/src/topology/token.d.ts.map +1 -0
  278. package/dist/src/topology/token.js +68 -0
  279. package/dist/src/topology/token.js.map +1 -0
  280. package/dist/src/topology/verify.d.ts +88 -0
  281. package/dist/src/topology/verify.d.ts.map +1 -0
  282. package/dist/src/topology/verify.js +128 -0
  283. package/dist/src/topology/verify.js.map +1 -0
  284. package/dist/src/transports/db_transport.d.ts +55 -0
  285. package/dist/src/transports/db_transport.d.ts.map +1 -0
  286. package/dist/src/transports/db_transport.js +202 -0
  287. package/dist/src/transports/db_transport.js.map +1 -0
  288. package/dist/src/transports/http_transport.d.ts +30 -0
  289. package/dist/src/transports/http_transport.d.ts.map +1 -0
  290. package/dist/src/transports/http_transport.js +51 -0
  291. package/dist/src/transports/http_transport.js.map +1 -0
  292. package/dist/src/transports/memory_transport.d.ts +29 -0
  293. package/dist/src/transports/memory_transport.d.ts.map +1 -0
  294. package/dist/src/transports/memory_transport.js +91 -0
  295. package/dist/src/transports/memory_transport.js.map +1 -0
  296. package/dist/src/transports/redis_transport.d.ts +50 -0
  297. package/dist/src/transports/redis_transport.d.ts.map +1 -0
  298. package/dist/src/transports/redis_transport.js +107 -0
  299. package/dist/src/transports/redis_transport.js.map +1 -0
  300. package/dist/src/transports/transport.d.ts +62 -0
  301. package/dist/src/transports/transport.d.ts.map +1 -0
  302. package/dist/src/transports/transport.js +2 -0
  303. package/dist/src/transports/transport.js.map +1 -0
  304. package/dist/src/types.d.ts +30 -0
  305. package/dist/src/types.d.ts.map +1 -0
  306. package/dist/src/types.js +2 -0
  307. package/dist/src/types.js.map +1 -0
  308. package/dist/src/usage.d.ts +18 -0
  309. package/dist/src/usage.d.ts.map +1 -0
  310. package/dist/src/usage.js +52 -0
  311. package/dist/src/usage.js.map +1 -0
  312. package/dist/stubs/config/flags.stub +50 -0
  313. package/dist/stubs/config/flags_dashboard.stub +35 -0
  314. package/dist/stubs/database/migrations/create_flags_tables.stub +27 -0
  315. package/dist/stubs/main.d.ts +3 -0
  316. package/dist/stubs/main.d.ts.map +1 -0
  317. package/dist/stubs/main.js +9 -0
  318. package/dist/stubs/main.js.map +1 -0
  319. package/package.json +178 -3
  320. package/skills/flags-basics/SKILL.md +142 -0
  321. package/skills/flags-deployment/SKILL.md +125 -0
  322. package/skills/flags-experiments/SKILL.md +99 -0
@@ -0,0 +1,104 @@
1
+ import { createHash, timingSafeEqual } from 'node:crypto';
2
+ const FORBIDDEN = { allowed: false, status: 403, reason: 'forbidden' };
3
+ function isAuthorizerClass(value) {
4
+ return (typeof value === 'function' &&
5
+ typeof value.prototype?.authorize === 'function');
6
+ }
7
+ /** A module namespace whose `default` export is an authorizer class: a lazy import resolved. */
8
+ function lazyModuleClass(value) {
9
+ if (typeof value !== 'object' || value === null || !('default' in value))
10
+ return undefined;
11
+ const candidate = value.default;
12
+ return isAuthorizerClass(candidate) ? candidate : undefined;
13
+ }
14
+ /**
15
+ * Normalize an authorizer's answer. Fails closed: only `true` or `{ allowed: true }` passes;
16
+ * `{ redirectTo }` with a non-empty string is a redirect; anything else is a denial (`401` for
17
+ * `reason: 'unauthenticated'`, `403` otherwise).
18
+ */
19
+ export function normalizeConsoleAuthorizeResult(result) {
20
+ if (result === true)
21
+ return { allowed: true };
22
+ if (typeof result !== 'object' || result === null)
23
+ return FORBIDDEN;
24
+ const value = result;
25
+ if (value.allowed === true)
26
+ return { allowed: true };
27
+ if (value.allowed === undefined && typeof value.redirectTo === 'string' && value.redirectTo) {
28
+ return { allowed: false, status: 302, redirectTo: value.redirectTo };
29
+ }
30
+ if (value.reason === 'unauthenticated') {
31
+ return { allowed: false, status: 401, reason: 'unauthenticated' };
32
+ }
33
+ return FORBIDDEN;
34
+ }
35
+ async function instantiate(Authorizer, ctx) {
36
+ const resolver = ctx.containerResolver;
37
+ if (resolver && typeof resolver.make === 'function') {
38
+ return (await resolver.make(Authorizer));
39
+ }
40
+ return new Authorizer();
41
+ }
42
+ /**
43
+ * Turn an `authorize` option into one guard function.
44
+ *
45
+ * - A class is built through the request's container (`ctx.containerResolver.make`), so
46
+ * `@inject()` works, and its `authorize(ctx)` is called.
47
+ * - A function is called with `ctx`. When it resolves to a module whose `default` is an
48
+ * authorizer class, it was a lazy import: the class is remembered (the import runs once per
49
+ * returned guard) and used as above.
50
+ * - A thrown error is a `403` denial, carried on `error` so the caller can log it.
51
+ */
52
+ export function resolveConsoleAuthorize(authorize) {
53
+ let lazyClass;
54
+ const run = async (ctx) => {
55
+ if (lazyClass)
56
+ return (await instantiate(lazyClass, ctx)).authorize(ctx);
57
+ if (isAuthorizerClass(authorize))
58
+ return (await instantiate(authorize, ctx)).authorize(ctx);
59
+ const result = await authorize(ctx);
60
+ const imported = lazyModuleClass(result);
61
+ if (imported) {
62
+ lazyClass = imported;
63
+ return (await instantiate(imported, ctx)).authorize(ctx);
64
+ }
65
+ return result;
66
+ };
67
+ return async (ctx) => {
68
+ try {
69
+ return normalizeConsoleAuthorizeResult(await run(ctx));
70
+ }
71
+ catch (error) {
72
+ return { ...FORBIDDEN, error };
73
+ }
74
+ };
75
+ }
76
+ function digest(value) {
77
+ return createHash('sha256').update(value).digest();
78
+ }
79
+ /**
80
+ * An `authorize` check for machine access: allows a request whose `Authorization` header is
81
+ * `Bearer <token>` (compared in constant time), and answers
82
+ * `{ allowed: false, reason: 'unauthenticated' }` (`401`) otherwise. Only the header is read.
83
+ *
84
+ * ```ts
85
+ * authorize: authorizeByToken({ token: env.get('CONSOLE_TOKEN') }),
86
+ * ```
87
+ *
88
+ * Throws at config time when `token` is empty or undefined.
89
+ */
90
+ export function authorizeByToken(options) {
91
+ const token = options?.token;
92
+ if (typeof token !== 'string' || token === '') {
93
+ throw new Error('[@adonis-agora/flags] authorizeByToken: `token` must be a non-empty string');
94
+ }
95
+ const expected = digest(token);
96
+ return (ctx) => {
97
+ const header = ctx.request.header('authorization');
98
+ const match = typeof header === 'string' ? /^Bearer\s+(.+)$/i.exec(header.trim()) : null;
99
+ if (match?.[1] && timingSafeEqual(digest(match[1]), expected))
100
+ return { allowed: true };
101
+ return { allowed: false, reason: 'unauthenticated' };
102
+ };
103
+ }
104
+ //# sourceMappingURL=console_authorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console_authorize.js","sourceRoot":"","sources":["../../../src/dashboard/console_authorize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import type { HttpContext } from '@adonisjs/core/http';
2
+ import type { Actor } from '../stores/store.js';
3
+ import type { AccessDeniedOption as GenericAccessDeniedOption, AccessDeniedRenderer as GenericAccessDeniedRenderer } from './access_denied_page.js';
4
+ import type { ConsoleAuthorize, ConsoleAuthorizeResult } from './console_authorize.js';
5
+ export type { AuthorizeDecision, AuthorizeResult } from './authorize_decision.js';
6
+ export type { AuthorizeByTokenOptions, ConsoleAuthorize, ConsoleAuthorizeResult, ConsoleAuthorizer, ConsoleAuthorizerClass, } from './console_authorize.js';
7
+ /** The function form of {@link FlagsDashboardConfig.accessDenied}. */
8
+ export type AccessDeniedRenderer = GenericAccessDeniedRenderer<HttpContext>;
9
+ /** `accessDenied` in either form — an options object for the built-in page, or a renderer. */
10
+ export type AccessDeniedOption = GenericAccessDeniedOption<HttpContext>;
11
+ /**
12
+ * The inline-function form of the dashboard's `authorize` option. Runs before every dashboard
13
+ * route (API + HTML) and may be async. Answer with:
14
+ *
15
+ * - `true` / `{ allowed: true }` — let the request through;
16
+ * - `{ allowed: false, reason: 'unauthenticated' }` — nobody is signed in: `401`;
17
+ * - `{ allowed: false, reason: 'forbidden' }`, `{ allowed: false }` or `false` — `403`;
18
+ * - `{ redirectTo: '/login' }` — a page navigation is redirected (`302`), an API call gets `401`.
19
+ *
20
+ * A hook that throws is a `403`. `@adonis-agora/authkit-client`'s `authkitDashboardAuthorize` and
21
+ * `@adonis-agora/authz`'s `authorizeByRoles` fit here as-is.
22
+ */
23
+ export type AuthorizeHook = (ctx: HttpContext) => ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>;
24
+ /**
25
+ * Who a console change is attributed to (audit log, change requests). Return an {@link Actor}, a
26
+ * bare id, or nothing to fall back to `'dashboard'`.
27
+ */
28
+ export type ActorResolver = (ctx: HttpContext) => Actor | string | null | undefined | Promise<Actor | string | null | undefined>;
29
+ /** Shape of `config/flags_dashboard.ts`. */
30
+ export interface FlagsDashboardConfig {
31
+ /** Master switch. `false` registers no routes at all. Default `true`. */
32
+ enabled?: boolean;
33
+ /**
34
+ * URL prefix the console and its API mount under. Default `/flags`. The HTML is served at the
35
+ * prefix root; the JSON API lives under `<path>/api`. Every route is an EXACT path (no SPA
36
+ * catch-all), so the prefix can sit next to other routes safely.
37
+ */
38
+ path?: string;
39
+ /**
40
+ * Who may open the console: an inline function, an authorizer class (built through the
41
+ * container, so `@inject()` works), or a lazy import of one. For machine access use
42
+ * `authorizeByToken({ token })`.
43
+ *
44
+ * Omitted: the console is open outside production and answers every request with `403` in
45
+ * production; the provider logs a one-time warning at boot saying so.
46
+ */
47
+ authorize?: ConsoleAuthorize;
48
+ /**
49
+ * Who the acting person is, for the audit log and two-person approvals. Default: the signed-in
50
+ * user's id (`ctx.auth.user.id`, with `email`/`name` as the display name), else `'dashboard'`.
51
+ *
52
+ * With approvals on, two people only count as two when this tells them apart: everyone falling
53
+ * back to `'dashboard'` means nobody can approve anybody's request.
54
+ */
55
+ actor?: ActorResolver;
56
+ /** What a BROWSER sees when the guard refuses a page navigation. API calls always get JSON. */
57
+ accessDenied?: AccessDeniedOption;
58
+ }
59
+ /** A fully-resolved config — every field present (defaults applied). */
60
+ export interface ResolvedFlagsDashboardConfig {
61
+ enabled: boolean;
62
+ path: string;
63
+ authorize: ConsoleAuthorize | null;
64
+ actor: ActorResolver | null;
65
+ accessDenied: AccessDeniedOption | null;
66
+ }
67
+ /** Apply defaults to a partial config, producing a fully-resolved one. */
68
+ export declare function resolveConfig(config?: FlagsDashboardConfig): ResolvedFlagsDashboardConfig;
69
+ /** Identity helper giving `config/flags_dashboard.ts` full type-checking. */
70
+ export declare function defineConfig(config?: FlagsDashboardConfig): FlagsDashboardConfig;
71
+ //# sourceMappingURL=define_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/dashboard/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EACV,kBAAkB,IAAI,yBAAyB,EAC/C,oBAAoB,IAAI,2BAA2B,EACpD,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAClF,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;AAE5E,8FAA8F;AAC9F,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,WAAW,KACb,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,WAAW,KACb,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEpF,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,+FAA+F;IAC/F,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED,wEAAwE;AACxE,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzC;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,MAAM,GAAE,oBAAyB,GAAG,4BAA4B,CAW7F;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,MAAM,GAAE,oBAAyB,GAAG,oBAAoB,CAEpF"}
@@ -0,0 +1,18 @@
1
+ /** Apply defaults to a partial config, producing a fully-resolved one. */
2
+ export function resolveConfig(config = {}) {
3
+ const rawPath = config.path ?? '/flags';
4
+ // Normalize: ensure a single leading slash and no trailing slash (root stays '').
5
+ const trimmed = `/${rawPath.replace(/^\/+/, '').replace(/\/+$/, '')}`;
6
+ return {
7
+ enabled: config.enabled ?? true,
8
+ path: trimmed === '/' ? '' : trimmed,
9
+ authorize: config.authorize ?? null,
10
+ actor: config.actor ?? null,
11
+ accessDenied: config.accessDenied ?? null,
12
+ };
13
+ }
14
+ /** Identity helper giving `config/flags_dashboard.ts` full type-checking. */
15
+ export function defineConfig(config = {}) {
16
+ return config;
17
+ }
18
+ //# sourceMappingURL=define_config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/dashboard/define_config.ts"],"names":[],"mappings":"AAuFA,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,MAAM,GAAyB,EAAE;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC;IACxC,kFAAkF;IAClF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IACtE,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,IAAI,EAAE,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO;QACpC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;QACnC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI;QAC3B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;KAC1C,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,MAAM,GAAyB,EAAE;IAC5D,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,172 @@
1
+ import { type FlagDefinition, type JsonValue } from '@adonis-agora/flags-core';
2
+ import type { FlagDeclaration } from '../declare.js';
3
+ import type { FlagsRuntime } from '../runtime.js';
4
+ import { type Actor } from '../stores/store.js';
5
+ /**
6
+ * Framework-light JSON handlers for the flags console.
7
+ *
8
+ * Each handler takes {@link Deps} (the runtime — `getRuntime()` unless a test hands one over — and
9
+ * the acting person) and a plain {@link ApiRequest}, and returns a plain {@link ApiResponse}. No
10
+ * AdonisJS types leak in, so they are unit-testable against a real runtime with no HTTP server.
11
+ * Same `Deps` / `ApiRequest` / `ApiResponse` convention as the payments and durable consoles.
12
+ *
13
+ * Every WRITE goes through `FlagsAdmin` — never the store directly — so the console gets exactly
14
+ * the validation, authorization, approvals and audit trail the commands get. Errors map to HTTP:
15
+ * `ValidationError` → `422 { error, issues }`, `ForbiddenError` → `403`, a missing change request
16
+ * → `404`, one that is no longer pending → `409`.
17
+ *
18
+ * Every call takes an `environment` (query string for reads, body for writes); omitted, it is the
19
+ * environment this app evaluates.
20
+ */
21
+ /** What the handlers need to answer a request. */
22
+ export interface Deps {
23
+ /** The booted runtime. Default: {@link getRuntime}. */
24
+ runtime?: FlagsRuntime;
25
+ /** Who is acting — the audit log and the two-person rule are keyed on `actor.id`. */
26
+ actor: Actor;
27
+ /** Injectable clock (stale report). */
28
+ now?: () => Date;
29
+ }
30
+ /** The subset of an HTTP request the handlers read. */
31
+ export interface ApiRequest {
32
+ params: Record<string, string | undefined>;
33
+ query: Record<string, string | string[] | undefined>;
34
+ body?: unknown;
35
+ }
36
+ /** A plain JSON response: an HTTP status and a serializable body. */
37
+ export interface ApiResponse {
38
+ status: number;
39
+ body: unknown;
40
+ }
41
+ export declare const ok: (body: unknown) => ApiResponse;
42
+ /** An error that already knows its HTTP answer. */
43
+ export declare class HttpError extends Error {
44
+ readonly status: number;
45
+ readonly extra: Record<string, unknown>;
46
+ constructor(status: number, message: string, extra?: Record<string, unknown>);
47
+ }
48
+ /** Map anything a handler threw to the answer the SPA can show. */
49
+ export declare function errorResponse(error: unknown): ApiResponse;
50
+ /** A declaration as the console shows it: what the code says, and which apps say it. */
51
+ export interface DeclaredFlag extends FlagDeclaration {
52
+ apps: string[];
53
+ /** `code`: declared in an app's config (read-only here). `console`: created and edited here. */
54
+ source: 'code' | 'console';
55
+ }
56
+ /** What a flag serves to someone no rule or override matches. */
57
+ export type Serving =
58
+ /** Not in the ruleset: everyone gets the default declared in code. */
59
+ {
60
+ kind: 'default';
61
+ value: JsonValue | null;
62
+ }
63
+ /** Kill switch: everyone gets `offVariant`. */
64
+ | {
65
+ kind: 'off';
66
+ variant: string;
67
+ } | {
68
+ kind: 'fixed';
69
+ variant: string;
70
+ }
71
+ /** An on/off split: `percent`% get `on`. */
72
+ | {
73
+ kind: 'rollout';
74
+ percent: number;
75
+ } | {
76
+ kind: 'split';
77
+ arms: Array<{
78
+ variant: string;
79
+ percent: number;
80
+ }>;
81
+ bucketBy?: string;
82
+ };
83
+ /** The one-line "what does this serve" every flag row shows. */
84
+ export declare function servingSummary(definition: FlagDefinition | undefined, declaration?: FlagDeclaration): Serving;
85
+ /** `GET /api/meta` — what the shell needs: environments, approvals, who you are. */
86
+ export declare function meta(deps: Deps, _req: ApiRequest): Promise<ApiResponse>;
87
+ /** `GET /api/flags` — every flag in the ruleset or declared in code, with what it serves. */
88
+ export declare function listFlags(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
89
+ /** `GET /api/flags/:key` — one flag: its definition (stored, or what the declaration implies), its
90
+ * audit trail, schedules and pending requests, plus the names the editor offers. */
91
+ export declare function flagDetail(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
92
+ /** `PUT /api/flags/:key` `{ definition, note? }` — save the whole definition. */
93
+ export declare function saveFlag(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
94
+ /** `POST /api/flags` `{ key, declaration, note? }` — create a flag here, without code. */
95
+ export declare function createFlag(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
96
+ /** `PUT /api/flags/:key/declaration` `{ declaration, note? }` — edit a console flag's declaration. */
97
+ export declare function updateDeclaration(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
98
+ /** `DELETE /api/flags/:key` — remove the flag from the ruleset (the code default takes over). */
99
+ export declare function deleteFlag(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
100
+ /** `POST /api/flags/:key/enabled` `{ enabled }` — the kill switch. */
101
+ export declare function setEnabled(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
102
+ /** `POST /api/flags/:key/rollout` `{ percent }` — on/off flags only. */
103
+ export declare function setRollout(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
104
+ /** `POST /api/flags/:key/variant` `{ variant }` — serve one variant to everyone. */
105
+ export declare function setVariant(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
106
+ /** `POST /api/flags/:key/overrides` `{ subject, variant | null }` — force (or clear) one subject. */
107
+ export declare function setOverride(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
108
+ /**
109
+ * `POST /api/preview` `{ environment, change }` — would this edit be accepted? Answers `200` either
110
+ * way (`{ valid, issues }`): the editor calls it on every keystroke, and an invalid draft is the
111
+ * normal state of a form being typed into, not an error.
112
+ */
113
+ export declare function preview(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
114
+ /**
115
+ * `POST /api/evaluate` `{ environment, context, flag?, definition? }` — what a context would get.
116
+ *
117
+ * Evaluates with the engine directly against the environment's STORED ruleset, so it records no
118
+ * exposure and counts no usage: testing a rule must not enrol a fake user in an experiment. With
119
+ * `definition`, the unsaved draft is evaluated in place of the stored flag. Without `flag`, every
120
+ * flag is evaluated.
121
+ */
122
+ export declare function evaluateContext(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
123
+ /** `GET /api/segments` — every segment and the flags whose rules reference it. */
124
+ export declare function listSegments(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
125
+ /** `PUT /api/segments/:key` `{ segment, note? }`. */
126
+ export declare function saveSegment(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
127
+ /** `DELETE /api/segments/:key` — refused (422) while a rule still references it. */
128
+ export declare function deleteSegment(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
129
+ /** `GET /api/layers` — layers with their allocations, the global holdout, and every experiment. */
130
+ export declare function listLayers(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
131
+ /** `PUT /api/layers/:key` `{ layer, note? }`. */
132
+ export declare function saveLayer(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
133
+ /** `DELETE /api/layers/:key`. */
134
+ export declare function deleteLayer(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
135
+ /** `PUT /api/holdout` `{ holdout | null, note? }` — `null` removes the global holdout. */
136
+ export declare function saveHoldout(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
137
+ /** `GET /api/experiments` — configured experiments with a summary of their last results. */
138
+ export declare function listExperiments(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
139
+ /** `GET /api/experiments/:key` — the last computed results (the worker refreshes them). */
140
+ export declare function experimentDetail(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
141
+ /** `POST /api/experiments/:key/recompute` — compute the results now instead of at the next tick. */
142
+ export declare function recomputeExperiment(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
143
+ /** `GET /api/change-requests?status=pending|…|all`. */
144
+ export declare function listChangeRequests(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
145
+ /** `POST /api/change-requests/:id/approve` `{ note? }` — the requester cannot approve (403). */
146
+ export declare function approveChangeRequest(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
147
+ /** `POST /api/change-requests/:id/reject` `{ note? }`. */
148
+ export declare function rejectChangeRequest(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
149
+ /** `POST /api/change-requests/:id/cancel` — only the requester can withdraw their request. */
150
+ export declare function cancelChangeRequest(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
151
+ /** `GET /api/audit?entity&key&before&limit` — newest first; page with `before=<at of last row>`. */
152
+ export declare function audit(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
153
+ /** `GET /api/schedules?flag&status`. */
154
+ export declare function listSchedules(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
155
+ /**
156
+ * `POST /api/flags/:key/schedules` — either one change at a time
157
+ * (`{ kind: 'enable' | 'disable' | 'rollout', runAt, percent? }`) or a gradual rollout
158
+ * (`{ steps: [{ at, percent }] }`, one schedule per step).
159
+ */
160
+ export declare function createSchedule(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
161
+ /** `DELETE /api/schedules/:id` — only a pending schedule can be cancelled. */
162
+ export declare function cancelSchedule(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
163
+ /** `GET /api/export` — the environment's ruleset as JSON. */
164
+ export declare function exportRuleset(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
165
+ /** `POST /api/import` `{ ruleset, note? }` — replaces every flag, segment, layer and the holdout. */
166
+ export declare function importRuleset(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
167
+ /** `POST /api/promote` `{ from, to, note? }` — copy one environment's ruleset over another's. */
168
+ export declare function promote(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
169
+ /** `GET /api/stale?unusedDays&staticDays` — flags that probably should be removed. */
170
+ export declare function stale(deps: Deps, req: ApiRequest): Promise<ApiResponse>;
171
+ export declare function ops(deps: Deps, _req: ApiRequest): Promise<ApiResponse>;
172
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/dashboard/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAOf,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,KAAK,KAAK,EAOX,MAAM,oBAAoB,CAAC;AAU5B;;;;;;;;;;;;;;;GAeG;AAEH,kDAAkD;AAClD,MAAM,WAAW,IAAI;IACnB,uDAAuD;IACvD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qFAAqF;IACrF,KAAK,EAAE,KAAK,CAAC;IACb,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,EAAE,SAAU,OAAO,KAAG,WAAsC,CAAC;AAE1E,mDAAmD;AACnD,qBAAa,SAAU,SAAQ,KAAK;IAEhC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAEvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAHzC,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACN,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAG7C;CACF;AAKD,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAmBzD;AAgGD,wFAAwF;AACxF,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gGAAgG;IAChG,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AA0BD,iEAAiE;AACjE,MAAM,MAAM,OAAO;AACjB,sEAAsE;AACpE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;CAAE;AAC9C,+CAA+C;GAC7C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AACpC,4CAA4C;GAC1C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA0B5F,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,UAAU,EAAE,cAAc,GAAG,SAAS,EACtC,WAAW,CAAC,EAAE,eAAe,GAC5B,OAAO,CAIT;AAWD,oFAAoF;AACpF,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvE;AAID,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8B3E;AAED;qFACqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAqC5E;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB1E;AAqCD,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB5E;AAED,sGAAsG;AACtG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBnF;AAED,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAU5E;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAU5E;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAY5E;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAY5E;AAED,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAqB7E;AA8BD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBzE;AAcD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA2BjF;AAeD,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAS9E;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAe7E;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAY/E;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8B5E;AAED,iDAAiD;AACjD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAe3E;AAED,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAY7E;AAED,0FAA0F;AAC1F,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAc7E;AAQD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAuDjF;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAclF;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBrF;AAYD,uDAAuD;AACvD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBpF;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAItF;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAIrF;AAED,8FAA8F;AAC9F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAIrF;AAMD,oGAAoG;AACpG,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAuBvE;AAMD,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB/E;AAeD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAoChF;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAUhF;AAID,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAK/E;AAED,qGAAqG;AACrG,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAc/E;AAED,iGAAiG;AACjG,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAQzE;AAID,sFAAsF;AACtF,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAavE;AA6BD,wBAAgB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA6BtE"}