[{"data":1,"prerenderedAt":2975},["ShallowReactive",2],{"navigation_docs":3,"-guides-block-types":412,"-guides-block-types-surround":2970},[4,38,84,326,386],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":37},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,24,28,32],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick start: Nuxt","\u002Fgetting-started\u002Fquick-start-nuxt","1.getting-started\u002F3.quick-start-nuxt",{"title":25,"path":26,"stem":27,"icon":6},"Quick start: plain Vue","\u002Fgetting-started\u002Fquick-start-vue","1.getting-started\u002F4.quick-start-vue",{"title":29,"path":30,"stem":31,"icon":6},"Quick start: React","\u002Fgetting-started\u002Fquick-start-react","1.getting-started\u002F5.quick-start-react",{"title":33,"path":34,"stem":35,"icon":36},"Glossary","\u002Fgetting-started\u002Fglossary","1.getting-started\u002F6.glossary","i-lucide-book-a",false,{"title":39,"icon":40,"path":41,"stem":42,"children":43,"page":37},"Tutorial","i-lucide-graduation-cap","\u002Ftutorial","2.tutorial",[44,49,54,59,64,69,74,79],{"title":45,"path":46,"stem":47,"icon":48},"Tutorial: overview","\u002Ftutorial\u002Foverview","2.tutorial\u002F1.overview","i-lucide-map",{"title":50,"path":51,"stem":52,"icon":53},"Chapter 2: A simple editor","\u002Ftutorial\u002Fsimple-editor","2.tutorial\u002F2.simple-editor","i-lucide-pencil",{"title":55,"path":56,"stem":57,"icon":58},"Chapter 3: Compose features","\u002Ftutorial\u002Fcompose-features","2.tutorial\u002F3.compose-features","i-lucide-blocks",{"title":60,"path":61,"stem":62,"icon":63},"Chapter 4: Your own block, path A","\u002Ftutorial\u002Fown-block-path-a","2.tutorial\u002F4.own-block-path-a","i-lucide-square-plus",{"title":65,"path":66,"stem":67,"icon":68},"Chapter 5: Your own feature, path B","\u002Ftutorial\u002Fown-feature-path-b","2.tutorial\u002F5.own-feature-path-b","i-lucide-puzzle",{"title":70,"path":71,"stem":72,"icon":73},"Chapter 6: Backend and collaboration","\u002Ftutorial\u002Fbackend-and-collaboration","2.tutorial\u002F6.backend-and-collaboration","i-lucide-users",{"title":75,"path":76,"stem":77,"icon":78},"Chapter 7: AI","\u002Ftutorial\u002Fai","2.tutorial\u002F7.ai","i-lucide-sparkles",{"title":80,"path":81,"stem":82,"icon":83},"Chapter 8: The React surface","\u002Ftutorial\u002Freact-surface","2.tutorial\u002F8.react-surface","i-lucide-atom",{"title":85,"icon":14,"path":86,"stem":87,"children":88,"page":37},"Guides","\u002Fguides","3.guides",[89,93,98,103,108,112,116,121,126,130,134,139,144,149,154,159,164,169,174,179,184,189,194,199,204,209,213,218,223,228,233,237,242,247,251,256,261,266,271,276,281,286,291,295,302,307,311,316,321],{"title":90,"path":91,"stem":92,"icon":58},"Feature composition and entries","\u002Fguides\u002Fcomposition","3.guides\u002F1.composition",{"title":94,"path":95,"stem":96,"icon":97},"Media, mentions and transcript features","\u002Fguides\u002Fmedia-mentions-transcript","3.guides\u002F10.media-mentions-transcript","i-lucide-image",{"title":99,"path":100,"stem":101,"icon":102},"Authors and comments","\u002Fguides\u002Fauthors-and-comments","3.guides\u002F11.authors-and-comments","i-lucide-message-square-text",{"title":104,"path":105,"stem":106,"icon":107},"Themes (Obsidian)","\u002Fguides\u002Fthemes","3.guides\u002F12.themes","i-lucide-palette",{"title":109,"path":110,"stem":111,"icon":58},"Composites and the settings UI","\u002Fguides\u002Fcomposites","3.guides\u002F13.composites",{"title":113,"path":114,"stem":115,"icon":78},"AI","\u002Fguides\u002Fai","3.guides\u002F14.ai",{"title":117,"path":118,"stem":119,"icon":120},"Document tree","\u002Fguides\u002Fdocument-tree","3.guides\u002F15.document-tree","i-lucide-folder-tree",{"title":122,"path":123,"stem":124,"icon":125},"Markdown and code","\u002Fguides\u002Fmarkdown-and-code","3.guides\u002F16.markdown-and-code","i-lucide-file-code",{"title":127,"path":128,"stem":129,"icon":83},"Advanced editor in React","\u002Fguides\u002Fadvanced-react","3.guides\u002F17.advanced-react",{"title":131,"path":132,"stem":133,"icon":6},"Kitchen sink: learning path","\u002Fguides\u002Fadvanced-nuxt-example","3.guides\u002F18.advanced-nuxt-example",{"title":135,"path":136,"stem":137,"icon":138},"Production","\u002Fguides\u002Fproduction","3.guides\u002F19.production","i-lucide-server",{"title":140,"path":141,"stem":142,"icon":143},"Register the Nuxt module","\u002Fguides\u002Fnuxt-module","3.guides\u002F2.nuxt-module","i-lucide-package",{"title":145,"path":146,"stem":147,"icon":148},"Storage adapters, comment stores, Nitro host","\u002Fguides\u002Fstorage-adapters","3.guides\u002F20.storage-adapters","i-lucide-database",{"title":150,"path":151,"stem":152,"icon":153},"Migrating from #tiptap-editor","\u002Fguides\u002Fmigration","3.guides\u002F21.migration","i-lucide-arrow-right-left",{"title":155,"path":156,"stem":157,"icon":158},"Content tree mechanics","\u002Fguides\u002Fcontent-tree","3.guides\u002F22.content-tree","i-lucide-git-fork",{"title":160,"path":161,"stem":162,"icon":163},"Block capabilities, abilities and actions","\u002Fguides\u002Fblock-capabilities","3.guides\u002F23.block-capabilities","i-lucide-shield-check",{"title":165,"path":166,"stem":167,"icon":168},"Block types in code and JSON","\u002Fguides\u002Fblock-types","3.guides\u002F24.block-types","i-lucide-shapes",{"title":170,"path":171,"stem":172,"icon":173},"Derive methods and the Derivation index","\u002Fguides\u002Fderive-methods","3.guides\u002F25.derive-methods","i-lucide-git-branch-plus",{"title":175,"path":176,"stem":177,"icon":178},"Block properties and Property definitions","\u002Fguides\u002Fblock-properties","3.guides\u002F26.block-properties","i-lucide-sliders-horizontal",{"title":180,"path":181,"stem":182,"icon":183},"Image studio","\u002Fguides\u002Fimage-studio","3.guides\u002F27.image-studio","i-lucide-image-plus",{"title":185,"path":186,"stem":187,"icon":188},"Prüfung and Freigabestatus","\u002Fguides\u002Fpruefung","3.guides\u002F28.pruefung","i-lucide-stamp",{"title":190,"path":191,"stem":192,"icon":193},"Workspace: find, read, reference and embed Blocks across Documents","\u002Fguides\u002Fworkspace","3.guides\u002F29.workspace","i-lucide-network",{"title":195,"path":196,"stem":197,"icon":198},"EditorPorts: auth and storage","\u002Fguides\u002Feditor-ports","3.guides\u002F3.editor-ports","i-lucide-plug",{"title":200,"path":201,"stem":202,"icon":203},"Collections: an ordered list of Blocks","\u002Fguides\u002Fcollections","3.guides\u002F30.collections","i-lucide-list-checks",{"title":205,"path":206,"stem":207,"icon":208},"Data views: a query shown as table, list or board","\u002Fguides\u002Fdata-views","3.guides\u002F31.data-views","i-lucide-table-properties",{"title":210,"path":211,"stem":212,"icon":193},"Explore: backlinks, related Blocks and the trail","\u002Fguides\u002Fexplore","3.guides\u002F32.explore",{"title":214,"path":215,"stem":216,"icon":217},"Render: export a Block or a Document to a file","\u002Fguides\u002Frender","3.guides\u002F33.render","i-lucide-file-output",{"title":219,"path":220,"stem":221,"icon":222},"Importers: what a dropped file becomes","\u002Fguides\u002Fimporters","3.guides\u002F34.importers","i-lucide-file-input",{"title":224,"path":225,"stem":226,"icon":227},"Templates: start a Document from a Dokumentvorlage","\u002Fguides\u002Ftemplates","3.guides\u002F35.templates","i-lucide-file-stack",{"title":229,"path":230,"stem":231,"icon":232},"Citations","\u002Fguides\u002Fcitations","3.guides\u002F36.citations","i-lucide-quote",{"title":234,"path":235,"stem":236,"icon":163},"AI proposals and the export check","\u002Fguides\u002Fexport-check","3.guides\u002F37.export-check",{"title":238,"path":239,"stem":240,"icon":241},"Query: filter, sort, group and total Blocks","\u002Fguides\u002Fquery","3.guides\u002F38.query","i-lucide-list-filter",{"title":243,"path":244,"stem":245,"icon":246},"Edges: backlinks and authored connections","\u002Fguides\u002Fedges","3.guides\u002F39.edges","i-lucide-link-2",{"title":248,"path":249,"stem":250,"icon":163},"Server routes and authentication","\u002Fguides\u002Froutes-and-auth","3.guides\u002F4.routes-and-auth",{"title":252,"path":253,"stem":254,"icon":255},"Speech: text to audio, and subtitle files","\u002Fguides\u002Fspeech","3.guides\u002F41.speech","i-lucide-audio-lines",{"title":257,"path":258,"stem":259,"icon":260},"Graph: the Edges around a Block","\u002Fguides\u002Fgraph","3.guides\u002F42.graph","i-lucide-waypoints",{"title":262,"path":263,"stem":264,"icon":265},"PDF viewer: passages, anchors and quotes","\u002Fguides\u002Fpdf-viewer","3.guides\u002F43.pdf-viewer","i-lucide-file-search",{"title":267,"path":268,"stem":269,"icon":270},"Obsidian: import and export a vault","\u002Fguides\u002Fobsidian","3.guides\u002F44.obsidian","i-lucide-folder-input",{"title":272,"path":273,"stem":274,"icon":275},"Typst: render a Document as a PDF with citations","\u002Fguides\u002Ftypst","3.guides\u002F45.typst","i-lucide-file-text",{"title":277,"path":278,"stem":279,"icon":280},"Audio: read aloud, mixdown and ElevenLabs","\u002Fguides\u002Faudio","3.guides\u002F46.audio","i-lucide-audio-waveform",{"title":282,"path":283,"stem":284,"icon":285},"Slides: decks, slide layouts and exports","\u002Fguides\u002Fslides","3.guides\u002F47.slides","i-lucide-presentation",{"title":287,"path":288,"stem":289,"icon":290},"Knowledge graph: sources and concepts beside the Documents","\u002Fguides\u002Fknowledge-graph","3.guides\u002F49.knowledge-graph","i-lucide-share-2",{"title":292,"path":293,"stem":294,"icon":78},"AI configuration and secrets","\u002Fguides\u002Fai-configuration","3.guides\u002F5.ai-configuration",{"title":296,"path":297,"stem":298,"children":299,"icon":301},"Index on Postgres: typos, meaning and SQL pushdown","\u002Fguides\u002Findex-pg","3.guides\u002F50.index-pg",[300],{"title":296,"path":297,"stem":298,"icon":301},"i-lucide-database-zap",{"title":303,"path":304,"stem":305,"icon":306},"Charts: bar, line, pie and scatter over a query","\u002Fguides\u002Fcharts","3.guides\u002F51.charts","i-lucide-chart-column",{"title":308,"path":309,"stem":310,"icon":73},"Collaboration on the client","\u002Fguides\u002Fcollaboration","3.guides\u002F6.collaboration",{"title":312,"path":313,"stem":314,"icon":315},"Block UI (drag handle, hover actions)","\u002Fguides\u002Fblock-ui","3.guides\u002F7.block-ui","i-lucide-grip-vertical",{"title":317,"path":318,"stem":319,"icon":320},"Settings and app lifetime","\u002Fguides\u002Fsettings","3.guides\u002F8.settings","i-lucide-settings",{"title":322,"path":323,"stem":324,"icon":325},"Language","\u002Fguides\u002Flanguage","3.guides\u002F9.language","i-lucide-languages",{"title":327,"icon":14,"path":328,"stem":329,"children":330,"page":37},"Reference","\u002Freference","4.reference",[331,335,339,344,348,352,356,360,364,368,373,378,382],{"title":332,"path":333,"stem":334,"icon":143},"Public exports","\u002Freference\u002Fexports","4.reference\u002F1.exports",{"title":336,"path":337,"stem":338,"icon":173},"Derive method contract","\u002Freference\u002Fderive-methods","4.reference\u002F10.derive-methods",{"title":340,"path":341,"stem":342,"icon":343},"Changelog","\u002Freference\u002Fchangelog","4.reference\u002F11.changelog","i-lucide-history",{"title":345,"path":346,"stem":347,"icon":217},"Renderer port","\u002Freference\u002Frenderer-port","4.reference\u002F12.renderer-port",{"title":349,"path":350,"stem":351,"icon":255},"Speech port","\u002Freference\u002Fspeech-port","4.reference\u002F13.speech-port",{"title":353,"path":354,"stem":355,"icon":58},"Presets and features","\u002Freference\u002Fpresets-and-features","4.reference\u002F2.presets-and-features",{"title":357,"path":358,"stem":359,"icon":68},"Feature contract","\u002Freference\u002Ffeature-contract","4.reference\u002F3.feature-contract",{"title":361,"path":362,"stem":363,"icon":107},"CSS and UI-provider requirements","\u002Freference\u002Fcss-and-ui","4.reference\u002F4.css-and-ui",{"title":365,"path":366,"stem":367,"icon":148},"Vue-free advanced schema","\u002Freference\u002Fadvanced-schema","4.reference\u002F5.advanced-schema",{"title":369,"path":370,"stem":371,"icon":372},"Dependency rules","\u002Freference\u002Fdependency-rules","4.reference\u002F6.dependency-rules","i-lucide-git-branch",{"title":374,"path":375,"stem":376,"icon":377},"Commands","\u002Freference\u002Fcommands","4.reference\u002F7.commands","i-lucide-terminal",{"title":379,"path":380,"stem":381,"icon":163},"Block capability contract","\u002Freference\u002Fblock-capabilities","4.reference\u002F8.block-capabilities",{"title":383,"path":384,"stem":385,"icon":168},"Block type contract","\u002Freference\u002Fblock-types","4.reference\u002F9.block-types",{"title":387,"path":388,"stem":389,"children":390,"icon":393},"AI agents","\u002Fai-agents","5.ai-agents\u002F1.index",[391,394,398,402,407],{"title":392,"path":388,"stem":389,"icon":393},"Overview","i-lucide-bot",{"title":395,"path":396,"stem":397,"icon":198},"Integrate the editor","\u002Fai-agents\u002Fintegrate","5.ai-agents\u002F2.integrate",{"title":399,"path":400,"stem":401,"icon":68},"Add a block or feature","\u002Fai-agents\u002Fextend","5.ai-agents\u002F3.extend",{"title":403,"path":404,"stem":405,"icon":406},"Pitfalls and invariants","\u002Fai-agents\u002Finvariants","5.ai-agents\u002F4.invariants","i-lucide-shield-alert",{"title":408,"path":409,"stem":410,"icon":411},"Verify","\u002Fai-agents\u002Fverify","5.ai-agents\u002F5.verify","i-lucide-check-check",{"id":413,"title":165,"body":414,"description":2963,"extension":2964,"links":2965,"meta":2966,"navigation":2967,"path":166,"seo":2968,"stem":167,"__hash__":2969},"docs\u002F3.guides\u002F24.block-types.md",{"type":415,"value":416,"toc":2955},"minimark",[417,460,466,471,501,1219,1238,1256,1290,1297,1301,1314,2018,2041,2199,2218,2227,2233,2269,2301,2308,2311,2322,2340,2344,2350,2884,2946,2951],[418,419,420,421,425,426,430,431,435,436,439,440,443,444,447,448,451,452,455,456,459],"p",{},"A ",[422,423,424],"strong",{},"Block type"," is what the ",[427,428,429],"code",{},"blockType"," attribute of a ",[432,433,434],"a",{"href":110},"Typed block"," selects. It is data: an ",[427,437,438],{},"id",", its presentation (",[427,441,442],{},"label",", ",[427,445,446],{},"icon",", placeholders, ",[427,449,450],{},"chrome",") and the ",[432,453,454],{"href":161},"Block capabilities"," it lists, each with its config. A capability that the type does not list is absent from its Typed blocks: no Block properties section, no Basket menu, no Block action that ",[427,457,458],{},"requires"," it. No other field on the type switches a behaviour.",[418,461,462,463,465],{},"Because a Block type has no functions, a host can write it in code or keep it in a JSON file. The ",[432,464,383],{"href":384}," lists every field.",[467,468,470],"h2",{"id":469},"block-types-in-code","Block types in code",[418,472,473,476,477,480,481,443,484,443,487,443,490,443,493,496,497,500],{},[427,474,475],{},"compositeFeature({ blockTypes })"," takes the list of Block types of the editor. It replaces the built-in ",[427,478,479],{},"defaultBlockTypes(t)"," (",[427,482,483],{},"section",[427,485,486],{},"task",[427,488,489],{},"note",[427,491,492],{},"folder",[427,494,495],{},"document",", ...; labelled in the language of ",[427,498,499],{},"t","), so spread the built-in list to keep it.",[502,503,509],"pre",{"className":504,"code":505,"filename":506,"language":507,"meta":508,"style":508},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { compositeFeature } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue'\nimport { type BlockType, defaultBlockTypes } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema'\nimport type { PropertiesConfig } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema'\nimport { coreContentFeature, coreUiFeature, createTranslator, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\n\nconst t = createTranslator('de')\n\nconst decisionProperties = {\n  definitions: [\n    { key: 'status', label: 'Status', type: 'select', options: [{ value: 'open', label: 'Offen' }, { value: 'done', label: 'Entschieden' }] },\n    { key: 'owner', label: 'Zuständig', type: 'text' },\n  ],\n} satisfies PropertiesConfig\n\n\u002F\u002F A Block type is data: presentation plus the capabilities it lists, each with its config.\nconst decision: BlockType = {\n  id: 'decision',\n  label: 'Entscheidung',\n  icon: 'i-lucide-gavel',\n  titlePlaceholder: 'Was wird entschieden?',\n  capabilities: [\n    { id: 'container', config: { accepts: ['task', 'note'] } },\n    { id: 'basket' },\n    { id: 'titleHidden' },\n    { id: 'properties', config: decisionProperties },\n  ],\n}\n\n\u002F\u002F `blockTypes` replaces the built-in list, so spread `defaultBlockTypes(t)` to keep the built-in types.\nexport const preset = defineEditor({\n  features: [coreContentFeature(), coreUiFeature(), compositeFeature({ blockTypes: [...defaultBlockTypes(t), decision] })],\n})\n","docs\u002Fsnippets\u002Fblock-types-code.ts","ts","",[427,510,511,544,574,596,632,639,669,674,687,700,820,865,874,887,892,899,916,933,950,967,984,994,1047,1065,1083,1109,1116,1122,1127,1133,1154,1212],{"__ignoreMap":508},[512,513,516,520,524,528,531,534,537,541],"span",{"class":514,"line":515},"line",1,[512,517,519],{"class":518},"s7zQu","import",[512,521,523],{"class":522},"sMK4o"," {",[512,525,527],{"class":526},"sTEyZ"," compositeFeature",[512,529,530],{"class":522}," }",[512,532,533],{"class":518}," from",[512,535,536],{"class":522}," '",[512,538,540],{"class":539},"sfazB","@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue",[512,542,543],{"class":522},"'\n",[512,545,547,549,551,554,557,560,563,565,567,569,572],{"class":514,"line":546},2,[512,548,519],{"class":518},[512,550,523],{"class":522},[512,552,553],{"class":518}," type",[512,555,556],{"class":526}," BlockType",[512,558,559],{"class":522},",",[512,561,562],{"class":526}," defaultBlockTypes",[512,564,530],{"class":522},[512,566,533],{"class":518},[512,568,536],{"class":522},[512,570,571],{"class":539},"@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema",[512,573,543],{"class":522},[512,575,577,579,581,583,586,588,590,592,594],{"class":514,"line":576},3,[512,578,519],{"class":518},[512,580,553],{"class":518},[512,582,523],{"class":522},[512,584,585],{"class":526}," PropertiesConfig",[512,587,530],{"class":522},[512,589,533],{"class":518},[512,591,536],{"class":522},[512,593,571],{"class":539},[512,595,543],{"class":522},[512,597,599,601,603,606,608,611,613,616,618,621,623,625,627,630],{"class":514,"line":598},4,[512,600,519],{"class":518},[512,602,523],{"class":522},[512,604,605],{"class":526}," coreContentFeature",[512,607,559],{"class":522},[512,609,610],{"class":526}," coreUiFeature",[512,612,559],{"class":522},[512,614,615],{"class":526}," createTranslator",[512,617,559],{"class":522},[512,619,620],{"class":526}," defineEditor",[512,622,530],{"class":522},[512,624,533],{"class":518},[512,626,536],{"class":522},[512,628,629],{"class":539},"@skaile\u002Fforge-editor\u002Fcore",[512,631,543],{"class":522},[512,633,635],{"class":514,"line":634},5,[512,636,638],{"emptyLinePlaceholder":637},true,"\n",[512,640,642,646,649,652,655,658,661,664,666],{"class":514,"line":641},6,[512,643,645],{"class":644},"spNyl","const",[512,647,648],{"class":526}," t ",[512,650,651],{"class":522},"=",[512,653,615],{"class":654},"s2Zo4",[512,656,657],{"class":526},"(",[512,659,660],{"class":522},"'",[512,662,663],{"class":539},"de",[512,665,660],{"class":522},[512,667,668],{"class":526},")\n",[512,670,672],{"class":514,"line":671},7,[512,673,638],{"emptyLinePlaceholder":637},[512,675,677,679,682,684],{"class":514,"line":676},8,[512,678,645],{"class":644},[512,680,681],{"class":526}," decisionProperties ",[512,683,651],{"class":522},[512,685,686],{"class":522}," {\n",[512,688,690,694,697],{"class":514,"line":689},9,[512,691,693],{"class":692},"swJcz","  definitions",[512,695,696],{"class":522},":",[512,698,699],{"class":526}," [\n",[512,701,703,706,709,711,713,716,718,720,723,725,727,730,732,734,736,738,740,743,745,747,750,752,755,758,761,763,765,768,770,772,774,776,778,781,783,786,788,790,792,794,797,799,801,803,805,807,810,812,814,817],{"class":514,"line":702},10,[512,704,705],{"class":522},"    {",[512,707,708],{"class":692}," key",[512,710,696],{"class":522},[512,712,536],{"class":522},[512,714,715],{"class":539},"status",[512,717,660],{"class":522},[512,719,559],{"class":522},[512,721,722],{"class":692}," label",[512,724,696],{"class":522},[512,726,536],{"class":522},[512,728,729],{"class":539},"Status",[512,731,660],{"class":522},[512,733,559],{"class":522},[512,735,553],{"class":692},[512,737,696],{"class":522},[512,739,536],{"class":522},[512,741,742],{"class":539},"select",[512,744,660],{"class":522},[512,746,559],{"class":522},[512,748,749],{"class":692}," options",[512,751,696],{"class":522},[512,753,754],{"class":526}," [",[512,756,757],{"class":522},"{",[512,759,760],{"class":692}," value",[512,762,696],{"class":522},[512,764,536],{"class":522},[512,766,767],{"class":539},"open",[512,769,660],{"class":522},[512,771,559],{"class":522},[512,773,722],{"class":692},[512,775,696],{"class":522},[512,777,536],{"class":522},[512,779,780],{"class":539},"Offen",[512,782,660],{"class":522},[512,784,785],{"class":522}," },",[512,787,523],{"class":522},[512,789,760],{"class":692},[512,791,696],{"class":522},[512,793,536],{"class":522},[512,795,796],{"class":539},"done",[512,798,660],{"class":522},[512,800,559],{"class":522},[512,802,722],{"class":692},[512,804,696],{"class":522},[512,806,536],{"class":522},[512,808,809],{"class":539},"Entschieden",[512,811,660],{"class":522},[512,813,530],{"class":522},[512,815,816],{"class":526},"] ",[512,818,819],{"class":522},"},\n",[512,821,823,825,827,829,831,834,836,838,840,842,844,847,849,851,853,855,857,860,862],{"class":514,"line":822},11,[512,824,705],{"class":522},[512,826,708],{"class":692},[512,828,696],{"class":522},[512,830,536],{"class":522},[512,832,833],{"class":539},"owner",[512,835,660],{"class":522},[512,837,559],{"class":522},[512,839,722],{"class":692},[512,841,696],{"class":522},[512,843,536],{"class":522},[512,845,846],{"class":539},"Zuständig",[512,848,660],{"class":522},[512,850,559],{"class":522},[512,852,553],{"class":692},[512,854,696],{"class":522},[512,856,536],{"class":522},[512,858,859],{"class":539},"text",[512,861,660],{"class":522},[512,863,864],{"class":522}," },\n",[512,866,868,871],{"class":514,"line":867},12,[512,869,870],{"class":526},"  ]",[512,872,873],{"class":522},",\n",[512,875,877,880,883],{"class":514,"line":876},13,[512,878,879],{"class":522},"}",[512,881,882],{"class":518}," satisfies",[512,884,886],{"class":885},"sBMFI"," PropertiesConfig\n",[512,888,890],{"class":514,"line":889},14,[512,891,638],{"emptyLinePlaceholder":637},[512,893,895],{"class":514,"line":894},15,[512,896,898],{"class":897},"sHwdD","\u002F\u002F A Block type is data: presentation plus the capabilities it lists, each with its config.\n",[512,900,902,904,907,909,911,914],{"class":514,"line":901},16,[512,903,645],{"class":644},[512,905,906],{"class":526}," decision",[512,908,696],{"class":522},[512,910,556],{"class":885},[512,912,913],{"class":522}," =",[512,915,686],{"class":522},[512,917,919,922,924,926,929,931],{"class":514,"line":918},17,[512,920,921],{"class":692},"  id",[512,923,696],{"class":522},[512,925,536],{"class":522},[512,927,928],{"class":539},"decision",[512,930,660],{"class":522},[512,932,873],{"class":522},[512,934,936,939,941,943,946,948],{"class":514,"line":935},18,[512,937,938],{"class":692},"  label",[512,940,696],{"class":522},[512,942,536],{"class":522},[512,944,945],{"class":539},"Entscheidung",[512,947,660],{"class":522},[512,949,873],{"class":522},[512,951,953,956,958,960,963,965],{"class":514,"line":952},19,[512,954,955],{"class":692},"  icon",[512,957,696],{"class":522},[512,959,536],{"class":522},[512,961,962],{"class":539},"i-lucide-gavel",[512,964,660],{"class":522},[512,966,873],{"class":522},[512,968,970,973,975,977,980,982],{"class":514,"line":969},20,[512,971,972],{"class":692},"  titlePlaceholder",[512,974,696],{"class":522},[512,976,536],{"class":522},[512,978,979],{"class":539},"Was wird entschieden?",[512,981,660],{"class":522},[512,983,873],{"class":522},[512,985,987,990,992],{"class":514,"line":986},21,[512,988,989],{"class":692},"  capabilities",[512,991,696],{"class":522},[512,993,699],{"class":526},[512,995,997,999,1002,1004,1006,1009,1011,1013,1016,1018,1020,1023,1025,1027,1029,1031,1033,1035,1037,1039,1041,1043,1045],{"class":514,"line":996},22,[512,998,705],{"class":522},[512,1000,1001],{"class":692}," id",[512,1003,696],{"class":522},[512,1005,536],{"class":522},[512,1007,1008],{"class":539},"container",[512,1010,660],{"class":522},[512,1012,559],{"class":522},[512,1014,1015],{"class":692}," config",[512,1017,696],{"class":522},[512,1019,523],{"class":522},[512,1021,1022],{"class":692}," accepts",[512,1024,696],{"class":522},[512,1026,754],{"class":526},[512,1028,660],{"class":522},[512,1030,486],{"class":539},[512,1032,660],{"class":522},[512,1034,559],{"class":522},[512,1036,536],{"class":522},[512,1038,489],{"class":539},[512,1040,660],{"class":522},[512,1042,816],{"class":526},[512,1044,879],{"class":522},[512,1046,864],{"class":522},[512,1048,1050,1052,1054,1056,1058,1061,1063],{"class":514,"line":1049},23,[512,1051,705],{"class":522},[512,1053,1001],{"class":692},[512,1055,696],{"class":522},[512,1057,536],{"class":522},[512,1059,1060],{"class":539},"basket",[512,1062,660],{"class":522},[512,1064,864],{"class":522},[512,1066,1068,1070,1072,1074,1076,1079,1081],{"class":514,"line":1067},24,[512,1069,705],{"class":522},[512,1071,1001],{"class":692},[512,1073,696],{"class":522},[512,1075,536],{"class":522},[512,1077,1078],{"class":539},"titleHidden",[512,1080,660],{"class":522},[512,1082,864],{"class":522},[512,1084,1086,1088,1090,1092,1094,1097,1099,1101,1103,1105,1107],{"class":514,"line":1085},25,[512,1087,705],{"class":522},[512,1089,1001],{"class":692},[512,1091,696],{"class":522},[512,1093,536],{"class":522},[512,1095,1096],{"class":539},"properties",[512,1098,660],{"class":522},[512,1100,559],{"class":522},[512,1102,1015],{"class":692},[512,1104,696],{"class":522},[512,1106,681],{"class":526},[512,1108,819],{"class":522},[512,1110,1112,1114],{"class":514,"line":1111},26,[512,1113,870],{"class":526},[512,1115,873],{"class":522},[512,1117,1119],{"class":514,"line":1118},27,[512,1120,1121],{"class":522},"}\n",[512,1123,1125],{"class":514,"line":1124},28,[512,1126,638],{"emptyLinePlaceholder":637},[512,1128,1130],{"class":514,"line":1129},29,[512,1131,1132],{"class":897},"\u002F\u002F `blockTypes` replaces the built-in list, so spread `defaultBlockTypes(t)` to keep the built-in types.\n",[512,1134,1136,1139,1142,1145,1147,1149,1151],{"class":514,"line":1135},30,[512,1137,1138],{"class":518},"export",[512,1140,1141],{"class":644}," const",[512,1143,1144],{"class":526}," preset ",[512,1146,651],{"class":522},[512,1148,620],{"class":654},[512,1150,657],{"class":526},[512,1152,1153],{"class":522},"{\n",[512,1155,1157,1160,1162,1164,1167,1170,1172,1174,1176,1178,1180,1182,1184,1187,1189,1191,1194,1197,1200,1202,1205,1207,1210],{"class":514,"line":1156},31,[512,1158,1159],{"class":692},"  features",[512,1161,696],{"class":522},[512,1163,754],{"class":526},[512,1165,1166],{"class":654},"coreContentFeature",[512,1168,1169],{"class":526},"()",[512,1171,559],{"class":522},[512,1173,610],{"class":654},[512,1175,1169],{"class":526},[512,1177,559],{"class":522},[512,1179,527],{"class":654},[512,1181,657],{"class":526},[512,1183,757],{"class":522},[512,1185,1186],{"class":692}," blockTypes",[512,1188,696],{"class":522},[512,1190,754],{"class":526},[512,1192,1193],{"class":522},"...",[512,1195,1196],{"class":654},"defaultBlockTypes",[512,1198,1199],{"class":526},"(t)",[512,1201,559],{"class":522},[512,1203,1204],{"class":526}," decision] ",[512,1206,879],{"class":522},[512,1208,1209],{"class":526},")]",[512,1211,873],{"class":522},[512,1213,1215,1217],{"class":514,"line":1214},32,[512,1216,879],{"class":522},[512,1218,668],{"class":526},[418,1220,1221,1224,1225,1228,1229,1232,1233,1237],{},[427,1222,1223],{},"capabilities"," is a list of ",[427,1226,1227],{},"{ id, config? }"," entries. The config of each entry is checked against the ",[427,1230,1231],{},"configSchema"," of its capability when the editor is created: an unknown capability id, a capability listed twice, a duplicate Block type id or an invalid config throws and names the Block type and the capability. The built-in capabilities and their configs are in the ",[432,1234,1236],{"href":1235},"\u002Freference\u002Fblock-capabilities#built-in-capabilities","capability contract",".",[418,1239,1240,1243,1244,1246,1247,1249,1250,480,1253,1255],{},[427,1241,1242],{},"blockTypesOf(editor)"," returns the editor's own list. A ",[427,1245,429],{}," id that the list does not define shows with the presentation of ",[427,1248,483],{}," under its own id. A host Feature that adds Block types to the list of the preset uses ",[427,1251,1252],{},"EditorFeature.blockTypes",[432,1254,357],{"href":358},"); the lists of all Features concatenate in feature order and are validated together.",[418,1257,1258,1259,443,1262,443,1265,1268,1269,1272,1273,1276,1277,480,1280,1282,1283,1268,1286,1289],{},"The pure accessors ",[427,1260,1261],{},"propertiesOf(type)",[427,1263,1264],{},"sourceMediaOf(type)",[427,1266,1267],{},"aiBriefOf(type)"," and ",[427,1270,1271],{},"acceptsOf(type)"," read a ",[427,1274,1275],{},"BlockType"," directly, without an editor; ",[427,1278,1279],{},"blockTypeConfigOf(type, id)",[427,1281,629],{},") reads the config of any capability. ",[427,1284,1285],{},"capabilitiesOf(editor, node)",[427,1287,1288],{},"capabilityConfigOf(editor, node, id)"," answer for a Block in an editor.",[418,1291,1292,1293,1237],{},"The tone, the chrome and the Accepted children of a Block type are described in ",[432,1294,1296],{"href":1295},"\u002Fguides\u002Fcomposites#what-the-feature-contributes","Typed blocks",[467,1298,1300],{"id":1299},"block-types-as-json","Block types as JSON",[418,1302,420,1303,1305,1306,1309,1310,1313],{},[427,1304,1275],{}," is plain data, so a host can keep its Block types in a JSON file (",[427,1307,1308],{},"BlockType[]",", one array) and load them when it creates the editor. This is the file of the reference app ",[427,1311,1312],{},"examples\u002Fvue-two-pane",", which defines the Block type „Idee“ only there:",[502,1315,1320],{"className":1316,"code":1317,"filename":1318,"language":1319,"meta":508,"style":508},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[\n  {\n    \"id\": \"idea\",\n    \"label\": \"Idee\",\n    \"icon\": \"i-lucide-lightbulb\",\n    \"titlePlaceholder\": \"Worum geht es bei der Idee?\",\n    \"descriptionPlaceholder\": \"Ein Satz dazu, was die Idee bringt\",\n    \"capabilities\": [\n      { \"id\": \"container\", \"config\": { \"accepts\": [\"task\", \"note\"] } },\n      { \"id\": \"basket\" },\n      { \"id\": \"titleHidden\" },\n      {\n        \"id\": \"properties\",\n        \"config\": {\n          \"definitions\": [\n            {\n              \"key\": \"stage\",\n              \"label\": \"Reifegrad\",\n              \"type\": \"select\",\n              \"options\": [\n                { \"value\": \"spark\", \"label\": \"Funke\" },\n                { \"value\": \"sketch\", \"label\": \"Skizze\" },\n                { \"value\": \"plan\", \"label\": \"Plan\" }\n              ]\n            },\n            { \"key\": \"impact\", \"label\": \"Wirkung (1–5)\", \"type\": \"number\" },\n            { \"key\": \"champion\", \"label\": \"Ansprechperson\", \"type\": \"text\" }\n          ]\n        }\n      },\n      { \"id\": \"ai-brief\", \"config\": { \"purpose\": \"Eine Idee, die noch geprüft wird: der Inhalt hält Begründung, Varianten und offene Fragen; Aufgaben und Notizen darunter bereiten die Entscheidung vor.\" } },\n      { \"id\": \"export\" }\n    ]\n  }\n]\n","examples\u002Fvue-two-pane\u002Fshared\u002Fblock-types.json","json",[427,1321,1322,1327,1332,1354,1373,1392,1412,1432,1444,1509,1529,1549,1554,1573,1585,1599,1604,1625,1644,1663,1676,1717,1755,1794,1799,1804,1860,1914,1919,1924,1929,1980,2000,2006,2012],{"__ignoreMap":508},[512,1323,1324],{"class":514,"line":515},[512,1325,1326],{"class":522},"[\n",[512,1328,1329],{"class":514,"line":546},[512,1330,1331],{"class":522},"  {\n",[512,1333,1334,1337,1339,1342,1344,1347,1350,1352],{"class":514,"line":576},[512,1335,1336],{"class":522},"    \"",[512,1338,438],{"class":644},[512,1340,1341],{"class":522},"\"",[512,1343,696],{"class":522},[512,1345,1346],{"class":522}," \"",[512,1348,1349],{"class":539},"idea",[512,1351,1341],{"class":522},[512,1353,873],{"class":522},[512,1355,1356,1358,1360,1362,1364,1366,1369,1371],{"class":514,"line":598},[512,1357,1336],{"class":522},[512,1359,442],{"class":644},[512,1361,1341],{"class":522},[512,1363,696],{"class":522},[512,1365,1346],{"class":522},[512,1367,1368],{"class":539},"Idee",[512,1370,1341],{"class":522},[512,1372,873],{"class":522},[512,1374,1375,1377,1379,1381,1383,1385,1388,1390],{"class":514,"line":634},[512,1376,1336],{"class":522},[512,1378,446],{"class":644},[512,1380,1341],{"class":522},[512,1382,696],{"class":522},[512,1384,1346],{"class":522},[512,1386,1387],{"class":539},"i-lucide-lightbulb",[512,1389,1341],{"class":522},[512,1391,873],{"class":522},[512,1393,1394,1396,1399,1401,1403,1405,1408,1410],{"class":514,"line":641},[512,1395,1336],{"class":522},[512,1397,1398],{"class":644},"titlePlaceholder",[512,1400,1341],{"class":522},[512,1402,696],{"class":522},[512,1404,1346],{"class":522},[512,1406,1407],{"class":539},"Worum geht es bei der Idee?",[512,1409,1341],{"class":522},[512,1411,873],{"class":522},[512,1413,1414,1416,1419,1421,1423,1425,1428,1430],{"class":514,"line":671},[512,1415,1336],{"class":522},[512,1417,1418],{"class":644},"descriptionPlaceholder",[512,1420,1341],{"class":522},[512,1422,696],{"class":522},[512,1424,1346],{"class":522},[512,1426,1427],{"class":539},"Ein Satz dazu, was die Idee bringt",[512,1429,1341],{"class":522},[512,1431,873],{"class":522},[512,1433,1434,1436,1438,1440,1442],{"class":514,"line":676},[512,1435,1336],{"class":522},[512,1437,1223],{"class":644},[512,1439,1341],{"class":522},[512,1441,696],{"class":522},[512,1443,699],{"class":522},[512,1445,1446,1449,1451,1453,1455,1457,1459,1461,1463,1465,1467,1470,1472,1474,1476,1478,1482,1484,1486,1488,1490,1492,1494,1496,1498,1500,1502,1505,1507],{"class":514,"line":689},[512,1447,1448],{"class":522},"      {",[512,1450,1346],{"class":522},[512,1452,438],{"class":885},[512,1454,1341],{"class":522},[512,1456,696],{"class":522},[512,1458,1346],{"class":522},[512,1460,1008],{"class":539},[512,1462,1341],{"class":522},[512,1464,559],{"class":522},[512,1466,1346],{"class":522},[512,1468,1469],{"class":885},"config",[512,1471,1341],{"class":522},[512,1473,696],{"class":522},[512,1475,523],{"class":522},[512,1477,1346],{"class":522},[512,1479,1481],{"class":1480},"sbssI","accepts",[512,1483,1341],{"class":522},[512,1485,696],{"class":522},[512,1487,754],{"class":522},[512,1489,1341],{"class":522},[512,1491,486],{"class":539},[512,1493,1341],{"class":522},[512,1495,559],{"class":522},[512,1497,1346],{"class":522},[512,1499,489],{"class":539},[512,1501,1341],{"class":522},[512,1503,1504],{"class":522},"]",[512,1506,530],{"class":522},[512,1508,864],{"class":522},[512,1510,1511,1513,1515,1517,1519,1521,1523,1525,1527],{"class":514,"line":702},[512,1512,1448],{"class":522},[512,1514,1346],{"class":522},[512,1516,438],{"class":885},[512,1518,1341],{"class":522},[512,1520,696],{"class":522},[512,1522,1346],{"class":522},[512,1524,1060],{"class":539},[512,1526,1341],{"class":522},[512,1528,864],{"class":522},[512,1530,1531,1533,1535,1537,1539,1541,1543,1545,1547],{"class":514,"line":822},[512,1532,1448],{"class":522},[512,1534,1346],{"class":522},[512,1536,438],{"class":885},[512,1538,1341],{"class":522},[512,1540,696],{"class":522},[512,1542,1346],{"class":522},[512,1544,1078],{"class":539},[512,1546,1341],{"class":522},[512,1548,864],{"class":522},[512,1550,1551],{"class":514,"line":867},[512,1552,1553],{"class":522},"      {\n",[512,1555,1556,1559,1561,1563,1565,1567,1569,1571],{"class":514,"line":876},[512,1557,1558],{"class":522},"        \"",[512,1560,438],{"class":885},[512,1562,1341],{"class":522},[512,1564,696],{"class":522},[512,1566,1346],{"class":522},[512,1568,1096],{"class":539},[512,1570,1341],{"class":522},[512,1572,873],{"class":522},[512,1574,1575,1577,1579,1581,1583],{"class":514,"line":889},[512,1576,1558],{"class":522},[512,1578,1469],{"class":885},[512,1580,1341],{"class":522},[512,1582,696],{"class":522},[512,1584,686],{"class":522},[512,1586,1587,1590,1593,1595,1597],{"class":514,"line":894},[512,1588,1589],{"class":522},"          \"",[512,1591,1592],{"class":1480},"definitions",[512,1594,1341],{"class":522},[512,1596,696],{"class":522},[512,1598,699],{"class":522},[512,1600,1601],{"class":514,"line":901},[512,1602,1603],{"class":522},"            {\n",[512,1605,1606,1609,1612,1614,1616,1618,1621,1623],{"class":514,"line":918},[512,1607,1608],{"class":522},"              \"",[512,1610,1611],{"class":692},"key",[512,1613,1341],{"class":522},[512,1615,696],{"class":522},[512,1617,1346],{"class":522},[512,1619,1620],{"class":539},"stage",[512,1622,1341],{"class":522},[512,1624,873],{"class":522},[512,1626,1627,1629,1631,1633,1635,1637,1640,1642],{"class":514,"line":935},[512,1628,1608],{"class":522},[512,1630,442],{"class":692},[512,1632,1341],{"class":522},[512,1634,696],{"class":522},[512,1636,1346],{"class":522},[512,1638,1639],{"class":539},"Reifegrad",[512,1641,1341],{"class":522},[512,1643,873],{"class":522},[512,1645,1646,1648,1651,1653,1655,1657,1659,1661],{"class":514,"line":952},[512,1647,1608],{"class":522},[512,1649,1650],{"class":692},"type",[512,1652,1341],{"class":522},[512,1654,696],{"class":522},[512,1656,1346],{"class":522},[512,1658,742],{"class":539},[512,1660,1341],{"class":522},[512,1662,873],{"class":522},[512,1664,1665,1667,1670,1672,1674],{"class":514,"line":969},[512,1666,1608],{"class":522},[512,1668,1669],{"class":692},"options",[512,1671,1341],{"class":522},[512,1673,696],{"class":522},[512,1675,699],{"class":522},[512,1677,1678,1681,1683,1687,1689,1691,1693,1696,1698,1700,1702,1704,1706,1708,1710,1713,1715],{"class":514,"line":986},[512,1679,1680],{"class":522},"                {",[512,1682,1346],{"class":522},[512,1684,1686],{"class":1685},"su27w","value",[512,1688,1341],{"class":522},[512,1690,696],{"class":522},[512,1692,1346],{"class":522},[512,1694,1695],{"class":539},"spark",[512,1697,1341],{"class":522},[512,1699,559],{"class":522},[512,1701,1346],{"class":522},[512,1703,442],{"class":1685},[512,1705,1341],{"class":522},[512,1707,696],{"class":522},[512,1709,1346],{"class":522},[512,1711,1712],{"class":539},"Funke",[512,1714,1341],{"class":522},[512,1716,864],{"class":522},[512,1718,1719,1721,1723,1725,1727,1729,1731,1734,1736,1738,1740,1742,1744,1746,1748,1751,1753],{"class":514,"line":996},[512,1720,1680],{"class":522},[512,1722,1346],{"class":522},[512,1724,1686],{"class":1685},[512,1726,1341],{"class":522},[512,1728,696],{"class":522},[512,1730,1346],{"class":522},[512,1732,1733],{"class":539},"sketch",[512,1735,1341],{"class":522},[512,1737,559],{"class":522},[512,1739,1346],{"class":522},[512,1741,442],{"class":1685},[512,1743,1341],{"class":522},[512,1745,696],{"class":522},[512,1747,1346],{"class":522},[512,1749,1750],{"class":539},"Skizze",[512,1752,1341],{"class":522},[512,1754,864],{"class":522},[512,1756,1757,1759,1761,1763,1765,1767,1769,1772,1774,1776,1778,1780,1782,1784,1786,1789,1791],{"class":514,"line":1049},[512,1758,1680],{"class":522},[512,1760,1346],{"class":522},[512,1762,1686],{"class":1685},[512,1764,1341],{"class":522},[512,1766,696],{"class":522},[512,1768,1346],{"class":522},[512,1770,1771],{"class":539},"plan",[512,1773,1341],{"class":522},[512,1775,559],{"class":522},[512,1777,1346],{"class":522},[512,1779,442],{"class":1685},[512,1781,1341],{"class":522},[512,1783,696],{"class":522},[512,1785,1346],{"class":522},[512,1787,1788],{"class":539},"Plan",[512,1790,1341],{"class":522},[512,1792,1793],{"class":522}," }\n",[512,1795,1796],{"class":514,"line":1067},[512,1797,1798],{"class":522},"              ]\n",[512,1800,1801],{"class":514,"line":1085},[512,1802,1803],{"class":522},"            },\n",[512,1805,1806,1809,1811,1813,1815,1817,1819,1822,1824,1826,1828,1830,1832,1834,1836,1839,1841,1843,1845,1847,1849,1851,1853,1856,1858],{"class":514,"line":1111},[512,1807,1808],{"class":522},"            {",[512,1810,1346],{"class":522},[512,1812,1611],{"class":692},[512,1814,1341],{"class":522},[512,1816,696],{"class":522},[512,1818,1346],{"class":522},[512,1820,1821],{"class":539},"impact",[512,1823,1341],{"class":522},[512,1825,559],{"class":522},[512,1827,1346],{"class":522},[512,1829,442],{"class":692},[512,1831,1341],{"class":522},[512,1833,696],{"class":522},[512,1835,1346],{"class":522},[512,1837,1838],{"class":539},"Wirkung (1–5)",[512,1840,1341],{"class":522},[512,1842,559],{"class":522},[512,1844,1346],{"class":522},[512,1846,1650],{"class":692},[512,1848,1341],{"class":522},[512,1850,696],{"class":522},[512,1852,1346],{"class":522},[512,1854,1855],{"class":539},"number",[512,1857,1341],{"class":522},[512,1859,864],{"class":522},[512,1861,1862,1864,1866,1868,1870,1872,1874,1877,1879,1881,1883,1885,1887,1889,1891,1894,1896,1898,1900,1902,1904,1906,1908,1910,1912],{"class":514,"line":1118},[512,1863,1808],{"class":522},[512,1865,1346],{"class":522},[512,1867,1611],{"class":692},[512,1869,1341],{"class":522},[512,1871,696],{"class":522},[512,1873,1346],{"class":522},[512,1875,1876],{"class":539},"champion",[512,1878,1341],{"class":522},[512,1880,559],{"class":522},[512,1882,1346],{"class":522},[512,1884,442],{"class":692},[512,1886,1341],{"class":522},[512,1888,696],{"class":522},[512,1890,1346],{"class":522},[512,1892,1893],{"class":539},"Ansprechperson",[512,1895,1341],{"class":522},[512,1897,559],{"class":522},[512,1899,1346],{"class":522},[512,1901,1650],{"class":692},[512,1903,1341],{"class":522},[512,1905,696],{"class":522},[512,1907,1346],{"class":522},[512,1909,859],{"class":539},[512,1911,1341],{"class":522},[512,1913,1793],{"class":522},[512,1915,1916],{"class":514,"line":1124},[512,1917,1918],{"class":522},"          ]\n",[512,1920,1921],{"class":514,"line":1129},[512,1922,1923],{"class":522},"        }\n",[512,1925,1926],{"class":514,"line":1135},[512,1927,1928],{"class":522},"      },\n",[512,1930,1931,1933,1935,1937,1939,1941,1943,1946,1948,1950,1952,1954,1956,1958,1960,1962,1965,1967,1969,1971,1974,1976,1978],{"class":514,"line":1156},[512,1932,1448],{"class":522},[512,1934,1346],{"class":522},[512,1936,438],{"class":885},[512,1938,1341],{"class":522},[512,1940,696],{"class":522},[512,1942,1346],{"class":522},[512,1944,1945],{"class":539},"ai-brief",[512,1947,1341],{"class":522},[512,1949,559],{"class":522},[512,1951,1346],{"class":522},[512,1953,1469],{"class":885},[512,1955,1341],{"class":522},[512,1957,696],{"class":522},[512,1959,523],{"class":522},[512,1961,1346],{"class":522},[512,1963,1964],{"class":1480},"purpose",[512,1966,1341],{"class":522},[512,1968,696],{"class":522},[512,1970,1346],{"class":522},[512,1972,1973],{"class":539},"Eine Idee, die noch geprüft wird: der Inhalt hält Begründung, Varianten und offene Fragen; Aufgaben und Notizen darunter bereiten die Entscheidung vor.",[512,1975,1341],{"class":522},[512,1977,530],{"class":522},[512,1979,864],{"class":522},[512,1981,1982,1984,1986,1988,1990,1992,1994,1996,1998],{"class":514,"line":1214},[512,1983,1448],{"class":522},[512,1985,1346],{"class":522},[512,1987,438],{"class":885},[512,1989,1341],{"class":522},[512,1991,696],{"class":522},[512,1993,1346],{"class":522},[512,1995,1138],{"class":539},[512,1997,1341],{"class":522},[512,1999,1793],{"class":522},[512,2001,2003],{"class":514,"line":2002},33,[512,2004,2005],{"class":522},"    ]\n",[512,2007,2009],{"class":514,"line":2008},34,[512,2010,2011],{"class":522},"  }\n",[512,2013,2015],{"class":514,"line":2014},35,[512,2016,2017],{"class":522},"]\n",[418,2019,2020,480,2023,1268,2026,2029,2030,2032,2033,2036,2037,2040],{},[427,2021,2022],{},"parseBlockTypes(input, { registry? })",[427,2024,2025],{},"@skaile\u002Fforge-editor\u002Fcomposites",[427,2027,2028],{},"\u002Fcomposites\u002Fschema",", Vue-free) takes the text of the file or its parsed value and returns the ",[427,2031,1308],{}," that the ",[427,2034,2035],{},"blockTypes"," option takes. ",[427,2038,2039],{},"mergeBlockTypes(base, extra)"," layers the file over the built-in types: a type with a known id replaces that one in place, new types follow. The example keeps both calls in one module that the browser and the server import:",[502,2042,2045],{"className":504,"code":2043,"filename":2044,"language":507,"meta":508,"style":508},"import { defaultBlockTypes, mergeBlockTypes, parseBlockTypes } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema'\nimport type { Translate } from '@skaile\u002Fforge-editor\u002Fcore'\nimport file from '.\u002Fblock-types.json'\n\n\u002F\u002F The Block types of this app: the library's built-in ones plus the ones `block-types.json` defines (the type „Idee“ exists\n\u002F\u002F only there). The browser (`composeEditor({ blockTypes })`) and the Nitro server (`installEditorServer({ blockTypes })`) both\n\u002F\u002F import this module, so the definitions live once. Parsing validates the file against the capabilities' config schemas; a\n\u002F\u002F mistake in it stops the server at start and the page at load, with the Block type, the capability and the path named.\nconst hostTypes = parseBlockTypes(file)\n\n\u002F** The built-in Block types in the language of `t`, with the types of `block-types.json` after them. *\u002F\nexport const blockTypesOf = (t: Translate) => mergeBlockTypes(defaultBlockTypes(t), hostTypes)\n","examples\u002Fvue-two-pane\u002Fshared\u002Fblock-types.ts",[427,2046,2047,2075,2096,2113,2117,2122,2127,2132,2137,2151,2155,2160],{"__ignoreMap":508},[512,2048,2049,2051,2053,2055,2057,2060,2062,2065,2067,2069,2071,2073],{"class":514,"line":515},[512,2050,519],{"class":518},[512,2052,523],{"class":522},[512,2054,562],{"class":526},[512,2056,559],{"class":522},[512,2058,2059],{"class":526}," mergeBlockTypes",[512,2061,559],{"class":522},[512,2063,2064],{"class":526}," parseBlockTypes",[512,2066,530],{"class":522},[512,2068,533],{"class":518},[512,2070,536],{"class":522},[512,2072,571],{"class":539},[512,2074,543],{"class":522},[512,2076,2077,2079,2081,2083,2086,2088,2090,2092,2094],{"class":514,"line":546},[512,2078,519],{"class":518},[512,2080,553],{"class":518},[512,2082,523],{"class":522},[512,2084,2085],{"class":526}," Translate",[512,2087,530],{"class":522},[512,2089,533],{"class":518},[512,2091,536],{"class":522},[512,2093,629],{"class":539},[512,2095,543],{"class":522},[512,2097,2098,2100,2103,2106,2108,2111],{"class":514,"line":576},[512,2099,519],{"class":518},[512,2101,2102],{"class":526}," file ",[512,2104,2105],{"class":518},"from",[512,2107,536],{"class":522},[512,2109,2110],{"class":539},".\u002Fblock-types.json",[512,2112,543],{"class":522},[512,2114,2115],{"class":514,"line":598},[512,2116,638],{"emptyLinePlaceholder":637},[512,2118,2119],{"class":514,"line":634},[512,2120,2121],{"class":897},"\u002F\u002F The Block types of this app: the library's built-in ones plus the ones `block-types.json` defines (the type „Idee“ exists\n",[512,2123,2124],{"class":514,"line":641},[512,2125,2126],{"class":897},"\u002F\u002F only there). The browser (`composeEditor({ blockTypes })`) and the Nitro server (`installEditorServer({ blockTypes })`) both\n",[512,2128,2129],{"class":514,"line":671},[512,2130,2131],{"class":897},"\u002F\u002F import this module, so the definitions live once. Parsing validates the file against the capabilities' config schemas; a\n",[512,2133,2134],{"class":514,"line":676},[512,2135,2136],{"class":897},"\u002F\u002F mistake in it stops the server at start and the page at load, with the Block type, the capability and the path named.\n",[512,2138,2139,2141,2144,2146,2148],{"class":514,"line":689},[512,2140,645],{"class":644},[512,2142,2143],{"class":526}," hostTypes ",[512,2145,651],{"class":522},[512,2147,2064],{"class":654},[512,2149,2150],{"class":526},"(file)\n",[512,2152,2153],{"class":514,"line":702},[512,2154,638],{"emptyLinePlaceholder":637},[512,2156,2157],{"class":514,"line":822},[512,2158,2159],{"class":897},"\u002F** The built-in Block types in the language of `t`, with the types of `block-types.json` after them. *\u002F\n",[512,2161,2162,2164,2166,2169,2171,2173,2176,2178,2180,2183,2186,2188,2190,2192,2194,2196],{"class":514,"line":867},[512,2163,1138],{"class":518},[512,2165,1141],{"class":644},[512,2167,2168],{"class":526}," blockTypesOf ",[512,2170,651],{"class":522},[512,2172,480],{"class":522},[512,2174,499],{"class":2175},"sHdIc",[512,2177,696],{"class":522},[512,2179,2085],{"class":885},[512,2181,2182],{"class":522},")",[512,2184,2185],{"class":644}," =>",[512,2187,2059],{"class":654},[512,2189,657],{"class":526},[512,2191,1196],{"class":654},[512,2193,1199],{"class":526},[512,2195,559],{"class":522},[512,2197,2198],{"class":526}," hostTypes)\n",[418,2200,2201,2204,2205,2208,2209,2211,2212,2214,2215,1237],{},[427,2202,2203],{},"blockTypesOf(t)"," then goes to ",[427,2206,2207],{},"composeEditor({ blockTypes })",", to ",[427,2210,475],{}," or to the ",[427,2213,2035],{}," prop of ",[427,2216,2217],{},"AdvancedEditor",[2219,2220,2222,2223,2226],"h3",{"id":2221},"what-parseblocktypes-checks","What ",[427,2224,2225],{},"parseBlockTypes"," checks",[418,2228,2229,2230,1237],{},"Every entry is checked against the capability registry. By default that is the built-in capabilities and those of the composites feature. A host whose Features declare more capabilities passes ",[427,2231,2232],{},"registry: preset.capabilities",[2234,2235,2236,2254,2257,2260],"ul",{},[2237,2238,2239,2241,2242,443,2245,2248,2249,1268,2251,2253],"li",{},[427,2240,438],{}," (letters, digits, ",[427,2243,2244],{},"_",[427,2246,2247],{},"-","), ",[427,2250,442],{},[427,2252,446],{}," are required, and ids are unique.",[2237,2255,2256],{},"A capability that the registry does not know is refused.",[2237,2258,2259],{},"One capability may be listed once.",[2237,2261,2262,2263,2265,2266,2268],{},"Its ",[427,2264,1469],{}," must pass the ",[427,2267,1231],{}," of the capability. A capability without a schema takes no config.",[418,2270,2271,2273,2274,2277,2278,2281,2282,2285,2286,443,2289,443,2292,443,2295,443,2298,2300],{},[427,2272,2225],{}," throws one ",[427,2275,2276],{},"BlockTypeJsonError"," for the whole file. ",[427,2279,2280],{},"message"," has one line per problem, and ",[427,2283,2284],{},"issues"," has the same as data (",[427,2287,2288],{},"index",[427,2290,2291],{},"typeId",[427,2293,2294],{},"capability",[427,2296,2297],{},"path",[427,2299,2280],{},"):",[502,2302,2306],{"className":2303,"code":2305,"language":859},[2304],"language-text","Block type \"idea\": capability \"teleport\" config: unknown capability; no feature declares it (known: container, title, properties, ...)\nBlock type \"idea\": capability \"properties\" config, definitions[1].type: Invalid option: expected one of \"text\"|\"textarea\"|...\nBlock type \"idea\": id: duplicate Block type id (first defined by entry 0)\n",[427,2307,2305],{"__ignoreMap":508},[418,2309,2310],{},"A mistake in the file stops the server at start and the page at load, with the Block type, the capability and the path named.",[418,2312,2313,2314,2317,2318,2321],{},"The file has one language, so labels, placeholders and Property definition labels in it are not translated; the built-in types still follow the editor's language. Icons are ",[427,2315,2316],{},"i-lucide-*"," names. A bundler that only ships the icons it finds in the sources of the app (Nuxt UI) needs the file scanned too (",[427,2319,2320],{},"examples\u002Fvue-two-pane\u002Fvite.config.ts",").",[418,2323,2324,2325,2328,2329,2332,2333,2335,2336,2339],{},"In the example, „Idee“ appears in the ",[427,2326,2327],{},"\u002F"," menu as ",[427,2330,2331],{},"\u002Fidea",", in the ",[432,2334,117],{"href":118}," and in the Block inspector. It has a Basket, the ",[432,2337,2338],{"href":176},"Block properties"," Reifegrad, Wirkung and Ansprechperson, an AI brief and the „Exportieren“ action, and it accepts tasks and notes as nested Typed blocks.",[467,2341,2343],{"id":2342},"the-server","The server",[418,2345,2346,2347,696],{},"The collaboration schema does not depend on Block types, because they are storage and not schema. Only the AI chat needs them on the server. Pass the same list to ",[427,2348,2349],{},"installEditorServer(nitroApp, { ports, blockTypes })",[502,2351,2354],{"className":504,"code":2352,"filename":2353,"language":507,"meta":508,"style":508},"import path from 'node:path'\nimport { createJsonAdapter } from '@skaile\u002Fforge-editor\u002Fadapters\u002Fjson'\nimport { defineEditorConfig, serverConfig } from '@skaile\u002Fforge-editor\u002Fconfig'\nimport { createJsonCommentStore } from '@skaile\u002Fforge-editor\u002Fcomments\u002Fjson'\nimport { installEditorServer } from '@skaile\u002Fforge-editor\u002Fserver\u002Fnitro'\nimport { defineNitroPlugin } from 'nitropack\u002Fruntime'\nimport { createTranslator } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { LOCAL_USER } from '..\u002F..\u002Fshared\u002Fidentity'\nimport { blockTypesOf } from '..\u002F..\u002Fshared\u002Fblock-types'\nimport { dataDir } from '..\u002Fdata-dir'\n\n\u002F\u002F The whole backend: documents as `\u003Cid>.json` (and the live collaboration state beside them) in one directory, comments\n\u002F\u002F in one JSON file, the editor's REST routes and the collaboration websocket on the Nitro app. The document index (titles\n\u002F\u002F and folders, which the JSON adapter does not keep) is served by `routes\u002Fapi\u002Ftwo-pane-index.*`.\nexport default defineNitroPlugin((nitroApp) => {\n  installEditorServer(nitroApp, {\n    ports: {\n      ...createJsonAdapter({\n        dir: path.join(dataDir, 'documents'),\n        \u002F\u002F Everyone is the local user. Without this, the adapter signs in an anonymous dev user outside production only.\n        authenticate: async () => ({ id: LOCAL_USER.id, username: LOCAL_USER.name, color: LOCAL_USER.color }),\n      }),\n      comments: createJsonCommentStore({ file: path.join(dataDir, 'comments.json') }),\n    },\n    \u002F\u002F `ai` (presets, roles, rate limit) and `collab` come from the one editor config; the AI routes need a key (`AI_KEY`).\n    ...serverConfig(defineEditorConfig({ ai: { apiKey: process.env.AI_KEY } })),\n    \u002F\u002F The same Block types as the browser (`shared\u002Fblock-types.json` over the built-in ones): the AI chat describes them to the model itself.\n    blockTypes: blockTypesOf(createTranslator()),\n  })\n})\n","examples\u002Fvue-two-pane\u002Fserver\u002Fplugins\u002Feditor.ts",[427,2355,2356,2372,2392,2417,2437,2457,2477,2495,2515,2535,2555,2559,2564,2569,2574,2596,2609,2618,2630,2663,2668,2731,2740,2786,2791,2796,2847,2852,2871,2878],{"__ignoreMap":508},[512,2357,2358,2360,2363,2365,2367,2370],{"class":514,"line":515},[512,2359,519],{"class":518},[512,2361,2362],{"class":526}," path ",[512,2364,2105],{"class":518},[512,2366,536],{"class":522},[512,2368,2369],{"class":539},"node:path",[512,2371,543],{"class":522},[512,2373,2374,2376,2378,2381,2383,2385,2387,2390],{"class":514,"line":546},[512,2375,519],{"class":518},[512,2377,523],{"class":522},[512,2379,2380],{"class":526}," createJsonAdapter",[512,2382,530],{"class":522},[512,2384,533],{"class":518},[512,2386,536],{"class":522},[512,2388,2389],{"class":539},"@skaile\u002Fforge-editor\u002Fadapters\u002Fjson",[512,2391,543],{"class":522},[512,2393,2394,2396,2398,2401,2403,2406,2408,2410,2412,2415],{"class":514,"line":576},[512,2395,519],{"class":518},[512,2397,523],{"class":522},[512,2399,2400],{"class":526}," defineEditorConfig",[512,2402,559],{"class":522},[512,2404,2405],{"class":526}," serverConfig",[512,2407,530],{"class":522},[512,2409,533],{"class":518},[512,2411,536],{"class":522},[512,2413,2414],{"class":539},"@skaile\u002Fforge-editor\u002Fconfig",[512,2416,543],{"class":522},[512,2418,2419,2421,2423,2426,2428,2430,2432,2435],{"class":514,"line":598},[512,2420,519],{"class":518},[512,2422,523],{"class":522},[512,2424,2425],{"class":526}," createJsonCommentStore",[512,2427,530],{"class":522},[512,2429,533],{"class":518},[512,2431,536],{"class":522},[512,2433,2434],{"class":539},"@skaile\u002Fforge-editor\u002Fcomments\u002Fjson",[512,2436,543],{"class":522},[512,2438,2439,2441,2443,2446,2448,2450,2452,2455],{"class":514,"line":634},[512,2440,519],{"class":518},[512,2442,523],{"class":522},[512,2444,2445],{"class":526}," installEditorServer",[512,2447,530],{"class":522},[512,2449,533],{"class":518},[512,2451,536],{"class":522},[512,2453,2454],{"class":539},"@skaile\u002Fforge-editor\u002Fserver\u002Fnitro",[512,2456,543],{"class":522},[512,2458,2459,2461,2463,2466,2468,2470,2472,2475],{"class":514,"line":641},[512,2460,519],{"class":518},[512,2462,523],{"class":522},[512,2464,2465],{"class":526}," defineNitroPlugin",[512,2467,530],{"class":522},[512,2469,533],{"class":518},[512,2471,536],{"class":522},[512,2473,2474],{"class":539},"nitropack\u002Fruntime",[512,2476,543],{"class":522},[512,2478,2479,2481,2483,2485,2487,2489,2491,2493],{"class":514,"line":671},[512,2480,519],{"class":518},[512,2482,523],{"class":522},[512,2484,615],{"class":526},[512,2486,530],{"class":522},[512,2488,533],{"class":518},[512,2490,536],{"class":522},[512,2492,629],{"class":539},[512,2494,543],{"class":522},[512,2496,2497,2499,2501,2504,2506,2508,2510,2513],{"class":514,"line":676},[512,2498,519],{"class":518},[512,2500,523],{"class":522},[512,2502,2503],{"class":526}," LOCAL_USER",[512,2505,530],{"class":522},[512,2507,533],{"class":518},[512,2509,536],{"class":522},[512,2511,2512],{"class":539},"..\u002F..\u002Fshared\u002Fidentity",[512,2514,543],{"class":522},[512,2516,2517,2519,2521,2524,2526,2528,2530,2533],{"class":514,"line":689},[512,2518,519],{"class":518},[512,2520,523],{"class":522},[512,2522,2523],{"class":526}," blockTypesOf",[512,2525,530],{"class":522},[512,2527,533],{"class":518},[512,2529,536],{"class":522},[512,2531,2532],{"class":539},"..\u002F..\u002Fshared\u002Fblock-types",[512,2534,543],{"class":522},[512,2536,2537,2539,2541,2544,2546,2548,2550,2553],{"class":514,"line":702},[512,2538,519],{"class":518},[512,2540,523],{"class":522},[512,2542,2543],{"class":526}," dataDir",[512,2545,530],{"class":522},[512,2547,533],{"class":518},[512,2549,536],{"class":522},[512,2551,2552],{"class":539},"..\u002Fdata-dir",[512,2554,543],{"class":522},[512,2556,2557],{"class":514,"line":822},[512,2558,638],{"emptyLinePlaceholder":637},[512,2560,2561],{"class":514,"line":867},[512,2562,2563],{"class":897},"\u002F\u002F The whole backend: documents as `\u003Cid>.json` (and the live collaboration state beside them) in one directory, comments\n",[512,2565,2566],{"class":514,"line":876},[512,2567,2568],{"class":897},"\u002F\u002F in one JSON file, the editor's REST routes and the collaboration websocket on the Nitro app. The document index (titles\n",[512,2570,2571],{"class":514,"line":889},[512,2572,2573],{"class":897},"\u002F\u002F and folders, which the JSON adapter does not keep) is served by `routes\u002Fapi\u002Ftwo-pane-index.*`.\n",[512,2575,2576,2578,2581,2583,2585,2587,2590,2592,2594],{"class":514,"line":894},[512,2577,1138],{"class":518},[512,2579,2580],{"class":518}," default",[512,2582,2465],{"class":654},[512,2584,657],{"class":526},[512,2586,657],{"class":522},[512,2588,2589],{"class":2175},"nitroApp",[512,2591,2182],{"class":522},[512,2593,2185],{"class":644},[512,2595,686],{"class":522},[512,2597,2598,2601,2603,2605,2607],{"class":514,"line":901},[512,2599,2600],{"class":654},"  installEditorServer",[512,2602,657],{"class":692},[512,2604,2589],{"class":526},[512,2606,559],{"class":522},[512,2608,686],{"class":522},[512,2610,2611,2614,2616],{"class":514,"line":918},[512,2612,2613],{"class":692},"    ports",[512,2615,696],{"class":522},[512,2617,686],{"class":522},[512,2619,2620,2623,2626,2628],{"class":514,"line":935},[512,2621,2622],{"class":522},"      ...",[512,2624,2625],{"class":654},"createJsonAdapter",[512,2627,657],{"class":692},[512,2629,1153],{"class":522},[512,2631,2632,2635,2637,2640,2642,2645,2647,2650,2652,2654,2657,2659,2661],{"class":514,"line":952},[512,2633,2634],{"class":692},"        dir",[512,2636,696],{"class":522},[512,2638,2639],{"class":526}," path",[512,2641,1237],{"class":522},[512,2643,2644],{"class":654},"join",[512,2646,657],{"class":692},[512,2648,2649],{"class":526},"dataDir",[512,2651,559],{"class":522},[512,2653,536],{"class":522},[512,2655,2656],{"class":539},"documents",[512,2658,660],{"class":522},[512,2660,2182],{"class":692},[512,2662,873],{"class":522},[512,2664,2665],{"class":514,"line":969},[512,2666,2667],{"class":897},"        \u002F\u002F Everyone is the local user. Without this, the adapter signs in an anonymous dev user outside production only.\n",[512,2669,2670,2673,2675,2678,2681,2683,2685,2687,2689,2691,2693,2695,2697,2699,2702,2704,2706,2708,2711,2713,2716,2718,2720,2722,2725,2727,2729],{"class":514,"line":986},[512,2671,2672],{"class":654},"        authenticate",[512,2674,696],{"class":522},[512,2676,2677],{"class":644}," async",[512,2679,2680],{"class":522}," ()",[512,2682,2185],{"class":644},[512,2684,480],{"class":692},[512,2686,757],{"class":522},[512,2688,1001],{"class":692},[512,2690,696],{"class":522},[512,2692,2503],{"class":526},[512,2694,1237],{"class":522},[512,2696,438],{"class":526},[512,2698,559],{"class":522},[512,2700,2701],{"class":692}," username",[512,2703,696],{"class":522},[512,2705,2503],{"class":526},[512,2707,1237],{"class":522},[512,2709,2710],{"class":526},"name",[512,2712,559],{"class":522},[512,2714,2715],{"class":692}," color",[512,2717,696],{"class":522},[512,2719,2503],{"class":526},[512,2721,1237],{"class":522},[512,2723,2724],{"class":526},"color",[512,2726,530],{"class":522},[512,2728,2182],{"class":692},[512,2730,873],{"class":522},[512,2732,2733,2736,2738],{"class":514,"line":996},[512,2734,2735],{"class":522},"      }",[512,2737,2182],{"class":692},[512,2739,873],{"class":522},[512,2741,2742,2745,2747,2749,2751,2753,2756,2758,2760,2762,2764,2766,2768,2770,2772,2775,2777,2780,2782,2784],{"class":514,"line":1049},[512,2743,2744],{"class":692},"      comments",[512,2746,696],{"class":522},[512,2748,2425],{"class":654},[512,2750,657],{"class":692},[512,2752,757],{"class":522},[512,2754,2755],{"class":692}," file",[512,2757,696],{"class":522},[512,2759,2639],{"class":526},[512,2761,1237],{"class":522},[512,2763,2644],{"class":654},[512,2765,657],{"class":692},[512,2767,2649],{"class":526},[512,2769,559],{"class":522},[512,2771,536],{"class":522},[512,2773,2774],{"class":539},"comments.json",[512,2776,660],{"class":522},[512,2778,2779],{"class":692},") ",[512,2781,879],{"class":522},[512,2783,2182],{"class":692},[512,2785,873],{"class":522},[512,2787,2788],{"class":514,"line":1067},[512,2789,2790],{"class":522},"    },\n",[512,2792,2793],{"class":514,"line":1085},[512,2794,2795],{"class":897},"    \u002F\u002F `ai` (presets, roles, rate limit) and `collab` come from the one editor config; the AI routes need a key (`AI_KEY`).\n",[512,2797,2798,2801,2804,2806,2809,2811,2813,2816,2818,2820,2823,2825,2828,2830,2833,2835,2838,2840,2842,2845],{"class":514,"line":1111},[512,2799,2800],{"class":522},"    ...",[512,2802,2803],{"class":654},"serverConfig",[512,2805,657],{"class":692},[512,2807,2808],{"class":654},"defineEditorConfig",[512,2810,657],{"class":692},[512,2812,757],{"class":522},[512,2814,2815],{"class":692}," ai",[512,2817,696],{"class":522},[512,2819,523],{"class":522},[512,2821,2822],{"class":692}," apiKey",[512,2824,696],{"class":522},[512,2826,2827],{"class":526}," process",[512,2829,1237],{"class":522},[512,2831,2832],{"class":526},"env",[512,2834,1237],{"class":522},[512,2836,2837],{"class":526},"AI_KEY",[512,2839,530],{"class":522},[512,2841,530],{"class":522},[512,2843,2844],{"class":692},"))",[512,2846,873],{"class":522},[512,2848,2849],{"class":514,"line":1118},[512,2850,2851],{"class":897},"    \u002F\u002F The same Block types as the browser (`shared\u002Fblock-types.json` over the built-in ones): the AI chat describes them to the model itself.\n",[512,2853,2854,2857,2859,2861,2863,2866,2869],{"class":514,"line":1124},[512,2855,2856],{"class":692},"    blockTypes",[512,2858,696],{"class":522},[512,2860,2523],{"class":654},[512,2862,657],{"class":692},[512,2864,2865],{"class":654},"createTranslator",[512,2867,2868],{"class":692},"())",[512,2870,873],{"class":522},[512,2872,2873,2876],{"class":514,"line":1129},[512,2874,2875],{"class":522},"  }",[512,2877,668],{"class":692},[512,2879,2880,2882],{"class":514,"line":1135},[512,2881,879],{"class":522},[512,2883,668],{"class":526},[2234,2885,2886,2903,2919,2940],{},[2237,2887,2888,2891,2892,2895,2896,2899,2900,1237],{},[427,2889,2890],{},"EditorServerOptions.blockTypes"," is the option of ",[427,2893,2894],{},"installEditorServer","; ",[427,2897,2898],{},"AiHandlerContext.blockTypes"," is the same for hand-wired handlers, and a Nuxt host passes ",[427,2901,2902],{},"provideEditorServer({ ports, blockTypes })",[2237,2904,2905,2908,2909,2912,2913,2915,2916,2918],{},[427,2906,2907],{},"POST \u002Fapi\u002Fai\u002Fchat"," then describes these types to the model (",[427,2910,2911],{},"aiBlockTypesOf(blockTypes)",": id, label, Block properties as fields, the ",[427,2914,1945],{}," purpose) and ignores the ",[427,2917,2035],{}," in the request. Import the same JSON and loader on both sides so the definitions live once.",[2237,2920,2921,2922,2924,2925,2927,2928,2931,2932,2935,2936,2939],{},"Without ",[427,2923,2035],{}," the server takes the ",[427,2926,2035],{}," of the client. The ",[427,2929,2930],{},"convert"," ",[427,2933,2934],{},"targets"," and the host ",[427,2937,2938],{},"blocks"," of the request still come from the client.",[2237,2941,2942,2943,2321],{},"The server describes the host's types in the language of the translator it built them with (German for ",[427,2944,2945],{},"createTranslator()",[418,2947,2948,2950],{},[427,2949,2035],{}," is storage on the server: it does not change the schema that the collaboration route builds.",[2952,2953,2954],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .su27w, html code.shiki .su27w{--shiki-light:#916B53;--shiki-default:#916B53;--shiki-dark:#916B53}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":508,"searchDepth":546,"depth":546,"links":2956},[2957,2958,2962],{"id":469,"depth":546,"text":470},{"id":1299,"depth":546,"text":1300,"children":2959},[2960],{"id":2221,"depth":576,"text":2961},"What parseBlockTypes checks",{"id":2342,"depth":546,"text":2343},"Define a Block type as data in code or in a JSON file, check it against the capability registry, and give the server the same list.","md",null,{},{"icon":168},{"title":165,"description":2963},"zQKM7dzWElFIUmXaaVNuGqDIFcefXgrEHKn00jRtcwk",[2971,2973],{"title":160,"path":161,"stem":162,"description":2972,"icon":163,"children":-1},"Declare a Block capability in a host Feature, gate a Block action with requires and ability, see what abilities gate and let a Block type opt in.",{"title":170,"path":171,"stem":172,"description":2974,"icon":173,"children":-1},"Register one way to make a block from another block, find the Derived blocks of an original and handle a missing source.",1793213904391]