@burdenoff/microfe-theculturepost 2026.704.2 → 2026.705.2
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.
- package/dist/theculturepost/TheCulturePostRoot.js +63 -45
- package/dist/theculturepost/TheCulturePostRoot.js.map +1 -1
- package/dist/theculturepost/TheCulturePostRoutes.js +17 -9
- package/dist/theculturepost/TheCulturePostRoutes.js.map +1 -1
- package/dist/theculturepost/components/AddCitationDialog.js +131 -102
- package/dist/theculturepost/components/AddCitationDialog.js.map +1 -1
- package/dist/theculturepost/components/ArchiveItemCard.js +56 -43
- package/dist/theculturepost/components/ArchiveItemCard.js.map +1 -1
- package/dist/theculturepost/components/AudioPlayer.js +74 -0
- package/dist/theculturepost/components/AudioPlayer.js.map +1 -0
- package/dist/theculturepost/components/CitationList.js +215 -105
- package/dist/theculturepost/components/CitationList.js.map +1 -1
- package/dist/theculturepost/components/CollectionCard.js +32 -32
- package/dist/theculturepost/components/CollectionCard.js.map +1 -1
- package/dist/theculturepost/components/CreateArchiveItemDialog.js +133 -93
- package/dist/theculturepost/components/CreateArchiveItemDialog.js.map +1 -1
- package/dist/theculturepost/components/CreateCollectionDialog.js +91 -70
- package/dist/theculturepost/components/CreateCollectionDialog.js.map +1 -1
- package/dist/theculturepost/components/CreateStoryDialog.js +311 -132
- package/dist/theculturepost/components/CreateStoryDialog.js.map +1 -1
- package/dist/theculturepost/components/DecorativeCover.js +78 -0
- package/dist/theculturepost/components/DecorativeCover.js.map +1 -0
- package/dist/theculturepost/components/DecorativeDivider.js +45 -0
- package/dist/theculturepost/components/DecorativeDivider.js.map +1 -0
- package/dist/theculturepost/components/DiscussionCard.js +75 -60
- package/dist/theculturepost/components/DiscussionCard.js.map +1 -1
- package/dist/theculturepost/components/HistoryTimeline.js +115 -0
- package/dist/theculturepost/components/HistoryTimeline.js.map +1 -0
- package/dist/theculturepost/components/LifecycleStepper.js +33 -0
- package/dist/theculturepost/components/LifecycleStepper.js.map +1 -0
- package/dist/theculturepost/components/OpenDiscussionDialog.js +66 -56
- package/dist/theculturepost/components/OpenDiscussionDialog.js.map +1 -1
- package/dist/theculturepost/components/OralHistoryCard.js +6 -73
- package/dist/theculturepost/components/OverlayBadge.js +22 -0
- package/dist/theculturepost/components/OverlayBadge.js.map +1 -0
- package/dist/theculturepost/components/PageHero.js +62 -0
- package/dist/theculturepost/components/PageHero.js.map +1 -0
- package/dist/theculturepost/components/RecordOralHistoryDialog.js +306 -131
- package/dist/theculturepost/components/RecordOralHistoryDialog.js.map +1 -1
- package/dist/theculturepost/components/ReplyThread.js +268 -139
- package/dist/theculturepost/components/ReplyThread.js.map +1 -1
- package/dist/theculturepost/components/StatusBadge.js +9 -9
- package/dist/theculturepost/components/StatusBadge.js.map +1 -1
- package/dist/theculturepost/components/StoryCard.js +54 -49
- package/dist/theculturepost/components/StoryCard.js.map +1 -1
- package/dist/theculturepost/components/TopicCard.js +60 -41
- package/dist/theculturepost/components/TopicCard.js.map +1 -1
- package/dist/theculturepost/components/Waveform.js +31 -0
- package/dist/theculturepost/components/Waveform.js.map +1 -0
- package/dist/theculturepost/components/categoryMeta.js +20 -0
- package/dist/theculturepost/components/categoryMeta.js.map +1 -0
- package/dist/theculturepost/components/index.js +41 -0
- package/dist/theculturepost/components/viz/BarChart.js +53 -0
- package/dist/theculturepost/components/viz/BarChart.js.map +1 -0
- package/dist/theculturepost/components/viz/Donut.js +58 -0
- package/dist/theculturepost/components/viz/Donut.js.map +1 -0
- package/dist/theculturepost/components/viz/StatTile.js +35 -0
- package/dist/theculturepost/components/viz/StatTile.js.map +1 -0
- package/dist/theculturepost/components/viz/index.js +3 -0
- package/dist/theculturepost/hooks/useFiles.js +1 -1
- package/dist/theculturepost/hooks/useFiles.js.map +1 -1
- package/dist/theculturepost/pages/HomePage.js +247 -124
- package/dist/theculturepost/pages/HomePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.js +319 -127
- package/dist/theculturepost/pages/archive/ArchiveItemDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/archive/ArchivePage.js +265 -180
- package/dist/theculturepost/pages/archive/ArchivePage.js.map +1 -1
- package/dist/theculturepost/pages/archive/CollectionDetailPage.js +158 -143
- package/dist/theculturepost/pages/archive/CollectionDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js +155 -93
- package/dist/theculturepost/pages/discussions/DiscussionDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js +16 -16
- package/dist/theculturepost/pages/discussions/DiscussionsPage.js.map +1 -1
- package/dist/theculturepost/pages/governance/GovernancePage.js +293 -0
- package/dist/theculturepost/pages/governance/GovernancePage.js.map +1 -0
- package/dist/theculturepost/pages/stories/StoriesPage.js +18 -18
- package/dist/theculturepost/pages/stories/StoriesPage.js.map +1 -1
- package/dist/theculturepost/pages/stories/StoryDetailPage.js +603 -285
- package/dist/theculturepost/pages/stories/StoryDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/timeline/TimelinePage.js +162 -0
- package/dist/theculturepost/pages/timeline/TimelinePage.js.map +1 -0
- package/dist/theculturepost/pages/topics/TopicDetailPage.js +239 -163
- package/dist/theculturepost/pages/topics/TopicDetailPage.js.map +1 -1
- package/dist/theculturepost/pages/topics/TopicsPage.js +76 -74
- package/dist/theculturepost/pages/topics/TopicsPage.js.map +1 -1
- package/dist/theculturepost/styles/injectDisplayFont.js +11 -0
- package/dist/theculturepost/styles/injectDisplayFont.js.map +1 -0
- package/dist/theculturepost/utils/formatters.js +6 -1
- package/dist/theculturepost/utils/formatters.js.map +1 -1
- package/package.json +1 -1
- package/dist/theculturepost/components/OralHistoryCard.js.map +0 -1
|
@@ -3,13 +3,13 @@ import { formatEnumLabel as t } from "../utils/formatters.js";
|
|
|
3
3
|
import { useTcpCollections as n, useTcpCreateArchiveItem as r } from "../hooks/useTcpApi.js";
|
|
4
4
|
import "../hooks/index.js";
|
|
5
5
|
import { describeError as ee, notify as te } from "../lib/toast.js";
|
|
6
|
-
import {
|
|
7
|
-
import { TagInput as
|
|
8
|
-
import { useState as
|
|
9
|
-
import { jsx as
|
|
10
|
-
import { Button as
|
|
6
|
+
import { Counter as i, MediaDropzone as a } from "./RecordOralHistoryDialog.js";
|
|
7
|
+
import { TagInput as o } from "./TagInput.js";
|
|
8
|
+
import { useState as s } from "react";
|
|
9
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
10
|
+
import { Button as u, Input as d, Label as f, ResponsiveDialog as ne, ResponsiveDialogContent as re, ResponsiveDialogDescription as ie, ResponsiveDialogFooter as ae, ResponsiveDialogHeader as p, ResponsiveDialogTitle as m, Select as h, SelectContent as g, SelectItem as _, SelectTrigger as v, SelectValue as y, Textarea as b } from "@burdenoff/fe-libs/ui";
|
|
11
11
|
//#region src/theculturepost/components/CreateArchiveItemDialog.tsx
|
|
12
|
-
var
|
|
12
|
+
var x = [
|
|
13
13
|
"DOCUMENT",
|
|
14
14
|
"MANUSCRIPT",
|
|
15
15
|
"PHOTOGRAPH",
|
|
@@ -17,120 +17,152 @@ var S = [
|
|
|
17
17
|
"VIDEO",
|
|
18
18
|
"MAP",
|
|
19
19
|
"OBJECT"
|
|
20
|
-
],
|
|
20
|
+
], oe = [
|
|
21
21
|
"PUBLIC",
|
|
22
22
|
"COMMUNITY",
|
|
23
23
|
"RESTRICTED",
|
|
24
24
|
"EMBARGOED"
|
|
25
|
-
],
|
|
25
|
+
], se = {
|
|
26
|
+
PUBLIC: "Visible to everyone.",
|
|
27
|
+
COMMUNITY: "Available to community members.",
|
|
28
|
+
RESTRICTED: "Visible to selected groups.",
|
|
29
|
+
EMBARGOED: "Hidden until a future date."
|
|
30
|
+
}, S = 160, C = 600, w = 600, ce = 160, le = (e) => {
|
|
26
31
|
if (!e) return null;
|
|
27
32
|
let t = new Date(e);
|
|
28
33
|
return Number.isNaN(t.getTime()) ? null : t.toISOString();
|
|
29
34
|
};
|
|
30
|
-
function T({ open: T, onOpenChange: E, collectionId: D, onCreated:
|
|
31
|
-
let
|
|
35
|
+
function T({ open: T, onOpenChange: E, collectionId: D, onCreated: O }) {
|
|
36
|
+
let k = r(), ue = n({ limit: 100 }), [A, j] = s(""), [M, N] = s(""), [P, F] = s("DOCUMENT"), [I, L] = s("PUBLIC"), [R, z] = s(D ?? ""), [B, V] = s(null), [H, U] = s(""), [W, G] = s(""), [K, q] = s([]), [J, Y] = s([]), [X, Z] = s(""), [Q, $] = s(null), de = () => {
|
|
32
37
|
j(""), N(""), F("DOCUMENT"), L("PUBLIC"), z(D ?? ""), V(null), U(""), G(""), q([]), Y([]), Z(""), $(null);
|
|
33
38
|
};
|
|
34
|
-
return /* @__PURE__ */
|
|
39
|
+
return /* @__PURE__ */ c(ne, {
|
|
35
40
|
open: T,
|
|
36
41
|
onOpenChange: E,
|
|
37
|
-
children: /* @__PURE__ */
|
|
38
|
-
className: "sm:max-w-
|
|
42
|
+
children: /* @__PURE__ */ l(re, {
|
|
43
|
+
className: "sm:max-w-2xl",
|
|
39
44
|
children: [
|
|
40
|
-
/* @__PURE__ */
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
className: "flex max-h-[
|
|
45
|
+
/* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c(m, { children: "Add an artifact" }), /* @__PURE__ */ c(ie, { children: "Catalogue a manuscript, photograph, recording, map, object or document with its provenance." })] }),
|
|
46
|
+
/* @__PURE__ */ l("div", {
|
|
47
|
+
className: "flex max-h-[64vh] flex-col gap-4 overflow-y-auto py-2",
|
|
43
48
|
children: [
|
|
44
|
-
/* @__PURE__ */
|
|
49
|
+
/* @__PURE__ */ l("div", {
|
|
45
50
|
className: "grid gap-1.5",
|
|
46
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ c(f, { children: "File" }), /* @__PURE__ */ c(a, {
|
|
47
52
|
folder: e.artifacts,
|
|
48
53
|
accept: "image/*,audio/*,video/*,application/pdf",
|
|
49
|
-
|
|
50
|
-
hint: "Image, audio, video or PDF
|
|
51
|
-
|
|
52
|
-
onUploaded: V,
|
|
53
|
-
|
|
54
|
+
promptLabel: "Drag and drop the artifact file here",
|
|
55
|
+
hint: "Image, audio, video or PDF, up to 25 MB. One file per artifact.",
|
|
56
|
+
value: B,
|
|
57
|
+
onUploaded: (e) => V(e),
|
|
58
|
+
onClear: () => V(null)
|
|
54
59
|
})]
|
|
55
60
|
}),
|
|
56
|
-
/* @__PURE__ */
|
|
61
|
+
/* @__PURE__ */ l("div", {
|
|
57
62
|
className: "grid gap-1.5",
|
|
58
|
-
children: [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ l(f, {
|
|
65
|
+
htmlFor: "item-title",
|
|
66
|
+
children: ["Title ", /* @__PURE__ */ c("span", {
|
|
67
|
+
className: "text-status-error-text",
|
|
68
|
+
children: "*"
|
|
69
|
+
})]
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ c(d, {
|
|
72
|
+
id: "item-title",
|
|
73
|
+
value: A,
|
|
74
|
+
maxLength: S,
|
|
75
|
+
onChange: (e) => j(e.target.value),
|
|
76
|
+
placeholder: "e.g. Palm-leaf manuscript, 18th c."
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ c(i, {
|
|
79
|
+
length: A.length,
|
|
80
|
+
max: S
|
|
81
|
+
})
|
|
82
|
+
]
|
|
67
83
|
}),
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
-
className: "grid grid-cols-2
|
|
70
|
-
children: [/* @__PURE__ */
|
|
84
|
+
/* @__PURE__ */ l("div", {
|
|
85
|
+
className: "grid gap-3 sm:grid-cols-2",
|
|
86
|
+
children: [/* @__PURE__ */ l("div", {
|
|
71
87
|
className: "grid gap-1.5",
|
|
72
|
-
children: [/* @__PURE__ */
|
|
88
|
+
children: [/* @__PURE__ */ c(f, { children: "Kind" }), /* @__PURE__ */ l(h, {
|
|
73
89
|
value: P,
|
|
74
90
|
onValueChange: (e) => F(e),
|
|
75
|
-
children: [/* @__PURE__ */
|
|
91
|
+
children: [/* @__PURE__ */ c(v, { children: /* @__PURE__ */ c(y, {}) }), /* @__PURE__ */ c(g, { children: x.map((e) => /* @__PURE__ */ c(_, {
|
|
76
92
|
value: e,
|
|
77
93
|
children: t(e)
|
|
78
94
|
}, e)) })]
|
|
79
95
|
})]
|
|
80
|
-
}), /* @__PURE__ */
|
|
96
|
+
}), /* @__PURE__ */ l("div", {
|
|
81
97
|
className: "grid gap-1.5",
|
|
82
|
-
children: [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
children:
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ c(f, { children: "Access level" }),
|
|
100
|
+
/* @__PURE__ */ l(h, {
|
|
101
|
+
value: I,
|
|
102
|
+
onValueChange: (e) => L(e),
|
|
103
|
+
children: [/* @__PURE__ */ c(v, { children: /* @__PURE__ */ c(y, {}) }), /* @__PURE__ */ c(g, { children: oe.map((e) => /* @__PURE__ */ c(_, {
|
|
104
|
+
value: e,
|
|
105
|
+
children: t(e)
|
|
106
|
+
}, e)) })]
|
|
107
|
+
}),
|
|
108
|
+
/* @__PURE__ */ c("p", {
|
|
109
|
+
className: "text-xs text-text-tertiary",
|
|
110
|
+
children: se[I]
|
|
111
|
+
})
|
|
112
|
+
]
|
|
90
113
|
})]
|
|
91
114
|
}),
|
|
92
|
-
!D && /* @__PURE__ */
|
|
115
|
+
!D && /* @__PURE__ */ l("div", {
|
|
93
116
|
className: "grid gap-1.5",
|
|
94
|
-
children: [/* @__PURE__ */
|
|
117
|
+
children: [/* @__PURE__ */ c(f, { children: "Collection" }), /* @__PURE__ */ l(h, {
|
|
95
118
|
value: R,
|
|
96
119
|
onValueChange: z,
|
|
97
|
-
children: [/* @__PURE__ */
|
|
120
|
+
children: [/* @__PURE__ */ c(v, { children: /* @__PURE__ */ c(y, { placeholder: "Add to a collection (optional)" }) }), /* @__PURE__ */ c(g, { children: (ue.data ?? []).map((e) => /* @__PURE__ */ c(_, {
|
|
98
121
|
value: e.id,
|
|
99
122
|
children: e.name
|
|
100
123
|
}, e.id)) })]
|
|
101
124
|
})]
|
|
102
125
|
}),
|
|
103
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ l("div", {
|
|
104
127
|
className: "grid gap-1.5",
|
|
105
|
-
children: [
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ c(f, {
|
|
130
|
+
htmlFor: "item-desc",
|
|
131
|
+
children: "Description"
|
|
132
|
+
}),
|
|
133
|
+
/* @__PURE__ */ c(b, {
|
|
134
|
+
id: "item-desc",
|
|
135
|
+
value: M,
|
|
136
|
+
maxLength: C,
|
|
137
|
+
onChange: (e) => N(e.target.value),
|
|
138
|
+
rows: 2
|
|
139
|
+
}),
|
|
140
|
+
/* @__PURE__ */ c(i, {
|
|
141
|
+
length: M.length,
|
|
142
|
+
max: C
|
|
143
|
+
})
|
|
144
|
+
]
|
|
114
145
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
-
className: "grid grid-cols-2
|
|
117
|
-
children: [/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ l("div", {
|
|
147
|
+
className: "grid gap-3 sm:grid-cols-2",
|
|
148
|
+
children: [/* @__PURE__ */ l("div", {
|
|
118
149
|
className: "grid gap-1.5",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
150
|
+
children: [/* @__PURE__ */ c(f, {
|
|
120
151
|
htmlFor: "item-origin",
|
|
121
152
|
children: "Origin"
|
|
122
|
-
}), /* @__PURE__ */
|
|
153
|
+
}), /* @__PURE__ */ c(d, {
|
|
123
154
|
id: "item-origin",
|
|
124
155
|
value: W,
|
|
156
|
+
maxLength: ce,
|
|
125
157
|
onChange: (e) => G(e.target.value),
|
|
126
158
|
placeholder: "Place of origin"
|
|
127
159
|
})]
|
|
128
|
-
}), /* @__PURE__ */
|
|
160
|
+
}), /* @__PURE__ */ l("div", {
|
|
129
161
|
className: "grid gap-1.5",
|
|
130
|
-
children: [/* @__PURE__ */
|
|
162
|
+
children: [/* @__PURE__ */ c(f, {
|
|
131
163
|
htmlFor: "item-dated",
|
|
132
164
|
children: "Dated"
|
|
133
|
-
}), /* @__PURE__ */
|
|
165
|
+
}), /* @__PURE__ */ c(d, {
|
|
134
166
|
id: "item-dated",
|
|
135
167
|
type: "date",
|
|
136
168
|
value: X,
|
|
@@ -138,25 +170,33 @@ function T({ open: T, onOpenChange: E, collectionId: D, onCreated: ie }) {
|
|
|
138
170
|
})]
|
|
139
171
|
})]
|
|
140
172
|
}),
|
|
141
|
-
/* @__PURE__ */
|
|
173
|
+
/* @__PURE__ */ l("div", {
|
|
142
174
|
className: "grid gap-1.5",
|
|
143
|
-
children: [
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
175
|
+
children: [
|
|
176
|
+
/* @__PURE__ */ c(f, {
|
|
177
|
+
htmlFor: "item-provenance",
|
|
178
|
+
children: "Provenance"
|
|
179
|
+
}),
|
|
180
|
+
/* @__PURE__ */ c(b, {
|
|
181
|
+
id: "item-provenance",
|
|
182
|
+
value: H,
|
|
183
|
+
maxLength: w,
|
|
184
|
+
onChange: (e) => U(e.target.value),
|
|
185
|
+
placeholder: "Chain of custody / source history",
|
|
186
|
+
rows: 2
|
|
187
|
+
}),
|
|
188
|
+
/* @__PURE__ */ c(i, {
|
|
189
|
+
length: H.length,
|
|
190
|
+
max: w
|
|
191
|
+
})
|
|
192
|
+
]
|
|
153
193
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ l("div", {
|
|
155
195
|
className: "grid gap-1.5",
|
|
156
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ c(f, {
|
|
157
197
|
htmlFor: "item-langs",
|
|
158
198
|
children: "Languages"
|
|
159
|
-
}), /* @__PURE__ */ o
|
|
199
|
+
}), /* @__PURE__ */ c(o, {
|
|
160
200
|
id: "item-langs",
|
|
161
201
|
value: K,
|
|
162
202
|
onChange: q,
|
|
@@ -164,54 +204,54 @@ function T({ open: T, onOpenChange: E, collectionId: D, onCreated: ie }) {
|
|
|
164
204
|
preserveCase: !0
|
|
165
205
|
})]
|
|
166
206
|
}),
|
|
167
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ l("div", {
|
|
168
208
|
className: "grid gap-1.5",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
209
|
+
children: [/* @__PURE__ */ c(f, {
|
|
170
210
|
htmlFor: "item-tags",
|
|
171
211
|
children: "Tags"
|
|
172
|
-
}), /* @__PURE__ */ o
|
|
212
|
+
}), /* @__PURE__ */ c(o, {
|
|
173
213
|
id: "item-tags",
|
|
174
214
|
value: J,
|
|
175
215
|
onChange: Y,
|
|
176
216
|
placeholder: "Add tags…"
|
|
177
217
|
})]
|
|
178
218
|
}),
|
|
179
|
-
Q && /* @__PURE__ */
|
|
219
|
+
Q && /* @__PURE__ */ c("p", {
|
|
180
220
|
className: "text-sm text-status-error-text",
|
|
181
221
|
children: Q
|
|
182
222
|
})
|
|
183
223
|
]
|
|
184
224
|
}),
|
|
185
|
-
/* @__PURE__ */
|
|
225
|
+
/* @__PURE__ */ l(ae, { children: [/* @__PURE__ */ c(u, {
|
|
186
226
|
variant: "outline",
|
|
187
227
|
onClick: () => E(!1),
|
|
188
228
|
children: "Cancel"
|
|
189
|
-
}), /* @__PURE__ */
|
|
229
|
+
}), /* @__PURE__ */ c(u, {
|
|
190
230
|
onClick: async () => {
|
|
191
231
|
if (!A.trim()) {
|
|
192
232
|
$("A title is required.");
|
|
193
233
|
return;
|
|
194
234
|
}
|
|
195
235
|
try {
|
|
196
|
-
let e = await
|
|
236
|
+
let e = await k.mutateAsync({
|
|
197
237
|
title: A.trim(),
|
|
198
238
|
description: M.trim() || null,
|
|
199
239
|
kind: P,
|
|
200
240
|
accessLevel: I,
|
|
201
241
|
collectionId: R || null,
|
|
202
|
-
fileId: B,
|
|
242
|
+
fileId: B?.id ?? null,
|
|
203
243
|
provenance: H.trim() || null,
|
|
204
244
|
origin: W.trim() || null,
|
|
205
245
|
languages: K.length ? K : null,
|
|
206
246
|
tags: J.length ? J : null,
|
|
207
|
-
datedAt:
|
|
247
|
+
datedAt: le(X)
|
|
208
248
|
});
|
|
209
|
-
te.success("Artifact added", e.title), E(!1),
|
|
249
|
+
te.success("Artifact added", e.title), E(!1), de(), O?.(e);
|
|
210
250
|
} catch (e) {
|
|
211
251
|
$(ee(e));
|
|
212
252
|
}
|
|
213
253
|
},
|
|
214
|
-
disabled:
|
|
254
|
+
disabled: k.isPending,
|
|
215
255
|
children: "Add artifact"
|
|
216
256
|
})] })
|
|
217
257
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateArchiveItemDialog.js","names":[],"sources":["../../../src/theculturepost/components/CreateArchiveItemDialog.tsx"],"sourcesContent":["/**\n * CreateArchiveItemDialog — add an artifact to the archive.\n * @module theculturepost/components\n *\n * Writes `tcpCreateArchiveItem`. The binary is uploaded to wspace-files-svc and\n * only its id is stored here. Kind + access level are chosen up front.\n */\n\nimport { useState } from 'react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { TagInput } from './TagInput';\nimport { FileUploadField } from './FileUploadField';\nimport { useTcpCreateArchiveItem, useTcpCollections, FILE_FOLDERS } from '../hooks';\nimport { formatEnumLabel } from '../utils/formatters';\nimport { notify, describeError } from '../lib/toast';\nimport type { TcpArchiveItem, TcpArchiveItemKind, TcpAccessLevel } from '../types';\n\nconst KINDS: TcpArchiveItemKind[] = [\n 'DOCUMENT',\n 'MANUSCRIPT',\n 'PHOTOGRAPH',\n 'AUDIO',\n 'VIDEO',\n 'MAP',\n 'OBJECT',\n];\n\nconst ACCESS_LEVELS: TcpAccessLevel[] = ['PUBLIC', 'COMMUNITY', 'RESTRICTED', 'EMBARGOED'];\n\nconst dateToIso = (value: string): string | null => {\n if (!value) return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n};\n\ninterface CreateArchiveItemDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Pre-select a collection (e.g. from a collection detail page). */\n collectionId?: string;\n onCreated?: (item: TcpArchiveItem) => void;\n}\n\nexport function CreateArchiveItemDialog({\n open,\n onOpenChange,\n collectionId,\n onCreated,\n}: CreateArchiveItemDialogProps) {\n const createItem = useTcpCreateArchiveItem();\n const collectionsQuery = useTcpCollections({ limit: 100 });\n\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [kind, setKind] = useState<TcpArchiveItemKind>('DOCUMENT');\n const [accessLevel, setAccessLevel] = useState<TcpAccessLevel>('PUBLIC');\n const [pickedCollection, setPickedCollection] = useState(collectionId ?? '');\n const [fileId, setFileId] = useState<string | null>(null);\n const [provenance, setProvenance] = useState('');\n const [origin, setOrigin] = useState('');\n const [languages, setLanguages] = useState<string[]>([]);\n const [tags, setTags] = useState<string[]>([]);\n const [datedAt, setDatedAt] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const reset = () => {\n setTitle('');\n setDescription('');\n setKind('DOCUMENT');\n setAccessLevel('PUBLIC');\n setPickedCollection(collectionId ?? '');\n setFileId(null);\n setProvenance('');\n setOrigin('');\n setLanguages([]);\n setTags([]);\n setDatedAt('');\n setError(null);\n };\n\n const submit = async () => {\n if (!title.trim()) {\n setError('A title is required.');\n return;\n }\n try {\n const created = await createItem.mutateAsync({\n title: title.trim(),\n description: description.trim() || null,\n kind,\n accessLevel,\n collectionId: pickedCollection || null,\n fileId,\n provenance: provenance.trim() || null,\n origin: origin.trim() || null,\n languages: languages.length ? languages : null,\n tags: tags.length ? tags : null,\n datedAt: dateToIso(datedAt),\n });\n notify.success('Artifact added', created.title);\n onOpenChange(false);\n reset();\n onCreated?.(created);\n } catch (err) {\n setError(describeError(err));\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add an artifact</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Catalogue a manuscript, photograph, recording, map, object or document with its\n provenance.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"flex max-h-[62vh] flex-col gap-4 overflow-y-auto py-2\">\n <div className=\"grid gap-1.5\">\n <Label>File</Label>\n <FileUploadField\n folder={FILE_FOLDERS.artifacts}\n accept=\"image/*,audio/*,video/*,application/pdf\"\n label=\"Upload artifact file\"\n hint=\"Image, audio, video or PDF. Up to 25 MB.\"\n fileId={fileId}\n onUploaded={setFileId}\n onCleared={() => setFileId(null)}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-title\">Title</Label>\n <Input\n id=\"item-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Palm-leaf manuscript, 18th c.\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"grid gap-1.5\">\n <Label>Kind</Label>\n <Select value={kind} onValueChange={(v) => setKind(v as TcpArchiveItemKind)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {formatEnumLabel(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label>Access level</Label>\n <Select\n value={accessLevel}\n onValueChange={(v) => setAccessLevel(v as TcpAccessLevel)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCESS_LEVELS.map((a) => (\n <SelectItem key={a} value={a}>\n {formatEnumLabel(a)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n {!collectionId && (\n <div className=\"grid gap-1.5\">\n <Label>Collection</Label>\n <Select value={pickedCollection} onValueChange={setPickedCollection}>\n <SelectTrigger>\n <SelectValue placeholder=\"Add to a collection (optional)\" />\n </SelectTrigger>\n <SelectContent>\n {(collectionsQuery.data ?? []).map((collection) => (\n <SelectItem key={collection.id} value={collection.id}>\n {collection.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-desc\">Description</Label>\n <Textarea\n id=\"item-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-origin\">Origin</Label>\n <Input\n id=\"item-origin\"\n value={origin}\n onChange={(e) => setOrigin(e.target.value)}\n placeholder=\"Place of origin\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-dated\">Dated</Label>\n <Input\n id=\"item-dated\"\n type=\"date\"\n value={datedAt}\n onChange={(e) => setDatedAt(e.target.value)}\n />\n </div>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-provenance\">Provenance</Label>\n <Textarea\n id=\"item-provenance\"\n value={provenance}\n onChange={(e) => setProvenance(e.target.value)}\n placeholder=\"Chain of custody / source history\"\n rows={2}\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-langs\">Languages</Label>\n <TagInput\n id=\"item-langs\"\n value={languages}\n onChange={setLanguages}\n placeholder=\"e.g. Tamil, Sanskrit…\"\n preserveCase\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-tags\">Tags</Label>\n <TagInput id=\"item-tags\" value={tags} onChange={setTags} placeholder=\"Add tags…\" />\n </div>\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={createItem.isPending}>\n Add artifact\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateArchiveItemDialog.js","names":[],"sources":["../../../src/theculturepost/components/CreateArchiveItemDialog.tsx"],"sourcesContent":["/**\n * CreateArchiveItemDialog — add an artifact to the archive.\n * @module theculturepost/components\n *\n * Writes `tcpCreateArchiveItem`. The binary is uploaded to wspace-files-svc via\n * the shared {@link MediaDropzone} (drag-drop) and only its id is stored here.\n * The schema exposes a SINGLE `file` per item — never a gallery. Kind + access\n * level are chosen up front.\n */\n\nimport { useState } from 'react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { TagInput } from './TagInput';\nimport { MediaDropzone, Counter, type UploadedRef } from './RecordOralHistoryDialog';\nimport { useTcpCreateArchiveItem, useTcpCollections, FILE_FOLDERS } from '../hooks';\nimport { formatEnumLabel } from '../utils/formatters';\nimport { notify, describeError } from '../lib/toast';\nimport type { TcpArchiveItem, TcpArchiveItemKind, TcpAccessLevel } from '../types';\n\nconst KINDS: TcpArchiveItemKind[] = [\n 'DOCUMENT',\n 'MANUSCRIPT',\n 'PHOTOGRAPH',\n 'AUDIO',\n 'VIDEO',\n 'MAP',\n 'OBJECT',\n];\n\nconst ACCESS_LEVELS: TcpAccessLevel[] = ['PUBLIC', 'COMMUNITY', 'RESTRICTED', 'EMBARGOED'];\n\nconst ACCESS_HELP: Record<TcpAccessLevel, string> = {\n PUBLIC: 'Visible to everyone.',\n COMMUNITY: 'Available to community members.',\n RESTRICTED: 'Visible to selected groups.',\n EMBARGOED: 'Hidden until a future date.',\n};\n\nconst TITLE_MAX = 160;\nconst DESCRIPTION_MAX = 600;\nconst PROVENANCE_MAX = 600;\nconst ORIGIN_MAX = 160;\n\nconst dateToIso = (value: string): string | null => {\n if (!value) return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n};\n\ninterface CreateArchiveItemDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Pre-select a collection (e.g. from a collection detail page). */\n collectionId?: string;\n onCreated?: (item: TcpArchiveItem) => void;\n}\n\nexport function CreateArchiveItemDialog({\n open,\n onOpenChange,\n collectionId,\n onCreated,\n}: CreateArchiveItemDialogProps) {\n const createItem = useTcpCreateArchiveItem();\n const collectionsQuery = useTcpCollections({ limit: 100 });\n\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [kind, setKind] = useState<TcpArchiveItemKind>('DOCUMENT');\n const [accessLevel, setAccessLevel] = useState<TcpAccessLevel>('PUBLIC');\n const [pickedCollection, setPickedCollection] = useState(collectionId ?? '');\n const [file, setFile] = useState<UploadedRef | null>(null);\n const [provenance, setProvenance] = useState('');\n const [origin, setOrigin] = useState('');\n const [languages, setLanguages] = useState<string[]>([]);\n const [tags, setTags] = useState<string[]>([]);\n const [datedAt, setDatedAt] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const reset = () => {\n setTitle('');\n setDescription('');\n setKind('DOCUMENT');\n setAccessLevel('PUBLIC');\n setPickedCollection(collectionId ?? '');\n setFile(null);\n setProvenance('');\n setOrigin('');\n setLanguages([]);\n setTags([]);\n setDatedAt('');\n setError(null);\n };\n\n const submit = async () => {\n if (!title.trim()) {\n setError('A title is required.');\n return;\n }\n try {\n const created = await createItem.mutateAsync({\n title: title.trim(),\n description: description.trim() || null,\n kind,\n accessLevel,\n collectionId: pickedCollection || null,\n fileId: file?.id ?? null,\n provenance: provenance.trim() || null,\n origin: origin.trim() || null,\n languages: languages.length ? languages : null,\n tags: tags.length ? tags : null,\n datedAt: dateToIso(datedAt),\n });\n notify.success('Artifact added', created.title);\n onOpenChange(false);\n reset();\n onCreated?.(created);\n } catch (err) {\n setError(describeError(err));\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-2xl\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add an artifact</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Catalogue a manuscript, photograph, recording, map, object or document with its\n provenance.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"flex max-h-[64vh] flex-col gap-4 overflow-y-auto py-2\">\n <div className=\"grid gap-1.5\">\n <Label>File</Label>\n <MediaDropzone\n folder={FILE_FOLDERS.artifacts}\n accept=\"image/*,audio/*,video/*,application/pdf\"\n promptLabel=\"Drag and drop the artifact file here\"\n hint=\"Image, audio, video or PDF, up to 25 MB. One file per artifact.\"\n value={file}\n onUploaded={(ref) => setFile(ref)}\n onClear={() => setFile(null)}\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-title\">\n Title <span className=\"text-status-error-text\">*</span>\n </Label>\n <Input\n id=\"item-title\"\n value={title}\n maxLength={TITLE_MAX}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Palm-leaf manuscript, 18th c.\"\n />\n <Counter length={title.length} max={TITLE_MAX} />\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label>Kind</Label>\n <Select value={kind} onValueChange={(v) => setKind(v as TcpArchiveItemKind)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {formatEnumLabel(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid gap-1.5\">\n <Label>Access level</Label>\n <Select\n value={accessLevel}\n onValueChange={(v) => setAccessLevel(v as TcpAccessLevel)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCESS_LEVELS.map((a) => (\n <SelectItem key={a} value={a}>\n {formatEnumLabel(a)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-text-tertiary\">{ACCESS_HELP[accessLevel]}</p>\n </div>\n </div>\n\n {!collectionId && (\n <div className=\"grid gap-1.5\">\n <Label>Collection</Label>\n <Select value={pickedCollection} onValueChange={setPickedCollection}>\n <SelectTrigger>\n <SelectValue placeholder=\"Add to a collection (optional)\" />\n </SelectTrigger>\n <SelectContent>\n {(collectionsQuery.data ?? []).map((collection) => (\n <SelectItem key={collection.id} value={collection.id}>\n {collection.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-desc\">Description</Label>\n <Textarea\n id=\"item-desc\"\n value={description}\n maxLength={DESCRIPTION_MAX}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n />\n <Counter length={description.length} max={DESCRIPTION_MAX} />\n </div>\n\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-origin\">Origin</Label>\n <Input\n id=\"item-origin\"\n value={origin}\n maxLength={ORIGIN_MAX}\n onChange={(e) => setOrigin(e.target.value)}\n placeholder=\"Place of origin\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-dated\">Dated</Label>\n <Input\n id=\"item-dated\"\n type=\"date\"\n value={datedAt}\n onChange={(e) => setDatedAt(e.target.value)}\n />\n </div>\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-provenance\">Provenance</Label>\n <Textarea\n id=\"item-provenance\"\n value={provenance}\n maxLength={PROVENANCE_MAX}\n onChange={(e) => setProvenance(e.target.value)}\n placeholder=\"Chain of custody / source history\"\n rows={2}\n />\n <Counter length={provenance.length} max={PROVENANCE_MAX} />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-langs\">Languages</Label>\n <TagInput\n id=\"item-langs\"\n value={languages}\n onChange={setLanguages}\n placeholder=\"e.g. Tamil, Sanskrit…\"\n preserveCase\n />\n </div>\n\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"item-tags\">Tags</Label>\n <TagInput id=\"item-tags\" value={tags} onChange={setTags} placeholder=\"Add tags…\" />\n </div>\n\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={createItem.isPending}>\n Add artifact\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":";;;;;;;;;;;AAmCA,IAAM,IAA8B;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACD,EAEK,KAAkC;CAAC;CAAU;CAAa;CAAc;CAAY,EAEpF,KAA8C;CAClD,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,WAAW;CACZ,EAEK,IAAY,KACZ,IAAkB,KAClB,IAAiB,KACjB,KAAa,KAEb,MAAa,MAAiC;AAClD,KAAI,CAAC,EAAO,QAAO;CACnB,IAAM,IAAI,IAAI,KAAK,EAAM;AACzB,QAAO,OAAO,MAAM,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE,aAAa;;AAW3D,SAAgB,EAAwB,EACtC,SACA,iBACA,iBACA,gBAC+B;CAC/B,IAAM,IAAa,GAAyB,EACtC,KAAmB,EAAkB,EAAE,OAAO,KAAK,CAAC,EAEpD,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAM,KAAW,EAA6B,WAAW,EAC1D,CAAC,GAAa,KAAkB,EAAyB,SAAS,EAClE,CAAC,GAAkB,KAAuB,EAAS,KAAgB,GAAG,EACtE,CAAC,GAAM,KAAW,EAA6B,KAAK,EACpD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,CAAC,GAAW,KAAgB,EAAmB,EAAE,CAAC,EAClD,CAAC,GAAM,KAAW,EAAmB,EAAE,CAAC,EACxC,CAAC,GAAS,KAAc,EAAS,GAAG,EACpC,CAAC,GAAO,KAAY,EAAwB,KAAK,EAEjD,WAAc;AAYlB,EAXA,EAAS,GAAG,EACZ,EAAe,GAAG,EAClB,EAAQ,WAAW,EACnB,EAAe,SAAS,EACxB,EAAoB,KAAgB,GAAG,EACvC,EAAQ,KAAK,EACb,EAAc,GAAG,EACjB,EAAU,GAAG,EACb,EAAa,EAAE,CAAC,EAChB,EAAQ,EAAE,CAAC,EACX,EAAW,GAAG,EACd,EAAS,KAAK;;AA+BhB,QACE,kBAAC,IAAD;EAAwB;EAAoB;YAC1C,kBAAC,IAAD;GAAyB,WAAU;aAAnC;IACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAuB,mBAAuC,CAAA,EAC9D,kBAAC,IAAD,EAAA,UAA6B,+FAGC,CAAA,CACP,EAAA,CAAA;IAEzB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,QAAY,CAAA,EACnB,kBAAC,GAAD;QACE,QAAQ,EAAa;QACrB,QAAO;QACP,aAAY;QACZ,MAAK;QACL,OAAO;QACP,aAAa,MAAQ,EAAQ,EAAI;QACjC,eAAe,EAAQ,KAAK;QAC5B,CAAA,CACE;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SAAO,SAAQ;mBAAf,CAA4B,UACpB,kBAAC,QAAD;UAAM,WAAU;oBAAyB;UAAQ,CAAA,CACjD;;QACR,kBAAC,GAAD;SACE,IAAG;SACH,OAAO;SACP,WAAW;SACX,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;SACzC,aAAY;SACZ,CAAA;QACF,kBAAC,GAAD;SAAS,QAAQ,EAAM;SAAQ,KAAK;SAAa,CAAA;QAC7C;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,QAAY,CAAA,EACnB,kBAAC,GAAD;SAAQ,OAAO;SAAM,gBAAgB,MAAM,EAAQ,EAAwB;mBAA3E,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAe,CAAA,EACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAM,KAAK,MACV,kBAAC,GAAD;UAAoB,OAAO;oBACxB,EAAgB,EAAE;UACR,EAFI,EAEJ,CACb,EACY,CAAA,CACT;WACL;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,EAAA,UAAO,gBAAoB,CAAA;SAC3B,kBAAC,GAAD;UACE,OAAO;UACP,gBAAgB,MAAM,EAAe,EAAoB;oBAF3D,CAIE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAe,CAAA,EACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,GAAc,KAAK,MAClB,kBAAC,GAAD;WAAoB,OAAO;qBACxB,EAAgB,EAAE;WACR,EAFI,EAEJ,CACb,EACY,CAAA,CACT;;SACT,kBAAC,KAAD;UAAG,WAAU;oBAA8B,GAAY;UAAiB,CAAA;SACpE;UACF;;MAEL,CAAC,KACA,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAA,UAAO,cAAkB,CAAA,EACzB,kBAAC,GAAD;QAAQ,OAAO;QAAkB,eAAe;kBAAhD,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,aAAY,kCAAmC,CAAA,EAC9C,CAAA,EAChB,kBAAC,GAAD,EAAA,WACI,GAAiB,QAAQ,EAAE,EAAE,KAAK,MAClC,kBAAC,GAAD;SAAgC,OAAO,EAAW;mBAC/C,EAAW;SACD,EAFI,EAAW,GAEf,CACb,EACY,CAAA,CACT;UACL;;MAGR,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SAAO,SAAQ;mBAAY;SAAmB,CAAA;QAC9C,kBAAC,GAAD;SACE,IAAG;SACH,OAAO;SACP,WAAW;SACX,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;SAC/C,MAAM;SACN,CAAA;QACF,kBAAC,GAAD;SAAS,QAAQ,EAAY;SAAQ,KAAK;SAAmB,CAAA;QACzD;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAc;SAAc,CAAA,EAC3C,kBAAC,GAAD;SACE,IAAG;SACH,OAAO;SACP,WAAW;SACX,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;SAC1C,aAAY;SACZ,CAAA,CACE;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;mBAAa;SAAa,CAAA,EACzC,kBAAC,GAAD;SACE,IAAG;SACH,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAW,EAAE,OAAO,MAAM;SAC3C,CAAA,CACE;UACF;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SAAO,SAAQ;mBAAkB;SAAkB,CAAA;QACnD,kBAAC,GAAD;SACE,IAAG;SACH,OAAO;SACP,WAAW;SACX,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;SAC9C,aAAY;SACZ,MAAM;SACN,CAAA;QACF,kBAAC,GAAD;SAAS,QAAQ,EAAW;SAAQ,KAAK;SAAkB,CAAA;QACvD;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAO,SAAQ;kBAAa;QAAiB,CAAA,EAC7C,kBAAC,GAAD;QACE,IAAG;QACH,OAAO;QACP,UAAU;QACV,aAAY;QACZ,cAAA;QACA,CAAA,CACE;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAO,SAAQ;kBAAY;QAAY,CAAA,EACvC,kBAAC,GAAD;QAAU,IAAG;QAAY,OAAO;QAAM,UAAU;QAAS,aAAY;QAAc,CAAA,CAC/E;;MAEL,KAAS,kBAAC,KAAD;OAAG,WAAU;iBAAkC;OAAU,CAAA;MAC/D;;IAEN,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,eAAe,EAAa,GAAM;eAAE;KAErD,CAAA,EACT,kBAAC,GAAD;KAAQ,SAhMD,YAAY;AACzB,UAAI,CAAC,EAAM,MAAM,EAAE;AACjB,SAAS,uBAAuB;AAChC;;AAEF,UAAI;OACF,IAAM,IAAU,MAAM,EAAW,YAAY;QAC3C,OAAO,EAAM,MAAM;QACnB,aAAa,EAAY,MAAM,IAAI;QACnC;QACA;QACA,cAAc,KAAoB;QAClC,QAAQ,GAAM,MAAM;QACpB,YAAY,EAAW,MAAM,IAAI;QACjC,QAAQ,EAAO,MAAM,IAAI;QACzB,WAAW,EAAU,SAAS,IAAY;QAC1C,MAAM,EAAK,SAAS,IAAO;QAC3B,SAAS,GAAU,EAAQ;QAC5B,CAAC;AAIF,OAHA,GAAO,QAAQ,kBAAkB,EAAQ,MAAM,EAC/C,EAAa,GAAM,EACnB,IAAO,EACP,IAAY,EAAQ;eACb,GAAK;AACZ,SAAS,GAAc,EAAI,CAAC;;;KAwKC,UAAU,EAAW;eAAW;KAEhD,CAAA,CACc,EAAA,CAAA;IACD;;EACT,CAAA"}
|