@panneau/fields 5.0.0-alpha.14 → 5.0.0-alpha.16
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/README.md +53 -3
- package/dist/address/AddressField.css +44 -0
- package/dist/address/AddressField.d.ts +37 -0
- package/dist/address/AddressField.d.ts.map +1 -0
- package/dist/address/AddressField.js +411 -0
- package/dist/address/AddressField.js.map +1 -0
- package/dist/address/AddressField.module.js +22 -0
- package/dist/address/AddressField.module.js.map +1 -0
- package/dist/address/address.d.ts +23 -0
- package/dist/address/address.d.ts.map +1 -0
- package/dist/address/address.js +58 -0
- package/dist/address/address.js.map +1 -0
- package/dist/address/index.d.ts +3 -0
- package/dist/address/index.d.ts.map +1 -0
- package/dist/address/index.js +3 -0
- package/dist/color/ColorField.css +9 -0
- package/dist/color/ColorField.d.ts +10 -3
- package/dist/color/ColorField.d.ts.map +1 -1
- package/dist/color/ColorField.js +341 -81
- package/dist/color/ColorField.js.map +1 -1
- package/dist/color/ColorField.module.js +4 -2
- package/dist/color/ColorField.module.js.map +1 -1
- package/dist/color/index.d.ts +1 -0
- package/dist/color/index.d.ts.map +1 -1
- package/dist/color/index.js +3 -1
- package/dist/color/palette.d.ts +23 -0
- package/dist/color/palette.d.ts.map +1 -0
- package/dist/color/palette.js +34 -0
- package/dist/color/palette.js.map +1 -0
- package/dist/country/CountryField.css +42 -0
- package/dist/country/CountryField.d.ts +19 -4
- package/dist/country/CountryField.d.ts.map +1 -1
- package/dist/country/CountryField.js +355 -82
- package/dist/country/CountryField.js.map +1 -1
- package/dist/country/CountryField.module.js +20 -0
- package/dist/country/CountryField.module.js.map +1 -0
- package/dist/country/index.d.ts +1 -1
- package/dist/country/index.d.ts.map +1 -1
- package/dist/daterange/DateRangeField.css +9 -0
- package/dist/daterange/DateRangeField.d.ts +31 -0
- package/dist/daterange/DateRangeField.d.ts.map +1 -0
- package/dist/daterange/DateRangeField.js +372 -0
- package/dist/daterange/DateRangeField.js.map +1 -0
- package/dist/daterange/DateRangeField.module.js +12 -0
- package/dist/daterange/DateRangeField.module.js.map +1 -0
- package/dist/daterange/index.d.ts +3 -0
- package/dist/daterange/index.d.ts.map +1 -0
- package/dist/daterange/index.js +3 -0
- package/dist/daterange/range.d.ts +61 -0
- package/dist/daterange/range.d.ts.map +1 -0
- package/dist/daterange/range.js +119 -0
- package/dist/daterange/range.js.map +1 -0
- package/dist/duration/DurationField.css +1 -1
- package/dist/duration/DurationField.d.ts +54 -13
- package/dist/duration/DurationField.d.ts.map +1 -1
- package/dist/duration/DurationField.js +205 -159
- package/dist/duration/DurationField.js.map +1 -1
- package/dist/duration/DurationField.module.js.map +1 -1
- package/dist/duration/index.d.ts +1 -1
- package/dist/duration/index.d.ts.map +1 -1
- package/dist/duration/index.js +1 -1
- package/dist/embed/EmbedField.d.ts +11 -2
- package/dist/embed/EmbedField.d.ts.map +1 -1
- package/dist/embed/EmbedField.js +179 -116
- package/dist/embed/EmbedField.js.map +1 -1
- package/dist/link/LinkField.css +12 -0
- package/dist/link/LinkField.d.ts +38 -0
- package/dist/link/LinkField.d.ts.map +1 -0
- package/dist/link/LinkField.js +742 -0
- package/dist/link/LinkField.js.map +1 -0
- package/dist/link/LinkField.module.js +8 -0
- package/dist/link/LinkField.module.js.map +1 -0
- package/dist/link/index.d.ts +3 -0
- package/dist/link/index.d.ts.map +1 -0
- package/dist/link/index.js +3 -0
- package/dist/link/link.d.ts +30 -0
- package/dist/link/link.d.ts.map +1 -0
- package/dist/link/link.js +63 -0
- package/dist/link/link.js.map +1 -0
- package/dist/link/pages.d.ts +17 -0
- package/dist/link/pages.d.ts.map +1 -0
- package/dist/link/pages.js +104 -0
- package/dist/link/pages.js.map +1 -0
- package/dist/location/LocationField.d.ts.map +1 -1
- package/dist/location/LocationField.js +9 -85
- package/dist/location/LocationField.js.map +1 -1
- package/dist/location/nominatim.d.ts +8 -2
- package/dist/location/nominatim.d.ts.map +1 -1
- package/dist/location/nominatim.js +32 -3
- package/dist/location/nominatim.js.map +1 -1
- package/dist/location/search.d.ts +10 -0
- package/dist/location/search.d.ts.map +1 -0
- package/dist/location/search.js +83 -0
- package/dist/location/search.js.map +1 -0
- package/dist/location/types.d.ts +8 -2
- package/dist/location/types.d.ts.map +1 -1
- package/dist/money/MoneyField.d.ts +28 -0
- package/dist/money/MoneyField.d.ts.map +1 -0
- package/dist/money/MoneyField.js +269 -0
- package/dist/money/MoneyField.js.map +1 -0
- package/dist/money/index.d.ts +3 -0
- package/dist/money/index.d.ts.map +1 -0
- package/dist/money/index.js +3 -0
- package/dist/money/money.d.ts +27 -0
- package/dist/money/money.d.ts.map +1 -0
- package/dist/money/money.js +56 -0
- package/dist/money/money.js.map +1 -0
- package/dist/region/RegionField.js +1 -1
- package/dist/shared/builtIn.d.ts +3 -1
- package/dist/shared/builtIn.d.ts.map +1 -1
- package/dist/shared/builtIn.js +18 -8
- package/dist/shared/builtIn.js.map +1 -1
- package/dist/shared/dates.js +2 -2
- package/dist/shared/dates.js.map +1 -1
- package/dist/shared/flow.d.ts.map +1 -1
- package/dist/shared/flow.js +1 -0
- package/dist/shared/flow.js.map +1 -1
- package/dist/shared/part.d.ts +26 -0
- package/dist/shared/part.d.ts.map +1 -0
- package/dist/shared/part.js +64 -0
- package/dist/shared/part.js.map +1 -0
- package/dist/tel/TelField.css +25 -0
- package/dist/tel/TelField.d.ts +14 -2
- package/dist/tel/TelField.d.ts.map +1 -1
- package/dist/tel/TelField.js +246 -145
- package/dist/tel/TelField.js.map +1 -1
- package/dist/tel/TelField.module.js +12 -0
- package/dist/tel/TelField.module.js.map +1 -0
- package/dist/tel/index.d.ts +1 -1
- package/dist/tel/index.d.ts.map +1 -1
- package/dist/tel/index.js +2 -2
- package/dist/tel/phone.d.ts +28 -0
- package/dist/tel/phone.d.ts.map +1 -1
- package/dist/tel/phone.js +48 -1
- package/dist/tel/phone.js.map +1 -1
- package/dist/url/UrlField.d.ts.map +1 -1
- package/dist/url/UrlField.js +1 -1
- package/dist/url/UrlField.js.map +1 -1
- package/package.json +24 -4
package/dist/duration/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DurationField, DurationFieldEntry, formatDuration, splitDuration } from "./DurationField.js";
|
|
1
|
+
export { DurationField, DurationFieldEntry, formatDuration, getDurationUnits, isDurationUnit, resolveDurationUnits, splitDuration } from "./DurationField.js";
|
|
@@ -6,6 +6,12 @@ export interface EmbedFieldProps extends FieldProps<EmbedValue> {
|
|
|
6
6
|
placeholder?: string;
|
|
7
7
|
/** Where the preview comes from. Defaults to that of the `FieldsProvider`. */
|
|
8
8
|
embedSource?: EmbedSource | null;
|
|
9
|
+
/**
|
|
10
|
+
* The providers an embed may come from (`YouTube`), compared without case: the `providers`
|
|
11
|
+
* rule (decision 0058). The field names them under its help, and refuses an embed of another
|
|
12
|
+
* provider as soon as its preview comes back. The form's errors, once shown, replace that one.
|
|
13
|
+
*/
|
|
14
|
+
providers?: readonly string[];
|
|
9
15
|
}
|
|
10
16
|
/** Whether a value is an embed: an object with a `url`. */
|
|
11
17
|
export declare function isEmbed(value: unknown): value is EmbedValue;
|
|
@@ -14,7 +20,10 @@ export declare function isEmbed(value: unknown): value is EmbedValue;
|
|
|
14
20
|
* oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its
|
|
15
21
|
* preview follows. Without an embed source, the value is the URL alone.
|
|
16
22
|
*/
|
|
17
|
-
export declare function EmbedField({ value, onChange, onBlur, embedSource: embedSourceProp, errors, disabled, readOnly, required, ...props }: EmbedFieldProps): import("react").JSX.Element;
|
|
18
|
-
/**
|
|
23
|
+
export declare function EmbedField({ value, onChange, onBlur, embedSource: embedSourceProp, providers, errors, disabled, readOnly, required, description, ...props }: EmbedFieldProps): import("react").JSX.Element;
|
|
24
|
+
/**
|
|
25
|
+
* The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its
|
|
26
|
+
* `providers` rule names the providers it allows.
|
|
27
|
+
*/
|
|
19
28
|
export declare function EmbedFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
20
29
|
//# sourceMappingURL=EmbedField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbedField.d.ts","sourceRoot":"","sources":["../../src/embed/EmbedField.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EmbedField.d.ts","sourceRoot":"","sources":["../../src/embed/EmbedField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,UAAU,EAAE,CAAC;AAI3B,MAAM,WAAW,eAAgB,SAAQ,UAAU,CAAC,UAAU,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAM3D;AAgBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EAAE,eAAe,EAC5B,SAAS,EACT,MAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,GAAG,KAAK,EACX,EAAE,eAAe,+BAmGjB;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,+BAUrD"}
|
package/dist/embed/EmbedField.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { useFieldsContext } from "../shared/context.js";
|
|
2
|
-
import { getFieldProps, isString } from "../shared/entry.js";
|
|
2
|
+
import { findRule, getFieldProps, isString } from "../shared/entry.js";
|
|
3
3
|
import { messages } from "../shared/messages.js";
|
|
4
4
|
import EmbedField_module_default from "./EmbedField.module.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import { useEffect, useEffectEvent, useState } from "react";
|
|
7
7
|
import { Spinner, TextInput, usePanneauIntl } from "@panneau/ui";
|
|
8
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { formsMessages } from "@panneau/intl";
|
|
9
10
|
//#region src/embed/EmbedField.tsx
|
|
10
11
|
var RESOLVE_DELAY = 500;
|
|
11
12
|
/** Whether a value is an embed: an object with a `url`. */
|
|
12
13
|
function isEmbed(value) {
|
|
13
14
|
return value !== null && typeof value === "object" && isString(value.url);
|
|
14
15
|
}
|
|
16
|
+
/** Whether an embed comes from one of the providers. One without a provider is left to the backend. */
|
|
17
|
+
function isAllowed(value, providers) {
|
|
18
|
+
if (providers === void 0 || providers.length === 0 || value.provider === void 0) return true;
|
|
19
|
+
const provider = value.provider.toLowerCase();
|
|
20
|
+
return providers.some((allowed) => allowed.toLowerCase() === provider);
|
|
21
|
+
}
|
|
15
22
|
/** Whether a value has been resolved: it has more than its URL. */
|
|
16
23
|
function isResolved(value) {
|
|
17
24
|
return Object.keys(value).some((key) => key !== "url");
|
|
@@ -22,45 +29,51 @@ function isResolved(value) {
|
|
|
22
29
|
* preview follows. Without an embed source, the value is the URL alone.
|
|
23
30
|
*/
|
|
24
31
|
function EmbedField(t0) {
|
|
25
|
-
const $ = c(
|
|
32
|
+
const $ = c(60);
|
|
33
|
+
let description;
|
|
26
34
|
let disabled;
|
|
27
35
|
let embedSourceProp;
|
|
28
36
|
let onBlur;
|
|
29
37
|
let onChange;
|
|
30
38
|
let props;
|
|
39
|
+
let providers;
|
|
31
40
|
let readOnly;
|
|
32
41
|
let required;
|
|
33
42
|
let t1;
|
|
34
43
|
let value;
|
|
35
44
|
if ($[0] !== t0) {
|
|
36
|
-
({value, onChange, onBlur, embedSource: embedSourceProp, errors: t1, disabled, readOnly, required, ...props} = t0);
|
|
45
|
+
({value, onChange, onBlur, embedSource: embedSourceProp, providers, errors: t1, disabled, readOnly, required, description, ...props} = t0);
|
|
37
46
|
$[0] = t0;
|
|
38
|
-
$[1] =
|
|
39
|
-
$[2] =
|
|
40
|
-
$[3] =
|
|
41
|
-
$[4] =
|
|
42
|
-
$[5] =
|
|
43
|
-
$[6] =
|
|
44
|
-
$[7] =
|
|
45
|
-
$[8] =
|
|
46
|
-
$[9] =
|
|
47
|
+
$[1] = description;
|
|
48
|
+
$[2] = disabled;
|
|
49
|
+
$[3] = embedSourceProp;
|
|
50
|
+
$[4] = onBlur;
|
|
51
|
+
$[5] = onChange;
|
|
52
|
+
$[6] = props;
|
|
53
|
+
$[7] = providers;
|
|
54
|
+
$[8] = readOnly;
|
|
55
|
+
$[9] = required;
|
|
56
|
+
$[10] = t1;
|
|
57
|
+
$[11] = value;
|
|
47
58
|
} else {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
description = $[1];
|
|
60
|
+
disabled = $[2];
|
|
61
|
+
embedSourceProp = $[3];
|
|
62
|
+
onBlur = $[4];
|
|
63
|
+
onChange = $[5];
|
|
64
|
+
props = $[6];
|
|
65
|
+
providers = $[7];
|
|
66
|
+
readOnly = $[8];
|
|
67
|
+
required = $[9];
|
|
68
|
+
t1 = $[10];
|
|
69
|
+
value = $[11];
|
|
57
70
|
}
|
|
58
71
|
let t2;
|
|
59
|
-
if ($[
|
|
72
|
+
if ($[12] !== t1) {
|
|
60
73
|
t2 = t1 === void 0 ? [] : t1;
|
|
61
|
-
$[
|
|
62
|
-
$[
|
|
63
|
-
} else t2 = $[
|
|
74
|
+
$[12] = t1;
|
|
75
|
+
$[13] = t2;
|
|
76
|
+
} else t2 = $[13];
|
|
64
77
|
const errors = t2;
|
|
65
78
|
const intl = usePanneauIntl();
|
|
66
79
|
const context = useFieldsContext();
|
|
@@ -69,14 +82,14 @@ function EmbedField(t0) {
|
|
|
69
82
|
const [status, setStatus] = useState(null);
|
|
70
83
|
const pending = value !== null && value !== void 0 && !isResolved(value) ? value.url : null;
|
|
71
84
|
let t3;
|
|
72
|
-
if ($[
|
|
85
|
+
if ($[14] !== onChange) {
|
|
73
86
|
t3 = (embed) => onChange?.(embed);
|
|
74
|
-
$[
|
|
75
|
-
$[
|
|
76
|
-
} else t3 = $[
|
|
87
|
+
$[14] = onChange;
|
|
88
|
+
$[15] = t3;
|
|
89
|
+
} else t3 = $[15];
|
|
77
90
|
const resolved = useEffectEvent(t3);
|
|
78
91
|
let t4;
|
|
79
|
-
if ($[
|
|
92
|
+
if ($[16] !== embedSource || $[17] !== pending || $[18] !== resolved) {
|
|
80
93
|
t4 = () => {
|
|
81
94
|
if (embedSource === null || pending === null || !URL.canParse(pending)) return;
|
|
82
95
|
const controller = new AbortController();
|
|
@@ -103,80 +116,107 @@ function EmbedField(t0) {
|
|
|
103
116
|
controller.abort();
|
|
104
117
|
};
|
|
105
118
|
};
|
|
106
|
-
$[
|
|
107
|
-
$[
|
|
108
|
-
$[
|
|
109
|
-
$[
|
|
110
|
-
} else t4 = $[
|
|
119
|
+
$[16] = embedSource;
|
|
120
|
+
$[17] = pending;
|
|
121
|
+
$[18] = resolved;
|
|
122
|
+
$[19] = t4;
|
|
123
|
+
} else t4 = $[19];
|
|
111
124
|
let t5;
|
|
112
|
-
if ($[
|
|
125
|
+
if ($[20] !== embedSource || $[21] !== pending) {
|
|
113
126
|
t5 = [embedSource, pending];
|
|
114
|
-
$[
|
|
115
|
-
$[
|
|
116
|
-
$[
|
|
117
|
-
} else t5 = $[
|
|
127
|
+
$[20] = embedSource;
|
|
128
|
+
$[21] = pending;
|
|
129
|
+
$[22] = t5;
|
|
130
|
+
} else t5 = $[22];
|
|
118
131
|
useEffect(t4, t5);
|
|
119
132
|
const current = status !== null && status.url === url ? status.state : null;
|
|
133
|
+
let providerList;
|
|
120
134
|
let t6;
|
|
121
|
-
if ($[
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
$[
|
|
125
|
-
$[
|
|
126
|
-
$[
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
if ($[23] !== current || $[24] !== intl || $[25] !== providers || $[26] !== value) {
|
|
136
|
+
providerList = providers !== void 0 && providers.length > 0 ? intl.formatList(providers, { type: "disjunction" }) : null;
|
|
137
|
+
t6 = current === "failed" ? intl.formatMessage(messages.embedFailed) : value !== null && value !== void 0 && providerList !== null && !isAllowed(value, providers) ? intl.formatMessage(formsMessages.rule.providers, { providers: providerList }) : null;
|
|
138
|
+
$[23] = current;
|
|
139
|
+
$[24] = intl;
|
|
140
|
+
$[25] = providers;
|
|
141
|
+
$[26] = value;
|
|
142
|
+
$[27] = providerList;
|
|
143
|
+
$[28] = t6;
|
|
144
|
+
} else {
|
|
145
|
+
providerList = $[27];
|
|
146
|
+
t6 = $[28];
|
|
147
|
+
}
|
|
148
|
+
const ownError = t6;
|
|
129
149
|
let t7;
|
|
130
|
-
if ($[
|
|
131
|
-
t7 =
|
|
132
|
-
$[
|
|
133
|
-
$[
|
|
134
|
-
|
|
150
|
+
if ($[29] !== errors || $[30] !== ownError) {
|
|
151
|
+
t7 = ownError !== null && errors.length === 0 ? [ownError] : errors;
|
|
152
|
+
$[29] = errors;
|
|
153
|
+
$[30] = ownError;
|
|
154
|
+
$[31] = t7;
|
|
155
|
+
} else t7 = $[31];
|
|
156
|
+
const shownErrors = t7;
|
|
135
157
|
let t8;
|
|
136
|
-
if ($[
|
|
137
|
-
t8 = ()
|
|
138
|
-
$[
|
|
139
|
-
$[
|
|
140
|
-
|
|
158
|
+
if ($[32] !== description || $[33] !== intl || $[34] !== providerList || $[35] !== providers) {
|
|
159
|
+
t8 = providerList !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [description !== void 0 && description !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [description, " "] }) : null, intl.formatMessage(messages.embedProviders, { providers: intl.formatList(providers ?? [], { type: "conjunction" }) })] }) : description;
|
|
160
|
+
$[32] = description;
|
|
161
|
+
$[33] = intl;
|
|
162
|
+
$[34] = providerList;
|
|
163
|
+
$[35] = providers;
|
|
164
|
+
$[36] = t8;
|
|
165
|
+
} else t8 = $[36];
|
|
166
|
+
const help = t8;
|
|
141
167
|
let t9;
|
|
142
|
-
if ($[
|
|
143
|
-
t9 =
|
|
168
|
+
if ($[37] !== onChange) {
|
|
169
|
+
t9 = (next) => onChange?.(next.trim() === "" ? null : { url: next.trim() });
|
|
170
|
+
$[37] = onChange;
|
|
171
|
+
$[38] = t9;
|
|
172
|
+
} else t9 = $[38];
|
|
173
|
+
let t10;
|
|
174
|
+
if ($[39] !== onBlur) {
|
|
175
|
+
t10 = () => onBlur?.();
|
|
176
|
+
$[39] = onBlur;
|
|
177
|
+
$[40] = t10;
|
|
178
|
+
} else t10 = $[40];
|
|
179
|
+
let t11;
|
|
180
|
+
if ($[41] !== disabled || $[42] !== help || $[43] !== props || $[44] !== readOnly || $[45] !== required || $[46] !== shownErrors || $[47] !== t10 || $[48] !== t9 || $[49] !== url) {
|
|
181
|
+
t11 = /* @__PURE__ */ jsx(TextInput, {
|
|
144
182
|
...props,
|
|
145
183
|
type: "url",
|
|
146
184
|
inputMode: "url",
|
|
147
185
|
autoComplete: "off",
|
|
148
186
|
value: url,
|
|
149
|
-
onChange:
|
|
150
|
-
onBlur:
|
|
187
|
+
onChange: t9,
|
|
188
|
+
onBlur: t10,
|
|
151
189
|
errors: shownErrors,
|
|
190
|
+
description: help,
|
|
152
191
|
isDisabled: disabled,
|
|
153
192
|
isReadOnly: readOnly,
|
|
154
193
|
isRequired: required
|
|
155
194
|
});
|
|
156
|
-
$[
|
|
157
|
-
$[
|
|
158
|
-
$[
|
|
159
|
-
$[
|
|
160
|
-
$[
|
|
161
|
-
$[
|
|
162
|
-
$[
|
|
163
|
-
$[
|
|
164
|
-
$[
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
195
|
+
$[41] = disabled;
|
|
196
|
+
$[42] = help;
|
|
197
|
+
$[43] = props;
|
|
198
|
+
$[44] = readOnly;
|
|
199
|
+
$[45] = required;
|
|
200
|
+
$[46] = shownErrors;
|
|
201
|
+
$[47] = t10;
|
|
202
|
+
$[48] = t9;
|
|
203
|
+
$[49] = url;
|
|
204
|
+
$[50] = t11;
|
|
205
|
+
} else t11 = $[50];
|
|
206
|
+
let t12;
|
|
207
|
+
if ($[51] !== current || $[52] !== intl) {
|
|
208
|
+
t12 = current === "loading" ? /* @__PURE__ */ jsxs("div", {
|
|
169
209
|
className: EmbedField_module_default.status,
|
|
170
210
|
role: "status",
|
|
171
211
|
children: [/* @__PURE__ */ jsx(Spinner, { size: "sm" }), intl.formatMessage(messages.embedLoading)]
|
|
172
212
|
}) : null;
|
|
173
|
-
$[
|
|
174
|
-
$[
|
|
175
|
-
$[
|
|
176
|
-
} else
|
|
177
|
-
let
|
|
178
|
-
if ($[
|
|
179
|
-
|
|
213
|
+
$[51] = current;
|
|
214
|
+
$[52] = intl;
|
|
215
|
+
$[53] = t12;
|
|
216
|
+
} else t12 = $[53];
|
|
217
|
+
let t13;
|
|
218
|
+
if ($[54] !== value) {
|
|
219
|
+
t13 = value !== null && value !== void 0 && isResolved(value) ? /* @__PURE__ */ jsxs("a", {
|
|
180
220
|
className: EmbedField_module_default.preview,
|
|
181
221
|
href: value.url,
|
|
182
222
|
target: "_blank",
|
|
@@ -196,49 +236,72 @@ function EmbedField(t0) {
|
|
|
196
236
|
}) : null]
|
|
197
237
|
})]
|
|
198
238
|
}) : null;
|
|
199
|
-
$[
|
|
200
|
-
$[
|
|
201
|
-
} else
|
|
202
|
-
let
|
|
203
|
-
if ($[
|
|
204
|
-
|
|
239
|
+
$[54] = value;
|
|
240
|
+
$[55] = t13;
|
|
241
|
+
} else t13 = $[55];
|
|
242
|
+
let t14;
|
|
243
|
+
if ($[56] !== t11 || $[57] !== t12 || $[58] !== t13) {
|
|
244
|
+
t14 = /* @__PURE__ */ jsxs("div", {
|
|
205
245
|
className: EmbedField_module_default.embed,
|
|
206
246
|
children: [
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
247
|
+
t11,
|
|
248
|
+
t12,
|
|
249
|
+
t13
|
|
210
250
|
]
|
|
211
251
|
});
|
|
212
|
-
$[
|
|
213
|
-
$[
|
|
214
|
-
$[
|
|
215
|
-
$[
|
|
216
|
-
} else
|
|
217
|
-
return
|
|
252
|
+
$[56] = t11;
|
|
253
|
+
$[57] = t12;
|
|
254
|
+
$[58] = t13;
|
|
255
|
+
$[59] = t14;
|
|
256
|
+
} else t14 = $[59];
|
|
257
|
+
return t14;
|
|
258
|
+
}
|
|
259
|
+
/** The providers of a `providers` rule, if the field has one. */
|
|
260
|
+
function getProviders(field) {
|
|
261
|
+
const rule = findRule(field, "providers");
|
|
262
|
+
return rule !== void 0 && "value" in rule && Array.isArray(rule.value) ? rule.value.filter(isString) : void 0;
|
|
218
263
|
}
|
|
219
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its
|
|
266
|
+
* `providers` rule names the providers it allows.
|
|
267
|
+
*/
|
|
220
268
|
function EmbedFieldEntry(props) {
|
|
221
|
-
const $ = c(
|
|
269
|
+
const $ = c(11);
|
|
222
270
|
let t0;
|
|
223
|
-
if ($[0] !== props) {
|
|
224
|
-
t0 =
|
|
225
|
-
$[0] = props;
|
|
271
|
+
if ($[0] !== props.field) {
|
|
272
|
+
t0 = getProviders(props.field);
|
|
273
|
+
$[0] = props.field;
|
|
226
274
|
$[1] = t0;
|
|
227
275
|
} else t0 = $[1];
|
|
228
|
-
const
|
|
229
|
-
let
|
|
230
|
-
if ($[2] !== props
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
276
|
+
const providers = t0;
|
|
277
|
+
let t1;
|
|
278
|
+
if ($[2] !== props) {
|
|
279
|
+
t1 = getFieldProps(props);
|
|
280
|
+
$[2] = props;
|
|
281
|
+
$[3] = t1;
|
|
282
|
+
} else t1 = $[3];
|
|
283
|
+
const t2 = isEmbed(props.value) ? props.value : null;
|
|
284
|
+
let t3;
|
|
285
|
+
if ($[4] !== providers) {
|
|
286
|
+
t3 = providers !== void 0 ? { providers } : {};
|
|
287
|
+
$[4] = providers;
|
|
288
|
+
$[5] = t3;
|
|
289
|
+
} else t3 = $[5];
|
|
290
|
+
let t4;
|
|
291
|
+
if ($[6] !== props.onChange || $[7] !== t1 || $[8] !== t2 || $[9] !== t3) {
|
|
292
|
+
t4 = /* @__PURE__ */ jsx(EmbedField, {
|
|
293
|
+
...t1,
|
|
294
|
+
value: t2,
|
|
295
|
+
onChange: props.onChange,
|
|
296
|
+
...t3
|
|
235
297
|
});
|
|
236
|
-
$[
|
|
237
|
-
$[
|
|
238
|
-
$[
|
|
239
|
-
$[
|
|
240
|
-
|
|
241
|
-
|
|
298
|
+
$[6] = props.onChange;
|
|
299
|
+
$[7] = t1;
|
|
300
|
+
$[8] = t2;
|
|
301
|
+
$[9] = t3;
|
|
302
|
+
$[10] = t4;
|
|
303
|
+
} else t4 = $[10];
|
|
304
|
+
return t4;
|
|
242
305
|
}
|
|
243
306
|
//#endregion
|
|
244
307
|
export { EmbedField, EmbedFieldEntry, isEmbed };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbedField.js","names":["useEffect","useEffectEvent","useState","EmbedValue","Spinner","TextInput","usePanneauIntl","useFieldsContext","EmbedSource","getFieldProps","isString","messages","FieldEntryProps","FieldProps","styles","RESOLVE_DELAY","EmbedFieldProps","placeholder","embedSource","isEmbed","value","Record","url","isResolved","Object","keys","some","key","EmbedField","t0","$","_c","disabled","embedSourceProp","onBlur","onChange","props","readOnly","required","t1","errors","t2","undefined","intl","context","status","setStatus","pending","t3","embed","resolved","t4","URL","canParse","controller","AbortController","timeout","window","setTimeout","state","resolve","signal","then","embed_0","catch","aborted","clearTimeout","abort","t5","current","t6","length","formatMessage","embedFailed","shownErrors","t7","next","trim","t8","t9","t10","embedLoading","t11","preview","thumbnailUrl","thumbnail","text","title","provider","t12","EmbedFieldEntry","_c","styles"],"sources":["../../src/embed/EmbedField.tsx"],"sourcesContent":["import { useEffect, useEffectEvent, useState } from 'react';\n\nimport type { EmbedValue } from '@panneau/protocol';\nimport { Spinner, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport type { EmbedSource } from '../shared/embed';\nimport { getFieldProps, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './EmbedField.module.css';\n\nexport type { EmbedValue };\n\nconst RESOLVE_DELAY = 500;\n\nexport interface EmbedFieldProps extends FieldProps<EmbedValue> {\n placeholder?: string;\n /** Where the preview comes from. Defaults to that of the `FieldsProvider`. */\n embedSource?: EmbedSource | null;\n}\n\n/** Whether a value is an embed: an object with a `url`. */\nexport function isEmbed(value: unknown): value is EmbedValue {\n return (\n value !== null &&\n typeof value === 'object' &&\n isString((value as Record<string, unknown>).url)\n );\n}\n\n/** Whether a value has been resolved: it has more than its URL. */\nfunction isResolved(value: EmbedValue): boolean {\n return Object.keys(value).some((key) => key !== 'url');\n}\n\n/**\n * A URL of a video, a sound or a post, with the preview the backend gets from its provider's\n * oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its\n * preview follows. Without an embed source, the value is the URL alone.\n */\nexport function EmbedField({\n value,\n onChange,\n onBlur,\n embedSource: embedSourceProp,\n errors = [],\n disabled,\n readOnly,\n required,\n ...props\n}: EmbedFieldProps) {\n const intl = usePanneauIntl();\n const context = useFieldsContext();\n const embedSource = embedSourceProp === undefined ? context.embedSource : embedSourceProp;\n const url = value?.url ?? '';\n const [status, setStatus] = useState<{ url: string; state: 'loading' | 'failed' } | null>(null);\n\n // Resolves a URL that hasn't been, after a pause in typing\n const pending = value !== null && value !== undefined && !isResolved(value) ? value.url : null;\n // `onChange` changes on every render of a form: the latest one gets the preview\n const resolved = useEffectEvent((embed: EmbedValue) => onChange?.(embed));\n useEffect(() => {\n if (embedSource === null || pending === null || !URL.canParse(pending)) {\n return undefined;\n }\n const controller = new AbortController();\n const timeout = window.setTimeout(() => {\n setStatus({ url: pending, state: 'loading' });\n embedSource\n .resolve(pending, { signal: controller.signal })\n .then((embed) => {\n setStatus(null);\n resolved({ ...embed, url: pending });\n })\n .catch(() => {\n if (!controller.signal.aborted) {\n setStatus({ url: pending, state: 'failed' });\n }\n });\n }, RESOLVE_DELAY);\n return () => {\n window.clearTimeout(timeout);\n controller.abort();\n };\n }, [embedSource, pending]);\n\n const current = status !== null && status.url === url ? status.state : null;\n const shownErrors =\n current === 'failed' && errors.length === 0\n ? [intl.formatMessage(messages.embedFailed)]\n : errors;\n return (\n <div className={styles.embed}>\n <TextInput\n {...props}\n type=\"url\"\n inputMode=\"url\"\n autoComplete=\"off\"\n value={url}\n onChange={(next) => onChange?.(next.trim() === '' ? null : { url: next.trim() })}\n onBlur={() => onBlur?.()}\n errors={shownErrors}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n {current === 'loading' ? (\n <div className={styles.status} role=\"status\">\n <Spinner size=\"sm\" />\n {intl.formatMessage(messages.embedLoading)}\n </div>\n ) : null}\n {value !== null && value !== undefined && isResolved(value) ? (\n <a className={styles.preview} href={value.url} target=\"_blank\" rel=\"noreferrer\">\n {value.thumbnailUrl !== undefined ? (\n <img className={styles.thumbnail} src={value.thumbnailUrl} alt=\"\" />\n ) : null}\n <span className={styles.text}>\n <span className={styles.title}>{value.title ?? value.url}</span>\n {value.provider !== undefined ? (\n <span className={styles.provider}>{value.provider}</span>\n ) : null}\n </span>\n </a>\n ) : null}\n </div>\n );\n}\n\n/** The `embed` type: its preview comes from the embed source of the `FieldsProvider`. */\nexport function EmbedFieldEntry(props: FieldEntryProps) {\n return (\n <EmbedField\n {...getFieldProps(props)}\n value={isEmbed(props.value) ? props.value : null}\n onChange={props.onChange}\n />\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EmbedField.js","names":["ReactNode","useEffect","useEffectEvent","useState","formsMessages","EmbedValue","Spinner","TextInput","usePanneauIntl","useFieldsContext","EmbedSource","findRule","getFieldProps","isString","messages","FieldEntryProps","FieldProps","styles","RESOLVE_DELAY","EmbedFieldProps","placeholder","embedSource","providers","isEmbed","value","Record","url","isAllowed","undefined","length","provider","toLowerCase","some","allowed","isResolved","Object","keys","key","EmbedField","t0","$","_c","description","disabled","embedSourceProp","onBlur","onChange","props","readOnly","required","t1","errors","t2","intl","context","status","setStatus","pending","t3","embed","resolved","t4","URL","canParse","controller","AbortController","timeout","window","setTimeout","state","resolve","signal","then","embed_0","catch","aborted","clearTimeout","abort","t5","current","providerList","t6","formatList","type","formatMessage","embedFailed","rule","ownError","t7","shownErrors","t8","embedProviders","help","t9","next","trim","t10","t11","t12","embedLoading","t13","preview","thumbnailUrl","thumbnail","text","title","t14","getProviders","field","Array","isArray","filter","EmbedFieldEntry","_c","_Fragment","styles"],"sources":["../../src/embed/EmbedField.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useEffectEvent, useState } from 'react';\n\nimport { formsMessages } from '@panneau/intl';\nimport type { EmbedValue } from '@panneau/protocol';\nimport { Spinner, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { useFieldsContext } from '../shared/context';\nimport type { EmbedSource } from '../shared/embed';\nimport { findRule, getFieldProps, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport styles from './EmbedField.module.css';\n\nexport type { EmbedValue };\n\nconst RESOLVE_DELAY = 500;\n\nexport interface EmbedFieldProps extends FieldProps<EmbedValue> {\n placeholder?: string;\n /** Where the preview comes from. Defaults to that of the `FieldsProvider`. */\n embedSource?: EmbedSource | null;\n /**\n * The providers an embed may come from (`YouTube`), compared without case: the `providers`\n * rule (decision 0058). The field names them under its help, and refuses an embed of another\n * provider as soon as its preview comes back. The form's errors, once shown, replace that one.\n */\n providers?: readonly string[];\n}\n\n/** Whether a value is an embed: an object with a `url`. */\nexport function isEmbed(value: unknown): value is EmbedValue {\n return (\n value !== null &&\n typeof value === 'object' &&\n isString((value as Record<string, unknown>).url)\n );\n}\n\n/** Whether an embed comes from one of the providers. One without a provider is left to the backend. */\nfunction isAllowed(value: EmbedValue, providers: readonly string[] | undefined): boolean {\n if (providers === undefined || providers.length === 0 || value.provider === undefined) {\n return true;\n }\n const provider = value.provider.toLowerCase();\n return providers.some((allowed) => allowed.toLowerCase() === provider);\n}\n\n/** Whether a value has been resolved: it has more than its URL. */\nfunction isResolved(value: EmbedValue): boolean {\n return Object.keys(value).some((key) => key !== 'url');\n}\n\n/**\n * A URL of a video, a sound or a post, with the preview the backend gets from its provider's\n * oEmbed: its thumbnail, title and provider. The URL is kept as soon as it is typed, and its\n * preview follows. Without an embed source, the value is the URL alone.\n */\nexport function EmbedField({\n value,\n onChange,\n onBlur,\n embedSource: embedSourceProp,\n providers,\n errors = [],\n disabled,\n readOnly,\n required,\n description,\n ...props\n}: EmbedFieldProps) {\n const intl = usePanneauIntl();\n const context = useFieldsContext();\n const embedSource = embedSourceProp === undefined ? context.embedSource : embedSourceProp;\n const url = value?.url ?? '';\n const [status, setStatus] = useState<{ url: string; state: 'loading' | 'failed' } | null>(null);\n\n // Resolves a URL that hasn't been, after a pause in typing\n const pending = value !== null && value !== undefined && !isResolved(value) ? value.url : null;\n // `onChange` changes on every render of a form: the latest one gets the preview\n const resolved = useEffectEvent((embed: EmbedValue) => onChange?.(embed));\n useEffect(() => {\n if (embedSource === null || pending === null || !URL.canParse(pending)) {\n return undefined;\n }\n const controller = new AbortController();\n const timeout = window.setTimeout(() => {\n setStatus({ url: pending, state: 'loading' });\n embedSource\n .resolve(pending, { signal: controller.signal })\n .then((embed) => {\n setStatus(null);\n resolved({ ...embed, url: pending });\n })\n .catch(() => {\n if (!controller.signal.aborted) {\n setStatus({ url: pending, state: 'failed' });\n }\n });\n }, RESOLVE_DELAY);\n return () => {\n window.clearTimeout(timeout);\n controller.abort();\n };\n }, [embedSource, pending]);\n\n const current = status !== null && status.url === url ? status.state : null;\n const providerList =\n providers !== undefined && providers.length > 0\n ? intl.formatList(providers, { type: 'disjunction' })\n : null;\n const ownError =\n current === 'failed'\n ? intl.formatMessage(messages.embedFailed)\n : value !== null &&\n value !== undefined &&\n providerList !== null &&\n !isAllowed(value, providers)\n ? intl.formatMessage(formsMessages.rule.providers, { providers: providerList })\n : null;\n const shownErrors = ownError !== null && errors.length === 0 ? [ownError] : errors;\n const help: ReactNode =\n providerList !== null ? (\n <>\n {description !== undefined && description !== null ? <>{description} </> : null}\n {intl.formatMessage(messages.embedProviders, {\n providers: intl.formatList(providers ?? [], { type: 'conjunction' }),\n })}\n </>\n ) : (\n description\n );\n return (\n <div className={styles.embed}>\n <TextInput\n {...props}\n type=\"url\"\n inputMode=\"url\"\n autoComplete=\"off\"\n value={url}\n onChange={(next) => onChange?.(next.trim() === '' ? null : { url: next.trim() })}\n onBlur={() => onBlur?.()}\n errors={shownErrors}\n description={help}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n {current === 'loading' ? (\n <div className={styles.status} role=\"status\">\n <Spinner size=\"sm\" />\n {intl.formatMessage(messages.embedLoading)}\n </div>\n ) : null}\n {value !== null && value !== undefined && isResolved(value) ? (\n <a className={styles.preview} href={value.url} target=\"_blank\" rel=\"noreferrer\">\n {value.thumbnailUrl !== undefined ? (\n <img className={styles.thumbnail} src={value.thumbnailUrl} alt=\"\" />\n ) : null}\n <span className={styles.text}>\n <span className={styles.title}>{value.title ?? value.url}</span>\n {value.provider !== undefined ? (\n <span className={styles.provider}>{value.provider}</span>\n ) : null}\n </span>\n </a>\n ) : null}\n </div>\n );\n}\n\n/** The providers of a `providers` rule, if the field has one. */\nfunction getProviders(field: FieldEntryProps['field']): string[] | undefined {\n const rule = findRule(field, 'providers');\n return rule !== undefined && 'value' in rule && Array.isArray(rule.value)\n ? rule.value.filter(isString)\n : undefined;\n}\n\n/**\n * The `embed` type: its preview comes from the embed source of the `FieldsProvider`, and its\n * `providers` rule names the providers it allows.\n */\nexport function EmbedFieldEntry(props: FieldEntryProps) {\n const providers = getProviders(props.field);\n return (\n <EmbedField\n {...getFieldProps(props)}\n value={isEmbed(props.value) ? props.value : null}\n onChange={props.onChange}\n {...(providers !== undefined ? { providers } : {})}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* The type, its input, the label, then the new tab. */
|
|
2
|
+
.panneau-link-field-link {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: stretch;
|
|
6
|
+
gap: var(--panneau-space-3);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.panneau-link-field-link > :first-child {
|
|
10
|
+
align-self: flex-start;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { LinkValue } from '@panneau/protocol';
|
|
2
|
+
import { type LinkNewTab, type LinkType } from '@panneau/protocol/runtime';
|
|
3
|
+
import type { FieldEntryProps, FieldProps } from '../shared/types.js';
|
|
4
|
+
/** Whether links have a label: optional, required, or none. */
|
|
5
|
+
export type LinkLabelMode = 'optional' | 'required' | 'none';
|
|
6
|
+
export interface LinkFieldProps extends FieldProps<LinkValue> {
|
|
7
|
+
/** Dot path of the value, the prefix of the paths of its parts. Defaults to `name`. */
|
|
8
|
+
path?: string;
|
|
9
|
+
/** The types offered, in order. Defaults to `url`, `email` and `tel`. */
|
|
10
|
+
types?: readonly LinkType[];
|
|
11
|
+
/** The resources of `page` links. */
|
|
12
|
+
pages?: readonly string[];
|
|
13
|
+
/** The media libraries of `file` links. Defaults to every library. */
|
|
14
|
+
libraries?: readonly string[];
|
|
15
|
+
/** Which links open in a new tab. Defaults to `choose`, a checkbox. */
|
|
16
|
+
newTab?: LinkNewTab;
|
|
17
|
+
/** Whether links have a label. Defaults to `optional`. */
|
|
18
|
+
labelMode?: LinkLabelMode;
|
|
19
|
+
/**
|
|
20
|
+
* The label is a string, not a value per locale: in a `localized` link field, where the whole
|
|
21
|
+
* link is per locale already.
|
|
22
|
+
*/
|
|
23
|
+
singleLabel?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A link (decision 0055): its type, in a segmented control, then the input of the type (a URL, a
|
|
27
|
+
* page searched in the resources of `pages`, an email address, a phone number, a media, or the
|
|
28
|
+
* text of a type of the site), its label per locale, and whether it opens in a new tab. Each part
|
|
29
|
+
* shows the errors of its own path (`link.url`) in a form.
|
|
30
|
+
*/
|
|
31
|
+
export declare function LinkField({ value, onChange, onBlur, path, name, types: typesProp, pages, libraries, newTab, labelMode, singleLabel, label, description, errors, disabled, readOnly, required, className, }: LinkFieldProps): import("react").JSX.Element;
|
|
32
|
+
/**
|
|
33
|
+
* The `link` type: its `resource` (the resources of `page` links), and settings `types`,
|
|
34
|
+
* `newTab`, `label` and `libraries`. In a localized field, the label of each locale's link is a
|
|
35
|
+
* string.
|
|
36
|
+
*/
|
|
37
|
+
export declare function LinkFieldEntry(props: FieldEntryProps): import("react").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=LinkField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkField.d.ts","sourceRoot":"","sources":["../../src/link/LinkField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAS,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EACH,KAAK,UAAU,EACf,KAAK,QAAQ,EAGhB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQnE,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,cAAe,SAAQ,UAAU,CAAC,SAAS,CAAC;IACzD,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC5B,qCAAqC;IACrC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,sEAAsE;IACtE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,uEAAuE;IACvE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAoBD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,KAAU,EACV,SAAS,EACT,MAAiB,EACjB,SAAsB,EACtB,WAAmB,EACnB,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,GACZ,EAAE,cAAc,+BA8OhB;AAgFD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,+BAyBpD"}
|