@devultur/convex 1.0.3 → 1.2.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 (47) hide show
  1. package/README.md +126 -0
  2. package/dist/bin/init.js +1 -0
  3. package/dist/{chunk-FHWT3GD6.js → chunk-GKLFRSGI.js} +2 -0
  4. package/dist/component/_generated/api.d.ts +12 -0
  5. package/dist/component/_generated/api.d.ts.map +1 -1
  6. package/dist/component/_generated/api.js.map +1 -1
  7. package/dist/component/_generated/component.d.ts +49 -0
  8. package/dist/component/_generated/component.d.ts.map +1 -1
  9. package/dist/component/lock.d.ts +33 -0
  10. package/dist/component/lock.d.ts.map +1 -0
  11. package/dist/component/lock.js +47 -0
  12. package/dist/component/lock.js.map +1 -0
  13. package/dist/component/lockValidators.d.ts +25 -0
  14. package/dist/component/lockValidators.d.ts.map +1 -0
  15. package/dist/component/lockValidators.js +14 -0
  16. package/dist/component/lockValidators.js.map +1 -0
  17. package/dist/component/mediaClient.d.ts +3 -0
  18. package/dist/component/mediaClient.d.ts.map +1 -0
  19. package/dist/component/mediaClient.js +7 -0
  20. package/dist/component/mediaClient.js.map +1 -0
  21. package/dist/component/public.d.ts +72 -0
  22. package/dist/component/public.d.ts.map +1 -1
  23. package/dist/component/public.js +48 -13
  24. package/dist/component/public.js.map +1 -1
  25. package/dist/component/schema.d.ts +10 -1
  26. package/dist/component/schema.d.ts.map +1 -1
  27. package/dist/component/schema.js +10 -1
  28. package/dist/component/schema.js.map +1 -1
  29. package/dist/component/uploadKeys.d.ts +14 -0
  30. package/dist/component/uploadKeys.d.ts.map +1 -0
  31. package/dist/component/uploadKeys.js +23 -0
  32. package/dist/component/uploadKeys.js.map +1 -0
  33. package/dist/component/uploads.d.ts +119 -0
  34. package/dist/component/uploads.d.ts.map +1 -0
  35. package/dist/component/uploads.js +106 -0
  36. package/dist/component/uploads.js.map +1 -0
  37. package/dist/component/workerErrors.d.ts +17 -0
  38. package/dist/component/workerErrors.d.ts.map +1 -0
  39. package/dist/component/workerErrors.js +41 -0
  40. package/dist/component/workerErrors.js.map +1 -0
  41. package/dist/index.d.ts +138 -4
  42. package/dist/index.js +102 -4
  43. package/dist/react.d.ts +18 -5
  44. package/dist/react.js +35 -13
  45. package/dist/validators.d.ts +5 -3
  46. package/dist/validators.js +1 -1
  47. package/package.json +7 -3
package/README.md CHANGED
@@ -67,6 +67,94 @@ function CoverUpload({ onSaved }) {
67
67
  }
