milkdown_engine 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +15 -0
- data/Rakefile +11 -0
- data/app/assets/javascripts/milkdown_engine/milkdown.min.js +997 -0
- data/app/assets/stylesheets/milkdown_engine/application.css +40 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_AMS-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_AMS-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Bold.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Bold.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Bold.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Italic.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Italic.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Italic.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Main-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-Italic.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-Italic.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Math-Italic.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Script-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Script-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Script-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size1-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size1-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size2-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size2-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size3-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size3-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size4-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size4-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- data/app/assets/stylesheets/milkdown_engine/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- data/app/assets/stylesheets/milkdown_engine/milkdown.css +1 -0
- data/app/controllers/milkdown_engine/application_controller.rb +6 -0
- data/app/helpers/milkdown_engine/application_helper.rb +88 -0
- data/app/javascript/milkdown_engine/controllers/editor_controller.js +122 -0
- data/app/models/milkdown_engine/application_record.rb +7 -0
- data/app/models/milkdown_engine/md_document.rb +104 -0
- data/config/importmap.rb +8 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20260325000000_create_milkdown_engine_md_documents.rb +16 -0
- data/lib/milkdown_engine/engine.rb +46 -0
- data/lib/milkdown_engine/version.rb +5 -0
- data/lib/milkdown_engine/version.rb.erb +5 -0
- data/lib/milkdown_engine.rb +7 -0
- metadata +175 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* MilkdownEngine — Fomantic-UI integration styles.
|
|
2
|
+
*
|
|
3
|
+
* Include both this file AND milkdown_engine/milkdown in your layout:
|
|
4
|
+
*
|
|
5
|
+
* stylesheet_link_tag "milkdown_engine/application"
|
|
6
|
+
* stylesheet_link_tag "milkdown_engine/milkdown"
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* The editor wrapper is a Fomantic segment with Stimulus controller attrs. */
|
|
10
|
+
.milkdown-editor.ui.segment {
|
|
11
|
+
padding: 0;
|
|
12
|
+
position: relative;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.milkdown-editor-label {
|
|
16
|
+
display: block;
|
|
17
|
+
padding: 0.75em 1em 0;
|
|
18
|
+
font-weight: 700;
|
|
19
|
+
font-size: 0.92857143em;
|
|
20
|
+
color: rgba(0, 0, 0, 0.87);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* The inner surface where Crepe mounts the ProseMirror editor. */
|
|
24
|
+
.milkdown-editor-surface {
|
|
25
|
+
min-height: 12rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* When used inside a Fomantic form field, drop the segment border so it
|
|
29
|
+
inherits the field styling instead. */
|
|
30
|
+
.ui.form .field > .milkdown-editor.ui.segment {
|
|
31
|
+
box-shadow: none;
|
|
32
|
+
border: 1px solid rgba(34, 36, 38, 0.15);
|
|
33
|
+
border-radius: 0.28571429rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Read-only state: dim the editor slightly. */
|
|
37
|
+
.milkdown-editor[data-milkdown-engine--editor-readonly-value="true"] {
|
|
38
|
+
opacity: 0.75;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ProseMirror{position:relative}.ProseMirror{word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:"liga" 0}.ProseMirror pre{white-space:pre-wrap}.ProseMirror li{position:relative}.ProseMirror-hideselection *::selection{background:transparent}.ProseMirror-hideselection *::-moz-selection{background:transparent}.ProseMirror-hideselection{caret-color:transparent}.ProseMirror [draggable][contenteditable=false]{user-select:text}.ProseMirror-selectednode{outline:2px solid #8cf}li.ProseMirror-selectednode{outline:none}li.ProseMirror-selectednode:after{content:"";position:absolute;inset:-2px -2px -2px -32px;border:2px solid #8cf;pointer-events:none}img.ProseMirror-separator{display:inline!important;border:none!important;margin:0!important}.milkdown{position:relative}.milkdown *{margin:0;padding:0;box-sizing:border-box}.milkdown button,.milkdown input{border:none;background:none;box-shadow:none}.milkdown button:focus,.milkdown input:focus{outline:none}.milkdown :focus-visible{outline:none}.milkdown{font-family:var(--crepe-font-default);color:var(--crepe-color-on-background);background:var(--crepe-color-background)}.milkdown .milkdown-icon{display:inline-flex;align-items:center;justify-content:center}.milkdown .ProseMirror-focused{outline:none}.milkdown .ProseMirror{padding:60px 120px}.milkdown .ProseMirror *::-moz-selection{background:var(--crepe-color-selected)}.milkdown .ProseMirror *::selection{background:var(--crepe-color-selected)}.milkdown .ProseMirror li.ProseMirror-selectednode{background:var(--crepe-color-selected);outline:none}.milkdown .ProseMirror li.ProseMirror-selectednode ::-moz-selection{background:transparent}.milkdown .ProseMirror li.ProseMirror-selectednode ::selection{background:transparent}.milkdown .ProseMirror li.ProseMirror-selectednode::-moz-selection{background:transparent}.milkdown .ProseMirror li.ProseMirror-selectednode::selection{background:transparent}.milkdown .ProseMirror li.ProseMirror-selectednode:after{all:unset}.milkdown .ProseMirror .ProseMirror-selectednode{background:var(--crepe-color-selected);outline:none;background:color-mix(in srgb,var(--crepe-color-selected),transparent 60%)}.milkdown .ProseMirror .ProseMirror-selectednode ::-moz-selection{background:transparent}.milkdown .ProseMirror .ProseMirror-selectednode ::selection{background:transparent}.milkdown .ProseMirror .ProseMirror-selectednode::-moz-selection{background:transparent}.milkdown .ProseMirror .ProseMirror-selectednode::selection{background:transparent}.milkdown .ProseMirror[data-dragging=true]::-moz-selection,.milkdown .ProseMirror[data-dragging=true] *::-moz-selection{background:transparent}.milkdown .ProseMirror[data-dragging=true] .ProseMirror-selectednode,.milkdown .ProseMirror[data-dragging=true]::selection,.milkdown .ProseMirror[data-dragging=true] *::selection{background:transparent}.milkdown .ProseMirror[data-dragging=true] input::-moz-selection{background:var(--crepe-color-selected)}.milkdown .ProseMirror[data-dragging=true] input::selection{background:var(--crepe-color-selected)}.milkdown .ProseMirror img{vertical-align:bottom;max-width:100%}.milkdown .ProseMirror img.ProseMirror-selectednode{background:none;outline:2px solid var(--crepe-color-primary)}.milkdown .ProseMirror h1,.milkdown .ProseMirror h2,.milkdown .ProseMirror h3,.milkdown .ProseMirror h4,.milkdown .ProseMirror h5,.milkdown .ProseMirror h6{font-family:var(--crepe-font-title);font-weight:400;padding:2px 0}.milkdown .ProseMirror h1{font-size:42px;line-height:50px;margin-top:32px}.milkdown .ProseMirror h2{font-size:36px;line-height:44px;margin-top:28px}.milkdown .ProseMirror h3{font-size:32px;line-height:40px;margin-top:24px}.milkdown .ProseMirror h4{font-size:28px;line-height:36px;margin-top:20px}.milkdown .ProseMirror h5{font-size:24px;line-height:32px;margin-top:16px}.milkdown .ProseMirror h6{font-size:18px;font-weight:700;line-height:28px;margin-top:16px}.milkdown .ProseMirror p{font-size:16px;line-height:24px;padding:4px 0}.milkdown .ProseMirror code{color:var(--crepe-color-inline-code);background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);font-family:var(--crepe-font-code);padding:0 2px;border-radius:4px;font-size:87.5%;display:inline-block;line-height:1.4286}.milkdown .ProseMirror a{color:var(--crepe-color-primary);text-decoration:underline}.milkdown .ProseMirror pre{background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);padding:10px;border-radius:4px}.milkdown .ProseMirror pre code{padding:0;background:transparent}.milkdown .ProseMirror blockquote{position:relative;padding-left:40px;padding-top:0;padding-bottom:0;box-sizing:content-box;margin:4px 0}.milkdown .ProseMirror blockquote:before{content:"";width:4px;left:0;top:4px;bottom:4px;position:absolute;background:var(--crepe-color-selected);border-radius:100px}.milkdown .ProseMirror blockquote hr{margin-bottom:16px}.milkdown .ProseMirror hr{border:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);background-clip:content-box;padding:6px 0;height:13px;position:relative}.milkdown .ProseMirror hr.ProseMirror-selectednode{outline:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 20%);background-clip:content-box}.milkdown .ProseMirror hr.ProseMirror-selectednode:before{content:"";position:absolute;inset:0;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);pointer-events:none}.milkdown .ProseMirror ul,.milkdown .ProseMirror ol{padding:0}.milkdown .milkdown-block-handle[data-show=false]{opacity:0;pointer-events:none}.milkdown .milkdown-block-handle{transition:all .2s;position:absolute;cursor:pointer;display:flex;justify-content:center;align-items:center;gap:2px}.milkdown .milkdown-block-handle .operation-item{border-radius:4px;width:32px;height:32px;padding:4px}.milkdown .milkdown-block-handle .operation-item svg{width:24px;height:24px;fill:var(--crepe-color-outline)}.milkdown .milkdown-block-handle .operation-item:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-block-handle .operation-item.active{background:var(--crepe-color-selected)}.milkdown .milkdown-slash-menu[data-show=false]{display:none}.milkdown .milkdown-slash-menu{position:absolute;z-index:10;display:block;font-family:var(--crepe-font-default);color:var(--crepe-color-on-surface);background:var(--crepe-color-surface);border-radius:12px;box-shadow:var(--crepe-shadow-1)}.milkdown .milkdown-slash-menu ul{list-style-type:none}.milkdown .milkdown-slash-menu ul li{cursor:pointer;border-radius:8px}.milkdown .milkdown-slash-menu .tab-group{border-bottom:1px solid color-mix(in srgb,var(--crepe-color-outline),transparent 80%);padding:12px 12px 0}.milkdown .milkdown-slash-menu .tab-group ul{padding:8px 10px;display:flex;gap:10px;flex-wrap:nowrap}.milkdown .milkdown-slash-menu .tab-group ul li{padding:6px 10px;font-size:14px;font-style:normal;font-weight:600;line-height:20px}.milkdown .milkdown-slash-menu .tab-group ul li:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-slash-menu .tab-group ul li.selected{background:var(--crepe-color-selected)}.milkdown .milkdown-slash-menu .menu-groups{padding:0 12px 12px;max-height:420px;overflow:auto;overscroll-behavior:contain;scroll-behavior:smooth}.milkdown .milkdown-slash-menu .menu-groups .menu-group h6{font-size:14px;font-style:normal;font-weight:600;line-height:20px;padding:14px 10px;text-transform:uppercase;color:color-mix(in srgb,var(--crepe-color-on-surface),transparent 40%)}.milkdown .milkdown-slash-menu .menu-groups .menu-group li{min-width:220px;display:flex;justify-content:flex-start;align-items:center;gap:16px;padding:14px 10px}.milkdown .milkdown-slash-menu .menu-groups .menu-group li.hover{background:var(--crepe-color-hover)}.milkdown .milkdown-slash-menu .menu-groups .menu-group li.active{background:var(--crepe-color-selected)}.milkdown .milkdown-slash-menu .menu-groups .menu-group li svg{width:24px;height:24px;color:var(--crepe-color-outline);fill:var(--crepe-color-outline)}.milkdown .milkdown-slash-menu .menu-groups .menu-group li>span{font-size:14px;font-style:normal;font-weight:600;line-height:20px}.milkdown .milkdown-slash-menu .menu-groups .menu-group+.menu-group:before{content:"";display:block;height:1px;background:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);margin:0 10px}.milkdown .milkdown-code-block{display:block;position:relative;padding:8px 20px 20px;background:var(--crepe-color-surface);margin:4px 0}.milkdown .milkdown-code-block .language-picker{padding-top:10px;width:-moz-max-content;width:max-content;position:absolute;z-index:999}.milkdown .milkdown-code-block .hidden{display:none!important}.milkdown .milkdown-code-block.selected{outline:1px solid var(--crepe-color-primary)}.milkdown .milkdown-code-block .cm-editor{outline:none!important;background:var(--crepe-color-surface)}.milkdown .milkdown-code-block .cm-gutters{border-right:none;background:var(--crepe-color-surface)}.milkdown .milkdown-code-block .cm-panel{font-family:var(--crepe-font-default);background:var(--crepe-color-surface);color:var(--crepe-color-on-surface)}.milkdown .milkdown-code-block .cm-panel input{caret-color:var(--crepe-color-outline);border-radius:4px;background:var(--crepe-color-surface-low)}.milkdown .milkdown-code-block .cm-panel>button{text-transform:capitalize;background:var(--crepe-color-surface-low);color:var(--crepe-color-on-surface-variant);border:1px solid var(--crepe-color-outline);font-weight:600;cursor:pointer;border-radius:4px}.milkdown .milkdown-code-block .cm-panel>button:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-code-block .cm-panel>label{display:inline-flex;align-items:center;text-transform:capitalize}.milkdown .milkdown-code-block .cm-panel>label input[type=checkbox]{border-radius:4px;cursor:pointer;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:var(--crepe-color-surface-low);width:1.15em;height:1.15em;border:1px solid var(--crepe-color-outline);display:grid;place-content:center}.milkdown .milkdown-code-block .cm-panel>label input[type=checkbox]:before{content:"";transform-origin:bottom left;width:.65em;height:.65em;transform:scale(0);transition:.12s transform ease-in-out;box-shadow:inset 1em 1em var(--crepe-color-outline);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%)}.milkdown .milkdown-code-block .cm-panel>label input[type=checkbox]:checked:before{transform:scale(1)}.milkdown .milkdown-code-block .tools{display:flex;justify-content:space-between;align-items:center}.milkdown .milkdown-code-block .tools input{caret-color:var(--crepe-color-outline)}.milkdown .milkdown-code-block .tools .tools-button-group{display:flex;gap:2px}.milkdown .milkdown-code-block .tools .tools-button-group button{background:var(--crepe-color-secondary);color:var(--crepe-color-on-surface-variant);padding:4px 10px;opacity:0;cursor:pointer;border-radius:4px;font-size:12px;line-height:16px;font-weight:600;font-family:var(--crepe-font-default);transition:opacity .2s ease-in-out;display:flex;align-items:center;justify-content:center;gap:4px}.milkdown .milkdown-code-block .tools .tools-button-group button svg{width:14px;height:14px;fill:var(--crepe-color-on-surface-variant)}.milkdown .milkdown-code-block .tools .tools-button-group button:first-child{border-top-left-radius:100px;border-bottom-left-radius:100px}.milkdown .milkdown-code-block .tools .tools-button-group button:last-child{border-top-right-radius:100px;border-bottom-right-radius:100px}.milkdown .milkdown-code-block .tools .language-button{display:flex;align-items:center;font-family:var(--crepe-font-default);gap:6px;padding:2px 4px 2px 8px;background:var(--crepe-color-surface-low);color:var(--crepe-color-on-surface-variant);border-radius:4px;font-size:12px;font-weight:600;line-height:16px;margin-bottom:8px;opacity:0;cursor:pointer;transition:opacity .2s ease-in-out}.milkdown .milkdown-code-block .tools .language-button:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-code-block .tools .language-button .expand-icon{transition:transform .2s ease-in-out;width:18px;height:18px;display:flex;justify-content:center;align-items:center}.milkdown .milkdown-code-block .tools .language-button .expand-icon svg{width:14px;height:14px;color:var(--crepe-color-outline)}.milkdown .milkdown-code-block .tools .language-button[data-expanded=true] .expand-icon{transform:rotate(180deg)}.milkdown .milkdown-code-block .tools .language-button .expand-icon svg:focus,.milkdown .milkdown-code-block .tools .language-button .expand-icon:focus-visible{outline:none}.milkdown .milkdown-code-block:hover .language-button{opacity:1}.milkdown .milkdown-code-block:hover .tools-button-group>button{opacity:1}.milkdown .milkdown-code-block .list-wrapper{background:var(--crepe-color-surface-low);border-radius:12px;box-shadow:var(--crepe-shadow-1);width:240px;padding-top:12px}.milkdown .milkdown-code-block .language-list{height:410px;overflow-y:auto;overscroll-behavior:contain;margin:0;padding:0}.milkdown .milkdown-code-block .language-list-item{cursor:pointer;margin:0;display:flex;align-items:center;gap:8px;padding:4px 22px;font-size:14px;font-weight:600;line-height:20px}.milkdown .milkdown-code-block .language-list-item:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-code-block .language-list-item:focus-visible{outline:none;background:var(--crepe-color-hover)}.milkdown .milkdown-code-block .language-list-item .leading,.milkdown .milkdown-code-block .language-list-item .leading svg{width:24px;height:24px}.milkdown .milkdown-code-block .language-list-item.no-result{cursor:default;opacity:.6}.milkdown .milkdown-code-block .language-list-item.no-result:hover{background:transparent}.milkdown .milkdown-code-block .search-box{display:flex;align-items:center;margin:0 12px 8px;background:transparent;border-radius:4px;outline:1px solid var(--crepe-color-primary);gap:8px;padding:6px 10px}.milkdown .milkdown-code-block .search-box:has(input:focus){outline:2px solid var(--crepe-color-primary)}.milkdown .milkdown-code-block .search-box .search-input{width:100%;color:var(--crepe-color-on-surface)}.milkdown .milkdown-code-block .search-box .search-icon{display:none}.milkdown .milkdown-code-block .search-box .clear-icon{cursor:pointer;width:20px;height:20px}.milkdown .milkdown-code-block .search-box .clear-icon svg{width:20px;height:20px;color:var(--crepe-color-primary);fill:var(--crepe-color-primary)}.milkdown .milkdown-code-block .search-box .clear-icon:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-code-block .search-box input{font-family:var(--crepe-font-default);font-size:14px;line-height:20px;background:transparent}.milkdown .milkdown-code-block .search-box input:focus{outline:none}.milkdown .milkdown-code-block .preview-panel .preview-divider{height:1px;opacity:.2;background:var(--crepe-color-outline);margin:6px 0}.milkdown .milkdown-code-block .preview-panel .preview-label{margin:6px 0;font-size:12px;color:color-mix(in srgb,var(--crepe-color-on-surface),transparent 40%);font-weight:600;text-transform:uppercase;font-family:var(--crepe-font-default)}.milkdown .milkdown-code-block .preview-panel .preview{text-align:center;overflow-x:auto}.ProseMirror-gapcursor{display:none;pointer-events:none;position:absolute}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid black;animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror.virtual-cursor-enabled{caret-color:transparent}.ProseMirror-focused{--prosemirror-virtual-cursor-color: red}.ProseMirror .prosemirror-virtual-cursor{position:absolute;cursor:text;pointer-events:none;transform:translate(-1px);user-select:none;-webkit-user-select:none;border-left:2px solid var(--prosemirror-virtual-cursor-color)}.ProseMirror .prosemirror-virtual-cursor-left{width:1ch;transform:translate(calc(-1ch - 1px));border-bottom:2px solid var(--prosemirror-virtual-cursor-color);border-right:2px solid var(--prosemirror-virtual-cursor-color);border-left:none}.ProseMirror .prosemirror-virtual-cursor-right{width:1ch;border-bottom:2px solid var(--prosemirror-virtual-cursor-color);border-left:2px solid var(--prosemirror-virtual-cursor-color);border-right:none}.ProseMirror-focused .prosemirror-virtual-cursor-animation{animation:prosemirror-virtual-cursor-blink 1s linear infinite;animation-delay:.5s}@keyframes prosemirror-virtual-cursor-blink{0%{opacity:1}50%{opacity:0}to{opacity:1}}.milkdown .crepe-drop-cursor{background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 50%);opacity:.5;transition:all .2s;pointer-events:none}.milkdown .ProseMirror-gapcursor:after{box-sizing:border-box;border-top:1px solid var(--crepe-color-on-background)}.milkdown .ProseMirror-focused{--prosemirror-virtual-cursor-color: var(--crepe-color-outline)}.milkdown .milkdown-image-inline{outline:none;display:inline-flex;vertical-align:text-bottom}.milkdown .milkdown-image-inline input{background:transparent;outline:none;border:0;caret-color:var(--crepe-color-outline)}.milkdown .milkdown-image-inline>.empty-image-inline{display:inline-flex}.milkdown .milkdown-image-inline>.empty-image-inline .confirm{cursor:pointer}.milkdown .milkdown-image-inline>.empty-image-inline .link-importer{position:relative;flex:1}.milkdown .milkdown-image-inline>.empty-image-inline .link-importer>.link-input-area{width:208px;color:var(--crepe-color-on-background);display:flex}.milkdown .milkdown-image-inline>.empty-image-inline .link-importer .placeholder{position:absolute;top:0;left:0;bottom:0;display:flex;align-items:center;cursor:text}.milkdown .milkdown-image-inline>.empty-image-inline .link-importer .placeholder .uploader{cursor:pointer;display:flex}.milkdown .milkdown-image-inline .hidden{display:none!important}.milkdown .milkdown-image-inline.empty.selected{background:none;outline:none}.milkdown .milkdown-image-inline.empty.selected .empty-image-inline{box-shadow:var(--crepe-shadow-1)}.milkdown .milkdown-image-inline.selected{background:none;outline:1px solid var(--crepe-color-primary)}.milkdown .milkdown-image-inline.selected :not(input)::-moz-selection{background:transparent}.milkdown .milkdown-image-inline.selected :not(input)::selection{background:transparent}.milkdown .milkdown-image-inline .empty-image-inline{align-items:center;padding:4px 10px;gap:10px;background:var(--crepe-color-surface);font-family:var(--crepe-font-default);border-radius:8px;font-size:16px}.milkdown .milkdown-image-inline .empty-image-inline .image-icon svg{width:18px;height:18px;fill:var(--crepe-color-outline)}.milkdown .milkdown-image-inline .empty-image-inline .image-icon{padding:3px;width:24px;height:24px}.milkdown .milkdown-image-inline .empty-image-inline .link-importer{height:24px}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder{color:color-mix(in srgb,var(--crepe-color-on-background),transparent 60%)}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder :not(input)::-moz-selection{background:transparent}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder :not(input)::selection{background:transparent}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .link-input-area{line-height:24px}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder .uploader{gap:8px;color:var(--crepe-color-primary);justify-content:center;transition:color .2s;font-family:var(--crepe-font-default)}.milkdown .milkdown-image-inline .empty-image-inline .link-importer.focus .placeholder .uploader{color:unset}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder .uploader:hover{color:var(--crepe-color-primary)}.milkdown .milkdown-image-inline .empty-image-inline .link-importer .placeholder .text{margin-left:8px}.milkdown .milkdown-image-inline .empty-image-inline .confirm svg{width:18px;height:18px}.milkdown .milkdown-image-inline .empty-image-inline .confirm{display:flex;width:24px;height:24px;padding:3px;border-radius:8px;color:var(--crepe-color-primary)}.milkdown .milkdown-image-inline .empty-image-inline .confirm:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-image-block{outline:none;margin:4px 0;display:block}.milkdown .milkdown-image-block>.image-wrapper{position:relative;width:-moz-fit-content;width:fit-content;margin:0 auto;min-width:100px}.milkdown .milkdown-image-block>.image-wrapper .operation{position:absolute;display:flex}.milkdown .milkdown-image-block>.image-wrapper .operation>.operation-item{cursor:pointer}.milkdown .milkdown-image-block>.image-wrapper img{max-width:100%;min-height:100px;display:block;-o-object-fit:cover;object-fit:cover}.milkdown .milkdown-image-block>.image-wrapper>.image-resize-handle{position:absolute;left:50%;transform:translate(-50%)}.milkdown .milkdown-image-block>.image-wrapper>.image-resize-handle:hover{cursor:row-resize}.milkdown .milkdown-image-block input{background:transparent;outline:none;border:0;caret-color:var(--crepe-color-outline)}.milkdown .milkdown-image-block>.caption-input{display:block;width:100%;text-align:center;color:var(--crepe-color-on-background)}.milkdown .milkdown-image-block>.image-edit{display:flex}.milkdown .milkdown-image-block>.image-edit .confirm{cursor:pointer}.milkdown .milkdown-image-block>.image-edit .link-importer{position:relative;flex:1}.milkdown .milkdown-image-block>.image-edit .link-importer>.link-input-area{width:100%}.milkdown .milkdown-image-block>.image-edit .link-importer .placeholder{position:absolute;top:0;left:0;bottom:0;display:flex;align-items:center;cursor:text}.milkdown .milkdown-image-block>.image-edit .link-importer .placeholder .uploader{cursor:pointer;display:flex}.milkdown .milkdown-image-block .hidden{display:none!important}.milkdown .milkdown-image-block.selected>.image-edit:not(:has(input:focus)){position:relative}.milkdown .milkdown-image-block.selected>.image-edit:not(:has(input:focus)):before{content:"";position:absolute;inset:0;background:color-mix(in srgb,var(--crepe-color-selected),transparent 60%);pointer-events:none}.milkdown .milkdown-image-block.selected>.image-wrapper{position:relative}.milkdown .milkdown-image-block.selected>.image-wrapper:before{content:"";position:absolute;inset:0;background:color-mix(in srgb,var(--crepe-color-selected),transparent 60%)}.milkdown .milkdown-image-block.selected :not(input)::-moz-selection{background:transparent}.milkdown .milkdown-image-block.selected :not(input)::selection{background:transparent}.milkdown .milkdown-image-block .image-wrapper{display:flex;justify-content:center;align-items:center}.milkdown .milkdown-image-block .image-wrapper .operation{gap:12px;right:12px;top:12px;opacity:0;transition:all .2s}.milkdown .milkdown-image-block:hover>.image-wrapper .operation{opacity:1}.milkdown .milkdown-image-block .image-wrapper .operation>.operation-item{color:var(--crepe-color-on-inverse);padding:4px;background:var(--crepe-color-inverse);opacity:.6;border-radius:50%;width:32px;height:32px}.milkdown .milkdown-image-block .image-wrapper .operation>.operation-item svg{width:24px;height:24px}.milkdown .milkdown-image-block .image-wrapper .image-resize-handle{height:4px;bottom:-2px;max-width:160px;width:100%;background:var(--crepe-color-outline);opacity:0;transition:all .2s;border-radius:4px}.milkdown .milkdown-image-block:hover>.image-wrapper .image-resize-handle{opacity:1}.milkdown .milkdown-image-block .caption-input{margin:4px auto;font-family:var(--crepe-font-default)}.milkdown .milkdown-image-block .image-edit{align-items:center;padding:16px 24px;gap:16px;background:var(--crepe-color-surface);height:56px}.milkdown .milkdown-image-block .image-edit .image-icon{color:var(--crepe-color-outline)}.milkdown .milkdown-image-block .image-edit .image-icon svg{width:24px;height:24px;display:flex;justify-content:center;align-items:center;fill:var(--crepe-color-outline)}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder{color:color-mix(in srgb,var(--crepe-color-on-background),transparent 60%)}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder :not(input)::-moz-selection{background:transparent}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder :not(input)::selection{background:transparent}.milkdown .milkdown-image-block .image-edit .link-importer .link-input-area{line-height:24px;color:var(--crepe-color-on-background)}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder .uploader{gap:8px;color:var(--crepe-color-primary);justify-content:center;transition:color .2s;font-weight:600}.milkdown .milkdown-image-block .image-edit .link-importer.focus .placeholder .uploader{color:unset}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder .uploader:hover{color:var(--crepe-color-primary)}.milkdown .milkdown-image-block .image-edit .link-importer .placeholder .text{margin-left:8px}.milkdown .milkdown-image-block .image-edit .confirm{background:var(--crepe-color-secondary);color:var(--crepe-color-on-secondary);line-height:40px;padding:0 24px;border-radius:100px;font-size:14px;font-weight:600}.milkdown .milkdown-image-block .image-edit .confirm:hover{background:linear-gradient(0deg,#1d192b14 0% 100%),var(--crepe-color-secondary)}.milkdown .milkdown-link-preview{position:absolute;z-index:10}.milkdown .milkdown-link-preview[data-show=false]{display:none}.milkdown .milkdown-link-preview>.link-preview{height:32px;display:flex;justify-content:center;padding:4px 10px;background:var(--crepe-color-surface);gap:10px;border-radius:8px;cursor:pointer;box-shadow:var(--crepe-shadow-1)}.milkdown .milkdown-link-preview>.link-preview>.link-display{text-decoration:none;color:unset}.milkdown .milkdown-link-preview>.link-preview>.link-display:hover:before{display:block}.milkdown .milkdown-link-preview>.link-preview>.link-icon>svg{width:18px;height:18px;color:var(--crepe-color-outline);fill:var(--crepe-color-outline)}.milkdown .milkdown-link-preview>.link-preview>.link-icon{border-radius:8px;padding:3px;line-height:24px}.milkdown .milkdown-link-preview>.link-preview>.link-icon:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-link-preview>.link-preview>.link-display{width:240px;line-height:24px;overflow:hidden;text-overflow:ellipsis;font-size:14px;white-space:nowrap}.milkdown .milkdown-link-preview>.link-preview>.link-display:hover{text-decoration:underline}.milkdown .milkdown-link-preview>.link-preview>.button>svg{width:18px;height:18px;color:var(--crepe-color-outline);fill:var(--crepe-color-outline)}.milkdown .milkdown-link-preview>.link-preview>.button{padding:3px;border-radius:8px;line-height:24px}.milkdown .milkdown-link-preview>.link-preview>.button:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-link-edit{position:absolute;z-index:10}.milkdown .milkdown-link-edit[data-show=false]{display:none}.milkdown .milkdown-link-edit>.link-edit{height:32px;display:flex;justify-content:center;padding:4px 10px 4px 20px;background:var(--crepe-color-surface);gap:8px;border-radius:8px;box-shadow:var(--crepe-shadow-1)}.milkdown .milkdown-link-edit>.link-edit>.input-area{outline:none;background:transparent;width:200px;font-size:14px;color:var(--crepe-color-on-background)}.milkdown .milkdown-link-edit>.link-edit>.button>svg{width:18px;height:18px;color:var(--crepe-color-outline);fill:var(--crepe-color-outline)}.milkdown .milkdown-link-edit>.link-edit>.button{padding:3px;cursor:pointer;border-radius:8px;font-size:12px;line-height:24px}.milkdown .milkdown-link-edit>.link-edit>.button:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-link-edit>.link-edit>.button.hidden{visibility:hidden}.milkdown .milkdown-list-item-block{display:block;padding:0}.milkdown .milkdown-list-item-block>.list-item{display:flex;align-items:flex-start}.milkdown .milkdown-list-item-block>.list-item>.children{min-width:0;flex:1}.milkdown .milkdown-list-item-block li{gap:10px}.milkdown .milkdown-list-item-block li .label-wrapper{color:var(--crepe-color-outline)}.milkdown .milkdown-list-item-block li .label-wrapper svg{fill:var(--crepe-color-outline)}.milkdown .milkdown-list-item-block li .label-wrapper{height:32px;width:24px;display:flex;justify-content:center;align-items:center}.milkdown .milkdown-list-item-block li .label-wrapper .label{height:32px;padding:4px 0;width:24px;text-align:right}.milkdown .milkdown-list-item-block li .label-wrapper .checked,.milkdown .milkdown-list-item-block li .label-wrapper .unchecked{cursor:pointer}.milkdown .milkdown-list-item-block li .label-wrapper .readonly{cursor:not-allowed}.milkdown .crepe-placeholder:before{position:absolute;color:color-mix(in srgb,var(--crepe-color-on-background),transparent 60%);pointer-events:none;height:0;content:attr(data-placeholder)}.milkdown:has(.milkdown-link-preview[data-show=true]) .milkdown-toolbar,.milkdown:has(.milkdown-link-edit[data-show=true]) .milkdown-toolbar{display:none}.milkdown .milkdown-toolbar[data-show=false]{display:none}.milkdown .milkdown-toolbar{z-index:10;position:absolute;display:flex;background:var(--crepe-color-surface);box-shadow:var(--crepe-shadow-1);border-radius:8px;overflow:hidden}.milkdown .milkdown-toolbar .divider{width:1px;background:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);height:24px;margin:10px}.milkdown .milkdown-toolbar .toolbar-item{width:32px;height:32px;margin:6px;padding:4px;cursor:pointer;border-radius:4px}.milkdown .milkdown-toolbar .toolbar-item:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-toolbar .toolbar-item:active{background:var(--crepe-color-selected)}.milkdown .milkdown-toolbar .toolbar-item svg{height:24px;width:24px;color:var(--crepe-color-outline);fill:var(--crepe-color-outline)}.milkdown .milkdown-toolbar .toolbar-item.active svg{color:var(--crepe-color-primary);fill:var(--crepe-color-primary)}.ProseMirror .tableWrapper{overflow-x:auto}.ProseMirror table{border-collapse:collapse;table-layout:fixed;width:100%;overflow:hidden}.ProseMirror td,.ProseMirror th{vertical-align:top;box-sizing:border-box;position:relative}.ProseMirror td:not([data-colwidth]):not(.column-resize-dragging),.ProseMirror th:not([data-colwidth]):not(.column-resize-dragging){min-width:var(--default-cell-min-width)}.ProseMirror .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;z-index:20;background-color:#adf;pointer-events:none}.ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}.ProseMirror .selectedCell:after{z-index:2;position:absolute;content:"";inset:0;background:#c8c8ff66;pointer-events:none}.milkdown .milkdown-table-block{display:block;margin:4px 0}.milkdown .milkdown-table-block th,.milkdown .milkdown-table-block td{border:1px solid color-mix(in srgb,var(--crepe-color-outline),transparent 80%);padding:4px 16px}.milkdown .milkdown-table-block th .ProseMirror-selectednode,.milkdown .milkdown-table-block td .ProseMirror-selectednode{background-color:transparent!important}.milkdown .milkdown-table-block th:has(.ProseMirror-selectednode),.milkdown .milkdown-table-block td:has(.ProseMirror-selectednode){outline:1px solid var(--crepe-color-primary);outline-offset:-1px}.milkdown .milkdown-table-block .selectedCell:after{background-color:var(--crepe-color-selected);opacity:.4}.milkdown .milkdown-table-block .selectedCell ::-moz-selection{background:transparent}.milkdown .milkdown-table-block .selectedCell ::selection{background:transparent}.milkdown .milkdown-table-block .drag-preview{background-color:var(--crepe-color-surface);opacity:.4;position:absolute;z-index:100;display:flex;flex-direction:column;outline:1px solid var(--crepe-color-primary);outline-offset:-1px}.milkdown .milkdown-table-block .drag-preview[data-show=false]{display:none}.milkdown .milkdown-table-block .drag-preview th:has(.ProseMirror-selectednode),.milkdown .milkdown-table-block .drag-preview td:has(.ProseMirror-selectednode){outline:none}.milkdown .milkdown-table-block .handle{position:absolute;font-size:14px;transition:opacity ease-in-out .2s}.milkdown .milkdown-table-block .handle[data-show=false]{opacity:0}.milkdown .milkdown-table-block svg{fill:var(--crepe-color-outline)}.milkdown .milkdown-table-block .cell-handle{z-index:50;left:-999px;top:-999px;cursor:grab;background-color:var(--crepe-color-surface);color:var(--crepe-color-outline);border-radius:100px;box-shadow:var(--crepe-shadow-1);transition:background-color .2s ease-in-out}.milkdown .milkdown-table-block .cell-handle:hover{background-color:var(--crepe-color-hover)}.milkdown .milkdown-table-block .cell-handle:has(.button-group:hover){background-color:var(--crepe-color-surface)}.milkdown .milkdown-table-block .cell-handle[data-role=col-drag-handle]{transform:translateY(50%);padding:0 6px;width:28px;height:16px}.milkdown .milkdown-table-block .cell-handle[data-role=row-drag-handle]{transform:translate(50%);padding:6px 0;width:16px;height:28px}.milkdown .milkdown-table-block .cell-handle .button-group{position:absolute;transform:translate(-50%);left:50%;top:-52px;display:flex;background-color:var(--crepe-color-surface);border-radius:8px;box-shadow:var(--crepe-shadow-1)}.milkdown .milkdown-table-block .cell-handle .button-group:after{content:"";position:absolute;bottom:-8px;height:8px;background-color:transparent;width:100%}.milkdown .milkdown-table-block .cell-handle .button-group[data-show=false]{display:none}.milkdown .milkdown-table-block .cell-handle .button-group button{cursor:pointer;margin:6px;padding:4px;display:flex;justify-content:center;align-items:center;border-radius:4px}.milkdown .milkdown-table-block .cell-handle .button-group button svg{width:24px;height:24px}.milkdown .milkdown-table-block .cell-handle .button-group button:hover{border-radius:8px;background-color:var(--crepe-color-hover)}.milkdown .milkdown-table-block .cell-handle .button-group button:active{background:var(--crepe-color-selected)}.milkdown .milkdown-table-block .cell-handle:hover{opacity:1}.milkdown .milkdown-table-block .line-handle{z-index:20;background-color:var(--crepe-color-primary)}.milkdown .milkdown-table-block .line-handle:hover{opacity:1}.milkdown .milkdown-table-block .line-handle .add-button{cursor:pointer;background-color:var(--crepe-color-surface);color:var(--crepe-color-outline);border-radius:100px;box-shadow:var(--crepe-shadow-1);transition:background-color .2s ease-in-out}.milkdown .milkdown-table-block .line-handle .add-button svg{width:16px;height:16px}.milkdown .milkdown-table-block .line-handle .add-button:hover{background-color:var(--crepe-color-hover)}.milkdown .milkdown-table-block .line-handle .add-button:active{background:var(--crepe-color-selected)}.milkdown .milkdown-table-block .line-handle[data-role=x-line-drag-handle]{height:1px;z-index:2}.milkdown .milkdown-table-block .line-handle[data-role=x-line-drag-handle] .add-button{position:absolute;transform:translate(-50%) translateY(-50%);padding:6px 0;width:16px;height:28px}.milkdown .milkdown-table-block .line-handle[data-role=y-line-drag-handle]{width:1px;z-index:1}.milkdown .milkdown-table-block .line-handle[data-role=y-line-drag-handle] .add-button{position:absolute;transform:translateY(-50%) translate(-50%);padding:0 6px;width:28px;height:16px}.milkdown .milkdown-table-block .line-handle[data-display-type=indicator] .add-button,.milkdown .milkdown-table-block.readonly .handle{display:none}@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_AMS-Regular.woff2") format("woff2"),url("./fonts/KaTeX_AMS-Regular.woff") format("woff"),url("./fonts/KaTeX_AMS-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url("./fonts/KaTeX_Caligraphic-Bold.woff2") format("woff2"),url("./fonts/KaTeX_Caligraphic-Bold.woff") format("woff"),url("./fonts/KaTeX_Caligraphic-Bold.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Caligraphic-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Caligraphic-Regular.woff") format("woff"),url("./fonts/KaTeX_Caligraphic-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url("./fonts/KaTeX_Fraktur-Bold.woff2") format("woff2"),url("./fonts/KaTeX_Fraktur-Bold.woff") format("woff"),url("./fonts/KaTeX_Fraktur-Bold.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Fraktur-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Fraktur-Regular.woff") format("woff"),url("./fonts/KaTeX_Fraktur-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url("./fonts/KaTeX_Main-Bold.woff2") format("woff2"),url("./fonts/KaTeX_Main-Bold.woff") format("woff"),url("./fonts/KaTeX_Main-Bold.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url("./fonts/KaTeX_Main-BoldItalic.woff2") format("woff2"),url("./fonts/KaTeX_Main-BoldItalic.woff") format("woff"),url("./fonts/KaTeX_Main-BoldItalic.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url("./fonts/KaTeX_Main-Italic.woff2") format("woff2"),url("./fonts/KaTeX_Main-Italic.woff") format("woff"),url("./fonts/KaTeX_Main-Italic.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Main-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Main-Regular.woff") format("woff"),url("./fonts/KaTeX_Main-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url("./fonts/KaTeX_Math-BoldItalic.woff2") format("woff2"),url("./fonts/KaTeX_Math-BoldItalic.woff") format("woff"),url("./fonts/KaTeX_Math-BoldItalic.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url("./fonts/KaTeX_Math-Italic.woff2") format("woff2"),url("./fonts/KaTeX_Math-Italic.woff") format("woff"),url("./fonts/KaTeX_Math-Italic.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url("./fonts/KaTeX_SansSerif-Bold.woff2") format("woff2"),url("./fonts/KaTeX_SansSerif-Bold.woff") format("woff"),url("./fonts/KaTeX_SansSerif-Bold.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url("./fonts/KaTeX_SansSerif-Italic.woff2") format("woff2"),url("./fonts/KaTeX_SansSerif-Italic.woff") format("woff"),url("./fonts/KaTeX_SansSerif-Italic.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_SansSerif-Regular.woff2") format("woff2"),url("./fonts/KaTeX_SansSerif-Regular.woff") format("woff"),url("./fonts/KaTeX_SansSerif-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Script-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Script-Regular.woff") format("woff"),url("./fonts/KaTeX_Script-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Size1-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Size1-Regular.woff") format("woff"),url("./fonts/KaTeX_Size1-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Size2-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Size2-Regular.woff") format("woff"),url("./fonts/KaTeX_Size2-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Size3-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Size3-Regular.woff") format("woff"),url("./fonts/KaTeX_Size3-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Size4-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Size4-Regular.woff") format("woff"),url("./fonts/KaTeX_Size4-Regular.ttf") format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url("./fonts/KaTeX_Typewriter-Regular.woff2") format("woff2"),url("./fonts/KaTeX_Typewriter-Regular.woff") format("woff"),url("./fonts/KaTeX_Typewriter-Regular.ttf") format("truetype")}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.42"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}.milkdown span[data-type=math_inline]{padding:0 4px;display:inline-block;vertical-align:bottom;color:var(--crepe-color-primary)}.milkdown .milkdown-latex-inline-edit[data-show=false]{display:none}.milkdown .milkdown-latex-inline-edit{position:absolute;background:var(--crepe-color-surface);box-shadow:var(--crepe-shadow-1);border-radius:8px;padding:2px 6px 2px 12px}.milkdown .milkdown-latex-inline-edit .container{display:flex;gap:6px;align-items:flex-start}.milkdown .milkdown-latex-inline-edit .container button{width:24px;height:24px;cursor:pointer;border-radius:8px}.milkdown .milkdown-latex-inline-edit .container button:hover{background:var(--crepe-color-hover)}.milkdown .milkdown-latex-inline-edit .ProseMirror{padding:0;min-width:174px;max-width:294px;font-family:var(--crepe-font-code)}.milkdown{--crepe-color-background: #ffffff;--crepe-color-on-background: #000000;--crepe-color-surface: #f7f7f7;--crepe-color-surface-low: #ededed;--crepe-color-on-surface: #1c1c1c;--crepe-color-on-surface-variant: #4d4d4d;--crepe-color-outline: #a8a8a8;--crepe-color-primary: #333333;--crepe-color-secondary: #cfcfcf;--crepe-color-on-secondary: #000000;--crepe-color-inverse: #f0f0f0;--crepe-color-on-inverse: #1a1a1a;--crepe-color-inline-code: #ba1a1a;--crepe-color-error: #ba1a1a;--crepe-color-hover: #e0e0e0;--crepe-color-selected: #d5d5d5;--crepe-color-inline-area: #cacaca;--crepe-font-title: "Noto Serif", Cambria, "Times New Roman", Times, serif;--crepe-font-default: "Noto Sans", Arial, Helvetica, sans-serif;--crepe-font-code: "Space Mono", Fira Code, Menlo, Monaco, "Courier New", Courier, monospace;--crepe-shadow-1: 0px 1px 3px 1px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3);--crepe-shadow-2: 0px 2px 6px 2px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3)}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MilkdownEngine
|
|
4
|
+
module ApplicationHelper
|
|
5
|
+
CONTROLLER_ID = "milkdown-engine--editor"
|
|
6
|
+
EMPTY_DOC = { type: "doc", content: [{ type: "paragraph" }] }.to_json.freeze
|
|
7
|
+
|
|
8
|
+
# Renders a Milkdown editor wired to a hidden <input> for form submission.
|
|
9
|
+
#
|
|
10
|
+
# The hidden input holds the ProseMirror JSON representation of the document.
|
|
11
|
+
# On every content change the Stimulus controller serialises the editor state
|
|
12
|
+
# back into the hidden input so it is submitted with the form.
|
|
13
|
+
#
|
|
14
|
+
# The outer wrapper gets Fomantic-UI +ui segment+ classes so it integrates
|
|
15
|
+
# visually with rails-active-ui / Fomantic-UI layouts.
|
|
16
|
+
#
|
|
17
|
+
# ==== Options
|
|
18
|
+
#
|
|
19
|
+
# * <tt>:readonly</tt> – boolean, defaults to +false+.
|
|
20
|
+
# * <tt>:label</tt> – optional label text rendered above the editor.
|
|
21
|
+
# * <tt>:class</tt> – extra CSS class(es) added to the outer wrapper.
|
|
22
|
+
# * <tt>:editor_html</tt> – extra HTML attributes for the inner editor div.
|
|
23
|
+
#
|
|
24
|
+
# ==== Examples
|
|
25
|
+
#
|
|
26
|
+
# # Standalone (no form builder)
|
|
27
|
+
# <%= milkdown_editor "md_document[content]", @document.content %>
|
|
28
|
+
#
|
|
29
|
+
# # Inside a Fomantic-UI form
|
|
30
|
+
# <% Form { %>
|
|
31
|
+
# <div class="field">
|
|
32
|
+
# <%= milkdown_editor "md_document[content]", @document.content, label: "Content" %>
|
|
33
|
+
# </div>
|
|
34
|
+
# <% Button(variant: :primary, type: :submit) { text "Save" } %>
|
|
35
|
+
# <% } %>
|
|
36
|
+
#
|
|
37
|
+
# # With a Rails form builder
|
|
38
|
+
# <%= form_with model: @document, html: { class: "ui form" } do |f| %>
|
|
39
|
+
# <%= milkdown_editor_field f, :content, label: "Content" %>
|
|
40
|
+
# <% end %>
|
|
41
|
+
#
|
|
42
|
+
def milkdown_editor(name, value = nil, readonly: false, label: nil, **html_options)
|
|
43
|
+
editor_html = html_options.delete(:editor_html) || {}
|
|
44
|
+
|
|
45
|
+
json_value = case value
|
|
46
|
+
when String then value.presence || EMPTY_DOC
|
|
47
|
+
when Hash then value.present? ? value.to_json : EMPTY_DOC
|
|
48
|
+
when nil then EMPTY_DOC
|
|
49
|
+
else value.to_json
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
extra_class = html_options.delete(:class)
|
|
53
|
+
wrapper_classes = class_names("ui segment milkdown-editor", extra_class)
|
|
54
|
+
|
|
55
|
+
wrapper_attrs = html_options.merge(
|
|
56
|
+
class: wrapper_classes,
|
|
57
|
+
data: {
|
|
58
|
+
controller: CONTROLLER_ID,
|
|
59
|
+
"#{CONTROLLER_ID}-readonly-value": readonly
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
parts = []
|
|
64
|
+
parts << content_tag(:label, label, class: "milkdown-editor-label") if label
|
|
65
|
+
parts << hidden_field_tag(name, json_value, data: { "#{CONTROLLER_ID}-target": "input" })
|
|
66
|
+
parts << content_tag(:div, "", editor_html.merge(
|
|
67
|
+
class: class_names("milkdown-editor-surface", editor_html[:class]),
|
|
68
|
+
data: { "#{CONTROLLER_ID}-target": "editor" }
|
|
69
|
+
))
|
|
70
|
+
|
|
71
|
+
content_tag(:div, wrapper_attrs) { safe_join(parts) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Form-builder variant: reads the field value from the model automatically.
|
|
75
|
+
#
|
|
76
|
+
# <%= form_with model: @document, html: { class: "ui form" } do |f| %>
|
|
77
|
+
# <%= milkdown_editor_field f, :content, label: "Content" %>
|
|
78
|
+
# <% end %>
|
|
79
|
+
#
|
|
80
|
+
def milkdown_editor_field(form, method, **options)
|
|
81
|
+
record = form.object
|
|
82
|
+
value = record&.public_send(method)
|
|
83
|
+
name = "#{form.object_name}[#{method}]"
|
|
84
|
+
|
|
85
|
+
milkdown_editor(name, value, **options)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
import {
|
|
3
|
+
Crepe,
|
|
4
|
+
editorViewCtx,
|
|
5
|
+
schemaCtx,
|
|
6
|
+
Node,
|
|
7
|
+
} from "milkdown_engine/milkdown"
|
|
8
|
+
|
|
9
|
+
// Stimulus controller that wraps a Milkdown Crepe editor instance.
|
|
10
|
+
//
|
|
11
|
+
// Usage:
|
|
12
|
+
// <div data-controller="milkdown-engine--editor"
|
|
13
|
+
// data-milkdown-engine--editor-readonly-value="false">
|
|
14
|
+
// <input type="hidden"
|
|
15
|
+
// data-milkdown-engine--editor-target="input"
|
|
16
|
+
// name="md_document[content]"
|
|
17
|
+
// value='{"type":"doc","content":[]}'>
|
|
18
|
+
// <div data-milkdown-engine--editor-target="editor"></div>
|
|
19
|
+
// </div>
|
|
20
|
+
//
|
|
21
|
+
// The controller reads initial JSON from the hidden input, initialises the
|
|
22
|
+
// Milkdown editor inside the [data-target="editor"] element, and keeps the
|
|
23
|
+
// hidden input in sync with the document's ProseMirror JSON on every change.
|
|
24
|
+
//
|
|
25
|
+
// Dispatches a "milkdown-engine--editor:change" CustomEvent on the controller
|
|
26
|
+
// element whenever the document changes. event.detail.content holds the JSON.
|
|
27
|
+
|
|
28
|
+
export default class extends Controller {
|
|
29
|
+
static targets = ["editor", "input"]
|
|
30
|
+
static values = {
|
|
31
|
+
readonly: { type: Boolean, default: false },
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async connect() {
|
|
35
|
+
this.crepe = new Crepe({
|
|
36
|
+
root: this.editorTarget,
|
|
37
|
+
features: {
|
|
38
|
+
// Latex is heavy and rarely needed — disabled by default
|
|
39
|
+
latex: false,
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// Wire up the change listener *before* create() so it captures the
|
|
44
|
+
// initial mount as well.
|
|
45
|
+
this.crepe.on((listener) => {
|
|
46
|
+
listener.updated((_ctx, doc, _prevDoc) => {
|
|
47
|
+
this.#syncToInput(doc.toJSON())
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
await this.crepe.create()
|
|
52
|
+
|
|
53
|
+
// If the hidden input carries existing JSON, replace the empty doc.
|
|
54
|
+
this.#loadInitialContent()
|
|
55
|
+
|
|
56
|
+
if (this.readonlyValue) {
|
|
57
|
+
this.crepe.setReadonly(true)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async disconnect() {
|
|
62
|
+
if (this.crepe) {
|
|
63
|
+
await this.crepe.destroy()
|
|
64
|
+
this.crepe = null
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// --- public API (callable via Stimulus actions or from other controllers) ---
|
|
69
|
+
|
|
70
|
+
// Returns the current document as ProseMirror JSON.
|
|
71
|
+
getJSON() {
|
|
72
|
+
return this.crepe.editor.action((ctx) => {
|
|
73
|
+
const view = ctx.get(editorViewCtx)
|
|
74
|
+
return view.state.doc.toJSON()
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Replaces the entire document from a ProseMirror JSON object.
|
|
79
|
+
setJSON(json) {
|
|
80
|
+
this.crepe.editor.action((ctx) => {
|
|
81
|
+
const view = ctx.get(editorViewCtx)
|
|
82
|
+
const schema = ctx.get(schemaCtx)
|
|
83
|
+
const doc = Node.fromJSON(schema, json)
|
|
84
|
+
view.dispatch(
|
|
85
|
+
view.state.tr.replaceWith(0, view.state.doc.content.size, doc.content)
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// --- Stimulus value callbacks ---
|
|
91
|
+
|
|
92
|
+
readonlyValueChanged() {
|
|
93
|
+
if (this.crepe) {
|
|
94
|
+
this.crepe.setReadonly(this.readonlyValue)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// --- private ---
|
|
99
|
+
|
|
100
|
+
#syncToInput(json) {
|
|
101
|
+
if (this.hasInputTarget) {
|
|
102
|
+
this.inputTarget.value = JSON.stringify(json)
|
|
103
|
+
}
|
|
104
|
+
this.dispatch("change", { detail: { content: json } })
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#loadInitialContent() {
|
|
108
|
+
if (!this.hasInputTarget) return
|
|
109
|
+
|
|
110
|
+
const raw = this.inputTarget.value
|
|
111
|
+
if (!raw || raw === "" || raw === "{}") return
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const json = JSON.parse(raw)
|
|
115
|
+
if (json && json.type === "doc" && json.content) {
|
|
116
|
+
this.setJSON(json)
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
// The input does not contain valid JSON — start with an empty document.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|