@workflow/core 5.0.0-beta.2 → 5.0.0-beta.21

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 (251) hide show
  1. package/dist/attribute-changes.d.ts +7 -0
  2. package/dist/attribute-changes.d.ts.map +1 -0
  3. package/dist/attribute-changes.js +25 -0
  4. package/dist/capabilities.d.ts +22 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +41 -4
  7. package/dist/capture-stack.d.ts +16 -0
  8. package/dist/capture-stack.d.ts.map +1 -0
  9. package/dist/capture-stack.js +21 -0
  10. package/dist/class-serialization.d.ts +32 -0
  11. package/dist/class-serialization.d.ts.map +1 -1
  12. package/dist/class-serialization.js +37 -1
  13. package/dist/classify-error.d.ts +11 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +59 -6
  16. package/dist/context-errors.d.ts +27 -0
  17. package/dist/context-errors.d.ts.map +1 -0
  18. package/dist/context-errors.js +101 -0
  19. package/dist/context-violation-error.d.ts +97 -0
  20. package/dist/context-violation-error.d.ts.map +1 -0
  21. package/dist/context-violation-error.js +147 -0
  22. package/dist/create-hook.d.ts +40 -1
  23. package/dist/create-hook.d.ts.map +1 -1
  24. package/dist/create-hook.js +4 -3
  25. package/dist/define-hook.d.ts.map +1 -1
  26. package/dist/define-hook.js +20 -5
  27. package/dist/describe-error.d.ts +70 -0
  28. package/dist/describe-error.d.ts.map +1 -0
  29. package/dist/describe-error.js +165 -0
  30. package/dist/encryption.d.ts +22 -1
  31. package/dist/encryption.d.ts.map +1 -1
  32. package/dist/encryption.js +72 -27
  33. package/dist/events-consumer.d.ts +24 -0
  34. package/dist/events-consumer.d.ts.map +1 -1
  35. package/dist/events-consumer.js +79 -16
  36. package/dist/flushable-stream.d.ts +10 -10
  37. package/dist/flushable-stream.d.ts.map +1 -1
  38. package/dist/flushable-stream.js +18 -13
  39. package/dist/global.d.ts +15 -1
  40. package/dist/global.d.ts.map +1 -1
  41. package/dist/global.js +21 -3
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +2 -1
  45. package/dist/log-format.d.ts +25 -0
  46. package/dist/log-format.d.ts.map +1 -0
  47. package/dist/log-format.js +250 -0
  48. package/dist/logger.d.ts +28 -30
  49. package/dist/logger.d.ts.map +1 -1
  50. package/dist/logger.js +77 -31
  51. package/dist/private.d.ts +107 -2
  52. package/dist/private.d.ts.map +1 -1
  53. package/dist/private.js +80 -3
  54. package/dist/runtime/constants.d.ts +121 -0
  55. package/dist/runtime/constants.d.ts.map +1 -1
  56. package/dist/runtime/constants.js +206 -8
  57. package/dist/runtime/get-port-lazy.d.ts +25 -0
  58. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  59. package/dist/runtime/get-port-lazy.js +92 -0
  60. package/dist/runtime/get-world-lazy.d.ts +32 -0
  61. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  62. package/dist/runtime/get-world-lazy.js +56 -0
  63. package/dist/runtime/helpers.d.ts +50 -7
  64. package/dist/runtime/helpers.d.ts.map +1 -1
  65. package/dist/runtime/helpers.js +149 -31
  66. package/dist/runtime/replay-budget.d.ts +98 -0
  67. package/dist/runtime/replay-budget.d.ts.map +1 -0
  68. package/dist/runtime/replay-budget.js +191 -0
  69. package/dist/runtime/resume-hook.d.ts.map +1 -1
  70. package/dist/runtime/resume-hook.js +39 -23
  71. package/dist/runtime/run-id-time.d.ts +10 -0
  72. package/dist/runtime/run-id-time.d.ts.map +1 -0
  73. package/dist/runtime/run-id-time.js +31 -0
  74. package/dist/runtime/run.d.ts.map +1 -1
  75. package/dist/runtime/run.js +44 -9
  76. package/dist/runtime/runs.d.ts.map +1 -1
  77. package/dist/runtime/runs.js +4 -1
  78. package/dist/runtime/start.d.ts +30 -1
  79. package/dist/runtime/start.d.ts.map +1 -1
  80. package/dist/runtime/start.js +138 -20
  81. package/dist/runtime/step-executor.d.ts +108 -0
  82. package/dist/runtime/step-executor.d.ts.map +1 -0
  83. package/dist/runtime/step-executor.js +715 -0
  84. package/dist/runtime/step-handler.d.ts.map +1 -1
  85. package/dist/runtime/step-handler.js +715 -556
  86. package/dist/runtime/suspension-handler.d.ts +74 -7
  87. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  88. package/dist/runtime/suspension-handler.js +308 -116
  89. package/dist/runtime/wait-continuation.d.ts +84 -0
  90. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  91. package/dist/runtime/wait-continuation.js +92 -0
  92. package/dist/runtime/wait-until.d.ts +18 -0
  93. package/dist/runtime/wait-until.d.ts.map +1 -0
  94. package/dist/runtime/wait-until.js +42 -0
  95. package/dist/runtime/world-init.d.ts +75 -0
  96. package/dist/runtime/world-init.d.ts.map +1 -0
  97. package/dist/runtime/world-init.js +75 -0
  98. package/dist/runtime/world.d.ts.map +1 -1
  99. package/dist/runtime/world.js +47 -18
  100. package/dist/runtime.d.ts +11 -8
  101. package/dist/runtime.d.ts.map +1 -1
  102. package/dist/runtime.js +1395 -319
  103. package/dist/schemas.d.ts +1 -1
  104. package/dist/schemas.d.ts.map +1 -1
  105. package/dist/schemas.js +1 -1
  106. package/dist/serialization/client.d.ts +17 -0
  107. package/dist/serialization/client.d.ts.map +1 -0
  108. package/dist/serialization/client.js +48 -0
  109. package/dist/serialization/codec-devalue.d.ts +14 -0
  110. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  111. package/dist/serialization/codec-devalue.js +98 -0
  112. package/dist/serialization/codec.d.ts +106 -0
  113. package/dist/serialization/codec.d.ts.map +1 -0
  114. package/dist/serialization/codec.js +17 -0
  115. package/dist/serialization/compression.d.ts +104 -0
  116. package/dist/serialization/compression.d.ts.map +1 -0
  117. package/dist/serialization/compression.js +260 -0
  118. package/dist/serialization/encryption.d.ts +33 -0
  119. package/dist/serialization/encryption.d.ts.map +1 -0
  120. package/dist/serialization/encryption.js +70 -0
  121. package/dist/serialization/errors.d.ts +34 -0
  122. package/dist/serialization/errors.d.ts.map +1 -0
  123. package/dist/serialization/errors.js +59 -0
  124. package/dist/serialization/format.d.ts +60 -0
  125. package/dist/serialization/format.d.ts.map +1 -0
  126. package/dist/serialization/format.js +97 -0
  127. package/dist/serialization/index.d.ts +19 -0
  128. package/dist/serialization/index.d.ts.map +1 -0
  129. package/dist/serialization/index.js +22 -0
  130. package/dist/serialization/reducers/class.d.ts +11 -0
  131. package/dist/serialization/reducers/class.d.ts.map +1 -0
  132. package/dist/serialization/reducers/class.js +68 -0
  133. package/dist/serialization/reducers/common.d.ts +16 -0
  134. package/dist/serialization/reducers/common.d.ts.map +1 -0
  135. package/dist/serialization/reducers/common.js +417 -0
  136. package/dist/serialization/reducers/step-function.d.ts +35 -0
  137. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  138. package/dist/serialization/reducers/step-function.js +88 -0
  139. package/dist/serialization/step.d.ts +17 -0
  140. package/dist/serialization/step.d.ts.map +1 -0
  141. package/dist/serialization/step.js +48 -0
  142. package/dist/serialization/types.d.ts +253 -0
  143. package/dist/serialization/types.d.ts.map +1 -0
  144. package/dist/serialization/types.js +25 -0
  145. package/dist/serialization/workflow.d.ts +29 -0
  146. package/dist/serialization/workflow.d.ts.map +1 -0
  147. package/dist/serialization/workflow.js +54 -0
  148. package/dist/serialization-format.d.ts +15 -0
  149. package/dist/serialization-format.d.ts.map +1 -1
  150. package/dist/serialization-format.js +209 -11
  151. package/dist/serialization.d.ts +313 -214
  152. package/dist/serialization.d.ts.map +1 -1
  153. package/dist/serialization.js +1430 -658
  154. package/dist/set-attributes.d.ts +13 -0
  155. package/dist/set-attributes.d.ts.map +1 -0
  156. package/dist/set-attributes.js +42 -0
  157. package/dist/sleep.d.ts.map +1 -1
  158. package/dist/sleep.js +3 -2
  159. package/dist/source-map.d.ts +5 -0
  160. package/dist/source-map.d.ts.map +1 -1
  161. package/dist/source-map.js +102 -10
  162. package/dist/step/context-storage.d.ts +43 -0
  163. package/dist/step/context-storage.d.ts.map +1 -1
  164. package/dist/step/context-storage.js +1 -1
  165. package/dist/step/get-closure-vars.d.ts.map +1 -1
  166. package/dist/step/get-closure-vars.js +3 -2
  167. package/dist/step/get-step-metadata.d.ts.map +1 -1
  168. package/dist/step/get-step-metadata.js +3 -2
  169. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  170. package/dist/step/get-workflow-metadata.js +3 -2
  171. package/dist/step/writable-stream.d.ts.map +1 -1
  172. package/dist/step/writable-stream.js +49 -5
  173. package/dist/step-hydration-cache.d.ts +148 -0
  174. package/dist/step-hydration-cache.d.ts.map +1 -0
  175. package/dist/step-hydration-cache.js +171 -0
  176. package/dist/step.d.ts.map +1 -1
  177. package/dist/step.js +115 -21
  178. package/dist/symbols.d.ts +28 -0
  179. package/dist/symbols.d.ts.map +1 -1
  180. package/dist/symbols.js +29 -1
  181. package/dist/telemetry/semantic-conventions.d.ts +30 -2
  182. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  183. package/dist/telemetry/semantic-conventions.js +21 -1
  184. package/dist/telemetry.d.ts +60 -0
  185. package/dist/telemetry.d.ts.map +1 -1
  186. package/dist/telemetry.js +82 -4
  187. package/dist/types.d.ts +6 -0
  188. package/dist/types.d.ts.map +1 -1
  189. package/dist/types.js +23 -1
  190. package/dist/util.d.ts +16 -6
  191. package/dist/util.d.ts.map +1 -1
  192. package/dist/util.js +25 -16
  193. package/dist/version.d.ts +1 -1
  194. package/dist/version.d.ts.map +1 -1
  195. package/dist/version.js +2 -2
  196. package/dist/vm/index.d.ts.map +1 -1
  197. package/dist/vm/index.js +3 -2
  198. package/dist/vm/script-cache.d.ts +28 -0
  199. package/dist/vm/script-cache.d.ts.map +1 -0
  200. package/dist/vm/script-cache.js +140 -0
  201. package/dist/workflow/abort-controller.d.ts +65 -0
  202. package/dist/workflow/abort-controller.d.ts.map +1 -0
  203. package/dist/workflow/abort-controller.js +277 -0
  204. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  205. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  206. package/dist/workflow/attribute-dispatcher.js +48 -0
  207. package/dist/workflow/create-hook.d.ts.map +1 -1
  208. package/dist/workflow/create-hook.js +23 -2
  209. package/dist/workflow/define-hook.d.ts +1 -1
  210. package/dist/workflow/define-hook.d.ts.map +1 -1
  211. package/dist/workflow/define-hook.js +8 -4
  212. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  213. package/dist/workflow/get-workflow-metadata.js +14 -3
  214. package/dist/workflow/hook.d.ts.map +1 -1
  215. package/dist/workflow/hook.js +207 -33
  216. package/dist/workflow/index.d.ts +1 -0
  217. package/dist/workflow/index.d.ts.map +1 -1
  218. package/dist/workflow/index.js +5 -3
  219. package/dist/workflow/set-attributes.d.ts +73 -0
  220. package/dist/workflow/set-attributes.d.ts.map +1 -0
  221. package/dist/workflow/set-attributes.js +65 -0
  222. package/dist/workflow/sleep.d.ts.map +1 -1
  223. package/dist/workflow/sleep.js +45 -8
  224. package/dist/workflow/world-init-stub.d.ts +15 -0
  225. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  226. package/dist/workflow/world-init-stub.js +15 -0
  227. package/dist/workflow.d.ts +10 -1
  228. package/dist/workflow.d.ts.map +1 -1
  229. package/dist/workflow.js +168 -49
  230. package/docs/api-reference/create-hook.mdx +38 -0
  231. package/docs/api-reference/create-webhook.mdx +1 -0
  232. package/docs/api-reference/experimental-set-attributes.mdx +65 -0
  233. package/docs/api-reference/fetch.mdx +5 -0
  234. package/docs/api-reference/index.mdx +3 -0
  235. package/docs/foundations/cancellation.mdx +459 -0
  236. package/docs/foundations/errors-and-retries.mdx +7 -3
  237. package/docs/foundations/hooks.mdx +29 -0
  238. package/docs/foundations/idempotency.mdx +236 -11
  239. package/docs/foundations/index.mdx +3 -3
  240. package/docs/foundations/meta.json +3 -2
  241. package/docs/foundations/serialization.mdx +78 -42
  242. package/docs/foundations/starting-workflows.mdx +6 -2
  243. package/docs/foundations/streaming.mdx +14 -23
  244. package/docs/foundations/versioning.mdx +263 -0
  245. package/docs/how-it-works/cancellation.mdx +287 -0
  246. package/docs/how-it-works/code-transform.mdx +2 -2
  247. package/docs/how-it-works/encryption.mdx +2 -2
  248. package/docs/how-it-works/event-sourcing.mdx +2 -2
  249. package/docs/how-it-works/meta.json +2 -1
  250. package/package.json +22 -10
  251. package/docs/foundations/common-patterns.mdx +0 -265
