@gonvex/cli 0.1.32 → 0.3.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 (36) hide show
  1. package/README.md +30 -15
  2. package/dist/browser.d.ts +1 -1
  3. package/dist/browser.js +1 -1
  4. package/dist/browser.js.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +274 -555
  7. package/dist/index.js.map +1 -1
  8. package/dist/manifest-types.d.ts +261 -0
  9. package/dist/manifest-types.js +3 -0
  10. package/dist/manifest-types.js.map +1 -0
  11. package/dist/module-artifact.d.ts +26 -0
  12. package/dist/module-artifact.js +1585 -0
  13. package/dist/module-artifact.js.map +1 -0
  14. package/dist/react.d.ts +2 -2
  15. package/dist/react.js +1 -1
  16. package/dist/react.js.map +1 -1
  17. package/dist/templates/vite-react/README.md +5 -2
  18. package/dist/templates/vite-react/gonvex/_build/module.js +407 -0
  19. package/dist/templates/vite-react/gonvex/_generated/api.ts +185 -3
  20. package/dist/templates/vite-react/gonvex/_generated/client.ts +1 -1
  21. package/dist/templates/vite-react/gonvex/_generated/{landlord → control-plane}/schema.ts +2 -1
  22. package/dist/templates/vite-react/gonvex/_generated/{landlord → control-plane}/tables.ts +1 -1
  23. package/dist/templates/vite-react/gonvex/_generated/manifest.json +201 -66
  24. package/dist/templates/vite-react/gonvex/_generated/module.json +120 -0
  25. package/dist/templates/vite-react/gonvex/_generated/react.ts +2 -2
  26. package/dist/templates/vite-react/gonvex/_generated/schema.ts +4 -34
  27. package/dist/templates/vite-react/gonvex/_generated/tenant/schema.ts +1 -30
  28. package/dist/templates/vite-react/gonvex/_generated/tenant/tables.ts +0 -30
  29. package/dist/templates/vite-react/gonvex/index.ts +1 -0
  30. package/dist/templates/vite-react/gonvex/messages.ts +47 -0
  31. package/dist/templates/vite-react/migrations/0001_messages.sql +9 -0
  32. package/dist/templates/vite-react/package.json +1 -0
  33. package/dist/templates/vite-react/src/App.tsx +5 -5
  34. package/package.json +4 -3
  35. package/dist/templates/vite-react/gonvex/messages.go +0 -38
  36. package/dist/templates/vite-react/gonvex/schema.go +0 -14
@@ -1,11 +1,193 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
2
 
3
+ import type { LiveQueryPlan } from "@gonvex/client";
4
+
5
+ export type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };
6
+ export type FunctionKind = "query" | "reducer" | "action";
7
+ export type OptimisticID = string | readonly string[];
8
+ export type OptimisticValue = JsonValue | { readonly $arg: string | readonly string[] } | readonly OptimisticValue[] | { readonly [key: string]: OptimisticValue };
9
+ export type OptimisticEffectDefinition =
10
+ | { readonly operation: "patch"; readonly entity: string; readonly id: OptimisticID; readonly fields: Readonly<Record<string, OptimisticValue>> }
11
+ | { readonly operation: "upsert"; readonly entity: string; readonly id: OptimisticID; readonly value: Readonly<Record<string, OptimisticValue>> }
12
+ | { readonly operation: "delete"; readonly entity: string; readonly id: OptimisticID };
13
+ export type OptimisticTransactionDefinition = { readonly effects: readonly OptimisticEffectDefinition[]; readonly expectedRevision?: number };
14
+ export type FunctionReference<Kind extends FunctionKind = FunctionKind, Args = JsonValue, Result = JsonValue> = {
15
+ readonly kind: Kind;
16
+ readonly path: string;
17
+ readonly delivery?: "oneShot" | "live" | "replica";
18
+ readonly offline?: { readonly mode: "forbidden" | "allowed" | "onlineOnly"; readonly conflict?: "reject" | "expectedVersion" | "merge"; readonly reason?: string };
19
+ readonly args?: Args;
20
+ readonly result?: Result;
21
+ readonly live?: { readonly entity: string; readonly key: string; readonly resultPath?: readonly string[]; readonly plan: LiveQueryPlan };
22
+ readonly optimistic?: { readonly transaction?: OptimisticTransactionDefinition };
23
+ };
24
+
25
+ export type MessagesListArgs = { };
26
+ export type MessagesListResult = Array<{
27
+ id: string;
28
+ body: string;
29
+ author: string;
30
+ created_at: string;
31
+ }>;
32
+ export type MessagesSendArgs = {
33
+ body: string;
34
+ };
35
+ export type MessagesSendResult = {
36
+ id: string;
37
+ body: string;
38
+ author: string;
39
+ created_at: string;
40
+ };
41
+
3
42
  export const api = {
4
43
  messages: {
5
- list: { kind: "query", path: "messages.list" },
6
- send: { kind: "mutation", path: "messages.send" },
44
+ list: {
45
+ args: {
46
+ fields: {
47
+ },
48
+ kind: "object",
49
+ },
50
+ delivery: "live",
51
+ kind: "query",
52
+ live: {
53
+ entity: "messages",
54
+ key: "id",
55
+ plan: {
56
+ columns: ["id","body","author","created_at"],
57
+ key: "id",
58
+ sort: {
59
+ allowedColumns: ["created_at"],
60
+ columnArgument: undefined,
61
+ defaultColumn: "created_at",
62
+ defaultDirection: "asc",
63
+ directionArgument: undefined,
64
+ },
65
+ table: "messages",
66
+ },
67
+ resultPath: [],
68
+ },
69
+ path: "messages.list",
70
+ result: {
71
+ items: {
72
+ fields: {
73
+ author: {
74
+ kind: "string",
75
+ },
76
+ body: {
77
+ kind: "string",
78
+ },
79
+ created_at: {
80
+ format: "datetime",
81
+ kind: "string",
82
+ },
83
+ id: {
84
+ entity: "messages",
85
+ kind: "id",
86
+ },
87
+ },
88
+ kind: "object",
89
+ },
90
+ kind: "array",
91
+ },
92
+ } as unknown as FunctionReference<"query", MessagesListArgs, MessagesListResult>,
93
+ send: {
94
+ args: {
95
+ fields: {
96
+ body: {
97
+ kind: "string",
98
+ },
99
+ },
100
+ kind: "object",
101
+ },
102
+ kind: "reducer",
103
+ offline: {
104
+ mode: "onlineOnly",
105
+ reason: "server assigns the message id",
106
+ },
107
+ path: "messages.send",
108
+ result: {
109
+ fields: {
110
+ author: {
111
+ kind: "string",
112
+ },
113
+ body: {
114
+ kind: "string",
115
+ },
116
+ created_at: {
117
+ format: "datetime",
118
+ kind: "string",
119
+ },
120
+ id: {
121
+ entity: "messages",
122
+ kind: "id",
123
+ },
124
+ },
125
+ kind: "object",
126
+ },
127
+ } as unknown as FunctionReference<"reducer", MessagesSendArgs, MessagesSendResult>,
7
128
  },
8
129
  } as const;
9
130
 
10
- export const internal = api;
131
+ export const internal = {} as const;
11
132
  export type Api = typeof api;