68
68
  ```
69
69
 
70
+ ## Upload progress
71
+
72
+ `upload(file, { onProgress, signal })` reports the PUT's progress and resolves to the stored reference:
73
+
74
+ ```tsx
75
+ const { upload } = useDevultur();
76
+
77
+ const media = await upload(file, {
78
+ onProgress: ({ loadedBytes, totalBytes, fraction }) => setPercent(Math.round(fraction * 100)),
79
+ signal: controller.signal, // aborts the PUT; upload() rejects with an AbortError
80
+ });
81
+ media.key; // the uploaded object's key ("private/image/<id>/<name>"; a video's raw file)
82
+ await saveCover({ cover: media }); // a DevulturMedia: stores as-is in a dv.media() field, key included
83
+ ```
84
+
85
+ The PUT goes through `XMLHttpRequest` (`fetch` reports no upload progress), in parts for large files. `key` is an
86
+ optional field of `DevulturMedia` and of `dv.media()` (since 1.1.0), so references stored without it stay valid. It
87
+ is informational: delivery URLs are still derived from `id`, `kind`, `visibility` and `filename`.
88
+
89
+ ## Media library
90
+
91
+ Every upload, whatever its kind, gets a record in the component's `media` table once its bytes are stored, so
92
+ `listMedia` lists your images, files and videos:
93
+
94
+ ```typescript
95
+ // convex/library.ts
96
+ import { Devultur, mediaFromRecord } from "@devultur/convex";
97
+ import { query } from "./_generated/server";
98
+ import { components } from "./_generated/api";
99
+
100
+ const devultur = new Devultur(components.devultur);
101
+
102
+ export const images = query({
103
+ args: {},
104
+ handler: async (ctx) => {
105
+ // Check who's asking first: listMedia returns every record, of every user.
106
+ const records = await devultur.listMedia(ctx, { type: "image" }); // or "video" | "file", or no filter
107
+ return records.map((record) => ({ record, media: mediaFromRecord(record) }));
108
+ },
109
+ });
110
+ ```
111
+
112
+ `listMedia` reads every record at once: fine for a handful, unbounded for a library. Page a library with
113
+ `listMediaPage`, newest first, on a `by_type` index:
114
+
115
+ ```typescript
116
+ import { paginationOptsValidator } from "convex/server";
117
+ import { v } from "convex/values";
118
+
119
+ export const imagesPage = query({
120
+ args: { paginationOpts: paginationOptsValidator },
121
+ handler: async (ctx, { paginationOpts }) => {
122
+ // Check who's asking first.
123
+ return devultur.listMediaPage(ctx, { type: "image", paginationOpts });
124
+ },
125
+ });
126
+ // React: usePaginatedQuery(api.library.imagesPage, {}, { initialNumItems: 24 })
127
+ ```
128
+
129
+ `Devultur.exposeApi` also returns a `listMediaPage` query (`{ type?, paginationOpts }`). It lists every user's media,
130
+ so export it only when every caller may see the whole library.
131
+
132
+ A record is written only after the Worker confirms the object exists, so an abandoned upload never shows up:
133
+
134
+ 1. After its PUT, the client calls `confirmUpload({ key, filename, width, height })`. The component asks the Worker
135
+ for the object (a `HEAD`) and records its size and content type. `useDevultur().upload()` and `useMediaUpload` do
136
+ this for you when the `api` you pass `<DevulturProvider>` has `confirmUpload` (add it to the functions you export
137
+ from `Devultur.exposeApi` in `convex/devultur.ts`). From your server: `devultur.confirmUpload(ctx, { key })`.
138
+ 2. `createUploadUrl` also schedules the same check for 25 hours later, past the longest an upload can take. An upload
139
+ whose client never confirmed is recorded then; one that was never stored, or was deleted, isn't.
140
+
141
+ A record's `key` is the media id for every kind (what `getMedia` takes), and `objectKey` is the uploaded object's key.
142
+ `confirmUpload` only accepts upload keys (`{visibility}/{image|file}/{id}/{name}`, `{visibility}/video/{id}/raw/{name}`)
143
+ and is idempotent: a video's transcode state stays as it is.
144
+
145
+ `confirmUpload`, like every function `exposeApi` returns (and the `devultur-init` template exports), has no auth of
146
+ its own: anyone who can call your Convex deployment can call it. Wrap it with your app's auth, as you would the other
147
+ exposed functions: export your own action that checks `ctx.auth` and then calls `devultur.confirmUpload(ctx, { key })`.
148
+ The caller only names the key: the record's visibility, size and content type come from the Worker's `HEAD` of the
149
+ object, never from the arguments.
150
+
151
+ `deleteMedia` removes an image's or a file's record once
152
+ the Worker deleted the object (a delete refused by a lock keeps it). `deleteVideo` removes a video's.
153
+
154
+ Records from before 1.1.0 (and a video only `processVideo` recorded) have no `visibility` or `objectKey`;
155
+ `mediaFromRecord` returns `null` for them. Nothing needs migrating: the new fields are optional. `listMedia` doesn't
156
+ report an object's lock: read it from an action with `devultur.getLock(ctx, record.objectKey)`.
157
+
70
158
  ## Using a self-hosted Worker
71
159
 
72
160
  The component talks to any Worker built with `createWorker()` from
@@ -115,6 +203,44 @@ webhooks with the `webhookCredential` your plugin sets in the request state (or
115
203
  none; see [Plugins](https://github.com/devultur/devultur/blob/main/docs/guides/plugins.md)). Set `DEVULTUR_SECRET`
116
204
  to that value, and make sure your plugin also accepts it as the bearer of the component's calls.
117
205
 
206
+ ## Errors
207
+
208
+ When the media Worker refuses a request, component actions throw a `ConvexError` whose `data` is
209
+ `{ code, message, status, details? }`. A plain `Error` would lose these fields across the component boundary. `code` is
210
+ the Worker's stable code: for example `retention_active`, `compliance_extend_only`, `lock_conflict`,
211
+ `lock_privilege_required`, `file_too_large`, or `worker_error` when the Worker sent none. `details` carries the rest of
212
+ the Worker's answer, such as the `{ key, mode, until, hold }` of a `retention_active`.
213
+
214
+ ```ts
215
+ import { devulturErrorOf } from "@devultur/convex";
216
+
217
+ try {
218
+ await devultur.setLock(ctx, key, { until });
219
+ } catch (error) {
220
+ const refusal = devulturErrorOf(error); // null when it isn't a Worker refusal
221
+ if (refusal?.code === "compliance_extend_only") {
222
+ // the date can only move later
223
+ }
224
+ throw error;
225
+ }
226
+ ```
227
+
228
+ `isDevulturError(error)` is the matching type guard. Errors that aren't Worker refusals, such as a network failure,
229
+ are rethrown unchanged.
230
+
231
+ ## Object lock
232
+
233
+ - `devultur.createUploadUrl(ctx, { filename, contentType, lock, hold })` locks a file from its first write.
234
+ - `devultur.getLock(ctx, key)` and `devultur.setLock(ctx, key, { mode, until, period, derivatives })` read and change
235
+ a file's retention.
236
+ - `devultur.setHold(ctx, keys)` and `devultur.releaseHold(ctx, keys)` set and release holds.
237
+
238
+ These are server-side calls: `exposeApi` never lets a browser choose or change a lock. Its `createUploadUrl` applies
239
+ `config.upload.lock` instead. A bulk hold by prefix runs on your server with `@devultur/core`'s
240
+ `createWorkerClient(...).lock.holdAll({ prefix })`. The
241
+ [Retention and holds](https://github.com/devultur/devultur/blob/main/docs/guides/object-lock.md) guide covers the model,
242
+ what's enforced and the caveats.
243
+
118
244
  ## Documentation
119
245
 
120
246
  Guides and API reference: [github.com/devultur/devultur/tree/main/docs](https://github.com/devultur/devultur/tree/main/docs).
package/dist/bin/init.js CHANGED
@@ -76,6 +76,7 @@ import { components } from "./_generated/api";
76
76
  export const {
77
77
  issueViewerToken,
78
78
  createUploadUrl,
79
+ confirmUpload,
79
80
  deleteMedia,
80
81
  deleteVideo,
81
82
  processVideo,
@@ -4,6 +4,8 @@ var mediaFields = {
4
4
  id: v.string(),
5
5
  visibility: v.union(v.literal("public"), v.literal("private")),
6
6
  filename: v.optional(v.string()),
7
+ // The uploaded object's key, as `upload()` returns it. Optional: references stored before it stay valid.
8
+ key: v.optional(v.string()),
7
9
  width: v.optional(v.number()),
8
10
  height: v.optional(v.number())
9
11
  };
@@ -7,11 +7,23 @@
7
7
  * @module
8
8
  */
9
9
  import type * as http from "../http.js";
10
+ import type * as lock from "../lock.js";
11
+ import type * as lockValidators from "../lockValidators.js";
12
+ import type * as mediaClient from "../mediaClient.js";
10
13
  import type * as public_ from "../public.js";
14
+ import type * as uploadKeys from "../uploadKeys.js";
15
+ import type * as uploads from "../uploads.js";
16
+ import type * as workerErrors from "../workerErrors.js";
11
17
  import type { ApiFromModules, FilterApi, FunctionReference } from "convex/server";
12
18
  declare const fullApi: ApiFromModules<{
13
19
  http: typeof http;
20
+ lock: typeof lock;
21
+ lockValidators: typeof lockValidators;
22
+ mediaClient: typeof mediaClient;
14
23
  public: typeof public_;
24
+ uploadKeys: typeof uploadKeys;
25
+ uploads: typeof uploads;
26
+ workerErrors: typeof workerErrors;
15
27
  }>;
16
28
  /**
17
29
  * A utility for referencing Convex functions in your app's public API.
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,OAAO,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,OAAO,CAAC;CACxB,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,cAAc,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,KAAK,OAAO,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,WAAW,EAAE,OAAO,WAAW,CAAC;IAChC,MAAM,EAAE,OAAO,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,YAAY,CAAC;CACnC,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAUH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAGR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAgBH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GASR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
@@ -19,6 +19,26 @@ import type { FunctionReference } from "convex/server";
19
19
  * ```
