@aglyn/plugins-ai 1.0.0-beta.288 → 1.0.0-beta.290
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/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.d.ts +3 -2
- package/src/lib/activity/ai-activity-actions.js +3 -0
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +2 -0
- package/src/lib/components/ai-job-requests.js +2 -0
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +4 -0
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-import-job.component.d.ts +6 -1
- package/src/lib/components/ai-site-import-job.component.js +124 -17
- package/src/lib/components/ai-site-import-job.component.js.map +1 -1
- package/src/lib/components/ai-site-import-start.component.d.ts +6 -0
- package/src/lib/components/ai-site-import-start.component.js +18 -4
- package/src/lib/components/ai-site-import-start.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.js +2 -1
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/jobs/ai-image-reads.d.ts +20 -2
- package/src/lib/jobs/ai-image-reads.js +47 -0
- package/src/lib/jobs/ai-image-reads.js.map +1 -1
- package/src/lib/jobs/ai-job-import-step.d.ts +53 -3
- package/src/lib/jobs/ai-job-import-step.js +386 -64
- package/src/lib/jobs/ai-job-import-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +33 -0
- package/src/lib/jobs/ai-job-layout-language.js +75 -1
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.js +8 -3
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +29 -0
- package/src/lib/jobs/ai-job-page-language.js +178 -2
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +3 -0
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-site-import-document.d.ts +117 -0
- package/src/lib/jobs/ai-site-import-document.js +710 -0
- package/src/lib/jobs/ai-site-import-document.js.map +1 -0
- package/src/lib/jobs/ai-site-import-look.d.ts +112 -0
- package/src/lib/jobs/ai-site-import-look.js +402 -0
- package/src/lib/jobs/ai-site-import-look.js.map +1 -0
- package/src/lib/jobs/ai-site-import-publish.d.ts +41 -0
- package/src/lib/jobs/ai-site-import-publish.js +92 -0
- package/src/lib/jobs/ai-site-import-publish.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +27 -2
- package/src/lib/jobs/ai-theme-brand-inputs.js +37 -8
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame.d.ts +17 -0
- package/src/lib/layout-language/ai-layout-frame.js +73 -2
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-language.d.ts +43 -0
- package/src/lib/layout-language/ai-layout-language.js +199 -0
- package/src/lib/layout-language/ai-layout-language.js.map +1 -1
- package/src/lib/model/ai-credit-estimate.d.ts +15 -0
- package/src/lib/model/ai-credit-estimate.js +14 -1
- package/src/lib/model/ai-credit-estimate.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +13 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-site-import-view.d.ts +47 -3
- package/src/lib/model/ai-site-import-view.js +122 -20
- package/src/lib/model/ai-site-import-view.js.map +1 -1
- package/src/lib/model/ai-site-import.d.ts +232 -7
- package/src/lib/model/ai-site-import.js +365 -35
- package/src/lib/model/ai-site-import.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +18 -0
- package/src/lib/runtime/ai-doctrine-validators.js +16 -5
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-palette.generated.js +31 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/server/ai-image-reads-route.js +24 -1
- package/src/lib/server/ai-image-reads-route.js.map +1 -1
- package/src/lib/server/ai-jobs-resume.js +7 -1
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/site-import/fixtures/aglyn-com-recordings.d.ts +57 -0
- package/src/lib/site-import/fixtures/aglyn-com-recordings.js +172 -0
- package/src/lib/site-import/fixtures/aglyn-com-recordings.js.map +1 -0
- package/src/lib/site-import/site-import-crawl.d.ts +32 -7
- package/src/lib/site-import/site-import-crawl.js +133 -44
- package/src/lib/site-import/site-import-crawl.js.map +1 -1
- package/src/lib/site-import/site-import-edge-server.d.ts +31 -0
- package/src/lib/site-import/site-import-edge-server.js +31 -0
- package/src/lib/site-import/site-import-edge-server.js.map +1 -0
- package/src/lib/site-import/site-import-edge.d.ts +44 -0
- package/src/lib/site-import/site-import-edge.js +108 -0
- package/src/lib/site-import/site-import-edge.js.map +1 -0
- package/src/lib/site-import/site-import-html.d.ts +73 -3
- package/src/lib/site-import/site-import-html.js +332 -45
- package/src/lib/site-import/site-import-html.js.map +1 -1
- package/src/lib/site-import/site-import-images.d.ts +22 -0
- package/src/lib/site-import/site-import-images.js +78 -2
- package/src/lib/site-import/site-import-images.js.map +1 -1
- package/src/lib/site-import/site-import-page.d.ts +44 -2
- package/src/lib/site-import/site-import-page.js +116 -16
- package/src/lib/site-import/site-import-page.js.map +1 -1
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ /*==========================================
|
|
18
|
+
* A PAGE BROUGHT IN WORD FOR WORD (AGL-4084).
|
|
19
|
+
*
|
|
20
|
+
* An imported page is never rewritten. Its words are the source's, as the
|
|
21
|
+
* crawler read them (`AiSiteImportPageRead.blocks`), and this module is the
|
|
22
|
+
* only thing that puts them on the new page:
|
|
23
|
+
*
|
|
24
|
+
* - **Lines.** The page's main region, numbered: every heading, paragraph,
|
|
25
|
+
* list item, quote, link and picture in source order. A link inside a
|
|
26
|
+
* sentence is in its sentence already and is no line of its own.
|
|
27
|
+
* - **Sections.** One for the page's opening (its title and what comes
|
|
28
|
+
* before the first second-level heading), then one for each second-level
|
|
29
|
+
* heading, as the source divides itself. The page's plan has exactly
|
|
30
|
+
* these sections, by these names.
|
|
31
|
+
* - **Copied** (a collection's page, a long page): laid out by code, every
|
|
32
|
+
* line in order, the bands alternating plain and soft, with no model at
|
|
33
|
+
* all.
|
|
34
|
+
* - **Arranged** (a main page): the model's answer says each section's band
|
|
35
|
+
* and columns and which numbered lines go in which kind of block
|
|
36
|
+
* (`AI_LAYOUT_ARRANGE_TOOL`, which has no field for a word of copy). Code
|
|
37
|
+
* substitutes the lines exactly as written. A block naming a line already
|
|
38
|
+
* placed is dropped, a line of another section is not taken, and every
|
|
39
|
+
* line the answer never placed is added at the end of its own section, so
|
|
40
|
+
* each line is on the page exactly once.
|
|
41
|
+
*
|
|
42
|
+
* Both write the palette's own elements with the theme's tokens, the way the
|
|
43
|
+
* layout language compiler does (`ai-layout-compiler.ts`), so the page
|
|
44
|
+
* renders in the site's theme and every word stays editable in the
|
|
45
|
+
* Besigner's fields. Nothing is fitted, cut at a clean boundary or reworded:
|
|
46
|
+
* a paragraph longer than a text element holds is split between sentences,
|
|
47
|
+
* and a page longer than one page may weigh ends at a line, marked `cut`, so
|
|
48
|
+
* the review says how many of its words came through.
|
|
49
|
+
*=========================================*/ import { CANVAS_ROOT_ELEMENT_ID } from "@aglyn/aglyn/foundation/constants/canvas";
|
|
50
|
+
import { bandSx } from "../layout-language/ai-layout-compiler.js";
|
|
51
|
+
import { AI_LAYOUT_ARRANGE_ITEM_KINDS } from "../layout-language/ai-layout-language.js";
|
|
52
|
+
import { AiLayoutTreeBuilder, aiLayoutSpans } from "../layout-language/ai-layout-tree.js";
|
|
53
|
+
import { AI_SITE_IMPORT_LABEL_MAX_CHARS, AI_SITE_IMPORT_MAX_SECTIONS } from "../model/ai-site-import.js";
|
|
54
|
+
import { siteImportLabel } from "../site-import/site-import-page.js";
|
|
55
|
+
import { AI_TEXT_LIMITS } from "../runtime/ai-palette.js";
|
|
56
|
+
/** The unit input carrying a page brought in word for word: its lines, its photos and where its links go. */ export const AI_LAYOUT_IMPORTED_SECTIONS_INPUT = 'importedSections';
|
|
57
|
+
/** The most characters a text element holds (the palette's ceiling for body copy). */ export const AI_SITE_IMPORT_TEXT_MAX_CHARS = AI_TEXT_LIMITS.body;
|
|
58
|
+
/** The most characters a heading style holds; a longer heading is drawn in a subtitle style, still a heading. */ export const AI_SITE_IMPORT_HEADLINE_MAX_CHARS = AI_TEXT_LIMITS.headline;
|
|
59
|
+
/** The most characters a button's label holds; a longer link keeps its words as a line of text. */ export const AI_SITE_IMPORT_LABEL_CHARS = 40;
|
|
60
|
+
/**
|
|
61
|
+
* What one page may weigh, inside the budget of a page of its owner's own
|
|
62
|
+
* words (`AI_OWN_WORDS_PAGE_BUDGET`): a page that would run past it ends at
|
|
63
|
+
* the line before, marked `cut`.
|
|
64
|
+
*/ export const AI_SITE_IMPORT_DOC_MAX_NODES = 1400;
|
|
65
|
+
export const AI_SITE_IMPORT_DOC_MAX_CHARS = 200000;
|
|
66
|
+
const SECTION_PADDING = {
|
|
67
|
+
xs: 8,
|
|
68
|
+
md: 12
|
|
69
|
+
};
|
|
70
|
+
const clean = (text)=>String(text != null ? text : '').replace(/\s+/g, ' ').trim();
|
|
71
|
+
/** Whether a block is a line of its own: a link inside a sentence is in its sentence already. */ function isLine(block) {
|
|
72
|
+
if (block.kind === 'image') return !!block.url;
|
|
73
|
+
if (block.kind === 'link') return !block.inline && !!clean(block.text);
|
|
74
|
+
return !!clean(block.text);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The page's lines and sections (AGL-4084): the opening, then one section
|
|
78
|
+
* at each second-level heading, at most `AI_SITE_IMPORT_MAX_SECTIONS` (the
|
|
79
|
+
* last holds whatever follows). A page that opens on a second-level heading
|
|
80
|
+
* opens with it. Section names are the headings' words, neutralized and cut
|
|
81
|
+
* to a label, since they travel outside a fence.
|
|
82
|
+
*/ export function aiSiteImportDocLines(blocks, title) {
|
|
83
|
+
const lines = [];
|
|
84
|
+
const sections = [];
|
|
85
|
+
let current = null;
|
|
86
|
+
for (const block of blocks){
|
|
87
|
+
if (!isLine(block)) continue;
|
|
88
|
+
const starts = block.kind === 'heading' && block.level === 2 && sections.length < AI_SITE_IMPORT_MAX_SECTIONS;
|
|
89
|
+
if (!current || starts && current.lines.length > 0) {
|
|
90
|
+
current = {
|
|
91
|
+
name: '',
|
|
92
|
+
lines: []
|
|
93
|
+
};
|
|
94
|
+
sections.push(current);
|
|
95
|
+
}
|
|
96
|
+
const n = lines.length + 1;
|
|
97
|
+
lines.push({
|
|
98
|
+
n,
|
|
99
|
+
block,
|
|
100
|
+
section: sections.length - 1
|
|
101
|
+
});
|
|
102
|
+
current.lines.push(n);
|
|
103
|
+
}
|
|
104
|
+
const named = new Set();
|
|
105
|
+
sections.forEach((section, index)=>{
|
|
106
|
+
const heading = section.lines.map((n)=>lines[n - 1].block).find((block)=>block.kind === 'heading');
|
|
107
|
+
let name = siteImportLabel(heading && heading.kind === 'heading' ? heading.text : index === 0 ? title : '') || (index === 0 ? siteImportLabel(title) : '');
|
|
108
|
+
if (!name) name = `Section ${index + 1}`;
|
|
109
|
+
// Two sections of one name are told apart, so a link to either finds it.
|
|
110
|
+
let unique = name;
|
|
111
|
+
for(let attempt = 2; named.has(unique.toLowerCase()); attempt += 1){
|
|
112
|
+
unique = `${name.slice(0, AI_SITE_IMPORT_LABEL_MAX_CHARS - 4)} (${attempt})`;
|
|
113
|
+
}
|
|
114
|
+
named.add(unique.toLowerCase());
|
|
115
|
+
section.name = unique;
|
|
116
|
+
});
|
|
117
|
+
if (!sections.length) sections.push({
|
|
118
|
+
name: siteImportLabel(title) || 'Introduction',
|
|
119
|
+
lines: []
|
|
120
|
+
});
|
|
121
|
+
return {
|
|
122
|
+
lines,
|
|
123
|
+
sections
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** The words a line shows: an image's are its description. */ export function aiSiteImportLineText(line) {
|
|
127
|
+
return line.block.kind === 'image' ? clean(line.block.alt) : clean(line.block.text);
|
|
128
|
+
}
|
|
129
|
+
const wordsIn = (text)=>{
|
|
130
|
+
var _text_match;
|
|
131
|
+
return ((_text_match = text.match(RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]+", "gu"))) != null ? _text_match : []).length;
|
|
132
|
+
};
|
|
133
|
+
/** The input a page job carries, read defensively; `null` on every other job. */ export function aiSiteImportDocumentOf(inputs) {
|
|
134
|
+
const raw = inputs == null ? void 0 : inputs[AI_LAYOUT_IMPORTED_SECTIONS_INPUT];
|
|
135
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
136
|
+
const value = raw;
|
|
137
|
+
const build = value['build'] === 'copied' || value['build'] === 'arranged' ? value['build'] : null;
|
|
138
|
+
if (!build || !Array.isArray(value['blocks'])) return null;
|
|
139
|
+
const blocks = value['blocks'].flatMap((entry)=>{
|
|
140
|
+
if (!entry || typeof entry !== 'object') return [];
|
|
141
|
+
const block = entry;
|
|
142
|
+
const text = typeof block['text'] === 'string' ? block['text'] : '';
|
|
143
|
+
const region = 'main';
|
|
144
|
+
switch(block['kind']){
|
|
145
|
+
case 'heading':
|
|
146
|
+
{
|
|
147
|
+
const level = Number(block['level']);
|
|
148
|
+
return [
|
|
149
|
+
{
|
|
150
|
+
kind: 'heading',
|
|
151
|
+
level: Number.isInteger(level) && level >= 1 && level <= 6 ? level : 2,
|
|
152
|
+
text,
|
|
153
|
+
region
|
|
154
|
+
}
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
|
+
case 'paragraph':
|
|
158
|
+
case 'list-item':
|
|
159
|
+
case 'quote':
|
|
160
|
+
return [
|
|
161
|
+
{
|
|
162
|
+
kind: block['kind'],
|
|
163
|
+
text,
|
|
164
|
+
region
|
|
165
|
+
}
|
|
166
|
+
];
|
|
167
|
+
case 'image':
|
|
168
|
+
return typeof block['url'] === 'string' ? [
|
|
169
|
+
{
|
|
170
|
+
kind: 'image',
|
|
171
|
+
url: block['url'],
|
|
172
|
+
alt: typeof block['alt'] === 'string' ? block['alt'] : '',
|
|
173
|
+
region
|
|
174
|
+
}
|
|
175
|
+
] : [];
|
|
176
|
+
case 'link':
|
|
177
|
+
return typeof block['href'] === 'string' ? [
|
|
178
|
+
_extends({
|
|
179
|
+
kind: 'link',
|
|
180
|
+
text,
|
|
181
|
+
href: block['href'],
|
|
182
|
+
region
|
|
183
|
+
}, block['inline'] === true ? {
|
|
184
|
+
inline: true
|
|
185
|
+
} : {})
|
|
186
|
+
] : [];
|
|
187
|
+
default:
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
const strings = (list)=>Array.isArray(list) ? list.filter((entry)=>typeof entry === 'string') : [];
|
|
192
|
+
return {
|
|
193
|
+
build,
|
|
194
|
+
title: typeof value['title'] === 'string' ? value['title'] : '',
|
|
195
|
+
url: typeof value['url'] === 'string' ? value['url'].slice(0, 2048) : '',
|
|
196
|
+
blocks,
|
|
197
|
+
photos: (Array.isArray(value['photos']) ? value['photos'] : []).flatMap((entry)=>{
|
|
198
|
+
const photo = entry;
|
|
199
|
+
return photo && typeof photo['mediaId'] === 'string' && typeof photo['src'] === 'string' ? [
|
|
200
|
+
_extends({
|
|
201
|
+
mediaId: photo['mediaId'],
|
|
202
|
+
src: photo['src']
|
|
203
|
+
}, typeof photo['alt'] === 'string' ? {
|
|
204
|
+
alt: photo['alt']
|
|
205
|
+
} : {}, typeof photo['from'] === 'string' ? {
|
|
206
|
+
from: photo['from']
|
|
207
|
+
} : {})
|
|
208
|
+
] : [];
|
|
209
|
+
}),
|
|
210
|
+
links: (Array.isArray(value['links']) ? value['links'] : []).flatMap((entry)=>{
|
|
211
|
+
const link = entry;
|
|
212
|
+
return link && typeof link['path'] === 'string' && typeof link['id'] === 'string' ? [
|
|
213
|
+
{
|
|
214
|
+
path: link['path'],
|
|
215
|
+
id: link['id']
|
|
216
|
+
}
|
|
217
|
+
] : [];
|
|
218
|
+
}),
|
|
219
|
+
origins: strings(value['origins'])
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/*------------------------------------------
|
|
223
|
+
* Drawing the lines
|
|
224
|
+
*-----------------------------------------*/ /** A paragraph cut between sentences into parts a text element holds, every word kept in order. */ export function aiSiteImportTextParts(text, max = AI_SITE_IMPORT_TEXT_MAX_CHARS) {
|
|
225
|
+
var _words_match;
|
|
226
|
+
const words = clean(text);
|
|
227
|
+
if (words.length <= max) return words ? [
|
|
228
|
+
words
|
|
229
|
+
] : [];
|
|
230
|
+
const sentences = (_words_match = words.match(/[^.!?…]+(?:[.!?…]+["'”’)\]]*\s*|$)/g)) != null ? _words_match : [
|
|
231
|
+
words
|
|
232
|
+
];
|
|
233
|
+
const parts = [];
|
|
234
|
+
let part = '';
|
|
235
|
+
const push = ()=>{
|
|
236
|
+
if (part.trim()) parts.push(part.trim());
|
|
237
|
+
part = '';
|
|
238
|
+
};
|
|
239
|
+
for (const sentence of sentences){
|
|
240
|
+
if ((part + sentence).trim().length <= max) {
|
|
241
|
+
part += sentence;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
push();
|
|
245
|
+
// One sentence longer than an element holds is cut between words.
|
|
246
|
+
let rest = sentence.trim();
|
|
247
|
+
while(rest.length > max){
|
|
248
|
+
const at = rest.lastIndexOf(' ', max);
|
|
249
|
+
const cut = at > 0 ? at : max;
|
|
250
|
+
parts.push(rest.slice(0, cut).trim());
|
|
251
|
+
rest = rest.slice(cut).trim();
|
|
252
|
+
}
|
|
253
|
+
part = rest ? `${rest} ` : '';
|
|
254
|
+
}
|
|
255
|
+
push();
|
|
256
|
+
return parts;
|
|
257
|
+
}
|
|
258
|
+
/** Whether the page has room for one more line of this many characters. */ function room(scope, chars) {
|
|
259
|
+
if (scope.cut) return false;
|
|
260
|
+
if (Object.keys(scope.tree.nodes).length >= AI_SITE_IMPORT_DOC_MAX_NODES || scope.chars + chars > AI_SITE_IMPORT_DOC_MAX_CHARS) {
|
|
261
|
+
scope.cut = true;
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
function took(scope, line) {
|
|
267
|
+
scope.placed.push(line.n);
|
|
268
|
+
const text = aiSiteImportLineText(line);
|
|
269
|
+
scope.chars += text.length;
|
|
270
|
+
if (line.block.kind !== 'image') scope.words += wordsIn(text);
|
|
271
|
+
}
|
|
272
|
+
/** A heading at its place in the outline: the page's one h1 first, then the section's h2, then h3 under it. */ function headingNode(scope, text, level, centered) {
|
|
273
|
+
// The outline never skips a level: an h3 straight under the h1 is drawn an h2.
|
|
274
|
+
const tag = !scope.titled ? 1 : Math.max(2, Math.min(3, level, scope.lastLevel + 1));
|
|
275
|
+
scope.titled = true;
|
|
276
|
+
scope.lastLevel = tag;
|
|
277
|
+
const variant = text.length > AI_SITE_IMPORT_HEADLINE_MAX_CHARS ? 'subtitle1' : tag === 1 ? 'h1' : tag === 2 ? 'h2' : 'h4';
|
|
278
|
+
return scope.tree.add('muiTypography', _extends({
|
|
279
|
+
children: text,
|
|
280
|
+
variant,
|
|
281
|
+
component: `h${tag}`
|
|
282
|
+
}, centered ? {
|
|
283
|
+
align: 'center'
|
|
284
|
+
} : {}), null, null, 'heading');
|
|
285
|
+
}
|
|
286
|
+
const VARIANTS = {
|
|
287
|
+
eyebrow: 'overline',
|
|
288
|
+
lede: 'lede',
|
|
289
|
+
text: 'body1',
|
|
290
|
+
note: 'body2'
|
|
291
|
+
};
|
|
292
|
+
/** Words in a style, split where a text element would cut them. */ function textNodes(scope, text, style, centered) {
|
|
293
|
+
return aiSiteImportTextParts(text).map((part)=>scope.tree.add('muiTypography', _extends({
|
|
294
|
+
children: part,
|
|
295
|
+
variant: VARIANTS[style],
|
|
296
|
+
component: 'p'
|
|
297
|
+
}, centered ? {
|
|
298
|
+
align: 'center'
|
|
299
|
+
} : {}), style === 'note' ? {
|
|
300
|
+
color: 'text.secondary'
|
|
301
|
+
} : null, null, style));
|
|
302
|
+
}
|
|
303
|
+
/** Where a link goes on the new site, or `null` where it goes nowhere a page of it may send a visitor. */ function linkProps(scope, href) {
|
|
304
|
+
if (/^mailto:[^\s@]+@[^\s@]+$/i.test(href) || /^tel:\+?[\d\s().-]{3,}$/i.test(href)) return {
|
|
305
|
+
href
|
|
306
|
+
};
|
|
307
|
+
let url;
|
|
308
|
+
try {
|
|
309
|
+
url = new URL(href);
|
|
310
|
+
} catch (unused) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;
|
|
314
|
+
if (scope.doc.origins.includes(url.origin)) {
|
|
315
|
+
// The old site's own page: the page it became, where that page may be linked.
|
|
316
|
+
const path = url.pathname.replace(/\/+$/, '') || '/';
|
|
317
|
+
const id = scope.pathTo.get(path);
|
|
318
|
+
return id && scope.pageIds.has(id) ? {
|
|
319
|
+
screenId: id
|
|
320
|
+
} : null;
|
|
321
|
+
}
|
|
322
|
+
return url.protocol === 'https:' ? {
|
|
323
|
+
href: url.toString(),
|
|
324
|
+
target: '_blank'
|
|
325
|
+
} : null;
|
|
326
|
+
}
|
|
327
|
+
/** A link line: a button that goes where the source's did, or its words as a line where it cannot. */ function linkNodes(scope, line, style, centered) {
|
|
328
|
+
const block = line.block;
|
|
329
|
+
if (block.kind !== 'link') return [];
|
|
330
|
+
const label = clean(block.text);
|
|
331
|
+
const goes = label.length <= AI_SITE_IMPORT_LABEL_CHARS ? linkProps(scope, block.href) : null;
|
|
332
|
+
if (!goes) return textNodes(scope, label, 'text', centered);
|
|
333
|
+
const look = style === 'primary' ? {
|
|
334
|
+
variant: 'contained',
|
|
335
|
+
color: 'primary'
|
|
336
|
+
} : style === 'secondary' ? {
|
|
337
|
+
variant: 'outlined',
|
|
338
|
+
color: 'primary'
|
|
339
|
+
} : {
|
|
340
|
+
variant: 'text',
|
|
341
|
+
color: 'primary'
|
|
342
|
+
};
|
|
343
|
+
return [
|
|
344
|
+
scope.tree.add('muiButton', _extends({
|
|
345
|
+
children: label
|
|
346
|
+
}, look, {
|
|
347
|
+
size: 'medium'
|
|
348
|
+
}, goes), {
|
|
349
|
+
alignSelf: centered ? 'center' : 'flex-start'
|
|
350
|
+
}, null, 'button')
|
|
351
|
+
];
|
|
352
|
+
}
|
|
353
|
+
/** A picture line: the photo the library holds for it, or nothing where it could not be brought in. */ function imageNodes(scope, line) {
|
|
354
|
+
const block = line.block;
|
|
355
|
+
if (block.kind !== 'image') return [];
|
|
356
|
+
const photo = scope.photos.get(block.url);
|
|
357
|
+
if (!photo) return [];
|
|
358
|
+
const alt = clean(block.alt || photo.alt || '').slice(0, 200);
|
|
359
|
+
scope.pictures += 1;
|
|
360
|
+
return [
|
|
361
|
+
scope.tree.add('image', _extends({
|
|
362
|
+
src: photo.src
|
|
363
|
+
}, alt ? {
|
|
364
|
+
alt
|
|
365
|
+
} : {
|
|
366
|
+
decorative: true
|
|
367
|
+
}, {
|
|
368
|
+
objectFit: 'cover'
|
|
369
|
+
}, scope.pictures > 1 ? {
|
|
370
|
+
loading: 'lazy'
|
|
371
|
+
} : {}), null, null, 'image')
|
|
372
|
+
];
|
|
373
|
+
}
|
|
374
|
+
/** One line in a style a block asked for; a picture is a picture and a link a link, wherever they are placed. */ function lineNodes(scope, line, style, centered, button = 'quiet') {
|
|
375
|
+
if (!room(scope, aiSiteImportLineText(line).length)) return [];
|
|
376
|
+
const block = line.block;
|
|
377
|
+
let ids;
|
|
378
|
+
if (block.kind === 'image') ids = imageNodes(scope, line);
|
|
379
|
+
else if (block.kind === 'link') ids = linkNodes(scope, line, button, centered);
|
|
380
|
+
else if (style === 'heading' || block.kind === 'heading' && style === 'text') ids = [
|
|
381
|
+
headingNode(scope, clean(block.text), block.kind === 'heading' ? block.level : 2, centered)
|
|
382
|
+
];
|
|
383
|
+
else if (block.kind === 'quote' && style === 'text') {
|
|
384
|
+
ids = [
|
|
385
|
+
scope.tree.add('muiBox', {
|
|
386
|
+
component: 'blockquote'
|
|
387
|
+
}, null, textNodes(scope, block.text, 'text', centered), 'quote')
|
|
388
|
+
];
|
|
389
|
+
} else ids = textNodes(scope, block.text, style, centered);
|
|
390
|
+
// A picture the library could not bring in is not on the page.
|
|
391
|
+
if (ids.length) took(scope, line);
|
|
392
|
+
return ids;
|
|
393
|
+
}
|
|
394
|
+
/** A run of lines as a list, one item each. */ function listNode(scope, lines) {
|
|
395
|
+
const rows = [];
|
|
396
|
+
const rest = [];
|
|
397
|
+
for (const line of lines){
|
|
398
|
+
if (line.block.kind === 'image' || line.block.kind === 'link') {
|
|
399
|
+
rest.push(...lineNodes(scope, line, 'text', false));
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const text = aiSiteImportLineText(line);
|
|
403
|
+
if (!room(scope, text.length)) break;
|
|
404
|
+
for (const part of aiSiteImportTextParts(text)){
|
|
405
|
+
rows.push(scope.tree.add('muiListItem', {
|
|
406
|
+
disableGutters: true
|
|
407
|
+
}, null, [
|
|
408
|
+
scope.tree.add('muiListItemText', {
|
|
409
|
+
primary: part
|
|
410
|
+
}, null, null, 'line')
|
|
411
|
+
], 'row'));
|
|
412
|
+
}
|
|
413
|
+
took(scope, line);
|
|
414
|
+
}
|
|
415
|
+
return [
|
|
416
|
+
...rows.length ? [
|
|
417
|
+
scope.tree.add('muiList', {
|
|
418
|
+
disablePadding: true
|
|
419
|
+
}, null, rows, 'list')
|
|
420
|
+
] : [],
|
|
421
|
+
...rest
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
/** A group's items, each a title line over its text lines, laid out side by side. */ function groupNode(scope, kind, items) {
|
|
425
|
+
const pairs = [];
|
|
426
|
+
const rest = [];
|
|
427
|
+
for (const item of items){
|
|
428
|
+
const words = item.filter((line)=>line.block.kind !== 'image' && line.block.kind !== 'link');
|
|
429
|
+
for (const line of item)if (line.block.kind === 'image' || line.block.kind === 'link') rest.push(...lineNodes(scope, line, 'text', false));
|
|
430
|
+
if (!words.length) continue;
|
|
431
|
+
const [title, ...body] = words;
|
|
432
|
+
const text = body.map(aiSiteImportLineText).join(' ');
|
|
433
|
+
if (!room(scope, aiSiteImportLineText(title).length + text.length)) break;
|
|
434
|
+
const primary = aiSiteImportLineText(title);
|
|
435
|
+
if (primary.length > AI_SITE_IMPORT_TEXT_MAX_CHARS || text.length > AI_SITE_IMPORT_TEXT_MAX_CHARS) {
|
|
436
|
+
// An item too long for its element is its lines, one under another.
|
|
437
|
+
for (const line of words)rest.push(...lineNodes(scope, line, 'text', false));
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
pairs.push(scope.tree.add('muiListItemText', _extends({
|
|
441
|
+
primary
|
|
442
|
+
}, text ? {
|
|
443
|
+
secondary: text
|
|
444
|
+
} : {}), null, null, 'pair'));
|
|
445
|
+
for (const line of words)took(scope, line);
|
|
446
|
+
}
|
|
447
|
+
if (!pairs.length) return rest;
|
|
448
|
+
const perRow = kind === 'faq' || kind === 'steps' || pairs.length === 1 ? 1 : Math.min(3, pairs.length);
|
|
449
|
+
if (perRow === 1) return [
|
|
450
|
+
scope.tree.add('muiStack', {
|
|
451
|
+
spacing: '3'
|
|
452
|
+
}, null, pairs, kind),
|
|
453
|
+
...rest
|
|
454
|
+
];
|
|
455
|
+
const size = perRow === 2 ? 'xs:12 sm:6' : 'xs:12 md:4';
|
|
456
|
+
const cells = pairs.map((id)=>scope.tree.add('muiGrid', {
|
|
457
|
+
size
|
|
458
|
+
}, null, [
|
|
459
|
+
id
|
|
460
|
+
], 'cell'));
|
|
461
|
+
return [
|
|
462
|
+
scope.tree.add('muiGrid', {
|
|
463
|
+
container: true,
|
|
464
|
+
spacing: '3'
|
|
465
|
+
}, null, cells, kind),
|
|
466
|
+
...rest
|
|
467
|
+
];
|
|
468
|
+
}
|
|
469
|
+
/** A section root: its band, its container and its content, under the id its plan stores it by. */ function sectionNode(scope, index, name, band, parts, id, wide) {
|
|
470
|
+
const tree = scope.tree;
|
|
471
|
+
const content = parts.length === 1 ? parts[0] : tree.add('muiStack', {
|
|
472
|
+
spacing: '3',
|
|
473
|
+
useFlexGap: true
|
|
474
|
+
}, null, parts, 'content');
|
|
475
|
+
const container = tree.add('muiContainer', {
|
|
476
|
+
maxWidth: wide ? 'lg' : 'md'
|
|
477
|
+
}, {
|
|
478
|
+
py: _extends({}, SECTION_PADDING)
|
|
479
|
+
}, [
|
|
480
|
+
content
|
|
481
|
+
], 'container');
|
|
482
|
+
return tree.add('section', _extends({
|
|
483
|
+
element: 'section',
|
|
484
|
+
ariaLabel: name || `Section ${index + 1}`
|
|
485
|
+
}, band === 'dark' ? {
|
|
486
|
+
colorScheme: 'dark'
|
|
487
|
+
} : {}), bandSx(band), [
|
|
488
|
+
container
|
|
489
|
+
], 'section', id);
|
|
490
|
+
}
|
|
491
|
+
/** The lines of a section, in source order, as the source draws them: lists as lists, the rest one under another. */ function copiedParts(scope, lines) {
|
|
492
|
+
const parts = [];
|
|
493
|
+
for(let at = 0; at < lines.length; at += 1){
|
|
494
|
+
const line = lines[at];
|
|
495
|
+
if (line.block.kind === 'list-item') {
|
|
496
|
+
const run = [];
|
|
497
|
+
while(at < lines.length && lines[at].block.kind === 'list-item')run.push(lines[at++]);
|
|
498
|
+
at -= 1;
|
|
499
|
+
parts.push(...listNode(scope, run));
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
parts.push(...lineNodes(scope, line, 'text', false));
|
|
503
|
+
}
|
|
504
|
+
return parts;
|
|
505
|
+
}
|
|
506
|
+
/** One arranged block's lines, still unplaced and of its own section; `null` where it named a line already placed. */ function ownLines(lineOf, numbers, section, used) {
|
|
507
|
+
const lines = [];
|
|
508
|
+
for (const n of numbers){
|
|
509
|
+
const line = lineOf(n);
|
|
510
|
+
if (!line || line.section !== section) continue;
|
|
511
|
+
if (used.has(n)) return null;
|
|
512
|
+
lines.push(line);
|
|
513
|
+
}
|
|
514
|
+
return lines;
|
|
515
|
+
}
|
|
516
|
+
/** An arranged block drawn: its lines in the kind it asked for. */ function arrangedBlock(scope, block, lines, items, centered) {
|
|
517
|
+
switch(block.kind){
|
|
518
|
+
case 'list':
|
|
519
|
+
return listNode(scope, lines);
|
|
520
|
+
case 'cards':
|
|
521
|
+
case 'steps':
|
|
522
|
+
case 'stats':
|
|
523
|
+
case 'faq':
|
|
524
|
+
return groupNode(scope, block.kind, items.length ? items : lines.map((line)=>[
|
|
525
|
+
line
|
|
526
|
+
]));
|
|
527
|
+
case 'button':
|
|
528
|
+
{
|
|
529
|
+
const style = block.style === 'primary' || block.style === 'secondary' ? block.style : 'quiet';
|
|
530
|
+
return lines.flatMap((line)=>lineNodes(scope, line, 'text', centered, style));
|
|
531
|
+
}
|
|
532
|
+
case 'image':
|
|
533
|
+
return lines.flatMap((line)=>lineNodes(scope, line, 'text', centered));
|
|
534
|
+
case 'heading':
|
|
535
|
+
case 'eyebrow':
|
|
536
|
+
case 'lede':
|
|
537
|
+
case 'note':
|
|
538
|
+
{
|
|
539
|
+
const style = block.kind;
|
|
540
|
+
return lines.flatMap((line, position)=>// A heading block's first line is the heading; any more are its words.
|
|
541
|
+
lineNodes(scope, line, style === 'heading' && position > 0 ? 'text' : style, centered));
|
|
542
|
+
}
|
|
543
|
+
default:
|
|
544
|
+
return lines.flatMap((line)=>lineNodes(scope, line, line.block.kind === 'heading' ? 'heading' : 'text', centered));
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
/** One section as the arrangement lays it out, every line of it that the arrangement left out added at its end. */ function arrangedParts(scope, arranged, index, lines, lineOf, used) {
|
|
548
|
+
const centered = arranged.align === 'center';
|
|
549
|
+
const cols = arranged.cols && arranged.cols.length >= 2 ? arranged.cols : null;
|
|
550
|
+
const head = [];
|
|
551
|
+
const tail = [];
|
|
552
|
+
const columns = cols ? cols.map(()=>[]) : [];
|
|
553
|
+
let placedInRow = false;
|
|
554
|
+
for (const block of arranged.blocks){
|
|
555
|
+
var _block_items, _block_items1;
|
|
556
|
+
const groups = AI_LAYOUT_ARRANGE_ITEM_KINDS.has(block.kind);
|
|
557
|
+
const named = groups && ((_block_items = block.items) == null ? void 0 : _block_items.length) ? block.items.flat() : block.from;
|
|
558
|
+
const taken = ownLines(lineOf, named, index, used);
|
|
559
|
+
// A block that names a line twice is dropped; its other lines are added at the end.
|
|
560
|
+
if (!(taken == null ? void 0 : taken.length)) continue;
|
|
561
|
+
for (const line of taken)used.add(line.n);
|
|
562
|
+
const items = groups && ((_block_items1 = block.items) == null ? void 0 : _block_items1.length) ? block.items.map((item)=>taken.filter((line)=>item.includes(line.n))).filter((item)=>item.length) : [];
|
|
563
|
+
const ids = arrangedBlock(scope, block, taken, items, centered && block.col === undefined);
|
|
564
|
+
if (cols && block.col !== undefined) {
|
|
565
|
+
columns[Math.min(block.col, cols.length - 1)].push(...ids);
|
|
566
|
+
placedInRow = true;
|
|
567
|
+
} else (placedInRow ? tail : head).push(...ids);
|
|
568
|
+
}
|
|
569
|
+
// Every line the arrangement did not place, in source order, at the section's end.
|
|
570
|
+
const left = lines.filter((line)=>!used.has(line.n));
|
|
571
|
+
for (const line of left)used.add(line.n);
|
|
572
|
+
tail.push(...copiedParts(scope, left));
|
|
573
|
+
const filled = columns.map((ids, position)=>{
|
|
574
|
+
var _ref;
|
|
575
|
+
return {
|
|
576
|
+
ids,
|
|
577
|
+
weight: (_ref = cols == null ? void 0 : cols[position]) != null ? _ref : 1
|
|
578
|
+
};
|
|
579
|
+
}).filter((entry)=>entry.ids.length);
|
|
580
|
+
const parts = [
|
|
581
|
+
...head
|
|
582
|
+
];
|
|
583
|
+
if (filled.length >= 2) {
|
|
584
|
+
const spans = aiLayoutSpans(filled.map((entry)=>entry.weight));
|
|
585
|
+
const cells = filled.map((entry, position)=>scope.tree.add('muiGrid', {
|
|
586
|
+
size: `xs:12 md:${spans[position]}`
|
|
587
|
+
}, null, [
|
|
588
|
+
entry.ids.length === 1 ? entry.ids[0] : scope.tree.add('muiStack', {
|
|
589
|
+
spacing: '3'
|
|
590
|
+
}, null, entry.ids, 'column')
|
|
591
|
+
], 'cell'));
|
|
592
|
+
parts.push(scope.tree.add('muiGrid', {
|
|
593
|
+
container: true,
|
|
594
|
+
spacing: '6'
|
|
595
|
+
}, null, cells, 'row'));
|
|
596
|
+
} else if (filled.length === 1) parts.push(...filled[0].ids);
|
|
597
|
+
parts.push(...tail);
|
|
598
|
+
return {
|
|
599
|
+
parts,
|
|
600
|
+
wide: filled.length >= 2
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* The page brought in, compiled into its tree (AGL-4084): copied as the
|
|
605
|
+
* source has it, or as the arrangement lays it out, with every line on it
|
|
606
|
+
* exactly once in either case and never a word that is not the source's.
|
|
607
|
+
*/ export function aiCompileImportedDocument(input) {
|
|
608
|
+
const { doc } = input;
|
|
609
|
+
const { lines, sections } = aiSiteImportDocLines(doc.blocks, doc.title);
|
|
610
|
+
const tree = new AiLayoutTreeBuilder('li');
|
|
611
|
+
const pageIds = new Set(input.pages.map((page)=>page.id));
|
|
612
|
+
const scope = {
|
|
613
|
+
tree,
|
|
614
|
+
doc,
|
|
615
|
+
pageIds,
|
|
616
|
+
pathTo: new Map(doc.links.map((link)=>[
|
|
617
|
+
link.path.replace(/\/+$/, '') || '/',
|
|
618
|
+
link.id
|
|
619
|
+
])),
|
|
620
|
+
photos: new Map(doc.photos.flatMap((photo)=>photo.from ? [
|
|
621
|
+
[
|
|
622
|
+
photo.from,
|
|
623
|
+
photo
|
|
624
|
+
]
|
|
625
|
+
] : [])),
|
|
626
|
+
titled: false,
|
|
627
|
+
lastLevel: 1,
|
|
628
|
+
pictures: 0,
|
|
629
|
+
placed: [],
|
|
630
|
+
words: 0,
|
|
631
|
+
chars: 0,
|
|
632
|
+
cut: false
|
|
633
|
+
};
|
|
634
|
+
const lineOf = (n)=>lines[n - 1];
|
|
635
|
+
const used = new Set();
|
|
636
|
+
const arranged = doc.build === 'arranged' ? input.arrangement : null;
|
|
637
|
+
// An arranged opening with no heading block takes its first heading line as one, so the page keeps its h1.
|
|
638
|
+
const opening = arranged == null ? void 0 : arranged.sections[0];
|
|
639
|
+
if (opening && !opening.blocks.some((block)=>block.kind === 'heading')) {
|
|
640
|
+
const first = opening.blocks.find((block)=>block.from.some((n)=>{
|
|
641
|
+
var _lineOf;
|
|
642
|
+
return ((_lineOf = lineOf(n)) == null ? void 0 : _lineOf.block.kind) === 'heading';
|
|
643
|
+
}));
|
|
644
|
+
if (first && !AI_LAYOUT_ARRANGE_ITEM_KINDS.has(first.kind) && first.kind !== 'list') first.kind = 'heading';
|
|
645
|
+
}
|
|
646
|
+
const roots = sections.map((section, index)=>{
|
|
647
|
+
var _ref, _ref1, _input_sectionIds_index;
|
|
648
|
+
var _arranged_sections_;
|
|
649
|
+
const own = section.lines.map(lineOf);
|
|
650
|
+
// The page's h1: its title, where its opening shows no heading of its own.
|
|
651
|
+
const titleParts = [];
|
|
652
|
+
if (index === 0 && !own.some((line)=>line.block.kind === 'heading') && !(arranged == null ? void 0 : (_arranged_sections_ = arranged.sections[0]) == null ? void 0 : _arranged_sections_.blocks.some((block)=>block.kind === 'heading'))) {
|
|
653
|
+
titleParts.push(headingNode(scope, clean(doc.title) || section.name, 1, false));
|
|
654
|
+
}
|
|
655
|
+
const plan = (_ref = arranged == null ? void 0 : arranged.sections[index]) != null ? _ref : null;
|
|
656
|
+
const drawn = plan ? arrangedParts(scope, plan, index, own, lineOf, used) : {
|
|
657
|
+
parts: copiedParts(scope, own.filter((line)=>!used.has(line.n))),
|
|
658
|
+
wide: false
|
|
659
|
+
};
|
|
660
|
+
for (const line of own)used.add(line.n);
|
|
661
|
+
const band = (_ref1 = plan == null ? void 0 : plan.band) != null ? _ref1 : index % 2 === 1 ? 'soft' : 'plain';
|
|
662
|
+
const parts = [
|
|
663
|
+
...titleParts,
|
|
664
|
+
...drawn.parts
|
|
665
|
+
];
|
|
666
|
+
if (!parts.length) {
|
|
667
|
+
// A section whose lines could not come through (its pictures, the page's weight) keeps its place by its name.
|
|
668
|
+
parts.push(headingNode(scope, section.name, 2, false));
|
|
669
|
+
}
|
|
670
|
+
return sectionNode(scope, index, section.name, band, parts, (_input_sectionIds_index = input.sectionIds[index]) != null ? _input_sectionIds_index : `section-${index + 1}`, drawn.wide);
|
|
671
|
+
});
|
|
672
|
+
const rootId = tree.add('div', null, null, roots, 'page', CANVAS_ROOT_ELEMENT_ID);
|
|
673
|
+
for (const root of roots)tree.prune(root);
|
|
674
|
+
const sourceWords = lines.reduce((total, line)=>total + (line.block.kind === 'image' ? 0 : wordsIn(aiSiteImportLineText(line))), 0);
|
|
675
|
+
return {
|
|
676
|
+
tree: {
|
|
677
|
+
rootId,
|
|
678
|
+
nodes: tree.nodes
|
|
679
|
+
},
|
|
680
|
+
placed: scope.placed,
|
|
681
|
+
lines: lines.length,
|
|
682
|
+
words: scope.words,
|
|
683
|
+
sourceWords,
|
|
684
|
+
cut: scope.cut
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
/*------------------------------------------
|
|
688
|
+
* What the arrangement is shown
|
|
689
|
+
*-----------------------------------------*/ /** The most characters of a page's numbered lines an arrangement prompt shows. */ export const AI_SITE_IMPORT_ARRANGE_MAX_CHARS = 60000;
|
|
690
|
+
const LINE_KIND = {
|
|
691
|
+
heading: 'heading',
|
|
692
|
+
paragraph: 'text',
|
|
693
|
+
'list-item': 'list item',
|
|
694
|
+
quote: 'quote',
|
|
695
|
+
link: 'link',
|
|
696
|
+
image: 'picture'
|
|
697
|
+
};
|
|
698
|
+
/** The page's lines as the arrangement reads them: each section, its numbered lines and their kinds. */ export function aiSiteImportArrangeText(doc) {
|
|
699
|
+
const { lines, sections } = aiSiteImportDocLines(doc.blocks, doc.title);
|
|
700
|
+
return sections.map((section, index)=>[
|
|
701
|
+
`Section ${index + 1}: ${section.name}`,
|
|
702
|
+
...section.lines.map((n)=>{
|
|
703
|
+
const line = lines[n - 1];
|
|
704
|
+
const kind = line.block.kind === 'heading' ? `heading ${line.block.level}` : LINE_KIND[line.block.kind];
|
|
705
|
+
return `[${n}] (${kind}) ${aiSiteImportLineText(line) || '(no description)'}`;
|
|
706
|
+
})
|
|
707
|
+
].join('\n')).join('\n\n');
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
//# sourceMappingURL=ai-site-import-document.js.map
|