@@ -1,24 +1,91 @@
1
1
  import type { Span } from '@opentelemetry/api';
2
- import { type WorkflowRun, type World } from '@workflow/world';
3
- import type { WorkflowSuspension } from '../global.js';
2
+ import { type SerializedData, type WorkflowRun, type World } from '@workflow/world';
3
+ import type { StepInvocationQueueItem, WorkflowSuspension } from '../global.js';
4
4
  export interface SuspensionHandlerParams {
5
5
  suspension: WorkflowSuspension;
6
6
  world: World;
7
7
  run: WorkflowRun;
8
8
  span?: Span;
9
9
  requestId?: string;
10
+ /**
11
+ * Turbo mode only: a promise that resolves once the backgrounded
12
+ * `run_started` has landed (the run exists). When present, every world write
13
+ * this suspension performs (`hook_created`, `wait_created`, eager overflow
14
+ * `step_created`, …) is gated on it so the write never races ahead of the
15
+ * run's creation. The pure inline hot path defers all of its steps and writes
16
+ * nothing here, so it never awaits this barrier. `undefined` outside turbo,
17
+ * where `run_started` was already awaited up front.
18
+ */
19
+ runReadyBarrier?: Promise<unknown>;
10
20
  }
21
+ /**
22
+ * Result of handling a suspension. Returns pending step items so the caller
23
+ * can decide which to execute inline vs queue to background.
24
+ */
11
25
  export interface SuspensionHandlerResult {
12
- timeoutSeconds?: number;
26
+ /** Pending step items with events created but NOT queued */
27
+ pendingSteps: StepInvocationQueueItem[];
28
+ /**
29
+ * Correlation IDs for which this suspension call actually wrote the
30
+ * step_created event (as opposed to catching EntityConflictError because
31
+ * a concurrent handler wrote it first). Only the handler that wrote the
32
+ * step_created event should queue / inline-execute the step — this
33
+ * guarantees a single owner per step, even when multiple handlers race
34
+ * into the same batch boundary.
35
+ */
36
+ createdStepCorrelationIds: Set<string>;
37
+ /**
38
+ * The steps whose `step_created` writes were intentionally deferred so the
39
+ * caller can run them inline via lazy `step_started` events (which create
40
+ * the step on the fly), saving one world round-trip per inline step. Up to
41
+ * `getMaxInlineSteps()` steps are deferred; the caller runs them inline in
42
+ * parallel and queues the rest. Empty when no step was deferred (nothing
43
+ * pending, or a `hook.getConflict()` awaiter is present so nothing is
44
+ * executed inline). The caller passes each `dehydratedInput` straight to
45
+ * `executeStep`, which sends it as the `step_started` payload. The atomic
46
+ * create-claim inside each `step_started` is the exactly-one-owner gate that
47
+ * the standalone `step_created` provided before: the loser of the race gets
48
+ * `EntityConflictError` → `skipped` and does not run the body.
49
+ */
50
+ lazyInlineSteps: Array<{
51
+ correlationId: string;
52
+ stepName: string;
53
+ dehydratedInput: SerializedData;
54
+ }>;
55
+ /**
56
+ * The soonest pending wait, if any: seconds until it elapses and the
57
+ * correlationId of the wait that produced that timeout. The
58
+ * correlationId seeds the idempotency key for the wait-continuation
59
+ * queue message so that repeated suspension passes over the same
60
+ * pending wait collapse into a single delayed continuation.
61
+ */
62
+ waitTimeout?: {
63
+ seconds: number;
64
+ correlationId: string;
65
+ };
66
+ /** Whether a hook conflict was detected (should re-invoke immediately) */
67
+ hasHookConflict: boolean;
68
+ /** Whether a `hook.getConflict()` awaiter needs the workflow to continue immediately */
69
+ hasAwaitedHookCreation: boolean;
70
+ /** Whether native workflow attribute events were written for replay. */
71
+ hasAttributeEvents: boolean;
72
+ /**
73
+ * Whether this suspension created any hook (`hook_created`) events. Unlike
74
+ * `hasHookConflict` / `hasAwaitedHookCreation`, this is true even for a plain
75
+ * fire-and-forget hook with no conflict and no awaiter. Turbo mode uses it to
76
+ * detect "a hook was created this suspension" and stop forcing optimistic
77
+ * inline start (a hook introduces later resume invocations that could race).
78
+ */
79
+ hasHookEvents: boolean;
13
80
  }