133
+
134
+ export const optimisticTransactions: Record<string, OptimisticTransactionDefinition> = {
135
+ };
136
+
137
+ export type ApiArgs = {
138
+ "messages.list": MessagesListArgs;
139
+ "messages.send": MessagesSendArgs;
140
+ };
141
+
142
+ export type ApiResults = {
143
+ "messages.list": MessagesListResult;
144
+ "messages.send": MessagesSendResult;
145
+ };
146
+
147
+ export function optimisticPatchesFor(
148
+ path: string,
149
+ args: Record<string, unknown>,
150
+ ): Array<{ entity?: string; collection?: string; rowId: string; op: "patch" | "insert" | "upsert" | "delete"; fields?: Record<string, unknown> }> {
151
+ const transaction = Object.prototype.hasOwnProperty.call(optimisticTransactions, path)
152
+ ? optimisticTransactions[path]
153
+ : undefined;
154
+ if (transaction && Array.isArray(transaction.effects) && transaction.effects.length > 0) {
155
+ const readPath = (value: unknown, segments: readonly string[]): unknown =>
156
+ segments.reduce<unknown>((current, segment) =>
157
+ current && typeof current === "object" ? (current as Record<string, unknown>)[segment] : undefined, value);
158
+ const resolveValue = (value: unknown): unknown => {
159
+ if (Array.isArray(value)) return value.map(resolveValue);
160
+ if (!value || typeof value !== "object") return value;
161
+ const record = value as Record<string, unknown>;
162
+ if (Object.keys(record).length === 1 && Object.prototype.hasOwnProperty.call(record, "$arg")) {
163
+ const path = record.$arg;
164
+ const segments = Array.isArray(path)
165
+ ? path.filter((part): part is string => typeof part === "string" && part.trim().length > 0)
166
+ : typeof path === "string" ? path.split(".").map((part) => part.trim()).filter(Boolean) : [];
167
+ return segments.length > 0 ? readPath(args, segments) : undefined;
168
+ }
169
+ return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, resolveValue(item)]));
170
+ };
171
+ const containsUndefined = (value: unknown): boolean =>
172
+ value === undefined || (Array.isArray(value)
173
+ ? value.some(containsUndefined)
174
+ : !!value && typeof value === "object" && Object.values(value as Record<string, unknown>).some(containsUndefined));
175
+ const patches: Array<{ entity?: string; collection?: string; rowId: string; op: "patch" | "insert" | "upsert" | "delete"; fields?: Record<string, unknown> }> = [];
176
+ for (const effect of transaction.effects) {
177
+ const rawId = Array.isArray(effect.id) ? readPath(args, effect.id) : effect.id;
178
+ const rowId = String(rawId ?? "").trim();
179
+ if (!rowId || !effect.entity) return [];
180
+ if (effect.operation === "delete") {
181
+ patches.push({ entity: effect.entity, rowId, op: "delete" });
182
+ continue;
183
+ }
184
+ const template = effect.operation === "patch" ? effect.fields : effect.value;
185
+ if (!template || typeof template !== "object" || Array.isArray(template)) return [];
186
+ const fields = resolveValue(template);
187
+ if (!fields || typeof fields !== "object" || Array.isArray(fields) || containsUndefined(fields)) return [];
188
+ patches.push({ entity: effect.entity, rowId, op: effect.operation === "upsert" ? "upsert" : "patch", fields: { ...(fields as Record<string, unknown>) } });
189
+ }
190
+ return patches;
191
+ }
192
+ return [];
193
+ }
@@ -1,2 +1,2 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
- export { GonvexClient, ConvexReactClient } from "@gonvex/client";
2
+ export { GonvexClient } from "@gonvex/client";
@@ -1,11 +1,12 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
2
 
3
3
  export const schema = {
4
- scope: "landlord",
4
+ scope: "control-plane",
5
5
  tables: {
6
6
  },
7
7
  } as const;
8
8
 
9
+ export const controlPlane = schema;
9
10
  export const tables = schema.tables;
10
11
 
11
12
  export type TableName = keyof typeof tables;
@@ -1,6 +1,6 @@
1
1
  // Generated by gonvex dev. Do not edit.
2
2
 
3
- export const scope = "landlord" as const;
3
+ export const scope = "control-plane" as const;
4
4
 
5
5
  export const tables = {
6
6
  } as const;