20
20
  */
21
21
  export type ComponentApi<Name extends string | undefined = string | undefined> = {
22
+ lock: {
23
+ getLock: FunctionReference<"action", "internal", {
24
+ key: string;
25
+ }, any, Name>;
26
+ releaseHold: FunctionReference<"action", "internal", {
27
+ keys: Array<string>;
28
+ }, any, Name>;
29
+ setHold: FunctionReference<"action", "internal", {
30
+ keys: Array<string>;
31
+ }, any, Name>;
32
+ setLock: FunctionReference<"action", "internal", {
33
+ bypassGovernance?: boolean;
34
+ derivatives?: "inherit" | "original-only";
35
+ key: string;
36
+ mode?: "governance" | "compliance";
37
+ period?: number;
38
+ remove?: true;
39
+ until?: string;
40
+ }, any, Name>;
41
+ };
22
42
  public: {
23
43
  createMedia: FunctionReference<"mutation", "internal", {
24
44
  contentType: string;
@@ -30,6 +50,16 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
30
50
  createUploadUrl: FunctionReference<"action", "internal", {
31
51
  contentType: string;
32
52
  filename: string;
53
+ hold?: boolean;
54
+ lock?: {
55
+ hold?: boolean;
56
+ retention?: {
57
+ derivatives?: "inherit" | "original-only";
58
+ mode: "governance" | "compliance";
59
+ period?: number;
60
+ until?: string;
61
+ };
62
+ };
33
63
  visibility?: "public" | "private";
34
64
  }, any, Name>;
35
65
  deleteMediaAction: FunctionReference<"action", "internal", {
@@ -55,6 +85,17 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
55
85
  listMedia: FunctionReference<"query", "internal", {
56
86
  type?: "video" | "image" | "file";
57
87
  }, any, Name>;
88
+ listMediaPage: FunctionReference<"query", "internal", {
89
+ paginationOpts: {
90
+ cursor: string | null;
91
+ endCursor?: string | null;
92
+ id?: number;
93
+ maximumBytesRead?: number;
94
+ maximumRowsRead?: number;
95
+ numItems: number;
96
+ };
97
+ type?: "video" | "image" | "file";
98
+ }, any, Name>;
58
99
  loadProgress: FunctionReference<"query", "internal", {
59
100
  userId: string;
60
101
  videoId: string;
@@ -101,5 +142,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
101
142
  vttUrl: string;
102
143
  }, any, Name>;
103
144
  };
145
+ uploads: {
146
+ confirmUpload: FunctionReference<"action", "internal", {
147
+ filename?: string;
148
+ height?: number;
149
+ key: string;
150
+ width?: number;
151
+ }, any, Name>;
152
+ };
104
153
  };
105
154
  //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,IAC3E;IACE,MAAM,EAAE;QACN,WAAW,EAAE,iBAAiB,CAC5B,UAAU,EACV,UAAU,EACV;YACE,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,GAAG,EAAE,MAAM,CAAC;YACZ,SAAS,EAAE,MAAM,CAAC;YAClB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;SAClC,EACD,GAAG,EACH,IAAI,CACL,CAAC;QACF,eAAe,EAAE,iBAAiB,CAChC,QAAQ,EACR,UAAU,EACV;YACE,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;SACnC,EACD,GAAG,EACH,IAAI,CACL,CAAC;QACF,iBAAiB,EAAE,iBAAiB,CAClC,QAAQ,EACR,UAAU,EACV;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,EACf,GAAG,EACH,IAAI,CACL,CAAC;QACF,WAAW,EAAE,iBAAiB,CAC5B,QAAQ,EACR,UAAU,EACV;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;SAAE,EACtD,GAAG,EACH,IAAI,CACL,CAAC;QACF,iBAAiB,EAAE,iBAAiB,CAClC,OAAO,EACP,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;SAAE,EAC3C,GAAG,EACH,IAAI,CACL,CAAC;QACF,aAAa,EAAE,iBAAiB,CAC9B,OAAO,EACP,UAAU,EACV;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,EACf,GAAG,EACH,IAAI,CACL,CAAC;QACF,gBAAgB,EAAE,iBAAiB,CACjC,QAAQ,EACR,UAAU,EACV;YAAE,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,EAC1B,GAAG,EACH,IAAI,CACL,CAAC;QACF,mBAAmB,EAAE,iBAAiB,CACpC,OAAO,EACP,UAAU,EACV;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,EACpB,GAAG,EACH,IAAI,CACL,CAAC;QACF,SAAS,EAAE,iBAAiB,CAC1B,OAAO,EACP,UAAU,EACV;YAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;SAAE,EACrC,GAAG,EACH,IAAI,CACL,CAAC;QACF,YAAY,EAAE,iBAAiB,CAC7B,OAAO,EACP,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EACnC,GAAG,EACH,IAAI,CACL,CAAC;QACF,YAAY,EAAE,iBAAiB,CAC7B,UAAU,EACV,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EACnC,GAAG,EACH,IAAI,CACL,CAAC;QACF,YAAY,EAAE,iBAAiB,CAC7B,QAAQ,EACR,UAAU,EACV;YACE,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,GAAG,EAAE,MAAM,CAAC;YACZ,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACxB,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,EACD,GAAG,EACH,IAAI,CACL,CAAC;QACF,aAAa,EAAE,iBAAiB,CAC9B,UAAU,EACV,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EACnC,GAAG,EACH,IAAI,CACL,CAAC;QACF,YAAY,EAAE,iBAAiB,CAC7B,UAAU,EACV,UAAU,EACV;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EACrD,GAAG,EACH,IAAI,CACL,CAAC;QACF,WAAW,EAAE,iBAAiB,CAC5B,UAAU,EACV,UAAU,EACV;YACE,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;YAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,aAAa,CAAC,EACV,eAAe,GACf,mBAAmB,GACnB,SAAS,GACT,UAAU,GACV,UAAU,CAAC;YACf,GAAG,EAAE,MAAM,CAAC;YACZ,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,SAAS,CAAC,EAAE,OAAO,CAAC;YACpB,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,cAAc,CAAC,EAAE,MAAM,CAAC;YACxB,iBAAiB,CAAC,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,CAAC;YACvD,eAAe,CAAC,EACZ,QAAQ,GACR,aAAa,GACb,YAAY,GACZ,OAAO,GACP,QAAQ,CAAC;SACd,EACD,GAAG,EACH,IAAI,CACL,CAAC;QACF,aAAa,EAAE,iBAAiB,CAC9B,UAAU,EACV,UAAU,EACV;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EACrE,GAAG,EACH,IAAI,CACL,CAAC;KACH,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/component.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export declare const getLock: import("convex/server").RegisteredAction<"public", {
2
+ key: string;
3
+ }, Promise<import("@devultur/core").LockView>>;
4
+ export declare const setLock: import("convex/server").RegisteredAction<"public", {
5
+ mode?: "governance" | "compliance" | undefined;
6
+ until?: string | undefined;
7
+ period?: number | undefined;
8
+ derivatives?: "inherit" | "original-only" | undefined;
9
+ remove?: true | undefined;
10
+ bypassGovernance?: boolean | undefined;
11
+ key: string;
12
+ }, Promise<import("@devultur/core").LockView>>;
13
+ export declare const setHold: import("convex/server").RegisteredAction<"public", {
14
+ keys: string[];
15
+ }, Promise<{
16
+ updated: string[];
17
+ skipped: {
18
+ key: string;
19
+ reason: string;
20
+ }[];
21
+ pageSize: number;
22
+ }>>;
23
+ export declare const releaseHold: import("convex/server").RegisteredAction<"public", {
24
+ keys: string[];
25
+ }, Promise<{
26
+ updated: string[];
27
+ skipped: {
28
+ key: string;
29
+ reason: string;
30
+ }[];
31
+ pageSize: number;
32
+ }>>;
33
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/component/lock.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,OAAO;;8CAGlB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;8CAWlB,CAAC;AAcH,eAAO,MAAM,OAAO;;;;;aARG,MAAM;gBAAU,MAAM;;;GAW3C,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;aAbD,MAAM;gBAAU,MAAM;;;GAgB3C,CAAC"}
@@ -0,0 +1,47 @@
1
+ // Object lock from the app's server: read and change an object's retention, and set or release holds on a list of
2
+ // keys. These are component functions, so only the app's own functions can call them (never a browser). A bulk hold
3
+ // by prefix stays on the app's server, with `@devultur/core`'s `createWorkerClient(...).lock.holdAll({ prefix })`.
4
+ // A refusal throws a `ConvexError` whose `data.code` is the Worker's (`retention_active`, `compliance_extend_only`,
5
+ // `lock_privilege_required`, `lock_conflict`, ...); see workerErrors.ts.
6
+ import { HOLD_PAGE_SIZE } from "@devultur/core";
7
+ import { v } from "convex/values";
8
+ import { derivativesValidator, retentionModeValidator } from "./lockValidators";
9
+ import { getMediaClient } from "./mediaClient";
10
+ import { workerAction } from "./workerErrors";
11
+ const keysValidator = v.array(v.string());
12
+ export const getLock = workerAction({
13
+ args: { key: v.string() },
14
+ handler: async (_ctx, args) => getMediaClient().lock.get(args.key),
15
+ });
16
+ export const setLock = workerAction({
17
+ args: {
18
+ key: v.string(),
19
+ mode: v.optional(retentionModeValidator),
20
+ until: v.optional(v.string()),
21
+ period: v.optional(v.number()),
22
+ derivatives: v.optional(derivativesValidator),
23
+ remove: v.optional(v.literal(true)),
24
+ bypassGovernance: v.optional(v.boolean()),
25
+ },
26
+ handler: async (_ctx, { key, ...options }) => getMediaClient().lock.set(key, options),
27
+ });
28
+ /** Holds every key, a page of {@link HOLD_PAGE_SIZE} at a time; returns what changed and what didn't. */
29
+ async function changeHolds(keys, hold) {
30
+ const lock = getMediaClient().lock;
31
+ const updated = [];
32
+ const skipped = [];
33
+ for await (const page of hold ? lock.holdAll(keys) : lock.releaseAll(keys)) {
34
+ updated.push(...page.updated);
35
+ skipped.push(...page.skipped);
36
+ }
37
+ return { updated, skipped, pageSize: HOLD_PAGE_SIZE };
38
+ }
39
+ export const setHold = workerAction({
40
+ args: { keys: keysValidator },
41
+ handler: async (_ctx, args) => changeHolds(args.keys, true),
42
+ });
43
+ export const releaseHold = workerAction({
44
+ args: { keys: keysValidator },
45
+ handler: async (_ctx, args) => changeHolds(args.keys, false),
46
+ });
47
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/component/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare const retentionModeValidator: import("convex/values").VUnion<"governance" | "compliance", [import("convex/values").VLiteral<"governance", "required">, import("convex/values").VLiteral<"compliance", "required">], "required", never>;
2
+ export declare const derivativesValidator: import("convex/values").VUnion<"inherit" | "original-only", [import("convex/values").VLiteral<"inherit", "required">, import("convex/values").VLiteral<"original-only", "required">], "required", never>;
3
+ export declare const objectLockValidator: import("convex/values").VObject<{
4
+ retention?: {
5
+ until?: string | undefined;
6
+ period?: number | undefined;
7
+ derivatives?: "inherit" | "original-only" | undefined;
8
+ mode: "governance" | "compliance";
9
+ } | undefined;
10
+ hold?: boolean | undefined;
11
+ }, {
12
+ retention: import("convex/values").VObject<{
13
+ until?: string | undefined;
14
+ period?: number | undefined;
15
+ derivatives?: "inherit" | "original-only" | undefined;
16
+ mode: "governance" | "compliance";
17
+ } | undefined, {
18
+ mode: import("convex/values").VUnion<"governance" | "compliance", [import("convex/values").VLiteral<"governance", "required">, import("convex/values").VLiteral<"compliance", "required">], "required", never>;
19
+ until: import("convex/values").VString<string | undefined, "optional">;
20
+ period: import("convex/values").VFloat64<number | undefined, "optional">;
21
+ derivatives: import("convex/values").VUnion<"inherit" | "original-only" | undefined, [import("convex/values").VLiteral<"inherit", "required">, import("convex/values").VLiteral<"original-only", "required">], "optional", never>;
22
+ }, "optional", "mode" | "until" | "period" | "derivatives">;
23
+ hold: import("convex/values").VBoolean<boolean | undefined, "optional">;
24
+ }, "required", "retention" | "hold" | "retention.mode" | "retention.until" | "retention.period" | "retention.derivatives">;
25
+ //# sourceMappingURL=lockValidators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockValidators.d.ts","sourceRoot":"","sources":["../../src/component/lockValidators.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,0MAA4D,CAAC;AAChG,eAAO,MAAM,oBAAoB,0MAA4D,CAAC;AAE9F,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;0HAU9B,CAAC"}
@@ -0,0 +1,14 @@
1
+ // Validators of the object lock arguments (the shapes of `@devultur/core`'s `ObjectLock` and `SetLockOptions`).
2
+ import { v } from "convex/values";
3
+ export const retentionModeValidator = v.union(v.literal("governance"), v.literal("compliance"));
4
+ export const derivativesValidator = v.union(v.literal("inherit"), v.literal("original-only"));
5
+ export const objectLockValidator = v.object({
6
+ retention: v.optional(v.object({
7
+ mode: retentionModeValidator,
8
+ until: v.optional(v.string()),
9
+ period: v.optional(v.number()),
10
+ derivatives: v.optional(derivativesValidator),
11
+ })),
12
+ hold: v.optional(v.boolean()),
13
+ });
14
+ //# sourceMappingURL=lockValidators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockValidators.js","sourceRoot":"","sources":["../../src/component/lockValidators.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;AAE9F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,QAAQ,CACpB,CAAC,CAAC,MAAM,CAAC;QACR,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC;KAC7C,CAAC,CACF;IACD,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CAC7B,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type WorkerClient } from "@devultur/core";
2
+ export declare function getMediaClient(): WorkerClient;
3
+ //# sourceMappingURL=mediaClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mediaClient.d.ts","sourceRoot":"","sources":["../../src/component/mediaClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGvE,wBAAgB,cAAc,IAAI,YAAY,CAE7C"}
@@ -0,0 +1,7 @@
1
+ // The component's client of the media Worker, from the env the app mounts the component with.
2
+ import { createWorkerClient } from "@devultur/core";
3
+ import { env } from "./_generated/server";
4
+ export function getMediaClient() {
5
+ return createWorkerClient(env.DEVULTUR_SECRET, env.DEVULTUR_API_URL);
6
+ }
7
+ //# sourceMappingURL=mediaClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mediaClient.js","sourceRoot":"","sources":["../../src/component/mediaClient.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,MAAM,UAAU,cAAc;IAC7B,OAAO,kBAAkB,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACtE,CAAC"}
@@ -5,7 +5,17 @@ export declare const issueViewerToken: import("convex/server").RegisteredAction<
5
5
  expiresIn: number;
6
6
  }>>;