14
81
  /**
15
82
  * Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
16
- * Uses an event-sourced architecture where entities (steps, hooks) are created atomically
17
- * with their corresponding events via events.create().
83
+ * Creates events for all operations but does NOT queue step messages — returns the pending
84
+ * steps so the caller can decide which to execute inline vs queue to background.
18
85
  *
19
86
  * Processing order:
20
87
  * 1. Hooks are processed first to prevent race conditions with webhook receivers
21
- * 2. Steps and waits are processed in parallel after hooks complete
88
+ * 2. Step events and wait events are created in parallel
22
89
  */
23
- export declare function handleSuspension({ suspension, world, run, span, requestId, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
90
+ export declare function handleSuspension({ suspension, world, run, span, requestId, runReadyBarrier, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
24
91
  //# sourceMappingURL=suspension-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAO/C,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAwBtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,GACV,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAgS5D"}
1
+ {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,OAAO,EAGL,KAAK,cAAc,EAGnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAGV,uBAAuB,EAEvB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,YAAY,EAAE,uBAAuB,EAAE,CAAC;IACxC;;;;;;;OAOG;IACH,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;;;;;;;OAYG;IACH,eAAe,EAAE,KAAK,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,cAAc,CAAC;KACjC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAgED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,EACT,eAAe,GAChB,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAyd5D"}