@@ -1,96 +1,231 @@
1
1
  {
2
- "project": "my-vite-app",
3
- "generatedAt": "2026-07-27T02:13:04.841Z",
2
+ "project": "vite-react-template",
3
+ "generatedAt": "2026-08-20T20:01:00.762Z",
4
4
  "functions": {
5
5
  "messages.list": {
6
6
  "kind": "query",
7
- "handler": "ListMessages",
8
- "file": "gonvex/messages.go"
9
- },
10
- "messages.send": {
11
- "kind": "mutation",
12
- "handler": "SendMessage",
13
- "file": "gonvex/messages.go"
14
- }
15
- },
16
- "schema": {
17
- "tables": {
18
- "messages": {
19
- "columns": {
20
- "id": {
21
- "type": "id",
22
- "nullable": false,
23
- "primaryKey": true
24
- },
25
- "body": {
26
- "type": "string",
27
- "nullable": false,
28
- "primaryKey": false
29
- },
30
- "author": {
31
- "type": "string",
32
- "nullable": false,
33
- "primaryKey": false
34
- },
35
- "created_at": {
36
- "type": "time",
37
- "nullable": false,
38
- "primaryKey": false
7
+ "handler": "list",
8
+ "file": "gonvex/messages.ts",
9
+ "args": {
10
+ "kind": "object",
11
+ "fields": {}
12
+ },
13
+ "result": {
14
+ "kind": "array",
15
+ "items": {
16
+ "kind": "object",
17
+ "fields": {
18
+ "id": {
19
+ "kind": "id",
20
+ "entity": "messages"
21
+ },
22
+ "body": {
23
+ "kind": "string"
24
+ },
25
+ "author": {
26
+ "kind": "string"
27
+ },
28
+ "created_at": {
29
+ "kind": "string",
30
+ "format": "datetime"
31
+ }
39
32
  }
40
- },
41
- "indexes": {
42
- "by_created_at": {
43
- "columns": [
33
+ }
34
+ },
35
+ "delivery": "live",
36
+ "dependencies": {
37
+ "liveQueryPlan": {
38
+ "table": "messages",
39
+ "key": "id",
40
+ "columns": [
41
+ "id",
42
+ "body",
43
+ "author",
44
+ "created_at"
45
+ ],
46
+ "sort": {
47
+ "defaultColumn": "created_at",
48
+ "defaultDirection": "asc",
49
+ "allowedColumns": [
44
50
  "created_at"
45
- ],
46
- "unique": false
51
+ ]
47
52
  }
48
53
  }
49
54
  }
50
55
  },
51
- "landlordTables": {},
52
- "tenantTables": {
53
- "messages": {
54
- "columns": {
56
+ "messages.send": {
57
+ "kind": "reducer",
58
+ "handler": "send",
59
+ "file": "gonvex/messages.ts",
60
+ "args": {
61
+ "kind": "object",
62
+ "fields": {
63
+ "body": {
64
+ "kind": "string"
65
+ }
66
+ }
67
+ },
68
+ "result": {
69
+ "kind": "object",
70
+ "fields": {
55
71
  "id": {
56
- "type": "id",
57
- "nullable": false,
58
- "primaryKey": true
72
+ "kind": "id",
73
+ "entity": "messages"
59
74
  },
60
75
  "body": {
61
- "type": "string",
62
- "nullable": false,
63
- "primaryKey": false
76
+ "kind": "string"
64
77
  },
65
78
  "author": {
66
- "type": "string",
67
- "nullable": false,
68
- "primaryKey": false
79
+ "kind": "string"
69
80
  },
70
81
  "created_at": {
71
- "type": "time",
72
- "nullable": false,
73
- "primaryKey": false
82
+ "kind": "string",
83
+ "format": "datetime"
74
84
  }
85
+ }
86
+ },
87
+ "dependencies": {
88
+ "nonOptimisticReason": "server assigns the message id"
89
+ },
90
+ "offline": {
91
+ "mode": "onlineOnly",
92
+ "reason": "server assigns the message id"
93
+ }
94
+ }
95
+ },
96
+ "schema": {
97
+ "tables": {},
98
+ "controlPlaneTables": {},
99
+ "tenantTables": {}
100
+ },
101
+ "module": {
102
+ "language": "typescript",
103
+ "generation": 4,
104
+ "hash": "3032d0fd8002f04b1c8fd5599e2a33ae1b082a4001b4b80c6783f422909894ee",
105
+ "entrypoint": "gonvex/index.ts",
106
+ "functions": {
107
+ "messages.list": {
108
+ "kind": "query",
109
+ "handler": "list",
110
+ "file": "gonvex/messages.ts",
111
+ "export": "list",
112
+ "args": {
113
+ "kind": "object",
114
+ "fields": {}
75
115
  },
76
- "indexes": {
77
- "by_created_at": {
116
+ "result": {
117
+ "kind": "array",
118
+ "items": {
119
+ "kind": "object",
120
+ "fields": {
121
+ "id": {
122
+ "kind": "id",
123
+ "entity": "messages"
124
+ },
125
+ "body": {
126
+ "kind": "string"
127
+ },
128
+ "author": {
129
+ "kind": "string"
130
+ },
131
+ "created_at": {
132
+ "kind": "string",
133
+ "format": "datetime"
134
+ }
135
+ }
136
+ }
137
+ },
138
+ "dependencies": {
139
+ "liveQueryPlan": {
140
+ "table": "messages",
141
+ "key": "id",
78
142
  "columns": [
143
+ "id",
144
+ "body",
145
+ "author",
79
146
  "created_at"
80
147
  ],
81
- "unique": false
148
+ "sort": {
149
+ "defaultColumn": "created_at",
150
+ "defaultDirection": "asc",
151
+ "allowedColumns": [
152
+ "created_at"
153
+ ]
154
+ }
155
+ }
156
+ },
157
+ "delivery": "live"
158
+ },
159
+ "messages.send": {
160
+ "kind": "reducer",
161
+ "handler": "send",
162
+ "file": "gonvex/messages.ts",
163
+ "export": "send",
164
+ "args": {
165
+ "kind": "object",
166
+ "fields": {
167
+ "body": {
168
+ "kind": "string"
169
+ }
170
+ }
171
+ },
172
+ "result": {
173
+ "kind": "object",
174
+ "fields": {
175
+ "id": {
176
+ "kind": "id",
177
+ "entity": "messages"
178
+ },
179
+ "body": {
180
+ "kind": "string"
181
+ },
182
+ "author": {
183
+ "kind": "string"
184
+ },
185
+ "created_at": {
186
+ "kind": "string",
187
+ "format": "datetime"
188
+ }
82
189
  }
190
+ },
191
+ "dependencies": {
192
+ "nonOptimisticReason": "server assigns the message id"
193
+ },
194
+ "offline": {
195
+ "mode": "onlineOnly",
196
+ "reason": "server assigns the message id"
197
+ }
198
+ }
199
+ },
200
+ "visibility": {
201
+ "messages": {
202
+ "table": "messages",
203
+ "key": "id",
204
+ "sets": {},
205
+ "where": {
206
+ "operator": "public"
83
207
  }
84
208
  }
209
+ },
210
+ "files": {
211
+ "gonvex/index.ts": "ZXhwb3J0IHsgbGlzdCwgc2VuZCwgbWVzc2FnZXNWaXNpYmlsaXR5IH0gZnJvbSAiLi9tZXNzYWdlcy50cyI7Cg==",
212
+ "gonvex/messages.ts": "aW1wb3J0IHsgbGl2ZVF1ZXJ5LCByZWR1Y2VyLCBzY2hlbWEsIHZpc2liaWxpdHkgfSBmcm9tICJAZ29udmV4L21vZHVsZS1zZGsiOwoKZXhwb3J0IGNvbnN0IG1lc3NhZ2VzVmlzaWJpbGl0eSA9IHZpc2liaWxpdHkoewogIHRhYmxlOiAibWVzc2FnZXMiLAogIGtleTogImlkIiwKICBzZXRzOiB7fSwKICB3aGVyZTogeyBvcGVyYXRvcjogInB1YmxpYyIgfSwKfSk7CgpleHBvcnQgY29uc3QgbGlzdCA9IGxpdmVRdWVyeSh7CiAgYXJnczogc2NoZW1hLm9iamVjdCh7fSksCiAgcmVzdWx0OiBzY2hlbWEuYXJyYXkoc2NoZW1hLm9iamVjdCh7CiAgICBpZDogc2NoZW1hLmlkKCJtZXNzYWdlcyIpLAogICAgYm9keTogc2NoZW1hLnN0cmluZygpLAogICAgYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCiAgICBjcmVhdGVkX2F0OiBzY2hlbWEuZGF0ZXRpbWUoKSwKICB9KSksCiAgbGl2ZVF1ZXJ5UGxhbjogewogICAgdGFibGU6ICJtZXNzYWdlcyIsCiAgICBrZXk6ICJpZCIsCiAgICBjb2x1bW5zOiBbImlkIiwgImJvZHkiLCAiYXV0aG9yIiwgImNyZWF0ZWRfYXQiXSwKICAgIHNvcnQ6IHsKICAgICAgZGVmYXVsdENvbHVtbjogImNyZWF0ZWRfYXQiLAogICAgICBkZWZhdWx0RGlyZWN0aW9uOiAiYXNjIiwKICAgICAgYWxsb3dlZENvbHVtbnM6IFsiY3JlYXRlZF9hdCJdLAogICAgfSwKICB9LAogIHJ1bjogYXN5bmMgKCkgPT4gW10sCn0pOwoKZXhwb3J0IGNvbnN0IHNlbmQgPSByZWR1Y2VyKHsKICBhcmdzOiBzY2hlbWEub2JqZWN0KHsgYm9keTogc2NoZW1hLnN0cmluZygpIH0pLAogIHJlc3VsdDogc2NoZW1hLm9iamVjdCh7CiAgICBpZDogc2NoZW1hLmlkKCJtZXNzYWdlcyIpLAogICAgYm9keTogc2NoZW1hLnN0cmluZygpLAogICAgYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCiAgICBjcmVhdGVkX2F0OiBzY2hlbWEuZGF0ZXRpbWUoKSwKICB9KSwKICBvZmZsaW5lOiB7IG1vZGU6ICJvbmxpbmVPbmx5IiwgcmVhc29uOiAic2VydmVyIGFzc2lnbnMgdGhlIG1lc3NhZ2UgaWQiIH0sCiAgbm9uT3B0aW1pc3RpY1JlYXNvbjogInNlcnZlciBhc3NpZ25zIHRoZSBtZXNzYWdlIGlkIiwKICBydW46IGFzeW5jICh7IG5vdyB9LCBhcmdzKSA9PiAoewogICAgaWQ6ICJwZW5kaW5nIiwKICAgIGJvZHk6IGFyZ3MuYm9keSwKICAgIGF1dGhvcjogImRlbW8tdXNlciIsCiAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZShub3cpLnRvSVNPU3RyaW5nKCksCiAgfSksCn0pOwo=",
213
+ "migrations/0001_messages.sql": "LS0gZ29udmV4OnNjb3BlIHRlbmFudApDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyBtZXNzYWdlcyAoCiAgaWQgdGV4dCBQUklNQVJZIEtFWSwKICBib2R5IHRleHQgTk9UIE5VTEwsCiAgYXV0aG9yIHRleHQgTk9UIE5VTEwsCiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTAopOwoKQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgYnlfY3JlYXRlZF9hdCBPTiBtZXNzYWdlcyAoY3JlYXRlZF9hdCk7Cg=="
214
+ },
215
+ "javascript": {
216
+ "path": "gonvex/_build/module.js",
217
+ "hash": "17879ed408db6c0a2bc9ffccbe77c58f6297156a71c39c513471e9d6f6ad7674",
218
+ "code": "Ly8jcmVnaW9uIC4uLy4uL3BhY2thZ2VzL21vZHVsZS1zZGsvZGlzdC9pbmRleC5qcwpjb25zdCBmcmVlemUgPSAodmFsdWUpID0+IE9iamVjdC5mcmVlemUodmFsdWUpOwovKiogQ29uc3RydWN0b3JzIGZvciB0aGUgbGFuZ3VhZ2UtbmV1dHJhbCBzY2hlbWEgc3Vic2V0LiAqLwpjb25zdCBzY2hlbWEgPSB7CglzdHJpbmcob3B0aW9ucyA9IHt9KSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQkuLi5vcHRpb25zCgkJfSk7Cgl9LAoJZW1haWwoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJlbWFpbCIKCQl9KTsKCX0sCgl1cmkoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJ1cmkiCgkJfSk7Cgl9LAoJdXVpZCgpIHsKCQlyZXR1cm4gZnJlZXplKHsKCQkJa2luZDogInN0cmluZyIsCgkJCWZvcm1hdDogInV1aWQiCgkJfSk7Cgl9LAoJZGF0ZXRpbWUoKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJzdHJpbmciLAoJCQlmb3JtYXQ6ICJkYXRldGltZSIKCQl9KTsKCX0sCgludW1iZXIob3B0aW9ucyA9IHt9KSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJudW1iZXIiLAoJCQkuLi5vcHRpb25zCgkJfSk7Cgl9LAoJaW50ZWdlcihvcHRpb25zID0ge30pIHsKCQlyZXR1cm4gZnJlZXplKHsKCQkJa2luZDogIm51bWJlciIsCgkJCWludGVnZXI6IHRydWUsCgkJCS4uLm9wdGlvbnMKCQl9KTsKCX0sCglib29sZWFuKCkgewoJCXJldHVybiBmcmVlemUoeyBraW5kOiAiYm9vbGVhbiIgfSk7Cgl9LAoJbnVsbCgpIHsKCQlyZXR1cm4gZnJlZXplKHsga2luZDogIm51bGwiIH0pOwoJfSwKCWFueSgpIHsKCQlyZXR1cm4gZnJlZXplKHsga2luZDogImFueSIgfSk7Cgl9LAoJaWQoZW50aXR5KSB7CgkJaWYgKCFlbnRpdHkudHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoInNjaGVtYS5pZCByZXF1aXJlcyBhbiBlbnRpdHkgbmFtZSIpOwoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAiaWQiLAoJCQllbnRpdHkKCQl9KTsKCX0sCglsaXRlcmFsKHZhbHVlKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJsaXRlcmFsIiwKCQkJdmFsdWUKCQl9KTsKCX0sCglhcnJheShpdGVtcykgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAiYXJyYXkiLAoJCQlpdGVtcwoJCX0pOwoJfSwKCW9iamVjdChmaWVsZHMsIG9wdGlvbnMgPSB7fSkgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAib2JqZWN0IiwKCQkJZmllbGRzOiBmcmVlemUoeyAuLi5maWVsZHMgfSksCgkJCS4uLm9wdGlvbnMKCQl9KTsKCX0sCglyZWNvcmQodmFsdWVzKSB7CgkJcmV0dXJuIGZyZWV6ZSh7CgkJCWtpbmQ6ICJyZWNvcmQiLAoJCQl2YWx1ZXMKCQl9KTsKCX0sCglvcHRpb25hbCh2YWx1ZSkgewoJCXJldHVybiBmcmVlemUoewoJCQlraW5kOiAib3B0aW9uYWwiLAoJCQl2YWx1ZQoJCX0pOwoJfQp9Owpjb25zdCBpc1JlY29yZCA9ICh2YWx1ZSkgPT4gdHlwZW9mIHZhbHVlID09PSAib2JqZWN0IiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7CmNvbnN0IHZhbGlkYXRlT2ZmbGluZVBvbGljeSA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkgfHwgdmFsdWUubW9kZSAhPT0gImZvcmJpZGRlbiIgJiYgdmFsdWUubW9kZSAhPT0gImFsbG93ZWQiICYmIHZhbHVlLm1vZGUgIT09ICJvbmxpbmVPbmx5IikgdGhyb3cgbmV3IEVycm9yKGByZWR1Y2VyICR7cGF0aH0gbXVzdCBkZWNsYXJlIGEgdmFsaWQgb2ZmbGluZSBwb2xpY3lgKTsKCWlmICh2YWx1ZS5tb2RlID09PSAib25saW5lT25seSIgJiYgKHR5cGVvZiB2YWx1ZS5yZWFzb24gIT09ICJzdHJpbmciIHx8ICF2YWx1ZS5yZWFzb24udHJpbSgpKSkgdGhyb3cgbmV3IEVycm9yKGByZWR1Y2VyICR7cGF0aH0gb25saW5lT25seSBwb2xpY3kgcmVxdWlyZXMgYSByZWFzb25gKTsKCWlmICh2YWx1ZS5tb2RlID09PSAiYWxsb3dlZCIgJiYgdmFsdWUuY29uZmxpY3QgIT09IHZvaWQgMCAmJiB2YWx1ZS5jb25mbGljdCAhPT0gInJlamVjdCIgJiYgdmFsdWUuY29uZmxpY3QgIT09ICJleHBlY3RlZFZlcnNpb24iICYmIHZhbHVlLmNvbmZsaWN0ICE9PSAibWVyZ2UiKSB0aHJvdyBuZXcgRXJyb3IoYHJlZHVjZXIgJHtwYXRofSBoYXMgYW4gaW52YWxpZCBvZmZsaW5lIGNvbmZsaWN0IHBvbGljeWApOwp9Owpjb25zdCB2YWxpZGF0ZU9wdGltaXN0aWNUcmFuc2FjdGlvbiA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuZWZmZWN0cykgfHwgdmFsdWUuZWZmZWN0cy5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgbWV0YWRhdGEgbXVzdCBjb250YWluIGEgbm9uLWVtcHR5IGVmZmVjdHMgYXJyYXlgKTsKCWlmICh2YWx1ZS5leHBlY3RlZFJldmlzaW9uICE9PSB2b2lkIDAgJiYgKHR5cGVvZiB2YWx1ZS5leHBlY3RlZFJldmlzaW9uICE9PSAibnVtYmVyIiB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUuZXhwZWN0ZWRSZXZpc2lvbikgfHwgdmFsdWUuZXhwZWN0ZWRSZXZpc2lvbiA8IDApKSB0aHJvdyBuZXcgRXJyb3IoYHJlZHVjZXIgJHtwYXRofSBvcHRpbWlzdGljIGV4cGVjdGVkUmV2aXNpb24gbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyYCk7Cglmb3IgKGNvbnN0IGVmZmVjdCBvZiB2YWx1ZS5lZmZlY3RzKSB7CgkJaWYgKCFpc1JlY29yZChlZmZlY3QpIHx8IGVmZmVjdC5vcGVyYXRpb24gIT09ICJwYXRjaCIgJiYgZWZmZWN0Lm9wZXJhdGlvbiAhPT0gInVwc2VydCIgJiYgZWZmZWN0Lm9wZXJhdGlvbiAhPT0gImRlbGV0ZSIpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IGhhcyBhbiBpbnZhbGlkIG9wdGltaXN0aWMgZWZmZWN0YCk7CgkJaWYgKHR5cGVvZiBlZmZlY3QuZW50aXR5ICE9PSAic3RyaW5nIiB8fCAhZWZmZWN0LmVudGl0eS50cmltKCkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgZWZmZWN0cyByZXF1aXJlIGFuIGVudGl0eWApOwoJCWlmICh0eXBlb2YgZWZmZWN0LmlkID09PSAic3RyaW5nIiAmJiAhZWZmZWN0LmlkLnRyaW0oKSB8fCB0eXBlb2YgZWZmZWN0LmlkICE9PSAic3RyaW5nIiAmJiAoIUFycmF5LmlzQXJyYXkoZWZmZWN0LmlkKSB8fCBlZmZlY3QuaWQubGVuZ3RoID09PSAwIHx8IGVmZmVjdC5pZC5zb21lKChwYXJ0KSA9PiB0eXBlb2YgcGFydCAhPT0gInN0cmluZyIgfHwgIXBhcnQudHJpbSgpKSkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgZWZmZWN0cyByZXF1aXJlIGEgc3RyaW5nIGlkIG9yIGlkIHJlZmVyZW5jZXNgKTsKCQlpZiAoKGVmZmVjdC5vcGVyYXRpb24gPT09ICJwYXRjaCIgfHwgZWZmZWN0Lm9wZXJhdGlvbiA9PT0gInVwc2VydCIpICYmICFpc1JlY29yZChlZmZlY3Qub3BlcmF0aW9uID09PSAicGF0Y2giID8gZWZmZWN0LmZpZWxkcyA6IGVmZmVjdC52YWx1ZSkpIHRocm93IG5ldyBFcnJvcihgcmVkdWNlciAke3BhdGh9IG9wdGltaXN0aWMgJHtlZmZlY3Qub3BlcmF0aW9ufSBlZmZlY3RzIHJlcXVpcmUgYW4gb2JqZWN0IHZhbHVlYCk7Cgl9Cn07CmNvbnN0IHZhbGlkYXRlUmVwbGljYUNvbGxlY3Rpb24gPSAodmFsdWUsIHBhdGgpID0+IHsKCWlmICghaXNSZWNvcmQodmFsdWUpIHx8IHR5cGVvZiB2YWx1ZS50YWJsZSAhPT0gInN0cmluZyIgfHwgIXZhbHVlLnRhYmxlLnRyaW0oKSB8fCB0eXBlb2YgdmFsdWUua2V5ICE9PSAic3RyaW5nIiB8fCAhdmFsdWUua2V5LnRyaW0oKSB8fCAhQXJyYXkuaXNBcnJheSh2YWx1ZS5jb2x1bW5zKSB8fCB2YWx1ZS5jb2x1bW5zLnNvbWUoKGNvbHVtbikgPT4gdHlwZW9mIGNvbHVtbiAhPT0gInN0cmluZyIgfHwgIWNvbHVtbi50cmltKCkpKSB0aHJvdyBuZXcgRXJyb3IoYHJlcGxpY2EgY29sbGVjdGlvbiAke3BhdGh9IHJlcXVpcmVzIGEgdGFibGUsIGtleSwgYW5kIGNvbHVtbnNgKTsKCWZvciAoY29uc3QgZmllbGQgb2YgWwoJCSJtYXhSb3dzIiwKCQkibWF4Qnl0ZXMiLAoJCSJyZXRlbnRpb25NcyIKCV0pIHsKCQljb25zdCBidWRnZXQgPSB2YWx1ZVtmaWVsZF07CgkJaWYgKGJ1ZGdldCAhPT0gdm9pZCAwICYmICh0eXBlb2YgYnVkZ2V0ICE9PSAibnVtYmVyIiB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIoYnVkZ2V0KSB8fCBidWRnZXQgPD0gMCkpIHRocm93IG5ldyBFcnJvcihgcmVwbGljYSBjb2xsZWN0aW9uICR7cGF0aH0gJHtmaWVsZH0gbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXJgKTsKCX0KCWlmICh2YWx1ZS5tb2RlICE9PSB2b2lkIDAgJiYgdmFsdWUubW9kZSAhPT0gImVhZ2VyIiAmJiB2YWx1ZS5tb2RlICE9PSAicHJvZ3Jlc3NpdmUiKSB0aHJvdyBuZXcgRXJyb3IoYHJlcGxpY2EgY29sbGVjdGlvbiAke3BhdGh9IGhhcyBhbiBpbnZhbGlkIGNvbXBsZXRlbmVzcyBtb2RlYCk7CglpZiAodmFsdWUub3JkZXJEaXJlY3Rpb24gIT09IHZvaWQgMCAmJiB2YWx1ZS5vcmRlckRpcmVjdGlvbiAhPT0gImFzYyIgJiYgdmFsdWUub3JkZXJEaXJlY3Rpb24gIT09ICJkZXNjIikgdGhyb3cgbmV3IEVycm9yKGByZXBsaWNhIGNvbGxlY3Rpb24gJHtwYXRofSBoYXMgYW4gaW52YWxpZCBvcmRlciBkaXJlY3Rpb25gKTsKfTsKY29uc3QgdmFsaWRhdGVTdHJ1Y3R1cmVkUXVlcnlQbGFuID0gKHZhbHVlLCBwYXRoKSA9PiB7CglpZiAoIWlzUmVjb3JkKHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUudGFibGUgIT09ICJzdHJpbmciIHx8ICF2YWx1ZS50YWJsZS50cmltKCkgfHwgdHlwZW9mIHZhbHVlLmtleSAhPT0gInN0cmluZyIgfHwgIXZhbHVlLmtleS50cmltKCkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuY29sdW1ucykgfHwgdmFsdWUuY29sdW1ucy5sZW5ndGggPT09IDAgfHwgdmFsdWUuY29sdW1ucy5zb21lKChjb2x1bW4pID0+IHR5cGVvZiBjb2x1bW4gIT09ICJzdHJpbmciIHx8ICFjb2x1bW4udHJpbSgpKSkgdGhyb3cgbmV3IEVycm9yKGBvbmUtc2hvdCBxdWVyeSAke3BhdGh9IHJlcXVpcmVzIGEgc3RydWN0dXJlZCBsaXZlIHF1ZXJ5IHBsYW4gd2l0aCBhIHRhYmxlLCBrZXksIGFuZCBjb2x1bW5zYCk7CglpZiAoIXZhbHVlLmNvbHVtbnMuaW5jbHVkZXModmFsdWUua2V5KSkgdGhyb3cgbmV3IEVycm9yKGBvbmUtc2hvdCBxdWVyeSAke3BhdGh9IGxpdmUgcXVlcnkgcGxhbiBjb2x1bW5zIG11c3QgaW5jbHVkZSBpdHMga2V5YCk7CglpZiAodmFsdWUuZmlsdGVycyAhPT0gdm9pZCAwKSB7CgkJaWYgKCFpc1JlY29yZCh2YWx1ZS5maWx0ZXJzKSB8fCB0eXBlb2YgdmFsdWUuZmlsdGVycy5hcmd1bWVudCAhPT0gInN0cmluZyIgfHwgIXZhbHVlLmZpbHRlcnMuYXJndW1lbnQudHJpbSgpIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMpIHx8IHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMubGVuZ3RoID09PSAwIHx8IHZhbHVlLmZpbHRlcnMuYWxsb3dlZENvbHVtbnMuc29tZSgoY29sdW1uKSA9PiB0eXBlb2YgY29sdW1uICE9PSAic3RyaW5nIiB8fCAhY29sdW1uLnRyaW0oKSkgfHwgIUFycmF5LmlzQXJyYXkodmFsdWUuZmlsdGVycy5hbGxvd2VkT3BlcmF0b3JzKSB8fCB2YWx1ZS5maWx0ZXJzLmFsbG93ZWRPcGVyYXRvcnMubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoYHN0cnVjdHVyZWQgcXVlcnkgcGxhbiAke3BhdGh9IGZpbHRlcnMgbXVzdCBkZWNsYXJlIGFuIGFyZ3VtZW50LCBhbGxvd2VkIGNvbHVtbnMsIGFuZCBhbGxvd2VkIG9wZXJhdG9yc2ApOwoJCWNvbnN0IG9wZXJhdG9ycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCQkJImNvbnRhaW5zIiwKCQkJIm5vdENvbnRhaW5zIiwKCQkJImVxdWFscyIsCgkJCSJub3RFcXVhbHMiLAoJCQkic3RhcnRzV2l0aCIsCgkJCSJlbmRzV2l0aCIsCgkJCSJlbXB0eSIsCgkJCSJub3RFbXB0eSIsCgkJCSJvbmVPZiIsCgkJCSJsZXNzVGhhbiIsCgkJCSJsZXNzVGhhbk9yRXF1YWwiLAoJCQkiZ3JlYXRlclRoYW4iLAoJCQkiZ3JlYXRlclRoYW5PckVxdWFsIiwKCQkJImluUmFuZ2UiCgkJXSk7CgkJaWYgKHZhbHVlLmZpbHRlcnMuYWxsb3dlZE9wZXJhdG9ycy5zb21lKChvcGVyYXRvcikgPT4gdHlwZW9mIG9wZXJhdG9yICE9PSAic3RyaW5nIiB8fCAhb3BlcmF0b3JzLmhhcyhvcGVyYXRvcikpKSB0aHJvdyBuZXcgRXJyb3IoYHN0cnVjdHVyZWQgcXVlcnkgcGxhbiAke3BhdGh9IGZpbHRlcnMgY29udGFpbnMgYW4gdW5zdXBwb3J0ZWQgb3BlcmF0b3JgKTsKCX0KfTsKY29uc3QgdmlzaWJpbGl0eU9wZXJhdG9ycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCSJwdWJsaWMiLAoJInBlcm1pc3Npb24iLAoJInJvbGUiLAoJImVxQ29udGV4dCIsCgkiaW5TZXQiLAoJImFuZCIsCgkib3IiLAoJIm5vdCIKXSk7CmNvbnN0IHZpc2liaWxpdHlDb250ZXh0cyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsKCSJhY2NvdW50LmlkIiwKCSJtZW1iZXIuaWQiLAoJInRlbmFudC5pZCIKXSk7CmNvbnN0IHZhbGlkYXRlRXhhY3RPYmplY3QgPSAodmFsdWUsIHBhdGgsIGZpZWxkcykgPT4gewoJaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofSBtdXN0IGJlIGFuIG9iamVjdGApOwoJY29uc3QgYWxsb3dlZCA9IG5ldyBTZXQoZmllbGRzKTsKCWNvbnN0IHVuZXhwZWN0ZWQgPSBPYmplY3Qua2V5cyh2YWx1ZSkuZmluZCgoZmllbGQpID0+ICFhbGxvd2VkLmhhcyhmaWVsZCkpOwoJaWYgKHVuZXhwZWN0ZWQgIT09IHZvaWQgMCkgdGhyb3cgbmV3IEVycm9yKGAke3BhdGh9IGhhcyB1bnN1cHBvcnRlZCBmaWVsZCAke3VuZXhwZWN0ZWR9YCk7Cn07CmNvbnN0IHJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nID0gKHZhbHVlLCBwYXRoKSA9PiB7CglpZiAodHlwZW9mIHZhbHVlICE9PSAic3RyaW5nIiB8fCAhdmFsdWUudHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdgKTsKCXJldHVybiB2YWx1ZTsKfTsKY29uc3QgdmFsaWRhdGVWaXNpYmlsaXR5Q29udGV4dCA9ICh2YWx1ZSwgcGF0aCkgPT4gewoJaWYgKHR5cGVvZiB2YWx1ZSAhPT0gInN0cmluZyIgfHwgIXZpc2liaWxpdHlDb250ZXh0cy5oYXModmFsdWUpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0gbXVzdCBiZSBhY2NvdW50LmlkLCBtZW1iZXIuaWQsIG9yIHRlbmFudC5pZGApOwoJcmV0dXJuIHZhbHVlOwp9Owpjb25zdCB2YWxpZGF0ZVZpc2liaWxpdHlFeHByZXNzaW9uID0gKHZhbHVlLCBwYXRoLCBzZXRzLCBhbmNlc3RvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpKSA9PiB7Cgl2YWxpZGF0ZUV4YWN0T2JqZWN0KHZhbHVlLCBwYXRoLCBbCgkJIm9wZXJhdG9yIiwKCQkiY29sdW1uIiwKCQkiY29udGV4dCIsCgkJInNldCIsCgkJInZhbHVlIiwKCQkiY2hpbGRyZW4iCgldKTsKCWlmIChhbmNlc3RvcnMuaGFzKHZhbHVlKSkgdGhyb3cgbmV3IEVycm9yKGAke3BhdGh9IGNvbnRhaW5zIGEgY3ljbGVgKTsKCWNvbnN0IG9wZXJhdG9yID0gdmFsdWUub3BlcmF0b3I7CglpZiAodHlwZW9mIG9wZXJhdG9yICE9PSAic3RyaW5nIiB8fCAhdmlzaWJpbGl0eU9wZXJhdG9ycy5oYXMob3BlcmF0b3IpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0ub3BlcmF0b3IgaXMgdW5zdXBwb3J0ZWRgKTsKCWNvbnN0IG5lc3RlZCA9IG5ldyBTZXQoYW5jZXN0b3JzKTsKCW5lc3RlZC5hZGQodmFsdWUpOwoJc3dpdGNoIChvcGVyYXRvcikgewoJCWNhc2UgInB1YmxpYyI6CgkJCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsib3BlcmF0b3IiXSk7CgkJCXJldHVybjsKCQljYXNlICJwZXJtaXNzaW9uIjoKCQljYXNlICJyb2xlIjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJ2YWx1ZSJdKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcodmFsdWUudmFsdWUsIGAke3BhdGh9LnZhbHVlYCk7CgkJCXJldHVybjsKCQljYXNlICJlcUNvbnRleHQiOgoJCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KHZhbHVlLCBwYXRoLCBbCgkJCQkib3BlcmF0b3IiLAoJCQkJImNvbHVtbiIsCgkJCQkiY29udGV4dCIKCQkJXSk7CgkJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKHZhbHVlLmNvbHVtbiwgYCR7cGF0aH0uY29sdW1uYCk7CgkJCXZhbGlkYXRlVmlzaWJpbGl0eUNvbnRleHQodmFsdWUuY29udGV4dCwgYCR7cGF0aH0uY29udGV4dGApOwoJCQlyZXR1cm47CgkJY2FzZSAiaW5TZXQiOiB7CgkJCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsKCQkJCSJvcGVyYXRvciIsCgkJCQkiY29sdW1uIiwKCQkJCSJzZXQiCgkJCV0pOwoJCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyh2YWx1ZS5jb2x1bW4sIGAke3BhdGh9LmNvbHVtbmApOwoJCQljb25zdCBzZXQgPSByZXF1aXJlVmlzaWJpbGl0eVN0cmluZyh2YWx1ZS5zZXQsIGAke3BhdGh9LnNldGApOwoJCQlpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzZXRzLCBzZXQpKSB0aHJvdyBuZXcgRXJyb3IoYCR7cGF0aH0uc2V0IHJlZmVyZW5jZXMgdW5rbm93biB2aXNpYmlsaXR5IHNldCAke3NldH1gKTsKCQkJcmV0dXJuOwoJCX0KCQljYXNlICJhbmQiOgoJCWNhc2UgIm9yIjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJjaGlsZHJlbiJdKTsKCQkJaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlLmNoaWxkcmVuKSB8fCB2YWx1ZS5jaGlsZHJlbi5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS4ke29wZXJhdG9yfSByZXF1aXJlcyBjaGlsZHJlbmApOwoJCQl2YWx1ZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCwgaW5kZXgpID0+IHZhbGlkYXRlVmlzaWJpbGl0eUV4cHJlc3Npb24oY2hpbGQsIGAke3BhdGh9LmNoaWxkcmVuWyR7aW5kZXh9XWAsIHNldHMsIG5lc3RlZCkpOwoJCQlyZXR1cm47CgkJY2FzZSAibm90IjoKCQkJdmFsaWRhdGVFeGFjdE9iamVjdCh2YWx1ZSwgcGF0aCwgWyJvcGVyYXRvciIsICJjaGlsZHJlbiJdKTsKCQkJaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlLmNoaWxkcmVuKSB8fCB2YWx1ZS5jaGlsZHJlbi5sZW5ndGggIT09IDEpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS5ub3QgcmVxdWlyZXMgZXhhY3RseSBvbmUgY2hpbGRgKTsKCQkJdmFsaWRhdGVWaXNpYmlsaXR5RXhwcmVzc2lvbih2YWx1ZS5jaGlsZHJlblswXSwgYCR7cGF0aH0uY2hpbGRyZW5bMF1gLCBzZXRzLCBuZXN0ZWQpOwoJCQlyZXR1cm47Cgl9Cn07CmNvbnN0IHZhbGlkYXRlVmlzaWJpbGl0eVBsYW4gPSAodmFsdWUsIHBhdGgpID0+IHsKCXZhbGlkYXRlRXhhY3RPYmplY3QodmFsdWUsIHBhdGgsIFsKCQkidGFibGUiLAoJCSJrZXkiLAoJCSJzZXRzIiwKCQkid2hlcmUiCgldKTsKCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKHZhbHVlLnRhYmxlLCBgJHtwYXRofS50YWJsZWApOwoJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcodmFsdWUua2V5LCBgJHtwYXRofS5rZXlgKTsKCWlmICghaXNSZWNvcmQodmFsdWUuc2V0cykpIHRocm93IG5ldyBFcnJvcihgJHtwYXRofS5zZXRzIG11c3QgYmUgYW4gb2JqZWN0YCk7Cglmb3IgKGNvbnN0IFtuYW1lLCBjYW5kaWRhdGVdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlLnNldHMpKSB7CgkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcobmFtZSwgYCR7cGF0aH0uc2V0cyBrZXlgKTsKCQljb25zdCBzZXRQYXRoID0gYCR7cGF0aH0uc2V0cy4ke25hbWV9YDsKCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KGNhbmRpZGF0ZSwgc2V0UGF0aCwgWwoJCQkidGFibGUiLAoJCQkic2VsZWN0IiwKCQkJImpvaW5zIiwKCQkJIndoZXJlIgoJCV0pOwoJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKGNhbmRpZGF0ZS50YWJsZSwgYCR7c2V0UGF0aH0udGFibGVgKTsKCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyhjYW5kaWRhdGUuc2VsZWN0LCBgJHtzZXRQYXRofS5zZWxlY3RgKTsKCQlpZiAoIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlLmpvaW5zKSkgdGhyb3cgbmV3IEVycm9yKGAke3NldFBhdGh9LmpvaW5zIG11c3QgYmUgYW4gYXJyYXlgKTsKCQljYW5kaWRhdGUuam9pbnMuZm9yRWFjaCgoam9pbiwgaW5kZXgpID0+IHsKCQkJY29uc3Qgam9pblBhdGggPSBgJHtzZXRQYXRofS5qb2luc1ske2luZGV4fV1gOwoJCQl2YWxpZGF0ZUV4YWN0T2JqZWN0KGpvaW4sIGpvaW5QYXRoLCBbCgkJCQkidGFibGUiLAoJCQkJImxlZnRDb2x1bW4iLAoJCQkJInJpZ2h0Q29sdW1uIgoJCQldKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoam9pbi50YWJsZSwgYCR7am9pblBhdGh9LnRhYmxlYCk7CgkJCXJlcXVpcmVWaXNpYmlsaXR5U3RyaW5nKGpvaW4ubGVmdENvbHVtbiwgYCR7am9pblBhdGh9LmxlZnRDb2x1bW5gKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoam9pbi5yaWdodENvbHVtbiwgYCR7am9pblBhdGh9LnJpZ2h0Q29sdW1uYCk7CgkJfSk7CgkJaWYgKCFBcnJheS5pc0FycmF5KGNhbmRpZGF0ZS53aGVyZSkpIHRocm93IG5ldyBFcnJvcihgJHtzZXRQYXRofS53aGVyZSBtdXN0IGJlIGFuIGFycmF5YCk7CgkJY2FuZGlkYXRlLndoZXJlLmZvckVhY2goKGNvbnN0cmFpbnQsIGluZGV4KSA9PiB7CgkJCWNvbnN0IGNvbnN0cmFpbnRQYXRoID0gYCR7c2V0UGF0aH0ud2hlcmVbJHtpbmRleH1dYDsKCQkJdmFsaWRhdGVFeGFjdE9iamVjdChjb25zdHJhaW50LCBjb25zdHJhaW50UGF0aCwgWwoJCQkJInRhYmxlIiwKCQkJCSJjb2x1bW4iLAoJCQkJImNvbnRleHQiCgkJCV0pOwoJCQlyZXF1aXJlVmlzaWJpbGl0eVN0cmluZyhjb25zdHJhaW50LnRhYmxlLCBgJHtjb25zdHJhaW50UGF0aH0udGFibGVgKTsKCQkJcmVxdWlyZVZpc2liaWxpdHlTdHJpbmcoY29uc3RyYWludC5jb2x1bW4sIGAke2NvbnN0cmFpbnRQYXRofS5jb2x1bW5gKTsKCQkJdmFsaWRhdGVWaXNpYmlsaXR5Q29udGV4dChjb25zdHJhaW50LmNvbnRleHQsIGAke2NvbnN0cmFpbnRQYXRofS5jb250ZXh0YCk7CgkJfSk7Cgl9Cgl2YWxpZGF0ZVZpc2liaWxpdHlFeHByZXNzaW9uKHZhbHVlLndoZXJlLCBgJHtwYXRofS53aGVyZWAsIHZhbHVlLnNldHMpOwp9Owpjb25zdCBmcmVlemVWaXNpYmlsaXR5RXhwcmVzc2lvbiA9IChleHByZXNzaW9uKSA9PiBmcmVlemUoewoJLi4uZXhwcmVzc2lvbiwKCWNoaWxkcmVuOiBleHByZXNzaW9uLmNoaWxkcmVuID09PSB2b2lkIDAgPyB2b2lkIDAgOiBmcmVlemUoZXhwcmVzc2lvbi5jaGlsZHJlbi5tYXAoZnJlZXplVmlzaWJpbGl0eUV4cHJlc3Npb24pKQp9KTsKY29uc3QgZnJlZXplVmlzaWJpbGl0eVBsYW4gPSAocGxhbikgPT4gewoJY29uc3Qgc2V0cyA9IHt9OwoJZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHBsYW4uc2V0cykuc29ydCgpKSB7CgkJY29uc3Qgc2V0ID0gcGxhbi5zZXRzW25hbWVdOwoJCXNldHNbbmFtZV0gPSBmcmVlemUoewoJCQkuLi5zZXQsCgkJCWpvaW5zOiBmcmVlemUoc2V0LmpvaW5zLm1hcCgoam9pbikgPT4gZnJlZXplKHsgLi4uam9pbiB9KSkpLAoJCQl3aGVyZTogZnJlZXplKHNldC53aGVyZS5tYXAoKGNvbnN0cmFpbnQpID0+IGZyZWV6ZSh7IC4uLmNvbnN0cmFpbnQgfSkpKQoJCX0pOwoJfQoJcmV0dXJuIGZyZWV6ZSh7CgkJLi4ucGxhbiwKCQlzZXRzOiBmcmVlemUoc2V0cyksCgkJd2hlcmU6IGZyZWV6ZVZpc2liaWxpdHlFeHByZXNzaW9uKHBsYW4ud2hlcmUpCgl9KTsKfTsKLyoqIERlY2xhcmUgYW5kIHZhbGlkYXRlIG9uZSBzb3VyY2UgdGFibGUncyBsYW5ndWFnZS1uZXV0cmFsIHZpc2liaWxpdHkgcGxhbi4gKi8KZnVuY3Rpb24gdmlzaWJpbGl0eShvcHRpb25zKSB7Cgl2YWxpZGF0ZVZpc2liaWxpdHlQbGFuKG9wdGlvbnMsICJ2aXNpYmlsaXR5Iik7CglyZXR1cm4gZnJlZXplVmlzaWJpbGl0eVBsYW4ob3B0aW9ucyk7Cn0KY29uc3QgZXhlY3V0YWJsZU9wdGlvbnMgPSAob3B0aW9ucykgPT4gZnJlZXplKHsgLi4ub3B0aW9ucyB9KTsKY29uc3QgcXVlcnlEZWZpbml0aW9uID0gKG9wdGlvbnMsIGRlbGl2ZXJ5T3ZlcnJpZGUpID0+IHsKCWNvbnN0IGxpdmVRdWVyeVBsYW4gPSBvcHRpb25zLmxpdmVRdWVyeVBsYW47Cgljb25zdCByZXBsaWNhID0gb3B0aW9ucy5yZXBsaWNhOwoJY29uc3QgZGVsaXZlcnkgPSBkZWxpdmVyeU92ZXJyaWRlID8/IG9wdGlvbnMuZGVsaXZlcnkgPz8gIm9uZVNob3QiOwoJaWYgKGRlbGl2ZXJ5ID09PSAibGl2ZSIgJiYgIWxpdmVRdWVyeVBsYW4pIHRocm93IG5ldyBFcnJvcigibGl2ZSBxdWVyeSByZXF1aXJlcyBhIGxpdmUgcXVlcnkgcGxhbiIpOwoJaWYgKGRlbGl2ZXJ5ID09PSAib25lU2hvdCIpIHsKCQlpZiAoIWxpdmVRdWVyeVBsYW4pIHRocm93IG5ldyBFcnJvcigib25lLXNob3QgcXVlcnkgcmVxdWlyZXMgYSBzdHJ1Y3R1cmVkIGxpdmUgcXVlcnkgcGxhbiIpOwoJCXZhbGlkYXRlU3RydWN0dXJlZFF1ZXJ5UGxhbihsaXZlUXVlcnlQbGFuLCAiPGV4cG9ydD4iKTsKCX0KCWlmIChkZWxpdmVyeSA9PT0gInJlcGxpY2EiKSB7CgkJaWYgKCFyZXBsaWNhKSB0aHJvdyBuZXcgRXJyb3IoInJlcGxpY2EgY29sbGVjdGlvbiByZXF1aXJlcyBhIHJlcGxpY2EgZGVmaW5pdGlvbiIpOwoJCXZhbGlkYXRlUmVwbGljYUNvbGxlY3Rpb24ocmVwbGljYSwgIjxleHBvcnQ+Iik7Cgl9CglyZXR1cm4gZnJlZXplKHsKCQlraW5kOiAicXVlcnkiLAoJCWRlbGl2ZXJ5LAoJCWxpdmVRdWVyeVBsYW4sCgkJcmVwbGljYSwKCQlvcHRpb25zOiBleGVjdXRhYmxlT3B0aW9ucyhvcHRpb25zKSwKCQloYW5kbGVyOiBvcHRpb25zLnJ1bgoJfSk7Cn07Ci8qKiBEZWNsYXJlIGFuIGV4ZWN1dGFibGUgbGl2ZSBxdWVyeSBleHBvcnQgd2l0aCBhIHN0cnVjdHVyZWQgbGl2ZSBwbGFuLiAqLwpmdW5jdGlvbiBsaXZlUXVlcnkob3B0aW9ucyA9IHt9KSB7CglyZXR1cm4gcXVlcnlEZWZpbml0aW9uKHsKCQkuLi5vcHRpb25zLAoJCWRlbGl2ZXJ5OiAibGl2ZSIKCX0sICJsaXZlIik7Cn0KY29uc3QgcmVkdWNlckRlZmluaXRpb24gPSAob3B0aW9ucywgaW50ZXJuYWwgPSBmYWxzZSkgPT4gewoJdmFsaWRhdGVPZmZsaW5lUG9saWN5KG9wdGlvbnMub2ZmbGluZSwgIjxleHBvcnQ+Iik7CglpZiAob3B0aW9ucy5vcHRpbWlzdGljICE9PSB2b2lkIDApIHZhbGlkYXRlT3B0aW1pc3RpY1RyYW5zYWN0aW9uKG9wdGlvbnMub3B0aW1pc3RpYywgIjxleHBvcnQ+Iik7CglpZiAob3B0aW9ucy5pbnRlcmFjdGl2ZSA9PT0gZmFsc2UgJiYgb3B0aW9ucy5vcHRpbWlzdGljICE9PSB2b2lkIDApIHRocm93IG5ldyBFcnJvcigibm9uLWludGVyYWN0aXZlIHJlZHVjZXIgPGV4cG9ydD4gY2Fubm90IGRlY2xhcmUgb3B0aW1pc3RpYyBtZXRhZGF0YSIpOwoJaWYgKG9wdGlvbnMuaW50ZXJhY3RpdmUgIT09IGZhbHNlICYmIG9wdGlvbnMub3B0aW1pc3RpYyA9PT0gdm9pZCAwICYmICFvcHRpb25zLm5vbk9wdGltaXN0aWNSZWFzb24/LnRyaW0oKSkgdGhyb3cgbmV3IEVycm9yKCJpbnRlcmFjdGl2ZSByZWR1Y2VyIDxleHBvcnQ+IHJlcXVpcmVzIGFuIG9wdGltaXN0aWMgdHJhbnNhY3Rpb24gb3Igbm9uT3B0aW1pc3RpY1JlYXNvbiIpOwoJcmV0dXJuIGZyZWV6ZSh7CgkJa2luZDogInJlZHVjZXIiLAoJCWludGVybmFsOiBpbnRlcm5hbCB8fCBvcHRpb25zLmludGVybmFsLAoJCW9wdGlvbnM6IGV4ZWN1dGFibGVPcHRpb25zKG9wdGlvbnMpLAoJCWhhbmRsZXI6IG9wdGlvbnMucnVuCgl9KTsKfTsKLyoqIERlY2xhcmUgYW4gZXhlY3V0YWJsZSBwdWJsaWMgcmVkdWNlciBleHBvcnQuICovCmZ1bmN0aW9uIHJlZHVjZXIob3B0aW9ucykgewoJcmV0dXJuIHJlZHVjZXJEZWZpbml0aW9uKG9wdGlvbnMpOwp9Ci8vI2VuZHJlZ2lvbgovLyNyZWdpb24gZ29udmV4L21lc3NhZ2VzLnRzCmNvbnN0IG1lc3NhZ2VzVmlzaWJpbGl0eSA9IHZpc2liaWxpdHkoewoJdGFibGU6ICJtZXNzYWdlcyIsCglrZXk6ICJpZCIsCglzZXRzOiB7fSwKCXdoZXJlOiB7IG9wZXJhdG9yOiAicHVibGljIiB9Cn0pOwpjb25zdCBsaXN0ID0gbGl2ZVF1ZXJ5KHsKCWFyZ3M6IHNjaGVtYS5vYmplY3Qoe30pLAoJcmVzdWx0OiBzY2hlbWEuYXJyYXkoc2NoZW1hLm9iamVjdCh7CgkJaWQ6IHNjaGVtYS5pZCgibWVzc2FnZXMiKSwKCQlib2R5OiBzY2hlbWEuc3RyaW5nKCksCgkJYXV0aG9yOiBzY2hlbWEuc3RyaW5nKCksCgkJY3JlYXRlZF9hdDogc2NoZW1hLmRhdGV0aW1lKCkKCX0pKSwKCWxpdmVRdWVyeVBsYW46IHsKCQl0YWJsZTogIm1lc3NhZ2VzIiwKCQlrZXk6ICJpZCIsCgkJY29sdW1uczogWwoJCQkiaWQiLAoJCQkiYm9keSIsCgkJCSJhdXRob3IiLAoJCQkiY3JlYXRlZF9hdCIKCQldLAoJCXNvcnQ6IHsKCQkJZGVmYXVsdENvbHVtbjogImNyZWF0ZWRfYXQiLAoJCQlkZWZhdWx0RGlyZWN0aW9uOiAiYXNjIiwKCQkJYWxsb3dlZENvbHVtbnM6IFsiY3JlYXRlZF9hdCJdCgkJfQoJfSwKCXJ1bjogYXN5bmMgKCkgPT4gW10KfSk7CmNvbnN0IHNlbmQgPSByZWR1Y2VyKHsKCWFyZ3M6IHNjaGVtYS5vYmplY3QoeyBib2R5OiBzY2hlbWEuc3RyaW5nKCkgfSksCglyZXN1bHQ6IHNjaGVtYS5vYmplY3QoewoJCWlkOiBzY2hlbWEuaWQoIm1lc3NhZ2VzIiksCgkJYm9keTogc2NoZW1hLnN0cmluZygpLAoJCWF1dGhvcjogc2NoZW1hLnN0cmluZygpLAoJCWNyZWF0ZWRfYXQ6IHNjaGVtYS5kYXRldGltZSgpCgl9KSwKCW9mZmxpbmU6IHsKCQltb2RlOiAib25saW5lT25seSIsCgkJcmVhc29uOiAic2VydmVyIGFzc2lnbnMgdGhlIG1lc3NhZ2UgaWQiCgl9LAoJbm9uT3B0aW1pc3RpY1JlYXNvbjogInNlcnZlciBhc3NpZ25zIHRoZSBtZXNzYWdlIGlkIiwKCXJ1bjogYXN5bmMgKHsgbm93IH0sIGFyZ3MpID0+ICh7CgkJaWQ6ICJwZW5kaW5nIiwKCQlib2R5OiBhcmdzLmJvZHksCgkJYXV0aG9yOiAiZGVtby11c2VyIiwKCQljcmVhdGVkX2F0OiBuZXcgRGF0ZShub3cpLnRvSVNPU3RyaW5nKCkKCX0pCn0pOwovLyNlbmRyZWdpb24KZXhwb3J0IHsgbGlzdCwgbWVzc2FnZXNWaXNpYmlsaXR5LCBzZW5kIH07Cg=="
85
219
  }
86
220
  },
87
- "bundle": {
88
- "hash": "4dd5cc5bf465e6284d6c35a29a09c1a7eca8939c5c8a72fd62c01a78af4643db",
89
- "modulePath": "gonvexapp/my-vite-app",
90
- "packageName": "backend",
91
- "files": {
92
- "app/messages.go": "cGFja2FnZSBiYWNrZW5kCgppbXBvcnQgKAoJInRpbWUiCgoJImdpdGh1Yi5jb20vZ29udmV4L2dvbnZleC9wa2cvZ29udmV4IgopCgp0eXBlIExpc3RNZXNzYWdlc0FyZ3Mgc3RydWN0e30KCnR5cGUgU2VuZE1lc3NhZ2VBcmdzIHN0cnVjdCB7CglCb2R5IHN0cmluZyBganNvbjoiYm9keSJgCn0KCnR5cGUgTWVzc2FnZSBzdHJ1Y3QgewoJSUQgICAgICAgIHN0cmluZyAgICBganNvbjoiaWQiYAoJQm9keSAgICAgIHN0cmluZyAgICBganNvbjoiYm9keSJgCglBdXRob3IgICAgc3RyaW5nICAgIGBqc29uOiJhdXRob3IiYAoJQ3JlYXRlZEF0IHRpbWUuVGltZSBganNvbjoiY3JlYXRlZF9hdCJgCn0KCmZ1bmMgUmVnaXN0ZXIoYXBwICpnb252ZXguQXBwKSB7CglhcHAuUXVlcnkoIm1lc3NhZ2VzLmxpc3QiLCBMaXN0TWVzc2FnZXMpCglhcHAuTXV0YXRpb24oIm1lc3NhZ2VzLnNlbmQiLCBTZW5kTWVzc2FnZSkKfQoKZnVuYyBMaXN0TWVzc2FnZXMoY3R4ICpnb252ZXguUXVlcnlDdHgsIGFyZ3MgTGlzdE1lc3NhZ2VzQXJncykgKFtdTWVzc2FnZSwgZXJyb3IpIHsKCXJldHVybiBbXU1lc3NhZ2V7fSwgbmlsCn0KCmZ1bmMgU2VuZE1lc3NhZ2UoY3R4ICpnb252ZXguTXV0YXRpb25DdHgsIGFyZ3MgU2VuZE1lc3NhZ2VBcmdzKSAoTWVzc2FnZSwgZXJyb3IpIHsKCXJldHVybiBNZXNzYWdlewoJCUlEOiAgICAgICAgInBlbmRpbmciLAoJCUJvZHk6ICAgICAgYXJncy5Cb2R5LAoJCUF1dGhvcjogICAgImRlbW8tdXNlciIsCgkJQ3JlYXRlZEF0OiB0aW1lLk5vdygpLlVUQygpLAoJfSwgbmlsCn0K",
93
- "app/schema.go": "cGFja2FnZSBiYWNrZW5kCgppbXBvcnQgImdpdGh1Yi5jb20vZ29udmV4L2dvbnZleC9wa2cvZ29udmV4IgoKZnVuYyBTY2hlbWEocyAqZ29udmV4LlNjaGVtYSkgewoJcy5UZW5hbnRUYWJsZSgibWVzc2FnZXMiLCBmdW5jKHQgKmdvbnZleC5UYWJsZSkgewoJCXQuSUQoImlkIikKCQl0LlN0cmluZygiYm9keSIpCgkJdC5TdHJpbmcoImF1dGhvciIpCgkJdC5UaW1lKCJjcmVhdGVkX2F0IikKCgkJdC5JbmRleCgiYnlfY3JlYXRlZF9hdCIsICJjcmVhdGVkX2F0IikKCX0pCn0K"
221
+ "visibility": {
222
+ "messages": {
223
+ "table": "messages",
224
+ "key": "id",
225
+ "sets": {},
226
+ "where": {
227
+ "operator": "public"
228
+ }
94
229
  }
95
230
  }
96
231
  }