@fieldia/core 0.28.0 → 0.29.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.
- package/README.md +125 -1
- package/package.json +1 -1
- package/schema/page.schema.json +263 -6
- package/src/index.d.mts +8 -2
- package/src/index.d.ts +8 -2
- package/src/index.js +29 -2
- package/src/index.js.map +1 -1
- package/src/index.mjs +11 -2
- package/src/index.mjs.map +1 -1
- package/src/lib/format/approval-checks.d.mts +8 -0
- package/src/lib/format/approval-checks.d.ts +8 -0
- package/src/lib/format/approval-checks.js +29 -0
- package/src/lib/format/approval-checks.js.map +1 -0
- package/src/lib/format/approval-checks.mjs +26 -0
- package/src/lib/format/approval-checks.mjs.map +1 -0
- package/src/lib/format/approval.d.mts +20 -0
- package/src/lib/format/approval.d.ts +20 -0
- package/src/lib/format/approval.js +25 -0
- package/src/lib/format/approval.js.map +1 -0
- package/src/lib/format/approval.mjs +22 -0
- package/src/lib/format/approval.mjs.map +1 -0
- package/src/lib/format/assist-checks.d.mts +14 -0
- package/src/lib/format/assist-checks.d.ts +14 -0
- package/src/lib/format/assist-checks.js +68 -0
- package/src/lib/format/assist-checks.js.map +1 -0
- package/src/lib/format/assist-checks.mjs +64 -0
- package/src/lib/format/assist-checks.mjs.map +1 -0
- package/src/lib/format/assist.d.mts +41 -0
- package/src/lib/format/assist.d.ts +41 -0
- package/src/lib/format/assist.js +29 -0
- package/src/lib/format/assist.js.map +1 -0
- package/src/lib/format/assist.mjs +26 -0
- package/src/lib/format/assist.mjs.map +1 -0
- package/src/lib/format/editable-checks.d.mts +8 -0
- package/src/lib/format/editable-checks.d.ts +8 -0
- package/src/lib/format/editable-checks.js +38 -0
- package/src/lib/format/editable-checks.js.map +1 -0
- package/src/lib/format/editable-checks.mjs +35 -0
- package/src/lib/format/editable-checks.mjs.map +1 -0
- package/src/lib/format/field.d.mts +86 -0
- package/src/lib/format/field.d.ts +86 -0
- package/src/lib/format/field.js +56 -10
- package/src/lib/format/field.js.map +1 -1
- package/src/lib/format/field.mjs +55 -9
- package/src/lib/format/field.mjs.map +1 -1
- package/src/lib/format/languages-checks.d.mts +8 -0
- package/src/lib/format/languages-checks.d.ts +8 -0
- package/src/lib/format/languages-checks.js +40 -0
- package/src/lib/format/languages-checks.js.map +1 -0
- package/src/lib/format/languages-checks.mjs +37 -0
- package/src/lib/format/languages-checks.mjs.map +1 -0
- package/src/lib/format/later-checks.d.mts +4 -3
- package/src/lib/format/later-checks.d.ts +4 -3
- package/src/lib/format/later-checks.js +4 -3
- package/src/lib/format/later-checks.js.map +1 -1
- package/src/lib/format/later-checks.mjs +4 -3
- package/src/lib/format/later-checks.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +100 -26
- package/src/lib/format/layout.d.ts +100 -26
- package/src/lib/format/layout.js +19 -3
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +17 -1
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/layout.types.d.mts +2 -1
- package/src/lib/format/layout.types.d.ts +2 -1
- package/src/lib/format/list-editable.d.mts +20 -0
- package/src/lib/format/list-editable.d.ts +20 -0
- package/src/lib/format/list-editable.js +33 -0
- package/src/lib/format/list-editable.js.map +1 -0
- package/src/lib/format/list-editable.mjs +28 -0
- package/src/lib/format/list-editable.mjs.map +1 -0
- package/src/lib/format/page.d.mts +84 -9
- package/src/lib/format/page.d.ts +84 -9
- package/src/lib/format/page.js +4 -0
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +4 -0
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/photos-options.d.mts +29 -0
- package/src/lib/format/photos-options.d.ts +29 -0
- package/src/lib/format/photos-options.js +49 -0
- package/src/lib/format/photos-options.js.map +1 -0
- package/src/lib/format/photos-options.mjs +45 -0
- package/src/lib/format/photos-options.mjs.map +1 -0
- package/src/lib/format/references.js +31 -1
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +31 -1
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/scan-checks.d.mts +12 -0
- package/src/lib/format/scan-checks.d.ts +12 -0
- package/src/lib/format/scan-checks.js +89 -0
- package/src/lib/format/scan-checks.js.map +1 -0
- package/src/lib/format/scan-checks.mjs +86 -0
- package/src/lib/format/scan-checks.mjs.map +1 -0
- package/src/lib/format/scan-options.d.mts +84 -0
- package/src/lib/format/scan-options.d.ts +84 -0
- package/src/lib/format/scan-options.js +58 -0
- package/src/lib/format/scan-options.js.map +1 -0
- package/src/lib/format/scan-options.mjs +54 -0
- package/src/lib/format/scan-options.mjs.map +1 -0
- package/src/lib/format/upgrade.d.mts +4 -2
- package/src/lib/format/upgrade.d.ts +4 -2
- package/src/lib/format/upgrade.js +4 -2
- package/src/lib/format/upgrade.js.map +1 -1
- package/src/lib/format/upgrade.mjs +4 -2
- package/src/lib/format/upgrade.mjs.map +1 -1
- package/src/lib/format/version.d.mts +2 -2
- package/src/lib/format/version.d.ts +2 -2
- package/src/lib/format/version.js +2 -2
- package/src/lib/format/version.js.map +1 -1
- package/src/lib/format/version.mjs +2 -2
- package/src/lib/format/version.mjs.map +1 -1
- package/src/lib/record/approvals-part.d.mts +6 -0
- package/src/lib/record/approvals-part.d.ts +6 -0
- package/src/lib/record/approvals-part.js +14 -0
- package/src/lib/record/approvals-part.js.map +1 -0
- package/src/lib/record/approvals-part.mjs +7 -0
- package/src/lib/record/approvals-part.mjs.map +1 -0
- package/src/lib/record/approving.d.mts +45 -0
- package/src/lib/record/approving.d.ts +45 -0
- package/src/lib/record/approving.js +10 -0
- package/src/lib/record/approving.js.map +1 -0
- package/src/lib/record/approving.mjs +7 -0
- package/src/lib/record/approving.mjs.map +1 -0
- package/src/lib/record/check.js +4 -0
- package/src/lib/record/check.js.map +1 -1
- package/src/lib/record/check.mjs +4 -0
- package/src/lib/record/check.mjs.map +1 -1
- package/src/lib/record/data-source.d.mts +270 -0
- package/src/lib/record/data-source.d.ts +270 -0
- package/src/lib/record/data-source.js.map +1 -1
- package/src/lib/record/data-source.mjs.map +1 -1
- package/src/lib/record/files-part.d.mts +7 -0
- package/src/lib/record/files-part.d.ts +7 -0
- package/src/lib/record/files-part.js +167 -0
- package/src/lib/record/files-part.js.map +1 -0
- package/src/lib/record/files-part.mjs +163 -0
- package/src/lib/record/files-part.mjs.map +1 -0
- package/src/lib/record/filter.d.mts +5 -0
- package/src/lib/record/filter.d.ts +5 -0
- package/src/lib/record/filter.js +1 -0
- package/src/lib/record/filter.js.map +1 -1
- package/src/lib/record/filter.mjs +1 -1
- package/src/lib/record/filter.mjs.map +1 -1
- package/src/lib/record/form-approvals.d.mts +47 -0
- package/src/lib/record/form-approvals.d.ts +47 -0
- package/src/lib/record/form-approvals.js +186 -0
- package/src/lib/record/form-approvals.js.map +1 -0
- package/src/lib/record/form-approvals.mjs +180 -0
- package/src/lib/record/form-approvals.mjs.map +1 -0
- package/src/lib/record/form.d.mts +32 -1
- package/src/lib/record/form.d.ts +32 -1
- package/src/lib/record/form.js +49 -5
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +49 -5
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/languages-part.d.mts +32 -0
- package/src/lib/record/languages-part.d.ts +32 -0
- package/src/lib/record/languages-part.js +104 -0
- package/src/lib/record/languages-part.js.map +1 -0
- package/src/lib/record/languages-part.mjs +96 -0
- package/src/lib/record/languages-part.mjs.map +1 -0
- package/src/lib/record/languages.d.mts +26 -0
- package/src/lib/record/languages.d.ts +26 -0
- package/src/lib/record/languages.js +20 -0
- package/src/lib/record/languages.js.map +1 -0
- package/src/lib/record/languages.mjs +15 -0
- package/src/lib/record/languages.mjs.map +1 -0
- package/src/lib/record/locales/ar.js +5 -0
- package/src/lib/record/locales/ar.js.map +1 -1
- package/src/lib/record/locales/ar.mjs +5 -0
- package/src/lib/record/locales/ar.mjs.map +1 -1
- package/src/lib/record/locales/de.js +5 -0
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +5 -0
- package/src/lib/record/locales/de.mjs.map +1 -1
- package/src/lib/record/locales/fr.js +5 -0
- package/src/lib/record/locales/fr.js.map +1 -1
- package/src/lib/record/locales/fr.mjs +5 -0
- package/src/lib/record/locales/fr.mjs.map +1 -1
- package/src/lib/record/memory-approvals.d.mts +47 -0
- package/src/lib/record/memory-approvals.d.ts +47 -0
- package/src/lib/record/memory-approvals.js +78 -0
- package/src/lib/record/memory-approvals.js.map +1 -0
- package/src/lib/record/memory-approvals.mjs +75 -0
- package/src/lib/record/memory-approvals.mjs.map +1 -0
- package/src/lib/record/memory-assist.d.mts +53 -0
- package/src/lib/record/memory-assist.d.ts +53 -0
- package/src/lib/record/memory-assist.js +519 -0
- package/src/lib/record/memory-assist.js.map +1 -0
- package/src/lib/record/memory-assist.mjs +513 -0
- package/src/lib/record/memory-assist.mjs.map +1 -0
- package/src/lib/record/memory-clusters.d.mts +18 -0
- package/src/lib/record/memory-clusters.d.ts +18 -0
- package/src/lib/record/memory-clusters.js +83 -0
- package/src/lib/record/memory-clusters.js.map +1 -0
- package/src/lib/record/memory-clusters.mjs +80 -0
- package/src/lib/record/memory-clusters.mjs.map +1 -0
- package/src/lib/record/memory-data-source.d.mts +43 -3
- package/src/lib/record/memory-data-source.d.ts +43 -3
- package/src/lib/record/memory-data-source.js +105 -19
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +105 -19
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/memory-later.d.mts +1 -1
- package/src/lib/record/memory-later.d.ts +1 -1
- package/src/lib/record/memory-later.js +4 -1
- package/src/lib/record/memory-later.js.map +1 -1
- package/src/lib/record/memory-later.mjs +4 -1
- package/src/lib/record/memory-later.mjs.map +1 -1
- package/src/lib/record/messages.d.mts +14 -0
- package/src/lib/record/messages.d.ts +14 -0
- package/src/lib/record/messages.js +5 -0
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +5 -0
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/uploads.d.mts +35 -9
- package/src/lib/record/uploads.d.ts +35 -9
- package/src/lib/record/uploads.js +49 -169
- package/src/lib/record/uploads.js.map +1 -1
- package/src/lib/record/uploads.mjs +42 -164
- package/src/lib/record/uploads.mjs.map +1 -1
- package/src/lib/record/values.d.mts +23 -0
- package/src/lib/record/values.d.ts +23 -0
- package/src/lib/record/values.js +4 -0
- package/src/lib/record/values.js.map +1 -1
- package/src/lib/record/values.mjs +4 -0
- package/src/lib/record/values.mjs.map +1 -1
- package/src/runtime.d.mts +12 -5
- package/src/runtime.d.ts +12 -5
- package/src/runtime.js +18 -3
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +7 -1
- package/src/runtime.mjs.map +1 -1
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { foldForSearch } from './input-rules.mjs';
|
|
2
|
+
import { languagesOf } from './languages.mjs';
|
|
3
|
+
const STAND_IN = 'Stand-in AI, no model:';
|
|
4
|
+
/** Words as they are compared: small letters, no accents or marks, digits as 0-9, Arabic letters folded. */
|
|
5
|
+
const fold = (text) => foldForSearch(text).normalize('NFD').replace(/[̀-ͯ]/g, '');
|
|
6
|
+
const escape = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
7
|
+
/** Whole words of `words` in `text` (both folded), as a pattern: a word's plural too ("villa", "villas", "cities"). */
|
|
8
|
+
const wordsPattern = (words) => {
|
|
9
|
+
const body = escape(words).replace(/\s+/g, '\\s+');
|
|
10
|
+
const plural = /y$/.test(words) ? `(?:${body}|${escape(words.slice(0, -1))}ies)` : `${body}(?:e?s)?`;
|
|
11
|
+
return new RegExp(`(?<![\\p{L}\\p{N}])${plural}(?![\\p{L}\\p{N}])`, 'u');
|
|
12
|
+
};
|
|
13
|
+
/** A record's name, as a search finds it: its `name`, else its `label`, `title` or `display_name`. */
|
|
14
|
+
const nameOf = (values) => {
|
|
15
|
+
for (const key of ['name', 'label', 'title', 'display_name'])
|
|
16
|
+
if (typeof values[key] === 'string' && values[key].trim())
|
|
17
|
+
return values[key];
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
/** A number as people write it in a search or a message: "15M", "2.5 million", "800k", "15,000,000", "1.5". */
|
|
21
|
+
export function standInNumber(digits, unit = '') {
|
|
22
|
+
const clean = digits.replace(/\s/g, '');
|
|
23
|
+
// "15,000,000" and "15.000.000" group by threes; "1.5" and "1,5" are a fraction.
|
|
24
|
+
const grouped = /^\d{1,3}([,.]\d{3})+$/.test(clean) && !/^\d{1,3}[,.]\d{3}$/.test(clean) ? clean.replace(/[,.]/g, '') : /^\d{1,3},\d{3}$/.test(clean) ? clean.replace(',', '') : clean.replace(',', '.');
|
|
25
|
+
const value = Number(grouped);
|
|
26
|
+
if (!Number.isFinite(value))
|
|
27
|
+
return null;
|
|
28
|
+
const times = /^(k|thousand)$/i.test(unit) ? 1e3 : /^(m|mn|mio|million|millions)$/i.test(unit) ? 1e6 : /^(bn|b|billion|billions)$/i.test(unit) ? 1e9 : 1;
|
|
29
|
+
return Math.round(value * times * 100) / 100;
|
|
30
|
+
}
|
|
31
|
+
// ---- reading a signature or a message --------------------------------------------------------------------------
|
|
32
|
+
const TITLE_WORDS = /\b(manager|director|head|lead|engineer|officer|ceo|cfo|coo|cto|cmo|founder|co-founder|partner|consultant|specialist|coordinator|executive|president|vice|agent|broker|analyst|accountant|designer|developer|assistant|supervisor|owner|associate|advisor|adviser|representative|administrator|architect|doctor|dr\.?|nurse|lawyer|counsel)\b/i;
|
|
33
|
+
const COMPANY_WORDS = /\b(ltd|llc|l\.l\.c|inc|co|corp|corporation|company|group|gmbh|sae|s\.a\.e|plc|traders|trading|holding|holdings|developments|development|realty|properties|industries|foods|clinic|clinics|hospital|bank|partners|studio|agency|solutions|systems|consulting|logistics|pharma|labs?)\b\.?/i;
|
|
34
|
+
const STREET_WORDS = /\b(st|street|rd|road|ave|avenue|blvd|boulevard|sq|square|floor|building|bldg|tower|district|corniche|way|lane|plaza)\b/i;
|
|
35
|
+
const CLOSINGS = /^(best|kind|warm)?\s*(regards|wishes)|^thanks|^thank you|^cheers|^sincerely|^sent from|^--+$|^__+$|^(hi|hello|dear)\b/i;
|
|
36
|
+
const EMAIL = /[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g;
|
|
37
|
+
const URL = /\b(?:https?:\/\/[^\s<>()]+|www\.[\w-]+(?:\.[\w-]+)+(?:\/[^\s<>()]*)?)/gi;
|
|
38
|
+
const PHONE = /(?:\+|00)?\d[\d\s().-]{6,}\d/g;
|
|
39
|
+
const TAX = /\b(?:vat|tax(?:\s*(?:id|no\.?|number|reg(?:istration)?(?:\s*no\.?)?))?|trn)\b\s*[:#.]?\s*([A-Z0-9][A-Z0-9 -]{3,}[A-Z0-9])/i;
|
|
40
|
+
const ONE_EMAIL = /[\w.+-]+@[\w-]+(?:\.[\w-]+)+/;
|
|
41
|
+
const ONE_URL = /\b(?:https?:\/\/\S+|www\.[\w-]+(?:\.[\w-]+)+)/i;
|
|
42
|
+
const PERSON = /^[\p{Lu}][\p{L}'’.-]*(?:\s+[\p{Lu}][\p{L}'’.-]*){1,3}$|^[-ۿ]+(?:\s+[-ۿ]+){1,3}$/u;
|
|
43
|
+
/** A signature or a message, read line by line by its patterns. */
|
|
44
|
+
export function readSignature(text) {
|
|
45
|
+
const found = { emails: [...new Set(text.match(EMAIL) ?? [])], phones: [] };
|
|
46
|
+
// A line each, or parts of one line apart with a middle dot, as a signature copied on one line has them.
|
|
47
|
+
const lines = text.split(/\r?\n|\s[·•]\s/).map((line) => line.trim()).filter(Boolean);
|
|
48
|
+
const website = text.replace(EMAIL, ' ').match(URL)?.[0];
|
|
49
|
+
if (website)
|
|
50
|
+
found.website = /^https?:\/\//i.test(website) ? website.replace(/[.,;]+$/, '') : `https://${website.replace(/[.,;]+$/, '')}`;
|
|
51
|
+
const tax = TAX.exec(text);
|
|
52
|
+
if (tax)
|
|
53
|
+
found.tax = tax[1].trim();
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
const plain = line.replace(EMAIL, ' ').replace(URL, ' ');
|
|
56
|
+
// A tax id's digits are no phone's.
|
|
57
|
+
for (const match of (tax && line.includes(tax[1]) ? '' : plain).match(PHONE) ?? []) {
|
|
58
|
+
const number = match.trim();
|
|
59
|
+
if (number.replace(/\D/g, '').length < 7)
|
|
60
|
+
continue;
|
|
61
|
+
if (/\b(m|mob|mobile|cell|whatsapp)\b\s*[:.]?/i.test(line) && !found.mobile)
|
|
62
|
+
found.mobile = number;
|
|
63
|
+
else
|
|
64
|
+
found.phones.push(number);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (found.mobile && !found.phones.length)
|
|
68
|
+
found.phones.push(found.mobile);
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
// A greeting, a sign-off, an e-mail's, a website's or a phone's line names no one; an address keeps its numbers.
|
|
71
|
+
const address = /,/.test(line) && STREET_WORDS.test(line);
|
|
72
|
+
if (!address && (CLOSINGS.test(line) || ONE_EMAIL.test(line) || ONE_URL.test(line) || /\d{5,}/.test(line.replace(/[\s().+-]/g, ''))))
|
|
73
|
+
continue;
|
|
74
|
+
// "Sales Director | Nile Traders", "Sales Director, Nile Traders", "Sales Director at Nile Traders".
|
|
75
|
+
const split = /^(.+?)\s*(?:\||·|•|–|—|,| at | @ )\s*(.+)$/.exec(line);
|
|
76
|
+
if (!found.title && TITLE_WORDS.test(line)) {
|
|
77
|
+
if (split && TITLE_WORDS.test(split[1]) && !TITLE_WORDS.test(split[2])) {
|
|
78
|
+
found.title = split[1].trim();
|
|
79
|
+
if (!found.company)
|
|
80
|
+
found.company = split[2].trim();
|
|
81
|
+
}
|
|
82
|
+
else if (!STREET_WORDS.test(line))
|
|
83
|
+
found.title = line;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (!found.company && COMPANY_WORDS.test(line) && !STREET_WORDS.test(line) && !/\d/.test(line)) {
|
|
87
|
+
found.company = line;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!found.street && (STREET_WORDS.test(line) || /^\d+\s+\p{L}/u.test(line)) && line.length > 6) {
|
|
91
|
+
const parts = line.split(/\s*,\s*/).filter(Boolean);
|
|
92
|
+
found.street = parts.length > 2 ? parts.slice(0, -2).join(', ') : parts[0];
|
|
93
|
+
if (parts.length > 2) {
|
|
94
|
+
found.city = parts[parts.length - 2];
|
|
95
|
+
found.place = parts[parts.length - 1];
|
|
96
|
+
}
|
|
97
|
+
else if (parts.length === 2)
|
|
98
|
+
found.city = parts[1];
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (!found.person && PERSON.test(line) && !COMPANY_WORDS.test(line) && !TITLE_WORDS.test(line) && !STREET_WORDS.test(line))
|
|
102
|
+
found.person = line;
|
|
103
|
+
}
|
|
104
|
+
return found;
|
|
105
|
+
}
|
|
106
|
+
/** What a field holds, by its name and its label: an e-mail, a phone, a website, a job, a company, a person's name… */
|
|
107
|
+
function roleOf(name, def) {
|
|
108
|
+
const words = fold(`${name.replace(/_/g, ' ')} ${def.label}`);
|
|
109
|
+
if (/e-?mail/.test(words))
|
|
110
|
+
return 'email';
|
|
111
|
+
if (/mobile|whatsapp|cell/.test(words))
|
|
112
|
+
return 'mobile';
|
|
113
|
+
if (/phone|tel\b|telephone/.test(words))
|
|
114
|
+
return 'phone';
|
|
115
|
+
if (/website|web site|\burl\b|homepage|\bweb\b/.test(words))
|
|
116
|
+
return 'website';
|
|
117
|
+
if (/\bvat\b|\btax\b|\btrn\b/.test(words))
|
|
118
|
+
return 'tax';
|
|
119
|
+
if (/\bjob\b|position|\bfunction\b|\brole\b|job title/.test(words))
|
|
120
|
+
return 'title';
|
|
121
|
+
if (/company|organi[sz]ation|employer|business|\bfirm\b|account name/.test(words))
|
|
122
|
+
return 'company';
|
|
123
|
+
if (/street|address/.test(words))
|
|
124
|
+
return 'street';
|
|
125
|
+
if (/\bcity\b|\btown\b/.test(words))
|
|
126
|
+
return 'city';
|
|
127
|
+
if (/\bname\b|contact|person/.test(words))
|
|
128
|
+
return 'person';
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
/** A record of `model` named in `text` (folded), the longest name first: `{ id, label }`, or null. */
|
|
132
|
+
function recordIn(text, model, records) {
|
|
133
|
+
if (!model)
|
|
134
|
+
return null;
|
|
135
|
+
const named = Object.entries(records[model] ?? {})
|
|
136
|
+
.map(([id, values]) => ({ id, label: nameOf(values) }))
|
|
137
|
+
.filter((one) => !!one.label && one.label.trim().length > 1)
|
|
138
|
+
.sort((a, b) => b.label.length - a.label.length);
|
|
139
|
+
const one = named.find((record) => wordsPattern(fold(record.label)).test(text));
|
|
140
|
+
return one ? { id: /^\d+$/.test(one.id) ? Number(one.id) : one.id, label: one.label } : null;
|
|
141
|
+
}
|
|
142
|
+
/** An option of a choice named in `text` (folded), the longest words first. */
|
|
143
|
+
const optionIn = (text, options) => [...options].sort((a, b) => b.label.length - a.label.length).find((option) => wordsPattern(fold(option.label)).test(text));
|
|
144
|
+
/** A number beside the words of a field's label in `text`: "3 bedrooms", "Budget: 12M". */
|
|
145
|
+
function numberBy(text, def) {
|
|
146
|
+
const words = fold(def.label).split(/[^\p{L}]+/u).filter((word) => word.length > 2);
|
|
147
|
+
for (const word of words) {
|
|
148
|
+
const stem = escape(word.replace(/s$/, ''));
|
|
149
|
+
const after = new RegExp(`(\\d[\\d.,]*)\\s*(k|m|mn|million|thousand|bn)?\\s+${stem}`, 'iu').exec(text);
|
|
150
|
+
const before = new RegExp(`${stem}\\w*(?:\\s*(?:of|:|is|-|about|around|roughly|up to|max|maximum|under|below|egp|le|usd|\\$))*\\s*(\\d[\\d.,]*)\\s*(k|m|mn|million|thousand|bn)?(?![\\p{L}²\\d])`, 'iu').exec(text);
|
|
151
|
+
const hit = after ?? before;
|
|
152
|
+
if (hit)
|
|
153
|
+
return standInNumber(hit[1], hit[2] ?? '');
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
/** Lines of things to add: "2 x Dental chair @ 4,500", "3 × Botox 50u", "- 5 pcs Gloves". */
|
|
158
|
+
const LINE_ITEM = /^\s*[-*•]?\s*(\d+(?:[.,]\d+)?)\s*(?:x|×|pcs|pieces|units?|no\.?)\s+(.+?)(?:\s+(?:@|at)\s+([\d.,]+))?\s*$/i;
|
|
159
|
+
function linesFrom(text, found, def, records) {
|
|
160
|
+
const fields = def.fields ?? {};
|
|
161
|
+
const roles = Object.entries(fields).map(([name, sub]) => [name, sub, roleOf(name, sub)]);
|
|
162
|
+
const personal = roles.some(([, , role]) => role === 'person') && roles.some(([, , role]) => role === 'email' || role === 'phone' || role === 'title' || role === 'mobile');
|
|
163
|
+
if (personal && found.person) {
|
|
164
|
+
const line = {};
|
|
165
|
+
for (const [name, sub, role] of roles) {
|
|
166
|
+
const value = valueFor(role, found, sub, text, records);
|
|
167
|
+
if (value !== undefined)
|
|
168
|
+
line[name] = value;
|
|
169
|
+
}
|
|
170
|
+
return [line];
|
|
171
|
+
}
|
|
172
|
+
// Things to add, each a line: its quantity, its name (a product by its record), its price.
|
|
173
|
+
const quantity = roles.find(([, sub]) => sub.type === 'integer' || sub.type === 'float')?.[0];
|
|
174
|
+
const price = roles.find(([, sub]) => sub.type === 'monetary')?.[0] ?? roles.find(([name, sub]) => sub.type === 'float' && name !== quantity)?.[0];
|
|
175
|
+
const what = roles.find(([, sub]) => sub.type === 'many2one')?.[0] ?? roles.find(([, sub]) => sub.type === 'char' || sub.type === 'text')?.[0];
|
|
176
|
+
if (!what)
|
|
177
|
+
return [];
|
|
178
|
+
return text.split(/\r?\n/).flatMap((line) => {
|
|
179
|
+
const item = LINE_ITEM.exec(line);
|
|
180
|
+
if (!item)
|
|
181
|
+
return [];
|
|
182
|
+
const sub = fields[what];
|
|
183
|
+
const name = item[2].trim();
|
|
184
|
+
const link = sub.type === 'many2one' ? (recordIn(fold(name), sub.relation, records) ?? name) : name;
|
|
185
|
+
return [{ [what]: link, ...(quantity ? { [quantity]: standInNumber(item[1]) } : {}), ...(price && item[3] ? { [price]: standInNumber(item[3]) } : {}) }];
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function valueFor(role, found, def, text, records) {
|
|
189
|
+
const folded = fold(text);
|
|
190
|
+
if (def.type === 'many2one')
|
|
191
|
+
return (role === 'company' && found.company ? found.company : recordIn(folded, def.relation, records)) ?? undefined;
|
|
192
|
+
if (def.type === 'selection')
|
|
193
|
+
return optionIn(folded, def.options ?? [])?.value;
|
|
194
|
+
if (def.type === 'integer' || def.type === 'float' || def.type === 'monetary')
|
|
195
|
+
return numberBy(folded, def) ?? undefined;
|
|
196
|
+
if (def.type !== 'char' && def.type !== 'text')
|
|
197
|
+
return undefined;
|
|
198
|
+
switch (role) {
|
|
199
|
+
case 'email':
|
|
200
|
+
return found.emails[0];
|
|
201
|
+
case 'mobile':
|
|
202
|
+
return found.mobile ?? found.phones[1];
|
|
203
|
+
case 'phone':
|
|
204
|
+
return found.phones[0];
|
|
205
|
+
case 'website':
|
|
206
|
+
return found.website;
|
|
207
|
+
case 'tax':
|
|
208
|
+
return found.tax;
|
|
209
|
+
case 'title':
|
|
210
|
+
return found.title;
|
|
211
|
+
case 'company':
|
|
212
|
+
return found.company;
|
|
213
|
+
case 'street':
|
|
214
|
+
return found.street;
|
|
215
|
+
case 'city':
|
|
216
|
+
return found.city;
|
|
217
|
+
case 'person':
|
|
218
|
+
return found.person;
|
|
219
|
+
default:
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** What a file holds as words, where it is text; null for any other file. */
|
|
224
|
+
async function fileText(file) {
|
|
225
|
+
if (!/^text\/|json|rfc822|vcard|csv/i.test(file.type) && !/\.(txt|eml|vcf|csv|md|json)$/i.test(file.name))
|
|
226
|
+
return null;
|
|
227
|
+
// The host's own decoder (a browser's, or Node's): core names no DOM types.
|
|
228
|
+
const Decoder = globalThis.TextDecoder;
|
|
229
|
+
return new Decoder().decode(await file.arrayBuffer());
|
|
230
|
+
}
|
|
231
|
+
/** The kinds found, in words: "a name, a job title and an e-mail". */
|
|
232
|
+
const listed = (items) => (items.length < 2 ? (items[0] ?? '') : `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`);
|
|
233
|
+
/** A language by its English name, as the stand-in says it: "English", "Arabic". */
|
|
234
|
+
function english(tag) {
|
|
235
|
+
try {
|
|
236
|
+
return new Intl.DisplayNames(['en'], { type: 'language' }).of(tag) ?? tag;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return tag;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/** What a text kept in several languages was filled in: one language alone — the others are each a person's to type. */
|
|
243
|
+
const inOneLanguage = (filled) => (filled.length ? ` ${listed(filled)} only: each other language is a person's to type.` : '');
|
|
244
|
+
async function suggest(request, records) {
|
|
245
|
+
const unread = [];
|
|
246
|
+
const texts = [request.from.text ?? ''];
|
|
247
|
+
for (const file of request.from.files ?? []) {
|
|
248
|
+
const words = await fileText(file);
|
|
249
|
+
if (words === null)
|
|
250
|
+
unread.push(file.name);
|
|
251
|
+
else
|
|
252
|
+
texts.push(words);
|
|
253
|
+
}
|
|
254
|
+
const text = texts.join('\n');
|
|
255
|
+
const found = readSignature(text);
|
|
256
|
+
// A company's page: its name is the company's, the person a contact of it.
|
|
257
|
+
const companyPage = request.fields.some((name) => /company|organi[sz]ation|customer|account/.test(fold(request.page.fields[name]?.label ?? '')) && (name === 'name' || roleOf(name, request.page.fields[name]) === 'company'));
|
|
258
|
+
const values = {};
|
|
259
|
+
const said = new Set();
|
|
260
|
+
const words = { person: 'a name', title: 'a job title', company: 'a company', email: 'an e-mail', phone: 'a phone', mobile: 'a mobile', website: 'a website', street: 'a street', city: 'a city', tax: 'a tax id' };
|
|
261
|
+
for (const name of request.fields) {
|
|
262
|
+
const def = request.page.fields[name];
|
|
263
|
+
if (!def)
|
|
264
|
+
continue;
|
|
265
|
+
if (def.type === 'one2many') {
|
|
266
|
+
const lines = linesFrom(text, found, def, records);
|
|
267
|
+
if (lines.length) {
|
|
268
|
+
values[name] = lines;
|
|
269
|
+
said.add(lines.length === 1 ? `a line for ${def.label}` : `${lines.length} lines for ${def.label}`);
|
|
270
|
+
}
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
let role = roleOf(name, def);
|
|
274
|
+
if (role === 'person' && name === 'name' && companyPage)
|
|
275
|
+
role = 'company';
|
|
276
|
+
const value = role === 'company' && def.type === 'char' ? found.company : valueFor(role, found, def, text, records);
|
|
277
|
+
if (value === undefined || value === null || value === '')
|
|
278
|
+
continue;
|
|
279
|
+
values[name] = value;
|
|
280
|
+
said.add(role && words[role] ? words[role] : `the ${def.label.toLowerCase()}`);
|
|
281
|
+
}
|
|
282
|
+
// A text kept in several languages: the language asked for alone, said so.
|
|
283
|
+
const filledIn = Object.entries(request.languages ?? {}).filter(([name]) => values[name] !== undefined).map(([name, tag]) => `${request.page.fields[name]?.label ?? name} in ${english(tag)}`);
|
|
284
|
+
const why = [`${STAND_IN} read by its patterns${said.size ? ` — ${listed([...said])}` : ''}.${inOneLanguage(filledIn)}`, unread.length ? `It reads text files only: ${unread.join(', ')} not read.` : ''].filter(Boolean).join(' ');
|
|
285
|
+
return { values, why };
|
|
286
|
+
}
|
|
287
|
+
// ---- writing and polishing ------------------------------------------------------------------------------------------
|
|
288
|
+
const SHORTHAND = [
|
|
289
|
+
[/\bu\b/gi, 'you'],
|
|
290
|
+
[/\bur\b/gi, 'your'],
|
|
291
|
+
[/\b(pls|plz)\b/gi, 'please'],
|
|
292
|
+
[/\b(thx|thnx|thanx)\b/gi, 'thanks'],
|
|
293
|
+
[/\basap\b/gi, 'as soon as possible'],
|
|
294
|
+
[/\bmsg\b/gi, 'message'],
|
|
295
|
+
[/\bappt\b/gi, 'appointment'],
|
|
296
|
+
[/\b(tmrw|tmr|2moro)\b/gi, 'tomorrow'],
|
|
297
|
+
[/\bb4\b/gi, 'before'],
|
|
298
|
+
[/\bw\/o\b/gi, 'without'],
|
|
299
|
+
[/\bw\/(?=\s)/gi, 'with'],
|
|
300
|
+
[/\babt\b/gi, 'about'],
|
|
301
|
+
[/\bim\b/gi, "I'm"],
|
|
302
|
+
[/\bive\b/gi, "I've"],
|
|
303
|
+
[/\bdont\b/gi, "don't"],
|
|
304
|
+
[/\bcant\b/gi, "can't"],
|
|
305
|
+
[/\bwont\b/gi, "won't"],
|
|
306
|
+
[/\bdidnt\b/gi, "didn't"],
|
|
307
|
+
[/\bisnt\b/gi, "isn't"],
|
|
308
|
+
[/\bdoesnt\b/gi, "doesn't"],
|
|
309
|
+
[/\bi\b/g, 'I'],
|
|
310
|
+
];
|
|
311
|
+
/** Words made clearer, the same every time: what it did, in words. */
|
|
312
|
+
export function polishText(text) {
|
|
313
|
+
const did = new Set();
|
|
314
|
+
let out = text.replace(/\r\n?/g, '\n');
|
|
315
|
+
const spaced = out.replace(/[ \t]+/g, ' ').replace(/ *\n */g, '\n').replace(/\n{3,}/g, '\n\n').replace(/ +([,.!?;:])/g, '$1').replace(/([,.!?;:])(?=[\p{L}])/gu, '$1 ').trim();
|
|
316
|
+
if (spaced !== out.trim())
|
|
317
|
+
did.add('tidied the spaces');
|
|
318
|
+
out = spaced;
|
|
319
|
+
const marks = out.replace(/([!?])\1+/g, '$1').replace(/\.{4,}/g, '…');
|
|
320
|
+
if (marks !== out)
|
|
321
|
+
did.add('one mark where there were several');
|
|
322
|
+
out = marks;
|
|
323
|
+
for (const [pattern, words] of SHORTHAND) {
|
|
324
|
+
const next = out.replace(pattern, words);
|
|
325
|
+
if (next !== out && words !== 'I')
|
|
326
|
+
did.add('wrote out shorthand');
|
|
327
|
+
out = next;
|
|
328
|
+
}
|
|
329
|
+
// The sign-off: a last paragraph of short lines after another ("regards" / "mona") — its first ends with a comma, the
|
|
330
|
+
// name under it written with capitals and nothing after it.
|
|
331
|
+
const all = out.split('\n');
|
|
332
|
+
const gap = all.lastIndexOf('');
|
|
333
|
+
const closing = gap > 0 && all.length - gap - 1 >= 1 && all.length - gap - 1 <= 3 && all.slice(gap + 1).every((line) => line.trim().split(/\s+/).length <= 3) ? gap + 1 : all.length;
|
|
334
|
+
const lines = all.map((line, i) => {
|
|
335
|
+
if (!line.trim())
|
|
336
|
+
return line;
|
|
337
|
+
if (i >= closing) {
|
|
338
|
+
const words = line.replace(/(^|\s)(\p{Ll})/gu, (_, space, letter) => space + letter.toUpperCase());
|
|
339
|
+
return i === closing && !/[.!?:,…]$/.test(words) ? `${words},` : words;
|
|
340
|
+
}
|
|
341
|
+
// A greeting: "hi mona" → "Hi Mona,".
|
|
342
|
+
const greeting = /^(hi|hello|dear|hey)\b\s*(.*)$/i.exec(line);
|
|
343
|
+
if (greeting && line.split(/\s+/).length <= 4) {
|
|
344
|
+
const name = greeting[2].replace(/[,.!:]+$/, '').replace(/(^|\s)(\p{Ll})/gu, (_, space, letter) => space + letter.toUpperCase());
|
|
345
|
+
return `${greeting[1][0].toUpperCase()}${greeting[1].slice(1).toLowerCase()}${name ? ` ${name}` : ''},`;
|
|
346
|
+
}
|
|
347
|
+
let sentence = line.replace(/(^|[.!?]\s+)(\p{Ll})/gu, (_, before, letter) => before + letter.toUpperCase());
|
|
348
|
+
// A line that ends a paragraph ends its sentence; a short sign-off ("Kind regards") ends with a comma.
|
|
349
|
+
const last = i === all.length - 1 || !all[i + 1].trim();
|
|
350
|
+
const short = line.split(/\s+/).length <= 3;
|
|
351
|
+
if (last && !/[.!?:,…)"”]$/.test(sentence))
|
|
352
|
+
sentence += short && !/^(thanks|thank you)/i.test(sentence) && i > 0 ? ',' : '.';
|
|
353
|
+
return sentence;
|
|
354
|
+
});
|
|
355
|
+
const polished = lines.join('\n');
|
|
356
|
+
if (polished !== out)
|
|
357
|
+
did.add('put capitals and full stops in');
|
|
358
|
+
return { text: polished, did: [...did] };
|
|
359
|
+
}
|
|
360
|
+
/** An html field's words as lines, and back: each paragraph a line. */
|
|
361
|
+
const fromHtml = (html) => html.replace(/<\/p>\s*<p[^>]*>/gi, '\n\n').replace(/<br\s*\/?>/gi, '\n').replace(/<[^>]*>/g, '').replace(/ /g, ' ').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').trim();
|
|
362
|
+
const toHtml = (text) => text.split(/\n{2,}/).map((part) => `<p>${part.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>')}</p>`).join('');
|
|
363
|
+
/** A short reply that greets the person the record names: the stand-in's draft where the app gave no template. */
|
|
364
|
+
function plainDraft(request) {
|
|
365
|
+
const named = Object.entries(request.page.fields).find(([name, def]) => def.type === 'char' && roleOf(name, def) === 'person' && typeof request.values[name] === 'string' && request.values[name].trim());
|
|
366
|
+
const first = named ? request.values[named[0]].trim().split(/\s+/)[0] : '';
|
|
367
|
+
return [`${first ? `Dear ${first}` : 'Hello'},`, '', 'Thank you for your message. We have it, and will come back to you shortly with what you asked for.', '', 'Kind regards,'].join('\n');
|
|
368
|
+
}
|
|
369
|
+
async function rewrite(request, options) {
|
|
370
|
+
const def = request.page.fields[request.field];
|
|
371
|
+
const html = def?.type === 'html';
|
|
372
|
+
// A text kept in several languages: written in the language asked for alone, said so.
|
|
373
|
+
const one = languagesOf(def) ? inOneLanguage([`Written in ${english(request.language)}`]) : '';
|
|
374
|
+
if (request.how === 'draft') {
|
|
375
|
+
const own = options.drafts?.[`${request.model}.${request.field}`] ?? options.drafts?.[`${request.pageId}.${request.field}`];
|
|
376
|
+
const text = own ? own(request.values, request) : plainDraft(request);
|
|
377
|
+
return { text: html ? toHtml(text) : text, why: `${STAND_IN} written from this record’s fields by a template.${one}` };
|
|
378
|
+
}
|
|
379
|
+
const { text, did } = polishText(html ? fromHtml(request.text) : request.text);
|
|
380
|
+
return { text: html ? toHtml(text) : text, why: `${STAND_IN} ${did.length ? `${listed(did)}.` : 'nothing to make clearer.'}${one}` };
|
|
381
|
+
}
|
|
382
|
+
// ---- a search in plain words ------------------------------------------------------------------------------------
|
|
383
|
+
// A unit read only where no letter, digit or square follows it: "15m" is fifteen million, "200 m²" two hundred.
|
|
384
|
+
const NUMBER = String.raw `(\d+(?:[.,]\d+)*)\s*(k|m|mn|million|millions|thousand|bn|billion)?(?![\p{L}²\d])`;
|
|
385
|
+
const UNDER = String.raw `(?:under|below|less than|up to|upto|max(?:imum)?|at most|no more than|cheaper than|<=?)`;
|
|
386
|
+
const OVER = String.raw `(?:over|above|more than|at least|min(?:imum)?|starting (?:at|from)|>=?)`;
|
|
387
|
+
const AREA_UNITS = /^\s*(m²|m2|sqm|sq\.?\s*m|square\s*(?:metres|meters|m))/i;
|
|
388
|
+
const STOPS = new Set(['in', 'at', 'on', 'with', 'for', 'and', 'or', 'the', 'a', 'an', 'of', 'to', 'near', 'by', 'around', 'egp', 'le', 'usd', 'pounds', 'dollars', 'show', 'me', 'find', 'all', 'any', 'some', 'that', 'which', 'is', 'are', 'has', 'have', 'from', 'between']);
|
|
389
|
+
function searchToFilter(request, records) {
|
|
390
|
+
let rest = ` ${fold(request.text)} `;
|
|
391
|
+
const read = [];
|
|
392
|
+
const filter = [];
|
|
393
|
+
const fields = request.fields.map((name) => [name, request.page.fields[name]]).filter(([, def]) => !!def);
|
|
394
|
+
const numbers = fields.filter(([, def]) => def.type === 'integer' || def.type === 'float' || def.type === 'monetary');
|
|
395
|
+
/** The number field words beside a number name: a field's label ("bedrooms") or its unit ("m²"); else the first amount. */
|
|
396
|
+
const numberField = (after, before) => {
|
|
397
|
+
const near = `${before.split(/\s+/).slice(-2).join(' ')} ${after.split(/\s+/).slice(0, 3).join(' ')}`;
|
|
398
|
+
if (AREA_UNITS.test(after))
|
|
399
|
+
return numbers.find(([name, def]) => /area|m²|m2|size|surface/.test(fold(`${name} ${def.label}`)))?.[0];
|
|
400
|
+
const byLabel = numbers.find(([, def]) => fold(def.label).split(/[^\p{L}]+/u).some((word) => word.length > 2 && new RegExp(`\\b${escape(word.replace(/s$/, ''))}`, 'u').test(near)));
|
|
401
|
+
return byLabel?.[0] ?? numbers.find(([, def]) => def.type === 'monetary')?.[0] ?? numbers[0]?.[0];
|
|
402
|
+
};
|
|
403
|
+
const blank = (at, length) => (rest = rest.slice(0, at) + ' '.repeat(length) + rest.slice(at + length));
|
|
404
|
+
const take = (match) => {
|
|
405
|
+
read.push(match[0].trim());
|
|
406
|
+
blank(match.index, match[0].length);
|
|
407
|
+
};
|
|
408
|
+
/** The words of a number's field beside it — "bedrooms" after "3+", "m²" after "200" — taken with it. */
|
|
409
|
+
const takeFieldWords = (field, end) => {
|
|
410
|
+
if (!field)
|
|
411
|
+
return;
|
|
412
|
+
const near = rest.slice(end, end + 24);
|
|
413
|
+
const words = fold(request.page.fields[field].label).split(/[^\p{L}]+/u).filter((word) => word.length > 2);
|
|
414
|
+
const hit = [AREA_UNITS, ...words.map((word) => new RegExp(`^[\\s-]*${escape(word.replace(/s$/, ''))}\\p{L}*`, 'u'))].map((pattern) => pattern.exec(near)).find(Boolean);
|
|
415
|
+
if (hit)
|
|
416
|
+
blank(end, hit[0].length);
|
|
417
|
+
};
|
|
418
|
+
const ranges = [
|
|
419
|
+
[new RegExp(String.raw `(?:between|from)\s+${NUMBER}\s*(?:and|to|-|–)\s*${NUMBER}`, 'iu'), (m) => {
|
|
420
|
+
const field = numberField(rest.slice(m.index + m[0].length), rest.slice(0, m.index));
|
|
421
|
+
const from = standInNumber(m[1], m[2] ?? '');
|
|
422
|
+
const to = standInNumber(m[3], m[4] ?? m[2] ?? '');
|
|
423
|
+
if (field && from !== null && to !== null)
|
|
424
|
+
filter.push({ field, op: 'between', value: [from, to] });
|
|
425
|
+
}],
|
|
426
|
+
[new RegExp(String.raw `${UNDER}\s+${NUMBER}`, 'iu'), (m) => {
|
|
427
|
+
const field = numberField(rest.slice(m.index + m[0].length), rest.slice(0, m.index));
|
|
428
|
+
const to = standInNumber(m[1], m[2] ?? '');
|
|
429
|
+
if (field && to !== null)
|
|
430
|
+
filter.push({ field, op: '<=', value: to });
|
|
431
|
+
}],
|
|
432
|
+
[new RegExp(String.raw `${OVER}\s+${NUMBER}`, 'iu'), (m) => {
|
|
433
|
+
const field = numberField(rest.slice(m.index + m[0].length), rest.slice(0, m.index));
|
|
434
|
+
const from = standInNumber(m[1], m[2] ?? '');
|
|
435
|
+
if (field && from !== null)
|
|
436
|
+
filter.push({ field, op: '>=', value: from });
|
|
437
|
+
}],
|
|
438
|
+
[new RegExp(String.raw `${NUMBER}\s*\+`, 'iu'), (m) => {
|
|
439
|
+
const field = numberField(rest.slice(m.index + m[0].length), rest.slice(0, m.index));
|
|
440
|
+
const from = standInNumber(m[1], m[2] ?? '');
|
|
441
|
+
if (field && from !== null)
|
|
442
|
+
filter.push({ field, op: '>=', value: from });
|
|
443
|
+
}],
|
|
444
|
+
];
|
|
445
|
+
for (const [pattern, made] of ranges) {
|
|
446
|
+
for (let match = pattern.exec(rest); match; match = pattern.exec(rest)) {
|
|
447
|
+
const before = filter.length;
|
|
448
|
+
made(match);
|
|
449
|
+
take(match);
|
|
450
|
+
if (filter.length > before)
|
|
451
|
+
takeFieldWords(filter[filter.length - 1].field, match.index + match[0].length);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// A number beside a field's label or unit, as it is: "3 bedrooms", "200 m²".
|
|
455
|
+
const plain = new RegExp(String.raw `(?<![\p{L}\d])${NUMBER}`, 'iu');
|
|
456
|
+
for (let match = plain.exec(rest); match; match = plain.exec(rest)) {
|
|
457
|
+
const after = rest.slice(match.index + match[0].length);
|
|
458
|
+
const field = numberField(after, '');
|
|
459
|
+
const value = standInNumber(match[1], match[2] ?? '');
|
|
460
|
+
const unit = AREA_UNITS.exec(after);
|
|
461
|
+
const labelled = field && fold(request.page.fields[field].label).split(/[^\p{L}]+/u).some((word) => word.length > 2 && new RegExp(`^[\\s-]*${escape(word.replace(/s$/, ''))}`, 'u').test(after));
|
|
462
|
+
if (field && value !== null && (labelled || unit))
|
|
463
|
+
filter.push({ field, op: '=', value });
|
|
464
|
+
take(match);
|
|
465
|
+
if (field && (labelled || unit))
|
|
466
|
+
takeFieldWords(field, match.index + match[0].length);
|
|
467
|
+
}
|
|
468
|
+
// Choices and links by their names, the longest first, each word once: "garden city" before "garden".
|
|
469
|
+
const named = [];
|
|
470
|
+
for (const [name, def] of fields) {
|
|
471
|
+
if (def.type === 'selection')
|
|
472
|
+
for (const option of def.options)
|
|
473
|
+
named.push({ field: name, value: option.value, words: fold(option.label), link: false });
|
|
474
|
+
if (def.type === 'many2one' || def.type === 'many2many') {
|
|
475
|
+
for (const [id, values] of Object.entries(records[def.relation ?? ''] ?? {})) {
|
|
476
|
+
const label = nameOf(values);
|
|
477
|
+
if (label)
|
|
478
|
+
named.push({ field: name, value: { id: /^\d+$/.test(id) ? Number(id) : id, label }, words: fold(label), link: true });
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
named.sort((a, b) => b.words.length - a.words.length);
|
|
483
|
+
const picked = new Map();
|
|
484
|
+
for (const one of named) {
|
|
485
|
+
const match = wordsPattern(one.words).exec(rest);
|
|
486
|
+
if (!match)
|
|
487
|
+
continue;
|
|
488
|
+
picked.set(one.field, [...(picked.get(one.field) ?? []), { value: one.value, at: match.index }]);
|
|
489
|
+
take(match);
|
|
490
|
+
}
|
|
491
|
+
// In the order the list names its fields, each field's values in the order they were written.
|
|
492
|
+
for (const [field, found] of [...picked].sort(([a], [b]) => request.fields.indexOf(a) - request.fields.indexOf(b))) {
|
|
493
|
+
const values = [...found].sort((a, b) => a.at - b.at).map((one) => one.value);
|
|
494
|
+
const many = request.page.fields[field].type === 'many2many';
|
|
495
|
+
if (many)
|
|
496
|
+
for (const value of values)
|
|
497
|
+
filter.push({ field, op: 'contains', value });
|
|
498
|
+
else
|
|
499
|
+
filter.push(values.length === 1 ? { field, op: '=', value: values[0] } : { field, op: 'in', value: values });
|
|
500
|
+
}
|
|
501
|
+
const left = rest.split(/\s+/).filter((word) => word && !STOPS.has(word) && /[\p{L}\d]/u.test(word)).join(' ');
|
|
502
|
+
const why = read.length ? `${STAND_IN} read ${listed(read.map((words) => `“${words}”`))} by their patterns.` : `${STAND_IN} found no field in these words.`;
|
|
503
|
+
return { filter, ...(left ? { text: left } : {}), why };
|
|
504
|
+
}
|
|
505
|
+
/** The stand-in's AI help, for a memory source's `assist`: see above. */
|
|
506
|
+
export function assistStandIn(options = {}) {
|
|
507
|
+
return {
|
|
508
|
+
suggest: (request, records) => suggest(request, records),
|
|
509
|
+
rewrite: (request) => rewrite(request, options),
|
|
510
|
+
searchToFilter: (request, records) => searchToFilter(request, records),
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
//# sourceMappingURL=memory-assist.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-assist.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/memory-assist.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA+B1C,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AAE1C,4GAA4G;AAC5G,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC1F,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAC7E,uHAAuH;AACvH,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC;IACrG,OAAO,IAAI,MAAM,CAAC,sBAAsB,MAAM,oBAAoB,EAAE,GAAG,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,sGAAsG;AACtG,MAAM,MAAM,GAAG,CAAC,MAAc,EAAiB,EAAE;IAC/C,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC;QAAE,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAK,MAAM,CAAC,GAAG,CAAY,CAAC,IAAI,EAAE;YAAE,OAAO,MAAM,CAAC,GAAG,CAAW,CAAC;IAClK,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,+GAA+G;AAC/G,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,IAAI,GAAG,EAAE;IACrD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxC,iFAAiF;IACjF,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACzM,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzJ,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AAC/C,CAAC;AAED,mHAAmH;AAEnH,MAAM,WAAW,GAAG,+UAA+U,CAAC;AACpW,MAAM,aAAa,GAAG,2RAA2R,CAAC;AAClT,MAAM,YAAY,GAAG,yHAAyH,CAAC;AAC/I,MAAM,QAAQ,GAAG,wHAAwH,CAAC;AAC1I,MAAM,KAAK,GAAG,+BAA+B,CAAC;AAC9C,MAAM,GAAG,GAAG,yEAAyE,CAAC;AACtF,MAAM,KAAK,GAAG,+BAA+B,CAAC;AAC9C,MAAM,GAAG,GAAG,4HAA4H,CAAC;AACzI,MAAM,SAAS,GAAG,8BAA8B,CAAC;AACjD,MAAM,OAAO,GAAG,gDAAgD,CAAC;AACjE,MAAM,MAAM,GAAG,oFAAoF,CAAC;AAkBpG,mEAAmE;AACnE,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC1F,yGAAyG;IACzG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,OAAO;QAAE,KAAK,CAAC,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC;IAC1I,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,GAAG;QAAE,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACzD,oCAAoC;QACpC,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACnF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YACnD,IAAI,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;;gBAC9F,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,iHAAiH;QACjH,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;YAAE,SAAS;QAC/I,qGAAqG;QACrG,MAAM,KAAK,GAAG,4CAA4C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,OAAO;oBAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACtD,CAAC;iBAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACxD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/F,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACrC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACxC,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACrD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IAClJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uHAAuH;AACvH,SAAS,MAAM,CAAC,IAAY,EAAE,GAAsB;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxD,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACxD,IAAI,2CAA2C,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9E,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,kDAAkD,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACnF,IAAI,iEAAiE,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACpG,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACnD,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sGAAsG;AACtG,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAyB,EAAE,OAAgB;IACzE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACtD,MAAM,CAAC,CAAC,GAAG,EAAwC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;SACjG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/F,CAAC;AAED,+EAA+E;AAC/E,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,OAA0B,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAE1L,2FAA2F;AAC3F,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAsB;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,qDAAqD,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvG,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,gKAAgK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpN,MAAM,GAAG,GAAG,KAAK,IAAI,MAAM,CAAC;QAC5B,IAAI,GAAG;YAAE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6FAA6F;AAC7F,MAAM,SAAS,GAAG,2GAA2G,CAAC;AAE9H,SAAS,SAAS,CAAC,IAAY,EAAE,KAAmB,EAAE,GAAsB,EAAE,OAAgB;IAC5F,MAAM,MAAM,GAAI,GAA8C,CAAC,MAAM,IAAI,EAAE,CAAC;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAU,CAAC,CAAC;IACnG,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,AAAD,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC5K,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAW,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC9C,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,2FAA2F;IAC3F,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnJ,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/I,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAY,EAAE;QACpD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAG,GAA6B,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/H,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAiB,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxK,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB,EAAE,KAAmB,EAAE,GAAsB,EAAE,IAAY,EAAE,OAAgB;IAChH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAG,GAA6B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,SAAS,CAAC;IAC5K,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,QAAQ,CAAC,MAAM,EAAG,GAA8B,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC;IAC5G,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;IACzH,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACjE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzC,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,GAAG,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,KAAK,UAAU,QAAQ,CAAC,IAAgB;IACtC,IAAI,CAAC,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvH,4EAA4E;IAC5E,MAAM,OAAO,GAAI,UAA2F,CAAC,WAAW,CAAC;IACzH,OAAO,IAAI,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,MAAM,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AAE9I,oFAAoF;AACpF,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AACD,wHAAwH;AACxH,MAAM,aAAa,GAAG,CAAC,MAAgB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEzI,KAAK,UAAU,OAAO,CAAC,OAAuB,EAAE,OAAgB;IAC9D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YACtC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,2EAA2E;IAC3E,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,0CAA0C,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IAC/N,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,KAAK,GAA2B,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IAC5O,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,GAAG,KAA6B,CAAC;gBAC7C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YACtG,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM,IAAI,WAAW;YAAE,IAAI,GAAG,SAAS,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpH,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QACpE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/L,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,wBAAwB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpO,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACzB,CAAC;AAED,wHAAwH;AAExH,MAAM,SAAS,GAAuB;IACpC,CAAC,SAAS,EAAE,KAAK,CAAC;IAClB,CAAC,UAAU,EAAE,MAAM,CAAC;IACpB,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC7B,CAAC,wBAAwB,EAAE,QAAQ,CAAC;IACpC,CAAC,YAAY,EAAE,qBAAqB,CAAC;IACrC,CAAC,WAAW,EAAE,SAAS,CAAC;IACxB,CAAC,YAAY,EAAE,aAAa,CAAC;IAC7B,CAAC,wBAAwB,EAAE,UAAU,CAAC;IACtC,CAAC,UAAU,EAAE,QAAQ,CAAC;IACtB,CAAC,YAAY,EAAE,SAAS,CAAC;IACzB,CAAC,eAAe,EAAE,MAAM,CAAC;IACzB,CAAC,WAAW,EAAE,OAAO,CAAC;IACtB,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,YAAY,EAAE,OAAO,CAAC;IACvB,CAAC,YAAY,EAAE,OAAO,CAAC;IACvB,CAAC,YAAY,EAAE,OAAO,CAAC;IACvB,CAAC,aAAa,EAAE,QAAQ,CAAC;IACzB,CAAC,YAAY,EAAE,OAAO,CAAC;IACvB,CAAC,cAAc,EAAE,SAAS,CAAC;IAC3B,CAAC,QAAQ,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,sEAAsE;AACtE,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/K,IAAI,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxD,GAAG,GAAG,MAAM,CAAC;IACb,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACtE,IAAI,KAAK,KAAK,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAChE,GAAG,GAAG,KAAK,CAAC;IACZ,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG;YAAE,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAClE,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;IACD,sHAAsH;IACtH,4DAA4D;IAC5D,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IACrL,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,KAAa,EAAE,MAAc,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YACnH,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACzE,CAAC;QACD,sCAAsC;QACtC,MAAM,QAAQ,GAAG,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,KAAa,EAAE,MAAc,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YACjJ,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAC1G,CAAC;QACD,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5H,uGAAuG;QACvG,MAAM,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,QAAQ,IAAI,KAAK,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7H,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,QAAQ,KAAK,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAChE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,uEAAuE;AACvE,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACtO,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEzL,kHAAkH;AAClH,SAAS,UAAU,CAAC,OAAuB;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAY,CAAC,IAAI,EAAE,CAAC,CAAC;IACtN,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,oGAAoG,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7L,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAuB,EAAE,OAAuB;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC;IAClC,sFAAsF;IACtF,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,cAAc,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,IAAI,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5H,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,QAAQ,oDAAoD,GAAG,EAAE,EAAE,CAAC;IACzH,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B,GAAG,GAAG,EAAE,EAAE,CAAC;AACvI,CAAC;AAED,oHAAoH;AAEpH,gHAAgH;AAChH,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA,kFAAkF,CAAC;AAC5G,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA,yFAAyF,CAAC;AAClH,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,yEAAyE,CAAC;AACjG,MAAM,UAAU,GAAG,yDAAyD,CAAC;AAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAEjR,SAAS,cAAc,CAAC,OAA8B,EAAE,OAAgB;IACtE,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;IACrC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACnH,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACtH,2HAA2H;IAC3H,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,MAAc,EAAsB,EAAE;QACxE,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACtG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpI,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrL,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpG,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,MAAc,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IACxH,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAE,EAAE;QACtC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3B,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC;IACF,yGAAyG;IACzG,MAAM,cAAc,GAAG,CAAC,KAAyB,EAAE,GAAW,EAAE,EAAE;QAChE,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3G,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzK,IAAI,GAAG;YAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,MAAM,MAAM,GAA6C;QACvD,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,sBAAsB,MAAM,uBAAuB,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBAC9F,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrF,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7C,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACnD,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACtG,CAAC,CAAC;QACF,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,KAAK,MAAM,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBACzD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrF,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC3C,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC;QACF,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,IAAI,MAAM,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBACxD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrF,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7C,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5E,CAAC,CAAC;QACF,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,GAAG,MAAM,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBACnD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrF,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7C,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5E,CAAC,CAAC;KACH,CAAC;IACF,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QACrC,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,CAAC;YACZ,IAAI,CAAC,KAAK,CAAC,CAAC;YACZ,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM;gBAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IACD,6EAA6E;IAC7E,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,iBAAiB,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IACpE,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACjM,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,KAAK,CAAC,CAAC;QACZ,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YAAE,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxF,CAAC;IACD,sGAAsG;IACtG,MAAM,KAAK,GAAwE,EAAE,CAAC;IACtF,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzJ,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACxD,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAE,GAA6B,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBACxG,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC7B,IAAI,KAAK;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACnI,CAAC;QACH,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8C,CAAC;IACrE,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACjG,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;IACD,8FAA8F;IAC9F,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnH,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC;QAC7D,IAAI,IAAI;YAAE,KAAK,MAAM,KAAK,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;;YAC/E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACpH,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/G,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,QAAQ,iCAAiC,CAAC;IAC5J,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAC1D,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,UAA0B,EAAE;IACxD,OAAO;QACL,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;QACxD,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;QAC/C,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC;KACvE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ClustersRequest, ClustersResult, ListedRecord } from './data-source.mjs';
|
|
2
|
+
import { type RecordId, type Values } from './values.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* How a memory source answers `clusters` (its `clusters` option), for demos and tests: as a server gathers a map's
|
|
5
|
+
* records by a grid. The records the search finds in the view, each put in a square of the world as the map draws it
|
|
6
|
+
* at its zoom — `radius` pixels a side, the squares fixed to the world, so a record keeps its square as the map pans —
|
|
7
|
+
* and each square holding two or more one bubble: their middle, their count, the box they lie in (and their `weight`,
|
|
8
|
+
* added up, where asked). A square holding one is that record, standing alone, as a list's row gives it (the memory
|
|
9
|
+
* source's `row`: the fields asked, as this person may read them). Those the search finds with no place are counted
|
|
10
|
+
* (`unplaced`). `models` names the models it gathers; a map of any other is answered `false`, and loads its records as
|
|
11
|
+
* without it. A map that moved on (`signal`) is refused with an AbortError. Outside the one-tag script, as
|
|
12
|
+
* `alikeRecords` is.
|
|
13
|
+
*
|
|
14
|
+
* createMemoryDataSource({ records, clusters: gridClusters({ models: ['home'] }) })
|
|
15
|
+
*/
|
|
16
|
+
export declare function gridClusters(how?: {
|
|
17
|
+
models?: string[];
|
|
18
|
+
}): (request: ClustersRequest, records: Readonly<Record<string, Record<string, Values>>>, row?: (id: RecordId, values: Values) => ListedRecord) => ClustersResult | false;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ClustersRequest, ClustersResult, ListedRecord } from './data-source';
|
|
2
|
+
import { type RecordId, type Values } from './values';
|
|
3
|
+
/**
|
|
4
|
+
* How a memory source answers `clusters` (its `clusters` option), for demos and tests: as a server gathers a map's
|
|
5
|
+
* records by a grid. The records the search finds in the view, each put in a square of the world as the map draws it
|
|
6
|
+
* at its zoom — `radius` pixels a side, the squares fixed to the world, so a record keeps its square as the map pans —
|
|
7
|
+
* and each square holding two or more one bubble: their middle, their count, the box they lie in (and their `weight`,
|
|
8
|
+
* added up, where asked). A square holding one is that record, standing alone, as a list's row gives it (the memory
|
|
9
|
+
* source's `row`: the fields asked, as this person may read them). Those the search finds with no place are counted
|
|
10
|
+
* (`unplaced`). `models` names the models it gathers; a map of any other is answered `false`, and loads its records as
|
|
11
|
+
* without it. A map that moved on (`signal`) is refused with an AbortError. Outside the one-tag script, as
|
|
12
|
+
* `alikeRecords` is.
|
|
13
|
+
*
|
|
14
|
+
* createMemoryDataSource({ records, clusters: gridClusters({ models: ['home'] }) })
|
|
15
|
+
*/
|
|
16
|
+
export declare function gridClusters(how?: {
|
|
17
|
+
models?: string[];
|
|
18
|
+
}): (request: ClustersRequest, records: Readonly<Record<string, Record<string, Values>>>, row?: (id: RecordId, values: Values) => ListedRecord) => ClustersResult | false;
|