7
7
  export declare const createUploadUrl: import("convex/server").RegisteredAction<"public", {
8
+ hold?: boolean | undefined;
8
9
  visibility?: "public" | "private" | undefined;
10
+ lock?: {
11
+ retention?: {
12
+ until?: string | undefined;
13
+ period?: number | undefined;
14
+ derivatives?: "inherit" | "original-only" | undefined;
15
+ mode: "governance" | "compliance";
16
+ } | undefined;
17
+ hold?: boolean | undefined;
18
+ } | undefined;
9
19
  filename: string;
10
20
  contentType: string;
11
21
  }, Promise<import("@devultur/core").WorkerUploadResult>>;
@@ -62,6 +72,10 @@ export declare const getMediaByKey: import("convex/server").RegisteredQuery<"pub
62
72
  }, Promise<{
63
73
  _id: import("convex/values").GenericId<"media">;
64
74
  _creationTime: number;
75
+ width?: number | undefined;
76
+ height?: number | undefined;
77
+ visibility?: "public" | "private" | undefined;
78
+ objectKey?: string | undefined;
65
79
  transcodeStatus?: "queued" | "transcoding" | "captioning" | "ready" | "failed" | undefined;
66
80
  transcodeProgress?: {
67
81
  phase?: "captioning" | "downloading" | "encoding" | "uploading" | undefined;
@@ -103,6 +117,10 @@ export declare const listMedia: import("convex/server").RegisteredQuery<"public"
103
117
  }, Promise<{
104
118
  _id: import("convex/values").GenericId<"media">;
105
119
  _creationTime: number;
120
+ width?: number | undefined;
121
+ height?: number | undefined;
122
+ visibility?: "public" | "private" | undefined;
123
+ objectKey?: string | undefined;
106
124
  transcodeStatus?: "queued" | "transcoding" | "captioning" | "ready" | "failed" | undefined;
107
125
  transcodeProgress?: {
108
126
  phase?: "captioning" | "downloading" | "encoding" | "uploading" | undefined;
@@ -139,6 +157,60 @@ export declare const listMedia: import("convex/server").RegisteredQuery<"public"
139
157
  sizeBytes: number;
140
158
  createdAt: number;
141
159
  }[]>>;
160
+ /** One page of the media library, newest first, optionally of one type (`by_type` index). */
161
+ export declare const listMediaPage: import("convex/server").RegisteredQuery<"public", {
162
+ type?: "video" | "image" | "file" | undefined;
163
+ paginationOpts: {
164
+ id?: number;
165
+ endCursor?: string | null;
166
+ maximumRowsRead?: number;
167
+ maximumBytesRead?: number;
168
+ numItems: number;
169
+ cursor: string | null;
170
+ };
171
+ }, Promise<import("convex/server").PaginationResult<{
172
+ _id: import("convex/values").GenericId<"media">;
173
+ _creationTime: number;
174
+ width?: number | undefined;
175
+ height?: number | undefined;
176
+ visibility?: "public" | "private" | undefined;
177
+ objectKey?: string | undefined;
178
+ transcodeStatus?: "queued" | "transcoding" | "captioning" | "ready" | "failed" | undefined;
179
+ transcodeProgress?: {
180
+ phase?: "captioning" | "downloading" | "encoding" | "uploading" | undefined;
181
+ current: number;
182
+ total: number;
183
+ } | undefined;
184
+ transcodeError?: string | undefined;
185
+ failureReason?: "invalid_input" | "unsupported_codec" | "timeout" | "capacity" | "internal" | undefined;
186
+ retriable?: boolean | undefined;
187
+ playlistUrl?: string | undefined;
188
+ thumbnailKey?: string | undefined;
189
+ captionLocales?: string[] | undefined;
190
+ captionsPending?: boolean | undefined;
191
+ duration?: number | undefined;
192
+ renditions?: {
193
+ width?: number | undefined;
194
+ height?: number | undefined;
195
+ variant: string;
196
+ kind: "hls" | "mp4";
197
+ rung: string;
198
+ key: string;
199
+ url: string;
200
+ }[] | undefined;
201
+ posterUrls?: {
202
+ jpg?: string | undefined;
203
+ avif?: string | undefined;
204
+ } | undefined;
205
+ hasAudio?: boolean | undefined;
206
+ storyboardKey?: string | undefined;
207
+ type: "video" | "image" | "file";
208
+ key: string;
209
+ filename: string;
210
+ contentType: string;
211
+ sizeBytes: number;
212
+ createdAt: number;
213
+ }>>>;
142
214
  export declare const upsertCaption: import("convex/server").RegisteredMutation<"public", {
143
215
  srtUrl?: string | undefined;
144
216
  mediaKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/component/public.ts"],"names":[],"mappings":"AAwCA,eAAO,MAAM,gBAAgB;;;;;GAU3B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;wDAW1B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;iBAM5B,CAAC;AAEH,eAAO,MAAM,WAAW;;;uDAUtB,CAAC;AAKH,eAAO,MAAM,mBAAmB;;iBAe9B,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;wDAyEvB,CAAC;AAIH,eAAO,MAAM,YAAY;;iBAevB,CAAC;AAIH,eAAO,MAAM,sBAAsB;;iBAiBjC,CAAC;AAIH,eAAO,MAAM,mBAAmB;;iBAkB9B,CAAC;AAIH,eAAO,MAAM,WAAW;;;;;;uDAWtB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;iBAsCtB,CAAC;AAIH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAQxB,CAAC;AAEH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASpB,CAAC;AAIH,eAAO,MAAM,aAAa;;;;;0DAmBxB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;KAQ9B,CAAC;AAWH,eAAO,MAAM,YAAY;;;;0DAgBvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;UAKvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;0DAmBvB,CAAC;AAEH,eAAO,MAAM,aAAa;;;iBAQxB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;aAK5B,CAAC;AAIH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6F7B,CAAC"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/component/public.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,gBAAgB;;;;;GAU3B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;wDAoB1B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;iBAQ5B,CAAC;AAEH,eAAO,MAAM,WAAW;;;uDAUtB,CAAC;AAKH,eAAO,MAAM,mBAAmB;;iBAe9B,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;wDAyEvB,CAAC;AAIH,eAAO,MAAM,YAAY;;iBAevB,CAAC;AAIH,eAAO,MAAM,sBAAsB;;iBAiBjC,CAAC;AAIH,eAAO,MAAM,mBAAmB;;iBAkB9B,CAAC;AAIH,eAAO,MAAM,WAAW;;;;;;uDAiBtB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;iBAsCtB,CAAC;AAIH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAQxB,CAAC;AAGH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASpB,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYxB,CAAC;AAIH,eAAO,MAAM,aAAa;;;;;0DAmBxB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;KAQ9B,CAAC;AAWH,eAAO,MAAM,YAAY;;;;0DAgBvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;UAKvB,CAAC;AAEH,eAAO,MAAM,YAAY;;;0DAmBvB,CAAC;AAEH,eAAO,MAAM,aAAa;;;iBAQxB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;aAK5B,CAAC;AAIH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6F7B,CAAC"}