[{"data":1,"prerenderedAt":1617},["ShallowReactive",2],{"navigation_docs":3,"-guides-pdf-viewer":412,"-guides-pdf-viewer-surround":1612},[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":262,"body":414,"description":1605,"extension":1606,"links":1607,"meta":1608,"navigation":1609,"path":263,"seo":1610,"stem":264,"__hash__":1611},"docs\u002F3.guides\u002F43.pdf-viewer.md",{"type":415,"value":416,"toc":1599},"minimark",[417,444,565,570,613,624,655,676,680,941,944,1014,1032,1036,1055,1084,1088,1099,1434,1441,1447,1595],[418,419,420,421,425,426,430,431,434,435,439,440,443],"p",{},"The add-on ",[422,423,424],"code",{},"@skaile\u002Fforge-editor-pdf-viewer"," shows a PDF next to the text that cites it. A text selection in the PDF becomes an ",[427,428,429],"strong",{},"anchor",": the page, the area on the page and the quoted words. The button „Zitat anlegen“ turns the anchor into a ",[422,432,433],{},"quote"," Typed block that is ",[436,437,438],"a",{"href":171},"derived"," from the PDF. A click on a ",[436,441,442],{"href":230},"reference chip"," with a page locator scrolls the viewer to the passage.",[445,446,447,463],"table",{},[448,449,450],"thead",{},[451,452,453,457,460],"tr",{},[454,455,456],"th",{},"Piece",[454,458,459],{},"What it does",[454,461,462],{},"Where",[464,465,466,488,501,520,540,553],"tbody",{},[451,467,468,474,481],{},[469,470,471],"td",{},[422,472,473],{},"source-anchor",[469,475,476,477,480],{},"the ",[436,478,479],{"href":176},"Block property"," type of a passage of a PDF",[469,482,483,484,487],{},"library (",[422,485,486],{},"@skaile\u002Fforge-editor\u002Fcore",")",[451,489,490,495,498],{},[469,491,492],{},[422,493,494],{},"page=\u003Cn>&anchor=\u003Cbase64 JSON>",[469,496,497],{},"the reference locator that names such a passage",[469,499,500],{},"library",[451,502,503,508,517],{},[469,504,505],{},[422,506,507],{},"quoteBlockTypes(locale)",[469,509,510,511,513,514,516],{},"the Block type ",[422,512,433],{}," with one ",[422,515,473],{}," property",[469,518,519],{},"editor and server",[451,521,522,531,537],{},[469,523,524,527,528],{},[422,525,526],{},"anchorOfSelection",", ",[422,529,530],{},"quoteBlockOf",[469,532,533,534,536],{},"pure: selection to anchor, anchor to ",[422,535,433],{}," block",[469,538,539],{},"anywhere",[451,541,542,547,550],{},[469,543,544],{},[422,545,546],{},"pdfViewerFeature()",[469,548,549],{},"the viewer in the inspector of a Typed block that keeps a PDF",[469,551,552],{},"editor",[451,554,555,560,563],{},[469,556,557],{},[422,558,559],{},"PdfViewer",[469,561,562],{},"the viewer as a component for any page",[469,564,552],{},[566,567,569],"h2",{"id":568},"the-source-anchor-property-and-the-locator","The source-anchor property and the locator",[418,571,572,573,575,576,579,580,583,584,587,588,527,591,527,594,527,597,600,601,604,605,608,609,612],{},"A ",[422,574,473],{}," value is ",[422,577,578],{},"{ page, rects, quote: { exact, prefix?, suffix? } }",". ",[422,581,582],{},"page"," counts from 1. ",[422,585,586],{},"rects"," are fractions of the page (",[422,589,590],{},"x",[422,592,593],{},"y",[422,595,596],{},"w",[422,598,599],{},"h"," from 0 to 1, origin top left), so the passage stays right at any zoom. ",[422,602,603],{},"quote.exact"," is the selected text with white space cut to single blanks; ",[422,606,607],{},"prefix"," and ",[422,610,611],{},"suffix"," are a little text around it.",[418,614,615,616,619,620,623],{},"The property kind orders and compares by page, reads as the quoted text and groups by page (",[422,617,618],{},"PROPERTY_KINDS['source-anchor']","), so a ",[436,621,622],{"href":239},"query"," can filter quotes by page or by words. The properties form shows page and quote read-only. Only the viewer writes the value.",[418,625,626,627,579,630,633,634,637,638,641,642,645,646,527,648,527,651,654],{},"The same passage as text is the locator of a reference chip: ",[422,628,629],{},"page=12&anchor=\u003Cbase64url JSON>",[422,631,632],{},"anchorLocatorOf(anchor)"," writes it and ",[422,635,636],{},"parseAnchorLocator(text)"," reads it back (",[422,639,640],{},"null"," when the text is not an anchor or its page differs from the locator's). Chips and backlinks show it as ",[422,643,644],{},"S. 12","; the long base64 stays out of sight. A plain locator (",[422,647,644],{},[422,649,650],{},"12",[422,652,653],{},"3:07",") works as before.",[418,656,657,658,661,662,665,666,661,669,671,672,675],{},"When the editor reveals a source at an anchor locator, it sends two DOM events to the node view of the PDF's file block: ",[422,659,660],{},"sk-reveal-page"," (",[422,663,664],{},"detail"," is the page) and ",[422,667,668],{},"sk-reveal-anchor",[422,670,664],{}," is the ",[422,673,674],{},"SourceAnchor","). The viewer listens to both.",[566,677,679],{"id":678},"install-and-wire","Install and wire",[681,682,687],"pre",{"className":683,"code":684,"language":685,"meta":686,"style":686},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defaultBlockTypes } from '@skaile\u002Fforge-editor\u002Fcomposites'\nimport { quoteBlockTypes } from '@skaile\u002Fforge-editor-pdf-viewer'\nimport { pdfViewerFeature } from '@skaile\u002Fforge-editor-pdf-viewer\u002Fvue' \u002F\u002F or '\u002Freact'\nimport '@skaile\u002Fforge-editor-pdf-viewer\u002Fstyles\u002Fpdf-viewer.css'\n\nconst editor = composeEditor({\n  content: 'rich',\n  interaction: 'full',\n  \u002F\u002F The Block types of the editor: the built-in ones and `quote`.\n  blockTypes: [...defaultBlockTypes(t), ...quoteBlockTypes('de')],\n  add: [pdfViewerFeature({ workerSrc: '\u002Fpdf.worker.min.mjs' })],\n})\n","ts","",[422,688,689,722,742,768,780,787,810,830,847,853,896,932],{"__ignoreMap":686},[690,691,694,698,702,706,709,712,715,719],"span",{"class":692,"line":693},"line",1,[690,695,697],{"class":696},"s7zQu","import",[690,699,701],{"class":700},"sMK4o"," {",[690,703,705],{"class":704},"sTEyZ"," defaultBlockTypes",[690,707,708],{"class":700}," }",[690,710,711],{"class":696}," from",[690,713,714],{"class":700}," '",[690,716,718],{"class":717},"sfazB","@skaile\u002Fforge-editor\u002Fcomposites",[690,720,721],{"class":700},"'\n",[690,723,725,727,729,732,734,736,738,740],{"class":692,"line":724},2,[690,726,697],{"class":696},[690,728,701],{"class":700},[690,730,731],{"class":704}," quoteBlockTypes",[690,733,708],{"class":700},[690,735,711],{"class":696},[690,737,714],{"class":700},[690,739,424],{"class":717},[690,741,721],{"class":700},[690,743,745,747,749,752,754,756,758,761,764],{"class":692,"line":744},3,[690,746,697],{"class":696},[690,748,701],{"class":700},[690,750,751],{"class":704}," pdfViewerFeature",[690,753,708],{"class":700},[690,755,711],{"class":696},[690,757,714],{"class":700},[690,759,760],{"class":717},"@skaile\u002Fforge-editor-pdf-viewer\u002Fvue",[690,762,763],{"class":700},"'",[690,765,767],{"class":766},"sHwdD"," \u002F\u002F or '\u002Freact'\n",[690,769,771,773,775,778],{"class":692,"line":770},4,[690,772,697],{"class":696},[690,774,714],{"class":700},[690,776,777],{"class":717},"@skaile\u002Fforge-editor-pdf-viewer\u002Fstyles\u002Fpdf-viewer.css",[690,779,721],{"class":700},[690,781,783],{"class":692,"line":782},5,[690,784,786],{"emptyLinePlaceholder":785},true,"\n",[690,788,790,794,797,800,804,807],{"class":692,"line":789},6,[690,791,793],{"class":792},"spNyl","const",[690,795,796],{"class":704}," editor ",[690,798,799],{"class":700},"=",[690,801,803],{"class":802},"s2Zo4"," composeEditor",[690,805,806],{"class":704},"(",[690,808,809],{"class":700},"{\n",[690,811,813,817,820,822,825,827],{"class":692,"line":812},7,[690,814,816],{"class":815},"swJcz","  content",[690,818,819],{"class":700},":",[690,821,714],{"class":700},[690,823,824],{"class":717},"rich",[690,826,763],{"class":700},[690,828,829],{"class":700},",\n",[690,831,833,836,838,840,843,845],{"class":692,"line":832},8,[690,834,835],{"class":815},"  interaction",[690,837,819],{"class":700},[690,839,714],{"class":700},[690,841,842],{"class":717},"full",[690,844,763],{"class":700},[690,846,829],{"class":700},[690,848,850],{"class":692,"line":849},9,[690,851,852],{"class":766},"  \u002F\u002F The Block types of the editor: the built-in ones and `quote`.\n",[690,854,856,859,861,864,867,870,873,876,879,882,884,886,889,891,894],{"class":692,"line":855},10,[690,857,858],{"class":815},"  blockTypes",[690,860,819],{"class":700},[690,862,863],{"class":704}," [",[690,865,866],{"class":700},"...",[690,868,869],{"class":802},"defaultBlockTypes",[690,871,872],{"class":704},"(t)",[690,874,875],{"class":700},",",[690,877,878],{"class":700}," ...",[690,880,881],{"class":802},"quoteBlockTypes",[690,883,806],{"class":704},[690,885,763],{"class":700},[690,887,888],{"class":717},"de",[690,890,763],{"class":700},[690,892,893],{"class":704},")]",[690,895,829],{"class":700},[690,897,899,902,904,906,909,911,914,917,919,921,924,926,928,930],{"class":692,"line":898},11,[690,900,901],{"class":815},"  add",[690,903,819],{"class":700},[690,905,863],{"class":704},[690,907,908],{"class":802},"pdfViewerFeature",[690,910,806],{"class":704},[690,912,913],{"class":700},"{",[690,915,916],{"class":815}," workerSrc",[690,918,819],{"class":700},[690,920,714],{"class":700},[690,922,923],{"class":717},"\u002Fpdf.worker.min.mjs",[690,925,763],{"class":700},[690,927,708],{"class":700},[690,929,893],{"class":704},[690,931,829],{"class":700},[690,933,935,938],{"class":692,"line":934},12,[690,936,937],{"class":700},"}",[690,939,940],{"class":704},")\n",[418,942,943],{},"Give the Block type to the server too, so the schema, the AI chat and the query validation know it:",[681,945,947],{"className":683,"code":946,"language":685,"meta":686,"style":686},"import { quoteBlockTypes } from '@skaile\u002Fforge-editor-pdf-viewer\u002Fserver'\n\n\u002F\u002F installEditorServer({ blockTypes })\nexport const blockTypes = [...serverBlockTypes, ...quoteBlockTypes('de')]\n",[422,948,949,968,972,977],{"__ignoreMap":686},[690,950,951,953,955,957,959,961,963,966],{"class":692,"line":693},[690,952,697],{"class":696},[690,954,701],{"class":700},[690,956,731],{"class":704},[690,958,708],{"class":700},[690,960,711],{"class":696},[690,962,714],{"class":700},[690,964,965],{"class":717},"@skaile\u002Fforge-editor-pdf-viewer\u002Fserver",[690,967,721],{"class":700},[690,969,970],{"class":692,"line":724},[690,971,786],{"emptyLinePlaceholder":785},[690,973,974],{"class":692,"line":744},[690,975,976],{"class":766},"\u002F\u002F installEditorServer({ blockTypes })\n",[690,978,979,982,985,988,990,992,994,997,999,1001,1003,1005,1007,1009,1011],{"class":692,"line":770},[690,980,981],{"class":696},"export",[690,983,984],{"class":792}," const",[690,986,987],{"class":704}," blockTypes ",[690,989,799],{"class":700},[690,991,863],{"class":704},[690,993,866],{"class":700},[690,995,996],{"class":704},"serverBlockTypes",[690,998,875],{"class":700},[690,1000,878],{"class":700},[690,1002,881],{"class":802},[690,1004,806],{"class":704},[690,1006,763],{"class":700},[690,1008,888],{"class":717},[690,1010,763],{"class":700},[690,1012,1013],{"class":704},")]\n",[418,1015,1016,1017,1020,1021,1024,1025,1028,1029,1031],{},"pdfjs needs a worker. By default the viewer loads ",[422,1018,1019],{},"pdf.worker.min.mjs"," of the installed pdfjs version from jsDelivr. A host that cannot reach the CDN serves the file from ",[422,1022,1023],{},"pdfjs-dist\u002Fbuild\u002F"," itself and passes its URL as ",[422,1026,1027],{},"workerSrc"," (feature option, or prop of ",[422,1030,559],{},").",[566,1033,1035],{"id":1034},"the-viewer","The viewer",[418,1037,1038,1040,1041,1044,1045,527,1048,527,1051,1054],{},[422,1039,908],{}," adds a section „PDF-Ansicht“ to the Typed block inspector. It shows for every block whose source (the ",[422,1042,1043],{},"source"," capability: ",[422,1046,1047],{},"paper",[422,1049,1050],{},"book",[422,1052,1053],{},"document",") is a PDF file block. The viewer draws only the pages near the visible part, each as a canvas with a transparent text layer on top, so the text can be selected and searched with the browser.",[1056,1057,1058,1062,1065],"ul",{},[1059,1060,1061],"li",{},"The toolbar has previous and next page, a page field, zoom out and in (50 % to 300 %).",[1059,1063,1064],{},"A reveal of the PDF's block scrolls to the page, or to the first line of the anchor, and marks the anchor's rects for a few seconds. Reveals of other blocks do not move this viewer.",[1059,1066,1067,1069,1070,1073,1074,1076,1077,1080,1081,1083],{},[422,1068,559],{}," takes ",[422,1071,1072],{},"src"," (the URL of the PDF), ",[422,1075,552],{}," (to create quotes and follow reveals) and ",[422,1078,1079],{},"blockId"," (the Typed block that keeps the PDF). Without ",[422,1082,552],{}," it is a plain viewer.",[566,1085,1087],{"id":1086},"create-a-quote","Create a quote",[418,1089,1090,1091,1094,1095,1098],{},"Select text in one page and press ",[427,1092,1093],{},"Zitat anlegen",". The button works when the editor is editable and the PDF is a stored ",[436,1096,1097],{"href":95},"asset"," of a Document. The quote goes right behind the PDF's Typed block and is revealed.",[681,1100,1104],{"className":1101,"code":1102,"language":1103,"meta":686,"style":686},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"type\": \"typedBlock\",\n  \"attrs\": {\n    \"blockType\": \"quote\",\n    \"meta\": {\n      \"anchor\": { \"page\": 12, \"rects\": [{ \"x\": 0.15, \"y\": 0.1, \"w\": 0.5, \"h\": 0.025 }], \"quote\": { \"exact\": \"Der Hund bellt laut.\" } },\n      \"derivation\": { \"from\": { \"asset\": \"\u003Cname>.pdf\" }, \"method\": \"highlight\", \"inputHash\": \"\u003Csha256 of the PDF>\", \"outputHash\": \"\u003Csha256 of the body>\", \"createdAt\": \"…\" }\n    }\n  }\n}\n","json",[422,1105,1106,1110,1133,1147,1168,1181,1304,1419,1424,1429],{"__ignoreMap":686},[690,1107,1108],{"class":692,"line":693},[690,1109,809],{"class":700},[690,1111,1112,1115,1118,1121,1123,1126,1129,1131],{"class":692,"line":724},[690,1113,1114],{"class":700},"  \"",[690,1116,1117],{"class":792},"type",[690,1119,1120],{"class":700},"\"",[690,1122,819],{"class":700},[690,1124,1125],{"class":700}," \"",[690,1127,1128],{"class":717},"typedBlock",[690,1130,1120],{"class":700},[690,1132,829],{"class":700},[690,1134,1135,1137,1140,1142,1144],{"class":692,"line":744},[690,1136,1114],{"class":700},[690,1138,1139],{"class":792},"attrs",[690,1141,1120],{"class":700},[690,1143,819],{"class":700},[690,1145,1146],{"class":700}," {\n",[690,1148,1149,1152,1156,1158,1160,1162,1164,1166],{"class":692,"line":770},[690,1150,1151],{"class":700},"    \"",[690,1153,1155],{"class":1154},"sBMFI","blockType",[690,1157,1120],{"class":700},[690,1159,819],{"class":700},[690,1161,1125],{"class":700},[690,1163,433],{"class":717},[690,1165,1120],{"class":700},[690,1167,829],{"class":700},[690,1169,1170,1172,1175,1177,1179],{"class":692,"line":782},[690,1171,1151],{"class":700},[690,1173,1174],{"class":1154},"meta",[690,1176,1120],{"class":700},[690,1178,819],{"class":700},[690,1180,1146],{"class":700},[690,1182,1183,1186,1189,1191,1193,1195,1197,1199,1201,1203,1206,1208,1210,1212,1214,1216,1219,1221,1224,1226,1228,1231,1233,1235,1237,1239,1241,1244,1246,1248,1250,1252,1254,1257,1259,1261,1263,1265,1267,1270,1273,1275,1277,1279,1281,1283,1285,1288,1290,1292,1294,1297,1299,1301],{"class":692,"line":789},[690,1184,1185],{"class":700},"      \"",[690,1187,429],{"class":1188},"sbssI",[690,1190,1120],{"class":700},[690,1192,819],{"class":700},[690,1194,701],{"class":700},[690,1196,1125],{"class":700},[690,1198,582],{"class":815},[690,1200,1120],{"class":700},[690,1202,819],{"class":700},[690,1204,1205],{"class":1188}," 12",[690,1207,875],{"class":700},[690,1209,1125],{"class":700},[690,1211,586],{"class":815},[690,1213,1120],{"class":700},[690,1215,819],{"class":700},[690,1217,1218],{"class":700}," [{",[690,1220,1125],{"class":700},[690,1222,590],{"class":1223},"su27w",[690,1225,1120],{"class":700},[690,1227,819],{"class":700},[690,1229,1230],{"class":1188}," 0.15",[690,1232,875],{"class":700},[690,1234,1125],{"class":700},[690,1236,593],{"class":1223},[690,1238,1120],{"class":700},[690,1240,819],{"class":700},[690,1242,1243],{"class":1188}," 0.1",[690,1245,875],{"class":700},[690,1247,1125],{"class":700},[690,1249,596],{"class":1223},[690,1251,1120],{"class":700},[690,1253,819],{"class":700},[690,1255,1256],{"class":1188}," 0.5",[690,1258,875],{"class":700},[690,1260,1125],{"class":700},[690,1262,599],{"class":1223},[690,1264,1120],{"class":700},[690,1266,819],{"class":700},[690,1268,1269],{"class":1188}," 0.025",[690,1271,1272],{"class":700}," }],",[690,1274,1125],{"class":700},[690,1276,433],{"class":815},[690,1278,1120],{"class":700},[690,1280,819],{"class":700},[690,1282,701],{"class":700},[690,1284,1125],{"class":700},[690,1286,1287],{"class":1223},"exact",[690,1289,1120],{"class":700},[690,1291,819],{"class":700},[690,1293,1125],{"class":700},[690,1295,1296],{"class":717},"Der Hund bellt laut.",[690,1298,1120],{"class":700},[690,1300,708],{"class":700},[690,1302,1303],{"class":700}," },\n",[690,1305,1306,1308,1311,1313,1315,1317,1319,1322,1324,1326,1328,1330,1332,1334,1336,1338,1341,1343,1346,1348,1351,1353,1355,1357,1360,1362,1364,1366,1369,1371,1373,1375,1378,1380,1382,1384,1387,1389,1391,1393,1396,1398,1400,1402,1405,1407,1409,1411,1414,1416],{"class":692,"line":812},[690,1307,1185],{"class":700},[690,1309,1310],{"class":1188},"derivation",[690,1312,1120],{"class":700},[690,1314,819],{"class":700},[690,1316,701],{"class":700},[690,1318,1125],{"class":700},[690,1320,1321],{"class":815},"from",[690,1323,1120],{"class":700},[690,1325,819],{"class":700},[690,1327,701],{"class":700},[690,1329,1125],{"class":700},[690,1331,1097],{"class":1223},[690,1333,1120],{"class":700},[690,1335,819],{"class":700},[690,1337,1125],{"class":700},[690,1339,1340],{"class":717},"\u003Cname>.pdf",[690,1342,1120],{"class":700},[690,1344,1345],{"class":700}," },",[690,1347,1125],{"class":700},[690,1349,1350],{"class":815},"method",[690,1352,1120],{"class":700},[690,1354,819],{"class":700},[690,1356,1125],{"class":700},[690,1358,1359],{"class":717},"highlight",[690,1361,1120],{"class":700},[690,1363,875],{"class":700},[690,1365,1125],{"class":700},[690,1367,1368],{"class":815},"inputHash",[690,1370,1120],{"class":700},[690,1372,819],{"class":700},[690,1374,1125],{"class":700},[690,1376,1377],{"class":717},"\u003Csha256 of the PDF>",[690,1379,1120],{"class":700},[690,1381,875],{"class":700},[690,1383,1125],{"class":700},[690,1385,1386],{"class":815},"outputHash",[690,1388,1120],{"class":700},[690,1390,819],{"class":700},[690,1392,1125],{"class":700},[690,1394,1395],{"class":717},"\u003Csha256 of the body>",[690,1397,1120],{"class":700},[690,1399,875],{"class":700},[690,1401,1125],{"class":700},[690,1403,1404],{"class":815},"createdAt",[690,1406,1120],{"class":700},[690,1408,819],{"class":700},[690,1410,1125],{"class":700},[690,1412,1413],{"class":717},"…",[690,1415,1120],{"class":700},[690,1417,1418],{"class":700}," }\n",[690,1420,1421],{"class":692,"line":832},[690,1422,1423],{"class":700},"    }\n",[690,1425,1426],{"class":692,"line":849},[690,1427,1428],{"class":700},"  }\n",[690,1430,1431],{"class":692,"line":855},[690,1432,1433],{"class":700},"}\n",[418,1435,1436,1437,1440],{},"The title is the first words of the quote. The body is the quoted text as a block quote and, when the PDF belongs to a Typed block, a reference chip to it whose locator is the anchor: a click on the chip in the quote opens the PDF at the passage. Because the quote has a Derivation, the block shows its origin, the ",[436,1438,1439],{"href":211},"Explore trail"," lists it, and an edit of the body shows as „bearbeitet“.",[418,1442,1443,1446],{},[422,1444,1445],{},"quoteBlockOf(asset, anchor, options)"," builds the same JSON without a viewer: use it in an importer or a server tool.",[681,1448,1450],{"className":683,"code":1449,"language":685,"meta":686,"style":686},"import { anchorOfSelection, quoteBlockOf } from '@skaile\u002Fforge-editor-pdf-viewer\u002Fserver'\n\nconst anchor = anchorOfSelection({ page: 3, box: pageRect, rects: selectionRects, text, pageText })\nif (anchor) editor.commands.insertContent(quoteBlockOf({ name, hash }, anchor, { sourceBlockId: paperId }))\n",[422,1451,1452,1476,1480,1537],{"__ignoreMap":686},[690,1453,1454,1456,1458,1461,1463,1466,1468,1470,1472,1474],{"class":692,"line":693},[690,1455,697],{"class":696},[690,1457,701],{"class":700},[690,1459,1460],{"class":704}," anchorOfSelection",[690,1462,875],{"class":700},[690,1464,1465],{"class":704}," quoteBlockOf",[690,1467,708],{"class":700},[690,1469,711],{"class":696},[690,1471,714],{"class":700},[690,1473,965],{"class":717},[690,1475,721],{"class":700},[690,1477,1478],{"class":692,"line":724},[690,1479,786],{"emptyLinePlaceholder":785},[690,1481,1482,1484,1487,1489,1491,1493,1495,1498,1500,1503,1505,1508,1510,1513,1515,1518,1520,1523,1525,1528,1530,1533,1535],{"class":692,"line":744},[690,1483,793],{"class":792},[690,1485,1486],{"class":704}," anchor ",[690,1488,799],{"class":700},[690,1490,1460],{"class":802},[690,1492,806],{"class":704},[690,1494,913],{"class":700},[690,1496,1497],{"class":815}," page",[690,1499,819],{"class":700},[690,1501,1502],{"class":1188}," 3",[690,1504,875],{"class":700},[690,1506,1507],{"class":815}," box",[690,1509,819],{"class":700},[690,1511,1512],{"class":704}," pageRect",[690,1514,875],{"class":700},[690,1516,1517],{"class":815}," rects",[690,1519,819],{"class":700},[690,1521,1522],{"class":704}," selectionRects",[690,1524,875],{"class":700},[690,1526,1527],{"class":704}," text",[690,1529,875],{"class":700},[690,1531,1532],{"class":704}," pageText ",[690,1534,937],{"class":700},[690,1536,940],{"class":704},[690,1538,1539,1542,1545,1548,1551,1553,1556,1558,1560,1562,1564,1567,1569,1572,1575,1578,1580,1582,1585,1587,1590,1592],{"class":692,"line":770},[690,1540,1541],{"class":696},"if",[690,1543,1544],{"class":704}," (anchor) editor",[690,1546,1547],{"class":700},".",[690,1549,1550],{"class":704},"commands",[690,1552,1547],{"class":700},[690,1554,1555],{"class":802},"insertContent",[690,1557,806],{"class":704},[690,1559,530],{"class":802},[690,1561,806],{"class":704},[690,1563,913],{"class":700},[690,1565,1566],{"class":704}," name",[690,1568,875],{"class":700},[690,1570,1571],{"class":704}," hash ",[690,1573,1574],{"class":700},"},",[690,1576,1577],{"class":704}," anchor",[690,1579,875],{"class":700},[690,1581,701],{"class":700},[690,1583,1584],{"class":815}," sourceBlockId",[690,1586,819],{"class":700},[690,1588,1589],{"class":704}," paperId ",[690,1591,937],{"class":700},[690,1593,1594],{"class":704},"))\n",[1596,1597,1598],"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 .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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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}",{"title":686,"searchDepth":724,"depth":724,"links":1600},[1601,1602,1603,1604],{"id":568,"depth":724,"text":569},{"id":678,"depth":724,"text":679},{"id":1034,"depth":724,"text":1035},{"id":1086,"depth":724,"text":1087},"The add-on @skaile\u002Fforge-editor-pdf-viewer: the source-anchor property, a pdfjs viewer with a text layer, scrolling to a passage on reveal, and „Zitat anlegen“, which creates a quote block derived from the PDF.","md",null,{},{"icon":265},{"title":262,"description":1605},"kFWqMoQHXf2QqZjjHJjaE6977r1fiX2UYBPCgXYc5yY",[1613,1615],{"title":257,"path":258,"stem":259,"description":1614,"icon":260,"children":-1},"The graph route that walks the Edges of the Block index in both directions, the walk's limits, the client call, and the @skaile\u002Fforge-editor-graph add-on that draws the answer with sigma in Vue and React.",{"title":267,"path":268,"stem":269,"description":1616,"icon":270,"children":-1},"The add-on @skaile\u002Fforge-editor-obsidian: importVault plans one Document per note with frontmatter as properties, wikilinks as reference chips and ^id block ids kept; exportVault writes them back; a command uploads a vault to an editor server.",1793178235943]