[{"data":1,"prerenderedAt":2019},["ShallowReactive",2],{"navigation_docs":3,"-guides-block-capabilities":412,"-guides-block-capabilities-surround":2014},[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":160,"body":414,"description":2007,"extension":2008,"links":2009,"meta":2010,"navigation":2011,"path":161,"seo":2012,"stem":162,"__hash__":2013},"docs\u002F3.guides\u002F23.block-capabilities.md",{"type":415,"value":416,"toc":1998},"minimark",[417,444,447,534,540,587,592,624,1092,1095,1173,1183,1189,1221,1223,1266,1269,1376,1403,1407,1416,1854,1866,1870,1873,1946,1967,1971,1994],[418,419,420,421,425,426,430,431,434,435,439,440,443],"p",{},"A ",[422,423,424],"strong",{},"Block capability"," says what a Block supports: it is a Container block, it has a Source, it carries a Bibliographic record. It is code, and a Feature declares it. A ",[427,428,429],"a",{"href":166},"Block type"," is data: it lists the capabilities its Typed blocks have and configures them. A ",[422,432,433],{},"Block action"," names the capabilities a Block must have (",[436,437,438],"code",{},"requires",") and the ability its place in the document must have (",[436,441,442],{},"ability",").",[418,445,446],{},"Four words, four jobs:",[448,449,450,466],"table",{},[451,452,453],"thead",{},[454,455,456,460,463],"tr",{},[457,458,459],"th",{},"Word",[457,461,462],{},"Question it answers",[457,464,465],{},"Where it lives",[467,468,469,483,497,518],"tbody",{},[454,470,471,474,477],{},[472,473,424],"td",{},[472,475,476],{},"What is this Block?",[472,478,479,482],{},[436,480,481],{},"EditorFeature.blockCapabilities"," (code)",[454,484,485,487,490],{},[472,486,429],{},[472,488,489],{},"Which capabilities does a Typed block of this type have, and how are they set?",[472,491,492,493,496],{},"a ",[436,494,495],{},"BlockType"," (data, JSON)",[454,498,499,502,505],{},[472,500,501],{},"Ability",[472,503,504],{},"What is offered at this place in the document?",[472,506,507,510,511,514,515,517],{},[436,508,509],{},"ABILITY"," ids; the ",[436,512,513],{},"abilities"," rule of each node and the host's ",[436,516,513],{}," prop",[454,519,520,522,525],{},[472,521,433],{},[472,523,524],{},"What can the user run on this Block?",[472,526,527,530,531],{},[436,528,529],{},"EditorFeature.blockActions",", derive methods, the host's ",[436,532,533],{},"blockActions",[418,535,536,537,539],{},"A capability describes and gates nothing by itself; an action gates on it through ",[436,538,438],{},". It also never installs anything: the schema, the extensions and the node views stay with the Feature that owns the mechanism. A capability descriptor only tells the editor how to find out whether a Block has it, where its data lives and how to read it.",[418,541,542,543,546,547,550,551,554,555,554,558,554,561,554,564,554,567,554,570,554,573,554,576,546,579,582,583,586],{},"The library declares these capabilities: ",[436,544,545],{},"container"," and ",[436,548,549],{},"title"," are built in, the composites feature adds ",[436,552,553],{},"properties",", ",[436,556,557],{},"source",[436,559,560],{},"bibliography",[436,562,563],{},"basket",[436,565,566],{},"titleHidden",[436,568,569],{},"ai-brief",[436,571,572],{},"references",[436,574,575],{},"import",[436,577,578],{},"export",[436,580,581],{},"derived",". The ",[427,584,585],{"href":380},"capability contract"," lists them with their config.",[588,589,591],"h2",{"id":590},"declare-a-capability","Declare a capability",[418,593,594,595,598,599,602,603,605,606,554,609,612,613,615,616,619,620,623],{},"A host adds a capability as a Feature with ",[436,596,597],{},"blockCapabilities",". The library's own ",[436,600,601],{},"pruefung"," Feature is the worked example: a Typed block has ",[436,604,601],{}," when its Block type lists it, and the Block type names the kinds of Prüfung it takes (",[436,607,608],{},"redaktionell",[436,610,611],{},"fachlich","). The same Feature adds the Block action „Prüfung eintragen“, which ",[436,614,438],{}," the capability. The snippet shows the shape of the shipped ",[436,617,618],{},"pruefungCapability","; import it from ",[436,621,622],{},"@skaile\u002Fforge-editor\u002Fpruefung"," instead of declaring it again.",[625,626,632],"pre",{"className":627,"code":628,"filename":629,"language":630,"meta":631,"style":631},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { z } from 'zod'\nimport type { BlockCapability } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { listsCapability } from '@skaile\u002Fforge-editor\u002Fcore'\n\n\u002F\u002F The config a Block type gives. It is validated when the editor is created.\nconst pruefungConfig = z.strictObject({\n  kinds: z.array(z.string().min(1)).min(1),\n  chain: z.boolean().default(false),\n  lock: z.string().min(1).optional(),\n})\ntype PruefungConfig = z.infer\u003Ctypeof pruefungConfig>\n\n\u002F\u002F The capability only describes: a Typed block has `pruefung` when its Block type lists it. This is the shape of the\n\u002F\u002F shipped `pruefungCapability` (`@skaile\u002Fforge-editor\u002Fpruefung`); the `pruefung` Feature owns the mechanism (records, hash, actions).\nexport const capability: BlockCapability = {\n  id: 'pruefung',\n  configSchema: pruefungConfig,\n  appliesTo: (node, ctx) => listsCapability(ctx.blockTypeOf(node), 'pruefung'),\n  read: (node, ctx) => ctx.configOf\u003CPruefungConfig>(node, 'pruefung') ?? null,\n}\n","docs\u002Fsnippets\u002Fpruefung-capability.ts","ts","",[436,633,634,666,690,710,717,724,752,808,840,875,884,913,918,924,930,950,967,979,1030,1086],{"__ignoreMap":631},[635,636,639,642,646,650,653,656,659,663],"span",{"class":637,"line":638},"line",1,[635,640,575],{"class":641},"s7zQu",[635,643,645],{"class":644},"sMK4o"," {",[635,647,649],{"class":648},"sTEyZ"," z",[635,651,652],{"class":644}," }",[635,654,655],{"class":641}," from",[635,657,658],{"class":644}," '",[635,660,662],{"class":661},"sfazB","zod",[635,664,665],{"class":644},"'\n",[635,667,669,671,674,676,679,681,683,685,688],{"class":637,"line":668},2,[635,670,575],{"class":641},[635,672,673],{"class":641}," type",[635,675,645],{"class":644},[635,677,678],{"class":648}," BlockCapability",[635,680,652],{"class":644},[635,682,655],{"class":641},[635,684,658],{"class":644},[635,686,687],{"class":661},"@skaile\u002Fforge-editor\u002Fcore",[635,689,665],{"class":644},[635,691,693,695,697,700,702,704,706,708],{"class":637,"line":692},3,[635,694,575],{"class":641},[635,696,645],{"class":644},[635,698,699],{"class":648}," listsCapability",[635,701,652],{"class":644},[635,703,655],{"class":641},[635,705,658],{"class":644},[635,707,687],{"class":661},[635,709,665],{"class":644},[635,711,713],{"class":637,"line":712},4,[635,714,716],{"emptyLinePlaceholder":715},true,"\n",[635,718,720],{"class":637,"line":719},5,[635,721,723],{"class":722},"sHwdD","\u002F\u002F The config a Block type gives. It is validated when the editor is created.\n",[635,725,727,731,734,737,739,742,746,749],{"class":637,"line":726},6,[635,728,730],{"class":729},"spNyl","const",[635,732,733],{"class":648}," pruefungConfig ",[635,735,736],{"class":644},"=",[635,738,649],{"class":648},[635,740,741],{"class":644},".",[635,743,745],{"class":744},"s2Zo4","strictObject",[635,747,748],{"class":648},"(",[635,750,751],{"class":644},"{\n",[635,753,755,759,762,764,766,769,772,774,777,780,782,785,787,791,794,796,798,800,802,805],{"class":637,"line":754},7,[635,756,758],{"class":757},"swJcz","  kinds",[635,760,761],{"class":644},":",[635,763,649],{"class":648},[635,765,741],{"class":644},[635,767,768],{"class":744},"array",[635,770,771],{"class":648},"(z",[635,773,741],{"class":644},[635,775,776],{"class":744},"string",[635,778,779],{"class":648},"()",[635,781,741],{"class":644},[635,783,784],{"class":744},"min",[635,786,748],{"class":648},[635,788,790],{"class":789},"sbssI","1",[635,792,793],{"class":648},"))",[635,795,741],{"class":644},[635,797,784],{"class":744},[635,799,748],{"class":648},[635,801,790],{"class":789},[635,803,804],{"class":648},")",[635,806,807],{"class":644},",\n",[635,809,811,814,816,818,820,823,825,827,830,832,836,838],{"class":637,"line":810},8,[635,812,813],{"class":757},"  chain",[635,815,761],{"class":644},[635,817,649],{"class":648},[635,819,741],{"class":644},[635,821,822],{"class":744},"boolean",[635,824,779],{"class":648},[635,826,741],{"class":644},[635,828,829],{"class":744},"default",[635,831,748],{"class":648},[635,833,835],{"class":834},"sfNiH","false",[635,837,804],{"class":648},[635,839,807],{"class":644},[635,841,843,846,848,850,852,854,856,858,860,862,864,866,868,871,873],{"class":637,"line":842},9,[635,844,845],{"class":757},"  lock",[635,847,761],{"class":644},[635,849,649],{"class":648},[635,851,741],{"class":644},[635,853,776],{"class":744},[635,855,779],{"class":648},[635,857,741],{"class":644},[635,859,784],{"class":744},[635,861,748],{"class":648},[635,863,790],{"class":789},[635,865,804],{"class":648},[635,867,741],{"class":644},[635,869,870],{"class":744},"optional",[635,872,779],{"class":648},[635,874,807],{"class":644},[635,876,878,881],{"class":637,"line":877},10,[635,879,880],{"class":644},"}",[635,882,883],{"class":648},")\n",[635,885,887,890,894,897,899,901,904,907,910],{"class":637,"line":886},11,[635,888,889],{"class":729},"type",[635,891,893],{"class":892},"sBMFI"," PruefungConfig",[635,895,896],{"class":644}," =",[635,898,649],{"class":892},[635,900,741],{"class":644},[635,902,903],{"class":892},"infer",[635,905,906],{"class":644},"\u003Ctypeof",[635,908,909],{"class":648}," pruefungConfig",[635,911,912],{"class":644},">\n",[635,914,916],{"class":637,"line":915},12,[635,917,716],{"emptyLinePlaceholder":715},[635,919,921],{"class":637,"line":920},13,[635,922,923],{"class":722},"\u002F\u002F The capability only describes: a Typed block has `pruefung` when its Block type lists it. This is the shape of the\n",[635,925,927],{"class":637,"line":926},14,[635,928,929],{"class":722},"\u002F\u002F shipped `pruefungCapability` (`@skaile\u002Fforge-editor\u002Fpruefung`); the `pruefung` Feature owns the mechanism (records, hash, actions).\n",[635,931,933,935,938,941,943,945,947],{"class":637,"line":932},15,[635,934,578],{"class":641},[635,936,937],{"class":729}," const",[635,939,940],{"class":648}," capability",[635,942,761],{"class":644},[635,944,678],{"class":892},[635,946,896],{"class":644},[635,948,949],{"class":644}," {\n",[635,951,953,956,958,960,962,965],{"class":637,"line":952},16,[635,954,955],{"class":757},"  id",[635,957,761],{"class":644},[635,959,658],{"class":644},[635,961,601],{"class":661},[635,963,964],{"class":644},"'",[635,966,807],{"class":644},[635,968,970,973,975,977],{"class":637,"line":969},17,[635,971,972],{"class":757},"  configSchema",[635,974,761],{"class":644},[635,976,909],{"class":648},[635,978,807],{"class":644},[635,980,982,985,987,990,994,997,1000,1002,1005,1007,1010,1012,1015,1018,1020,1022,1024,1026,1028],{"class":637,"line":981},18,[635,983,984],{"class":744},"  appliesTo",[635,986,761],{"class":644},[635,988,989],{"class":644}," (",[635,991,993],{"class":992},"sHdIc","node",[635,995,996],{"class":644},",",[635,998,999],{"class":992}," ctx",[635,1001,804],{"class":644},[635,1003,1004],{"class":729}," =>",[635,1006,699],{"class":744},[635,1008,1009],{"class":648},"(ctx",[635,1011,741],{"class":644},[635,1013,1014],{"class":744},"blockTypeOf",[635,1016,1017],{"class":648},"(node)",[635,1019,996],{"class":644},[635,1021,658],{"class":644},[635,1023,601],{"class":661},[635,1025,964],{"class":644},[635,1027,804],{"class":648},[635,1029,807],{"class":644},[635,1031,1033,1036,1038,1040,1042,1044,1046,1048,1050,1052,1054,1057,1060,1063,1066,1069,1071,1073,1075,1077,1080,1083],{"class":637,"line":1032},19,[635,1034,1035],{"class":744},"  read",[635,1037,761],{"class":644},[635,1039,989],{"class":644},[635,1041,993],{"class":992},[635,1043,996],{"class":644},[635,1045,999],{"class":992},[635,1047,804],{"class":644},[635,1049,1004],{"class":729},[635,1051,999],{"class":648},[635,1053,741],{"class":644},[635,1055,1056],{"class":744},"configOf",[635,1058,1059],{"class":644},"\u003C",[635,1061,1062],{"class":892},"PruefungConfig",[635,1064,1065],{"class":644},">",[635,1067,1068],{"class":648},"(node",[635,1070,996],{"class":644},[635,1072,658],{"class":644},[635,1074,601],{"class":661},[635,1076,964],{"class":644},[635,1078,1079],{"class":648},") ",[635,1081,1082],{"class":644},"??",[635,1084,1085],{"class":644}," null,\n",[635,1087,1089],{"class":637,"line":1088},20,[635,1090,1091],{"class":644},"}\n",[418,1093,1094],{},"The members of the descriptor:",[1096,1097,1098,1112,1144,1150,1160],"ul",{},[1099,1100,1101,1104,1105,1107,1108,1111],"li",{},[436,1102,1103],{},"id"," is unique across the preset. Block types and ",[436,1106,438],{}," entries name it. A Feature may not use the id of a built-in capability, and two Features may not declare the same id: ",[436,1109,1110],{},"defineEditor"," throws.",[1099,1113,1114,1117,1118,1120,1121,1124,1125,1128,1129,1132,1133,1136,1137,1139,1140,1143],{},[436,1115,1116],{},"appliesTo(node, ctx)"," decides whether ",[436,1119,993],{}," has the capability. ",[436,1122,1123],{},"listsCapability(ctx.blockTypeOf(node), id)"," answers \"the Block type lists it\". The result is memoised per node type and Block type id, so the predicate may read only the node type (its spec and flags), ",[436,1126,1127],{},"ctx.blockTypeId"," and the Block type's config (",[436,1130,1131],{},"ctx.configOf","). A capability that must read an attribute of the node itself sets ",[436,1134,1135],{},"perNode: true"," and keeps the check a constant-time attribute read (",[436,1138,581],{}," reads ",[436,1141,1142],{},"meta.derivation"," this way).",[1099,1145,1146,1149],{},[436,1147,1148],{},"configSchema"," is a zod schema for the config a Block type gives. Without it the capability takes no config and a Block type that gives one is refused.",[1099,1151,1152,1155,1156,1159],{},[436,1153,1154],{},"read(node, ctx)"," returns what the Block holds for the capability, or ",[436,1157,1158],{},"null",": the Source media child, the Basket id, the Bibliographic record. It runs only for Blocks that have the capability and is not memoised.",[1099,1161,1162,1165,1166,554,1169,1172],{},[436,1163,1164],{},"storage"," describes where the data lives (",[436,1167,1168],{},"metaKeys",[436,1170,1171],{},"childTypes","), so conversion, Markdown and copy can treat it the same way. It is descriptive only.",[418,1174,1175,1178,1179,1182],{},[436,1176,1177],{},"appliesTo"," answers \"does a Block of this type support it\". What a single Block holds is Block contents, and ",[436,1180,1181],{},"read"," returns it. Keep the two apart.",[588,1184,1186,1187],{"id":1185},"gate-a-block-action-with-requires","Gate a Block action with ",[436,1188,438],{},[418,1190,1191,1194,1195,1198,1199,1202,1203,1205,1206,1209,1210,1214,1215,1218,1219,741],{},[436,1192,1193],{},"BlockAction.requires"," lists capability ids. The action is hidden on a Block that lacks one of them, and ",[436,1196,1197],{},"blockActionsOf"," throws when an id is declared by no Feature. It replaces node-name and Block-type-name checks in ",[436,1200,1201],{},"isVisible",". ",[436,1204,442],{}," is the second, independent gate: an action shows when the Block has every required capability ",[422,1207,1208],{},"and"," its place in the document has the ability (",[427,1211,1213],{"href":1212},"#abilities","Abilities","). ",[436,1216,1217],{},"blockTypes"," limits an action to named Block types and is only for an action that is truly specific to a type; if the action is about what a Block can do, use ",[436,1220,438],{},[588,1222,1213],{"id":513},[418,1224,1225,1226,1228,1229,1232,1233,1236,1237,1240,1241,1244,1245,1248,1249,1252,1253,1255,1256,554,1259,1262,1263,1265],{},"An ability is a plain string id (",[436,1227,509],{}," in ",[436,1230,1231],{},"@skaile\u002Fforge-editor\u002Fcore\u002Fschema",", or your own). Which abilities hold at a position follows from the nodes around it: the set starts with ",[436,1234,1235],{},"abilities.root"," (default ",[436,1238,1239],{},"ROOT_ABILITIES","), then every ancestor from the outside in adds its ",[436,1242,1243],{},"grants"," and removes its ",[436,1246,1247],{},"revokes",", and the innermost node finally adds its ",[436,1250,1251],{},"own",". A code block revokes marks and headings, media and the title row revoke text editing, and a Typed block's ",[436,1254,1251],{}," abilities (",[436,1257,1258],{},"composite.meta",[436,1260,1261],{},"composite.derive",", …) hold on the block itself, not on a paragraph inside it. A rule may be a function of the node, so it can read the node's attributes. Host rules passed through the ",[436,1264,513],{}," prop replace a node's own rule; the prop is read once at mount.",[418,1267,1268],{},"One ability gates many things. The editor checks it for:",[448,1270,1271,1284],{},[451,1272,1273],{},[454,1274,1275,1278,1281],{},[457,1276,1277],{},"Item",[457,1279,1280],{},"Field",[457,1282,1283],{},"Effect where the ability is missing",[467,1285,1286,1306,1325,1341,1354],{},[454,1287,1288,1295,1300],{},[472,1289,1290,1291,1294],{},"Toolbar and ",[436,1292,1293],{},"\u002F"," entries",[472,1296,1297],{},[436,1298,1299],{},"CommandDef.ability",[472,1301,1302,1303,1305],{},"disabled (toolbar) or not listed (",[436,1304,1293],{}," menu)",[454,1307,1308,1317,1322],{},[472,1309,1310,1293,1313,1316],{},[436,1311,1312],{},"Mod-",[436,1314,1315],{},"Alt-"," shortcuts and input rules of a node or mark type",[472,1318,1319],{},[436,1320,1321],{},"TYPE_ABILITIES",[472,1323,1324],{},"the key is swallowed; the typed text stays literal",[454,1326,1327,1330,1338],{},[472,1328,1329],{},"Block actions and derive methods",[472,1331,1332,554,1335],{},[436,1333,1334],{},"BlockAction.ability",[436,1336,1337],{},"DeriveMethod.ability",[472,1339,1340],{},"hidden",[454,1342,1343,1346,1351],{},[472,1344,1345],{},"„Umwandeln in …“ targets",[472,1347,1348,1350],{},[436,1349,1321],{}," of the target type",[472,1352,1353],{},"not offered",[454,1355,1356,1362,1373],{},[472,1357,1358,1361],{},[436,1359,1360],{},"@"," mentions, block references, AI rewrite and autocomplete",[472,1363,1364,554,1367,554,1370],{},[436,1365,1366],{},"insert.mention",[436,1368,1369],{},"insert.reference",[436,1371,1372],{},"ai.*",[472,1374,1375],{},"the popup, menu or ghost text does not open",[418,1377,1378,1379,1382,1383,1386,1387,1389,1390,1393,1394,1396,1397,989,1400,443],{},"An ability decides what the editor ",[422,1380,1381],{},"offers",", not what may be ",[422,1384,1385],{},"written",". Pasted and dropped content, collaborators' changes and commands called from code are not checked, plain typing and Backspace have no ability, and the editor knows no users: a host that wants per-role abilities passes a different ",[436,1388,513],{}," prop per mount. To refuse a change, use a ",[436,1391,1392],{},"transactionGuards"," contribution (",[427,1395,357],{"href":358},"); to make a whole document read-only for a user, use ",[436,1398,1399],{},"authorize",[427,1401,1402],{"href":196},"Editor ports",[588,1404,1406],{"id":1405},"let-a-block-type-opt-in","Let a Block type opt in",[418,1408,1409,1410,1412,1413,443],{},"A Block type lists the capability with its config. The Block type goes through the ",[436,1411,1217],{}," option of the composites feature (",[427,1414,1415],{"href":166},"Block types",[625,1417,1420],{"className":627,"code":1418,"filename":1419,"language":630,"meta":631,"style":631},"import { compositeFeature } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue'\nimport { type BlockType, defaultBlockTypes } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema'\nimport { coreContentFeature, coreUiFeature, createTranslator, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { pruefungFeature } from '@skaile\u002Fforge-editor\u002Fpruefung'\n\n\u002F\u002F A Block type opts into the capability and configures it.\nconst contract: BlockType = {\n  id: 'contract',\n  label: 'Vertrag',\n  icon: 'i-lucide-file-signature',\n  capabilities: [\n    { id: 'container', config: { accepts: 'all' } },\n    { id: 'pruefung', config: { kinds: ['redaktionell', 'fachlich'] } },\n  ],\n}\n\nconst blockTypes = [...defaultBlockTypes(createTranslator('de')), contract]\n\n\u002F\u002F A Block type that lists a capability no Feature declares throws when the editor is created; so does a block action that\n\u002F\u002F `requires` an undeclared id, when the actions are collected.\nexport const preset = defineEditor({\n  features: [\n    coreContentFeature(),\n    coreUiFeature(),\n    compositeFeature({ blockTypes }),\n    pruefungFeature(),\n  ],\n})\n","docs\u002Fsnippets\u002Fpruefung-preset.ts",[436,1421,1422,1442,1469,1503,1522,1526,1531,1546,1561,1577,1593,1603,1645,1696,1703,1707,1711,1749,1753,1758,1763,1781,1791,1801,1811,1830,1840,1847],{"__ignoreMap":631},[635,1423,1424,1426,1428,1431,1433,1435,1437,1440],{"class":637,"line":638},[635,1425,575],{"class":641},[635,1427,645],{"class":644},[635,1429,1430],{"class":648}," compositeFeature",[635,1432,652],{"class":644},[635,1434,655],{"class":641},[635,1436,658],{"class":644},[635,1438,1439],{"class":661},"@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue",[635,1441,665],{"class":644},[635,1443,1444,1446,1448,1450,1453,1455,1458,1460,1462,1464,1467],{"class":637,"line":668},[635,1445,575],{"class":641},[635,1447,645],{"class":644},[635,1449,673],{"class":641},[635,1451,1452],{"class":648}," BlockType",[635,1454,996],{"class":644},[635,1456,1457],{"class":648}," defaultBlockTypes",[635,1459,652],{"class":644},[635,1461,655],{"class":641},[635,1463,658],{"class":644},[635,1465,1466],{"class":661},"@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema",[635,1468,665],{"class":644},[635,1470,1471,1473,1475,1478,1480,1483,1485,1488,1490,1493,1495,1497,1499,1501],{"class":637,"line":692},[635,1472,575],{"class":641},[635,1474,645],{"class":644},[635,1476,1477],{"class":648}," coreContentFeature",[635,1479,996],{"class":644},[635,1481,1482],{"class":648}," coreUiFeature",[635,1484,996],{"class":644},[635,1486,1487],{"class":648}," createTranslator",[635,1489,996],{"class":644},[635,1491,1492],{"class":648}," defineEditor",[635,1494,652],{"class":644},[635,1496,655],{"class":641},[635,1498,658],{"class":644},[635,1500,687],{"class":661},[635,1502,665],{"class":644},[635,1504,1505,1507,1509,1512,1514,1516,1518,1520],{"class":637,"line":712},[635,1506,575],{"class":641},[635,1508,645],{"class":644},[635,1510,1511],{"class":648}," pruefungFeature",[635,1513,652],{"class":644},[635,1515,655],{"class":641},[635,1517,658],{"class":644},[635,1519,622],{"class":661},[635,1521,665],{"class":644},[635,1523,1524],{"class":637,"line":719},[635,1525,716],{"emptyLinePlaceholder":715},[635,1527,1528],{"class":637,"line":726},[635,1529,1530],{"class":722},"\u002F\u002F A Block type opts into the capability and configures it.\n",[635,1532,1533,1535,1538,1540,1542,1544],{"class":637,"line":754},[635,1534,730],{"class":729},[635,1536,1537],{"class":648}," contract",[635,1539,761],{"class":644},[635,1541,1452],{"class":892},[635,1543,896],{"class":644},[635,1545,949],{"class":644},[635,1547,1548,1550,1552,1554,1557,1559],{"class":637,"line":810},[635,1549,955],{"class":757},[635,1551,761],{"class":644},[635,1553,658],{"class":644},[635,1555,1556],{"class":661},"contract",[635,1558,964],{"class":644},[635,1560,807],{"class":644},[635,1562,1563,1566,1568,1570,1573,1575],{"class":637,"line":842},[635,1564,1565],{"class":757},"  label",[635,1567,761],{"class":644},[635,1569,658],{"class":644},[635,1571,1572],{"class":661},"Vertrag",[635,1574,964],{"class":644},[635,1576,807],{"class":644},[635,1578,1579,1582,1584,1586,1589,1591],{"class":637,"line":877},[635,1580,1581],{"class":757},"  icon",[635,1583,761],{"class":644},[635,1585,658],{"class":644},[635,1587,1588],{"class":661},"i-lucide-file-signature",[635,1590,964],{"class":644},[635,1592,807],{"class":644},[635,1594,1595,1598,1600],{"class":637,"line":886},[635,1596,1597],{"class":757},"  capabilities",[635,1599,761],{"class":644},[635,1601,1602],{"class":648}," [\n",[635,1604,1605,1608,1611,1613,1615,1617,1619,1621,1624,1626,1628,1631,1633,1635,1638,1640,1642],{"class":637,"line":915},[635,1606,1607],{"class":644},"    {",[635,1609,1610],{"class":757}," id",[635,1612,761],{"class":644},[635,1614,658],{"class":644},[635,1616,545],{"class":661},[635,1618,964],{"class":644},[635,1620,996],{"class":644},[635,1622,1623],{"class":757}," config",[635,1625,761],{"class":644},[635,1627,645],{"class":644},[635,1629,1630],{"class":757}," accepts",[635,1632,761],{"class":644},[635,1634,658],{"class":644},[635,1636,1637],{"class":661},"all",[635,1639,964],{"class":644},[635,1641,652],{"class":644},[635,1643,1644],{"class":644}," },\n",[635,1646,1647,1649,1651,1653,1655,1657,1659,1661,1663,1665,1667,1670,1672,1675,1677,1679,1681,1683,1685,1687,1689,1692,1694],{"class":637,"line":920},[635,1648,1607],{"class":644},[635,1650,1610],{"class":757},[635,1652,761],{"class":644},[635,1654,658],{"class":644},[635,1656,601],{"class":661},[635,1658,964],{"class":644},[635,1660,996],{"class":644},[635,1662,1623],{"class":757},[635,1664,761],{"class":644},[635,1666,645],{"class":644},[635,1668,1669],{"class":757}," kinds",[635,1671,761],{"class":644},[635,1673,1674],{"class":648}," [",[635,1676,964],{"class":644},[635,1678,608],{"class":661},[635,1680,964],{"class":644},[635,1682,996],{"class":644},[635,1684,658],{"class":644},[635,1686,611],{"class":661},[635,1688,964],{"class":644},[635,1690,1691],{"class":648},"] ",[635,1693,880],{"class":644},[635,1695,1644],{"class":644},[635,1697,1698,1701],{"class":637,"line":926},[635,1699,1700],{"class":648},"  ]",[635,1702,807],{"class":644},[635,1704,1705],{"class":637,"line":932},[635,1706,1091],{"class":644},[635,1708,1709],{"class":637,"line":952},[635,1710,716],{"emptyLinePlaceholder":715},[635,1712,1713,1715,1718,1720,1722,1725,1728,1730,1733,1735,1737,1740,1742,1744,1746],{"class":637,"line":969},[635,1714,730],{"class":729},[635,1716,1717],{"class":648}," blockTypes ",[635,1719,736],{"class":644},[635,1721,1674],{"class":648},[635,1723,1724],{"class":644},"...",[635,1726,1727],{"class":744},"defaultBlockTypes",[635,1729,748],{"class":648},[635,1731,1732],{"class":744},"createTranslator",[635,1734,748],{"class":648},[635,1736,964],{"class":644},[635,1738,1739],{"class":661},"de",[635,1741,964],{"class":644},[635,1743,793],{"class":648},[635,1745,996],{"class":644},[635,1747,1748],{"class":648}," contract]\n",[635,1750,1751],{"class":637,"line":981},[635,1752,716],{"emptyLinePlaceholder":715},[635,1754,1755],{"class":637,"line":1032},[635,1756,1757],{"class":722},"\u002F\u002F A Block type that lists a capability no Feature declares throws when the editor is created; so does a block action that\n",[635,1759,1760],{"class":637,"line":1088},[635,1761,1762],{"class":722},"\u002F\u002F `requires` an undeclared id, when the actions are collected.\n",[635,1764,1766,1768,1770,1773,1775,1777,1779],{"class":637,"line":1765},21,[635,1767,578],{"class":641},[635,1769,937],{"class":729},[635,1771,1772],{"class":648}," preset ",[635,1774,736],{"class":644},[635,1776,1492],{"class":744},[635,1778,748],{"class":648},[635,1780,751],{"class":644},[635,1782,1784,1787,1789],{"class":637,"line":1783},22,[635,1785,1786],{"class":757},"  features",[635,1788,761],{"class":644},[635,1790,1602],{"class":648},[635,1792,1794,1797,1799],{"class":637,"line":1793},23,[635,1795,1796],{"class":744},"    coreContentFeature",[635,1798,779],{"class":648},[635,1800,807],{"class":644},[635,1802,1804,1807,1809],{"class":637,"line":1803},24,[635,1805,1806],{"class":744},"    coreUiFeature",[635,1808,779],{"class":648},[635,1810,807],{"class":644},[635,1812,1814,1817,1819,1822,1824,1826,1828],{"class":637,"line":1813},25,[635,1815,1816],{"class":744},"    compositeFeature",[635,1818,748],{"class":648},[635,1820,1821],{"class":644},"{",[635,1823,1717],{"class":648},[635,1825,880],{"class":644},[635,1827,804],{"class":648},[635,1829,807],{"class":644},[635,1831,1833,1836,1838],{"class":637,"line":1832},26,[635,1834,1835],{"class":744},"    pruefungFeature",[635,1837,779],{"class":648},[635,1839,807],{"class":644},[635,1841,1843,1845],{"class":637,"line":1842},27,[635,1844,1700],{"class":648},[635,1846,807],{"class":644},[635,1848,1850,1852],{"class":637,"line":1849},28,[635,1851,880],{"class":644},[635,1853,883],{"class":648},[418,1855,1856,1857,1859,1860,1228,1863,741],{},"A Block that does not have the capability gets no „Prüfung eintragen“ button. A Typed block of the type ",[436,1858,1556],{}," gets it, with the config ",[436,1861,1862],{},"{ kinds: ['redaktionell', 'fachlich'] }",[436,1864,1865],{},"capabilityConfigOf",[588,1867,1869],{"id":1868},"read-a-capability-at-runtime","Read a capability at runtime",[418,1871,1872],{},"All of these take the editor, because the answer depends on the editor's own Block types:",[448,1874,1875,1885],{},[451,1876,1877],{},[454,1878,1879,1882],{},[457,1880,1881],{},"Function",[457,1883,1884],{},"Returns",[467,1886,1887,1903,1917,1930],{},[454,1888,1889,1894],{},[472,1890,1891],{},[436,1892,1893],{},"capabilitiesOf(editor, node)",[472,1895,1896,1897,1899,1900,804],{},"the ids of the capabilities ",[436,1898,993],{}," has (",[436,1901,1902],{},"ReadonlySet\u003Cstring>",[454,1904,1905,1910],{},[472,1906,1907],{},[436,1908,1909],{},"capabilitiesAt(editor, pos)",[472,1911,1912,1913,1916],{},"the same for the Block at ",[436,1914,1915],{},"pos","; empty where no node starts",[454,1918,1919,1924],{},[472,1920,1921],{},[436,1922,1923],{},"capabilityConfigOf(editor, node, id)",[472,1925,1926,1927],{},"the config the Block type gives the capability, or ",[436,1928,1929],{},"undefined",[454,1931,1932,1937],{},[472,1933,1934],{},[436,1935,1936],{},"capabilityDataOf(editor, node, id)",[472,1938,1939,1940,1942,1943,1945],{},"what ",[436,1941,1181],{}," returns, or ",[436,1944,1158],{}," when the Block lacks the capability or holds nothing",[418,1947,1948,1949,1951,1952,1955,1956,1959,1960,1963,1964,443],{},"They are exported from ",[436,1950,687],{}," and run without a framework. The preset keeps the merged registry as ",[436,1953,1954],{},"preset.capabilities","; pass it to ",[436,1957,1958],{},"parseBlockTypes"," as ",[436,1961,1962],{},"registry"," when a Block type file must name your capabilities (",[427,1965,1415],{"href":1966},"\u002Fguides\u002Fblock-types#block-types-as-json",[588,1968,1970],{"id":1969},"keep-a-capability-small","Keep a capability small",[418,1972,1973,1974,554,1977,554,1980,1983,1984,1986,1987,1989,1990,1993],{},"A capability stays a descriptor plus a storage contract. If it needs a node, a node view or a settings tab, that belongs to a Feature (",[436,1975,1976],{},"extensions",[436,1978,1979],{},"overlays",[436,1981,1982],{},"settingsTabs","), and the capability only says that the Block has it. Blocks that are no Typed blocks can have a capability too, but a host block that wants ",[436,1985,549],{}," or ",[436,1988,553],{}," must declare the chrome and the ",[436,1991,1992],{},"meta"," attribute itself: the capability tells the UI what to expect, not how to build the node.",[1995,1996,1997],"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 .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 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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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}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);}",{"title":631,"searchDepth":668,"depth":668,"links":1999},[2000,2001,2003,2004,2005,2006],{"id":590,"depth":668,"text":591},{"id":1185,"depth":668,"text":2002},"Gate a Block action with requires",{"id":513,"depth":668,"text":1213},{"id":1405,"depth":668,"text":1406},{"id":1868,"depth":668,"text":1869},{"id":1969,"depth":668,"text":1970},"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.","md",null,{},{"icon":163},{"title":160,"description":2007},"w3RSM2ZSFySG0zpsEy5RmQ0yqtdC_8X_iS_fJBMWyPc",[2015,2017],{"title":155,"path":156,"stem":157,"description":2016,"icon":158,"children":-1},"Work on a tree of Typed blocks: colour baskets and hidden titles, splitting by hand, by length or with AI, outline cleanup, focus and basket filter in the tree, and block transfer between two editors.",{"title":165,"path":166,"stem":167,"description":2018,"icon":168,"children":-1},"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.",1793219826073]