@teriusu/rich-editor 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/TipTapEditor.svelte +6 -2
- package/dist/components/TipTapEditor.svelte.d.ts.map +1 -1
- package/dist/extensions/ResizableImage.d.ts +10 -0
- package/dist/extensions/ResizableImage.d.ts.map +1 -0
- package/dist/extensions/ResizableImage.js +148 -0
- package/dist/extensions/ResizableImage.test.d.ts +2 -0
- package/dist/extensions/ResizableImage.test.d.ts.map +1 -0
- package/dist/extensions/ResizableImage.test.js +90 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/styles/editor.css +1 -1
- package/dist/utils/sanitize.test.js +11 -0
- package/package.json +1 -1
|
@@ -97,7 +97,6 @@
|
|
|
97
97
|
import StarterKit from "@tiptap/starter-kit";
|
|
98
98
|
import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
|
|
99
99
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
100
|
-
import Image from "@tiptap/extension-image";
|
|
101
100
|
import Link from "@tiptap/extension-link";
|
|
102
101
|
import Underline from "@tiptap/extension-underline";
|
|
103
102
|
import TextAlign from "@tiptap/extension-text-align";
|
|
@@ -128,6 +127,7 @@
|
|
|
128
127
|
import { Indent } from "../extensions/Indent";
|
|
129
128
|
import { FileAttachment } from "../extensions/FileAttachment";
|
|
130
129
|
import { MbusVideo } from "../extensions/MbusVideo";
|
|
130
|
+
import { ResizableImage } from "../extensions/ResizableImage";
|
|
131
131
|
import { VideoEmbed } from "../extensions/VideoEmbed";
|
|
132
132
|
import { CardBlock } from "../extensions/CardBlock";
|
|
133
133
|
import { MathInline, MathDisplay, type MathPrompt } from "../extensions/Math";
|
|
@@ -558,7 +558,11 @@
|
|
|
558
558
|
}),
|
|
559
559
|
]
|
|
560
560
|
: []),
|
|
561
|
-
|
|
561
|
+
/*
|
|
562
|
+
* 기본 `Image` 대신 확장본을 쓴다 — 노드 타입은 그대로 `image` 이고
|
|
563
|
+
* 드래그 손잡이(`width` 속성으로 저장)만 얹은 것이다. `ResizableImage.ts` 참고.
|
|
564
|
+
*/
|
|
565
|
+
ResizableImage.configure({ inline: false }),
|
|
562
566
|
Link.configure({
|
|
563
567
|
openOnClick: false,
|
|
564
568
|
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AA8FA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AA8FA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AA2BtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAYjD,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,uDAAuD;IACvD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wCAAwC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,mDAAmD;IACnD,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;AA8vBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 어떤 꼴로 들어오든 단위 없는 px 정수로 만든다. 못 읽으면 `null`.
|
|
3
|
+
*
|
|
4
|
+
* `%`·`em`·`auto` 처럼 px 로 환산할 수 없는 값은 **버린다**. 억지로 숫자를 뽑으면
|
|
5
|
+
* `50%` 가 `50px` 이 되어 이미지가 손톱만 해진다.
|
|
6
|
+
*/
|
|
7
|
+
export declare function normalizeImageWidth(value: unknown): number | null;
|
|
8
|
+
export declare const ResizableImage: import("@tiptap/core").Node<import("@tiptap/extension-image").ImageOptions, any>;
|
|
9
|
+
export default ResizableImage;
|
|
10
|
+
//# sourceMappingURL=ResizableImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResizableImage.d.ts","sourceRoot":"","sources":["../../src/extensions/ResizableImage.ts"],"names":[],"mappings":"AAqCA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYjE;AAED,eAAO,MAAM,cAAc,kFAyFzB,CAAC;AAEH,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import Image from "@tiptap/extension-image";
|
|
2
|
+
import { attachResize } from "../utils/resize";
|
|
3
|
+
/**
|
|
4
|
+
* 드래그로 폭을 조절할 수 있는 이미지.
|
|
5
|
+
*
|
|
6
|
+
* **새 노드가 아니라 `@tiptap/extension-image` 의 확장**이다. 저장본에 이미 쌓여 있는
|
|
7
|
+
* 이미지가 전부 `image` 노드라서, 새 타입을 만들면 옛 문서가 통째로 다른 것이 된다.
|
|
8
|
+
*
|
|
9
|
+
* ## 왜 `style` 이 아니라 `width` 속성인가
|
|
10
|
+
*
|
|
11
|
+
* 정올은 문항 목록에서 **저장 HTML 을 `{@html}` 로 먼저 그리면서** `sanitizeHtml` 을
|
|
12
|
+
* 태운다. 그 살균기의 `img` 허용 목록은 `src·alt·width·height` 뿐이라 **`style` 은
|
|
13
|
+
* 조용히 지워진다**(`utils/sanitize.ts`). 폭을 인라인 `style` 로 저장하면 정적 렌더에서는
|
|
14
|
+
* 원래 크기로 나왔다가 에디터가 뜨는 순간 조절한 크기로 튄다. 그래서 저장 형식은
|
|
15
|
+
* 단위 없는 px 숫자 `<img width="480">` 하나로 고정한다.
|
|
16
|
+
*
|
|
17
|
+
* ## 파싱은 관대하게, 쓰기는 좁게
|
|
18
|
+
*
|
|
19
|
+
* 읽을 때는 `width="480"` · `width="480px"` · `style="width:480px"` 을 모두 받는다
|
|
20
|
+
* (옛 문서·붙여넣기 대비). 쓸 때는 언제나 `width="480"` 한 가지다.
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ **폭이 없는 문서는 `null` 로 둔다.** 열었다 저장하는 것만으로 크기가 박히면,
|
|
23
|
+
* 손대지 않은 이미지가 그 시점의 렌더 폭에 고정돼 반응형이 죽는다.
|
|
24
|
+
* `%` 값은 px 로 환산하지 않고 그냥 무시한다(=`null`) — 환산하려면 컨테이너 폭을
|
|
25
|
+
* 알아야 하는데 파싱 시점엔 없다.
|
|
26
|
+
*
|
|
27
|
+
* ## 왜 `Image` 내장 리사이즈(`options.resize`)를 안 쓰나
|
|
28
|
+
*
|
|
29
|
+
* TipTap v3 의 `Image` 에는 `ResizableNodeView` 기반 리사이즈가 들어 있지만,
|
|
30
|
+
* (1) `width`·`height` 를 **둘 다** 쓰고 (2) 손잡이 모양이 이 패키지의 PDF·영상·카드와
|
|
31
|
+
* 다르다. 미디어 블록끼리 조작감이 갈리지 않도록 공용 `attachResize` 로 통일한다.
|
|
32
|
+
*/
|
|
33
|
+
/** 기본 최소값 240px 은 이미지엔 너무 크다 — 아이콘·뱃지 크기까지 줄일 수 있어야 한다. */
|
|
34
|
+
const MIN_WIDTH = 60;
|
|
35
|
+
/**
|
|
36
|
+
* 어떤 꼴로 들어오든 단위 없는 px 정수로 만든다. 못 읽으면 `null`.
|
|
37
|
+
*
|
|
38
|
+
* `%`·`em`·`auto` 처럼 px 로 환산할 수 없는 값은 **버린다**. 억지로 숫자를 뽑으면
|
|
39
|
+
* `50%` 가 `50px` 이 되어 이미지가 손톱만 해진다.
|
|
40
|
+
*/
|
|
41
|
+
export function normalizeImageWidth(value) {
|
|
42
|
+
if (value == null)
|
|
43
|
+
return null;
|
|
44
|
+
if (typeof value === "number") {
|
|
45
|
+
return Number.isFinite(value) && value > 0 ? Math.round(value) : null;
|
|
46
|
+
}
|
|
47
|
+
const raw = String(value).trim();
|
|
48
|
+
if (!raw)
|
|
49
|
+
return null;
|
|
50
|
+
const m = /^(\d+(?:\.\d+)?)(px)?$/i.exec(raw);
|
|
51
|
+
if (!m)
|
|
52
|
+
return null;
|
|
53
|
+
const n = Number.parseFloat(m[1]);
|
|
54
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
55
|
+
return null;
|
|
56
|
+
return Math.round(n);
|
|
57
|
+
}
|
|
58
|
+
export const ResizableImage = Image.extend({
|
|
59
|
+
addAttributes() {
|
|
60
|
+
return {
|
|
61
|
+
...this.parent?.(),
|
|
62
|
+
width: {
|
|
63
|
+
default: null,
|
|
64
|
+
parseHTML: (element) => {
|
|
65
|
+
const fromAttr = normalizeImageWidth(element.getAttribute("width"));
|
|
66
|
+
if (fromAttr != null)
|
|
67
|
+
return fromAttr;
|
|
68
|
+
// `style="width:480px"` 로만 크기가 박힌 옛 문서.
|
|
69
|
+
return normalizeImageWidth(element.style?.width ?? null);
|
|
70
|
+
},
|
|
71
|
+
// ⚠️ 값이 없으면 **속성을 아예 내보내지 않는다.** 빈 `width=""` 도 안 된다 —
|
|
72
|
+
// 옛 문서와 출력이 구분되지 않아야 한다.
|
|
73
|
+
renderHTML: (attributes) => {
|
|
74
|
+
const w = normalizeImageWidth(attributes.width);
|
|
75
|
+
return w == null ? {} : { width: String(w) };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
addNodeView() {
|
|
81
|
+
return ({ node, editor, getPos }) => {
|
|
82
|
+
// 리사이즈가 `setNodeMarkup` 으로 attrs 를 통째로 되쓰므로 **항상 최신 노드**여야
|
|
83
|
+
// 한다. 클로저의 `node` 를 쓰면 그 사이의 다른 속성 변경을 리사이즈가 되돌린다.
|
|
84
|
+
let currentNode = node;
|
|
85
|
+
let detachResize = null;
|
|
86
|
+
/*
|
|
87
|
+
* `<img>` 에는 자식을 붙일 수 없다 — 손잡이를 놓을 자리가 없다. 그래서
|
|
88
|
+
* `position:relative` 인 래퍼로 감싼다. 폭은 **래퍼**가 갖고 이미지는
|
|
89
|
+
* `width:100%` 로 따라간다(스타일은 `editor.css` 의 `.hce-image`).
|
|
90
|
+
*/
|
|
91
|
+
const dom = document.createElement("div");
|
|
92
|
+
dom.className = "hce-image";
|
|
93
|
+
dom.setAttribute("data-type", "image");
|
|
94
|
+
dom.setAttribute("data-node-view-wrapper", "");
|
|
95
|
+
const img = document.createElement("img");
|
|
96
|
+
dom.appendChild(img);
|
|
97
|
+
const applyAttrs = (attrs) => {
|
|
98
|
+
const src = attrs.src == null ? "" : String(attrs.src);
|
|
99
|
+
if (img.getAttribute("src") !== src)
|
|
100
|
+
img.setAttribute("src", src);
|
|
101
|
+
img.setAttribute("alt", attrs.alt == null ? "" : String(attrs.alt));
|
|
102
|
+
if (attrs.title == null)
|
|
103
|
+
img.removeAttribute("title");
|
|
104
|
+
else
|
|
105
|
+
img.setAttribute("title", String(attrs.title));
|
|
106
|
+
const w = normalizeImageWidth(attrs.width);
|
|
107
|
+
if (w == null)
|
|
108
|
+
dom.style.removeProperty("width");
|
|
109
|
+
else
|
|
110
|
+
dom.style.width = `${w}px`;
|
|
111
|
+
};
|
|
112
|
+
applyAttrs(node.attrs);
|
|
113
|
+
if (editor.isEditable) {
|
|
114
|
+
detachResize = attachResize({
|
|
115
|
+
dom,
|
|
116
|
+
editor,
|
|
117
|
+
getPos: () => (typeof getPos === "function" ? getPos() : undefined),
|
|
118
|
+
getNode: () => currentNode,
|
|
119
|
+
axis: "x",
|
|
120
|
+
attr: "width",
|
|
121
|
+
min: MIN_WIDTH,
|
|
122
|
+
label: "이미지 너비 조절",
|
|
123
|
+
// 저장 형식은 단위 없는 숫자 — 살균기가 `style` 을 지우므로 `width` 속성으로 간다.
|
|
124
|
+
format: (v) => String(Math.round(v))
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/*
|
|
128
|
+
* ⚠️ `selectNode`/`deselectNode` 를 **정의하지 않는다.** 빈 함수로라도 두는 순간
|
|
129
|
+
* ProseMirror 가 `ProseMirror-selectednode` 클래스를 직접 붙이지 않고 그 콜백에
|
|
130
|
+
* 맡겨 버려서, 선택 테두리 CSS 가 통째로 죽는다(PDF 재설계 때 실제로 밟았다).
|
|
131
|
+
*/
|
|
132
|
+
return {
|
|
133
|
+
dom,
|
|
134
|
+
update: (updated) => {
|
|
135
|
+
if (updated.type !== currentNode.type)
|
|
136
|
+
return false;
|
|
137
|
+
applyAttrs(updated.attrs);
|
|
138
|
+
currentNode = updated;
|
|
139
|
+
return true;
|
|
140
|
+
},
|
|
141
|
+
destroy: () => {
|
|
142
|
+
detachResize?.();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
export default ResizableImage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResizableImage.test.d.ts","sourceRoot":"","sources":["../../src/extensions/ResizableImage.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { Editor } from "@tiptap/core";
|
|
3
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
4
|
+
import { ResizableImage, normalizeImageWidth } from "./ResizableImage";
|
|
5
|
+
import { sanitizeHtml } from "../utils/sanitize";
|
|
6
|
+
let editor = null;
|
|
7
|
+
const make = (content) => {
|
|
8
|
+
editor = new Editor({
|
|
9
|
+
element: document.createElement("div"),
|
|
10
|
+
extensions: [StarterKit, ResizableImage.configure({ inline: false })],
|
|
11
|
+
content
|
|
12
|
+
});
|
|
13
|
+
return editor;
|
|
14
|
+
};
|
|
15
|
+
const imageAttrs = (e) => {
|
|
16
|
+
const node = e.getJSON().content?.find((n) => n.type === "image");
|
|
17
|
+
return node?.attrs ?? null;
|
|
18
|
+
};
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
editor?.destroy();
|
|
21
|
+
editor = null;
|
|
22
|
+
});
|
|
23
|
+
describe("normalizeImageWidth", () => {
|
|
24
|
+
it("숫자·px·공백을 단위 없는 정수로 만든다", () => {
|
|
25
|
+
expect(normalizeImageWidth("480")).toBe(480);
|
|
26
|
+
expect(normalizeImageWidth("480px")).toBe(480);
|
|
27
|
+
expect(normalizeImageWidth(" 480px ")).toBe(480);
|
|
28
|
+
expect(normalizeImageWidth(480.4)).toBe(480);
|
|
29
|
+
});
|
|
30
|
+
it("px 로 환산할 수 없는 값은 버린다", () => {
|
|
31
|
+
// 컨테이너 폭을 모르는 시점이라 `%` 를 px 로 바꿀 수 없다.
|
|
32
|
+
// 억지로 숫자만 뽑으면 `50%` 가 `50px` 이 되어 이미지가 손톱만 해진다.
|
|
33
|
+
expect(normalizeImageWidth("50%")).toBeNull();
|
|
34
|
+
expect(normalizeImageWidth("20em")).toBeNull();
|
|
35
|
+
expect(normalizeImageWidth("auto")).toBeNull();
|
|
36
|
+
expect(normalizeImageWidth("")).toBeNull();
|
|
37
|
+
expect(normalizeImageWidth(null)).toBeNull();
|
|
38
|
+
expect(normalizeImageWidth(0)).toBeNull();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("ResizableImage", () => {
|
|
42
|
+
it("노드 이름은 그대로 image 다 (저장본이 전부 image 노드다)", () => {
|
|
43
|
+
const e = make("<p></p>");
|
|
44
|
+
expect(e.extensionManager.extensions.find((x) => x.name === "image")).toBeDefined();
|
|
45
|
+
});
|
|
46
|
+
/*
|
|
47
|
+
* 가장 중요한 케이스. **열었다 저장하는 것만으로 크기가 박히면 안 된다** —
|
|
48
|
+
* 손대지 않은 이미지가 그 시점의 렌더 폭에 고정되면 반응형이 죽는다.
|
|
49
|
+
*/
|
|
50
|
+
it("width 없는 img 는 왕복해도 width 속성이 생기지 않는다", () => {
|
|
51
|
+
const e = make('<img src="https://example.com/a.png">');
|
|
52
|
+
expect(imageAttrs(e)?.width).toBeNull();
|
|
53
|
+
const html = e.getHTML();
|
|
54
|
+
expect(html).toContain('src="https://example.com/a.png"');
|
|
55
|
+
expect(html).not.toContain("width=");
|
|
56
|
+
});
|
|
57
|
+
it('width="480" 을 480 으로 읽는다', () => {
|
|
58
|
+
const e = make('<img src="https://example.com/a.png" width="480">');
|
|
59
|
+
expect(imageAttrs(e)?.width).toBe(480);
|
|
60
|
+
});
|
|
61
|
+
it('width="480px" 도 480 으로 정규화한다', () => {
|
|
62
|
+
const e = make('<img src="https://example.com/a.png" width="480px">');
|
|
63
|
+
expect(imageAttrs(e)?.width).toBe(480);
|
|
64
|
+
});
|
|
65
|
+
it('style="width:480px" 만 있는 옛 문서도 480 으로 읽는다', () => {
|
|
66
|
+
const e = make('<img src="https://example.com/a.png" style="width: 480px">');
|
|
67
|
+
expect(imageAttrs(e)?.width).toBe(480);
|
|
68
|
+
});
|
|
69
|
+
it("퍼센트 폭은 px 로 바꾸지 않고 무시한다", () => {
|
|
70
|
+
const e = make('<img src="https://example.com/a.png" style="width: 50%">');
|
|
71
|
+
expect(imageAttrs(e)?.width).toBeNull();
|
|
72
|
+
expect(e.getHTML()).not.toContain("width=");
|
|
73
|
+
});
|
|
74
|
+
/*
|
|
75
|
+
* 저장 형식이 `style` 이면 안 된다 — 정올이 저장 HTML 을 `{@html}` 로 그릴 때
|
|
76
|
+
* 태우는 `sanitizeHtml` 의 img 허용 목록에 `style` 이 없어서 조용히 지워진다.
|
|
77
|
+
* 그러면 정적 렌더는 원래 크기, 에디터는 조절한 크기로 화면이 튄다.
|
|
78
|
+
*/
|
|
79
|
+
it("저장은 언제나 단위 없는 width 속성 한 가지다", () => {
|
|
80
|
+
const e = make('<img src="https://example.com/a.png" style="width: 480px">');
|
|
81
|
+
const html = e.getHTML();
|
|
82
|
+
expect(html).toContain('width="480"');
|
|
83
|
+
expect(html).not.toContain("480px");
|
|
84
|
+
expect(html).not.toContain("style=");
|
|
85
|
+
});
|
|
86
|
+
it("저장한 폭이 살균을 통과해도 살아남는다", () => {
|
|
87
|
+
const e = make('<img src="https://example.com/a.png" width="480">');
|
|
88
|
+
expect(sanitizeHtml(e.getHTML())).toContain('width="480"');
|
|
89
|
+
});
|
|
90
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { FixedDetails } from "./extensions/FixedDetails";
|
|
|
11
11
|
export { FileAttachment } from "./extensions/FileAttachment";
|
|
12
12
|
export type { FileResolver, FileResolveResult } from "./extensions/FileAttachment";
|
|
13
13
|
export { MbusVideo } from "./extensions/MbusVideo";
|
|
14
|
+
export { ResizableImage, normalizeImageWidth } from "./extensions/ResizableImage";
|
|
14
15
|
export { CardBlock } from "./extensions/CardBlock";
|
|
15
16
|
export type { CardBackgroundPrompt, CardBlockOptions } from "./extensions/CardBlock";
|
|
16
17
|
export { Columns } from "./extensions/Columns";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAahC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG5D,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAahC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG5D,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { Indent } from "./extensions/Indent";
|
|
|
12
12
|
export { FixedDetails } from "./extensions/FixedDetails";
|
|
13
13
|
export { FileAttachment } from "./extensions/FileAttachment";
|
|
14
14
|
export { MbusVideo } from "./extensions/MbusVideo";
|
|
15
|
+
export { ResizableImage, normalizeImageWidth } from "./extensions/ResizableImage";
|
|
15
16
|
export { CardBlock } from "./extensions/CardBlock";
|
|
16
17
|
export { Columns } from "./extensions/Columns";
|
|
17
18
|
export { Column } from "./extensions/Column";
|
package/dist/styles/editor.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.top-full{top:100%}.z-30{z-index:30}.z-50{z-index:50}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.\!table{display:table!important}.table{display:table}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-px{height:1px}.min-h-\[52px\]{min-height:52px}.w-10{width:2.5rem}.w-\[360px\]{width:360px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-\[96px\]{min-width:96px}.max-w-\[90vw\]{max-width:90vw}.flex-shrink{flex-shrink:1}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\!transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.resize{resize:both}.columns-2{-moz-columns:2;column-count:2}.columns-3{-moz-columns:3;column-count:3}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:var(--radius-md,4px)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-xl,8px)}.rounded-md{border-radius:var(--radius-md,6px)}.rounded-xl{border-radius:var(--radius-2xl,12px)}.rounded-t-xl{border-top-left-radius:var(--radius-2xl,12px);border-top-right-radius:var(--radius-2xl,12px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-border{border-color:var(--border)}.bg-background{background-color:var(--background)}.bg-black\/40{background-color:rgba(0,0,0,.4)}.bg-border{background-color:var(--border)}.bg-popover{background-color:var(--popover)}.bg-transparent{background-color:transparent}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[11px\]{font-size:11px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-destructive{color:var(--destructive)}.text-muted-foreground{color:var(--muted-foreground)}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.shadow-lg{--tw-shadow:var(--shadow-dropdown,0 10px 15px -3px rgba(0,0,0,.1));--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:var(--shadow-popup,0 20px 25px -5px rgba(0,0,0,.1));--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hce-editor-wrapper{overflow:visible!important}.hce-color-divider{border-top:1px solid var(--border)}.bubble-toolbar-container button,.hce-editor-wrapper button,.slash-menu button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;cursor:pointer;box-sizing:border-box}.bubble-toolbar-container button:disabled,.hce-editor-wrapper button:disabled,.slash-menu button:disabled{cursor:default}.bubble-toolbar-container .hce-btn-primary,.hce-editor-wrapper .hce-btn-primary,.slash-menu .hce-btn-primary{background-color:var(--primary);color:var(--primary-foreground,#fff)}.tiptap{font-size:1.0625rem;line-height:1.8;color:var(--foreground);padding:1.5rem}.tiptap>*+*{margin-top:.25em}.tiptap [data-type=column]>:first-child,.tiptap [data-type=detailsContent]>:first-child,.tiptap blockquote>:first-child,.tiptap li>:first-child,.tiptap td>:first-child,.tiptap th>:first-child,.tiptap>:first-child{margin-top:0}.tiptap [data-type=column]>:last-child,.tiptap [data-type=detailsContent]>:last-child,.tiptap blockquote>:last-child,.tiptap li>:last-child,.tiptap td>:last-child,.tiptap th>:last-child,.tiptap>:last-child{margin-bottom:0}.tiptap p{margin:.5em 0!important;line-height:1.5}.tiptap p:first-child{margin-top:0!important}.tiptap p:last-child{margin-bottom:0!important}.tiptap p:empty,.tiptap p:has(>br:only-child){min-height:1.5em}.tiptap h1,.tiptap h2,.tiptap h3,.tiptap li,.tiptap p{white-space:pre-wrap}.tiptap h1{font-size:2rem;font-weight:700;margin:1.5em 0 .5em;line-height:1.25}.tiptap h2{font-size:1.5rem;font-weight:600;margin:1.2em 0 .4em;line-height:1.3}.tiptap h3{font-size:1.25rem;font-weight:600;margin:1em 0 .3em;line-height:1.35}.tiptap ul{list-style:disc}.tiptap ol,.tiptap ul{padding-left:1.5em;margin:.5em 0}.tiptap ol{list-style:decimal}.tiptap ul ul{list-style:circle}.tiptap ul ul ul{list-style:square}.tiptap ol ol{list-style:lower-alpha}.tiptap ol ol ol{list-style:lower-roman}.tiptap li{margin:.4em 0;line-height:1.7}.tiptap li>p{margin:0!important;line-height:inherit!important}.tiptap ul[data-type=taskList]{list-style:none;padding-left:0}.tiptap ul[data-type=taskList] li{display:flex;align-items:baseline;gap:.5rem;margin:.3em 0;line-height:1.7;list-style:none;list-style-type:none}.tiptap ul[data-type=taskList] li>label{flex-shrink:0;display:flex;align-items:center;height:1.5em}.tiptap ul[data-type=taskList] li>label input[type=checkbox]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:1.1em;height:1.1em;margin:0;padding:0;cursor:pointer;background-color:var(--background,#fff);border:1.5px solid var(--border);border-radius:4px;transition:background-color .12s ease,border-color .12s ease,box-shadow .12s ease;display:inline-block;vertical-align:middle;flex-shrink:0}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:hover{border-color:var(--muted-foreground)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--background,#fff),0 0 0 4px var(--primary)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:checked{background-color:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' viewBox='0 0 16 16'%3E%3Cpath d='m3.5 8.5 3 3 6-6.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.tiptap ul[data-type=taskList] li>div{flex:1}.tiptap ul[data-type=taskList] li[data-checked=true]>div{text-decoration:line-through;opacity:.6}.tiptap blockquote{border-left:3px solid var(--border);padding:.5rem 1rem;margin:.75em 0;color:var(--muted-foreground);font-style:italic}.tiptap hr{border:none;border-top:2px solid color-mix(in srgb,var(--foreground) 38%,transparent);margin:1.5em 0}.tiptap code{background:var(--muted);border-radius:4px;padding:.15em .35em;font-size:.9em}.tiptap pre{background:#282c34;color:#abb2bf;border-radius:8px;padding:1em;margin:.75em 0;overflow-x:auto;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:1em;line-height:1.6}.tiptap pre code{background:none;padding:0;border-radius:0;color:#abb2bf;font-size:inherit}.tiptap pre code .hljs-keyword,.tiptap pre code .hljs-operator{color:#c678dd}.tiptap pre code .hljs-addition,.tiptap pre code .hljs-doctag,.tiptap pre code .hljs-regexp,.tiptap pre code .hljs-string{color:#98c379}.tiptap pre code .hljs-attr,.tiptap pre code .hljs-number,.tiptap pre code .hljs-selector-class,.tiptap pre code .hljs-template-variable,.tiptap pre code .hljs-type,.tiptap pre code .hljs-variable{color:#d19a66}.tiptap pre code .hljs-function,.tiptap pre code .hljs-section,.tiptap pre code .hljs-title,.tiptap pre code .hljs-title.class_{color:#61aeee}.tiptap pre code .hljs-params,.tiptap pre code .hljs-punctuation{color:#abb2bf}.tiptap pre code .hljs-comment,.tiptap pre code .hljs-quote{color:#5c6370;font-style:italic}.tiptap pre code .hljs-built_in,.tiptap pre code .hljs-formula{color:#e6c07b}.tiptap pre code .hljs-meta,.tiptap pre code .hljs-meta .hljs-keyword{color:#61aeee}.tiptap pre code .hljs-meta .hljs-string{color:#98c379}.tiptap pre code .hljs-attribute,.tiptap pre code .hljs-deletion,.tiptap pre code .hljs-name,.tiptap pre code .hljs-property,.tiptap pre code .hljs-selector-tag,.tiptap pre code .hljs-subst,.tiptap pre code .hljs-tag{color:#e06c75}.tiptap pre code .hljs-literal{color:#56b6c2}.tiptap pre code .hljs-selector-attr,.tiptap pre code .hljs-selector-id,.tiptap pre code .hljs-selector-pseudo{color:#61aeee}.tiptap pre code .hljs-link{color:#61aeee;text-decoration:underline}.tiptap pre code .hljs-bullet,.tiptap pre code .hljs-symbol{color:#61aeee}.tiptap pre code .hljs-emphasis{font-style:italic}.tiptap pre code .hljs-strong{font-weight:700}.tiptap img{max-width:100%;height:auto;border-radius:8px;margin:.75em 0;cursor:pointer;transition:box-shadow .15s}.pdf-frame{position:relative;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:8px;background:var(--muted)}.pdf-frame canvas{display:block;max-width:100%;border-radius:7px}.pdf-frame:focus{outline:1px solid var(--primary);outline-offset:2px}.pdf-overlay{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .15s ease;-moz-user-select:none;user-select:none;-webkit-user-select:none}.pdf-overlay .pdf-page-input{-moz-user-select:text;user-select:text;-webkit-user-select:text}.pdf-frame:hover .pdf-overlay,.pdf-overlay:focus-within,.tiptap[contenteditable=true] [data-type=pdfBlock].ProseMirror-selectednode .pdf-overlay{opacity:1}@media (hover:none){.pdf-overlay{opacity:1}}@media (prefers-reduced-motion:reduce){.pdf-overlay{transition:none}}.pdf-cluster{position:absolute;display:flex;align-items:center;gap:2px;padding:3px 5px;border-radius:999px;background:rgba(24,24,27,.42);backdrop-filter:blur(10px) saturate(1.1);color:#fff;pointer-events:auto;max-width:calc(100% - 12px);transition:background-color .15s ease}.pdf-cluster:hover{background:rgba(24,24,27,.62)}.pdf-cluster-end{top:6px;right:8px}.pdf-cluster-page{bottom:6px;left:50%;transform:translateX(-50%)}.pdf-nav-rail{position:sticky;top:0;height:100vh;max-height:100%;pointer-events:none}.pdf-nav{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto}.pdf-nav-prev{left:12px}.pdf-nav-next{right:12px}.pdf-overlay .pdf-ctl,.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;padding:0;color:#e4e4e7;font-family:inherit;cursor:pointer;opacity:.92;transition:opacity .12s,color .12s}.pdf-overlay .pdf-ctl{width:20px;height:20px;flex:none}.pdf-overlay .pdf-ctl svg{width:14px;height:14px}.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{font-weight:500}.pdf-overlay .pdf-ctl:hover,.pdf-overlay .pdf-page:hover,.pdf-overlay .pdf-preset:hover{opacity:1;color:#fff}.pdf-overlay .pdf-ctl:disabled{opacity:.4;cursor:default}.pdf-overlay .pdf-ctl-danger:hover{opacity:1;color:#ff8f8f}.pdf-overlay .pdf-ctl:focus-visible,.pdf-overlay .pdf-page-input:focus-visible,.pdf-overlay .pdf-page:focus-visible,.pdf-overlay .pdf-preset:focus-visible{outline:2px solid hsla(0,0%,100%,.85);outline-offset:2px;border-radius:4px;opacity:1}.pdf-overlay .pdf-preset{height:18px;font-size:11px;line-height:1;font-variant-numeric:tabular-nums;flex:none}.pdf-overlay .pdf-preset.is-active,.pdf-overlay .pdf-preset.is-active:hover{opacity:1;color:#fff;font-weight:600;box-shadow:inset 0 -1px 0 0 currentColor}.pdf-overlay .pdf-fit{width:19px;height:18px;border-radius:3px}.pdf-overlay .pdf-fit svg{width:13px;height:13px}.pdf-overlay .pdf-fit.is-active,.pdf-overlay .pdf-fit.is-active:hover{opacity:1;color:#fff;box-shadow:inset 0 -1px 0 0 currentColor}.pdf-overlay [data-tip]{position:relative}.pdf-overlay [data-tip]:after{content:attr(data-tip);position:absolute;top:calc(100% + 7px);right:0;z-index:1;white-space:nowrap;font-size:11px;line-height:1.4;font-weight:400;padding:4px 8px;border-radius:5px;background:rgba(24,24,27,.94);backdrop-filter:blur(6px);color:#fff;box-shadow:0 4px 12px rgba(0,0,0,.35);opacity:0;pointer-events:none;transition:opacity .12s ease .35s}.pdf-overlay [data-tip]:focus-visible:after,.pdf-overlay [data-tip]:hover:after{opacity:1}.pdf-cluster-page [data-tip]:after{top:auto;bottom:calc(100% + 7px)}.pdf-nav-prev[data-tip]:after{right:auto;left:0}.pdf-overlay .pdf-page{height:16px;font-size:10px;line-height:1;font-variant-numeric:tabular-nums}.pdf-cluster-page{padding:2px 6px}.pdf-overlay .pdf-nav{width:30px;height:30px;padding:0;background:rgba(24,24,27,.42)}.pdf-overlay .pdf-nav:hover{background:rgba(24,24,27,.62)}.pdf-overlay .pdf-nav svg{width:18px;height:18px}.pdf-overlay .pdf-nav:disabled{opacity:.4}.pdf-divider{flex:none;width:1px;height:11px;margin:0 3px;background:hsla(0,0%,100%,.3)}.pdf-overlay .pdf-page-input{box-sizing:border-box;height:20px;width:46px;padding:0 5px;font-size:12px;text-align:center;font-variant-numeric:tabular-nums;background:rgba(24,24,27,.85);border:1px solid hsla(0,0%,100%,.5);color:#fff;border-radius:4px;font-family:inherit;outline:none}.pdf-status{display:flex;align-items:center;justify-content:center;gap:8px;padding:2.5rem 1rem;font-size:.875rem;color:var(--muted-foreground);text-align:center}.tiptap a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}.tiptap a:hover{opacity:.8}.tiptap mark{background-color:#fef08a;border-radius:2px;padding:.05em .1em}.tiptap [data-type=details]{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;display:grid;grid-template-columns:30px 1fr;align-items:start;transition:background .12s}.tiptap [data-type=details]:hover{background:var(--muted)}.tiptap [data-type=details]>button{background:none;border:none;cursor:pointer;padding:0;font:inherit;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;color:var(--muted-foreground);border-radius:4px;transition:transform .2s,color .15s,background-color .15s;flex-shrink:0;margin-top:calc(-2px + 1lh/2);margin-left:4px}.tiptap [data-type=details]>button:hover{background:color-mix(in srgb,var(--foreground) 8%,transparent)}.tiptap [data-type=details]>button:after{content:"";display:block;width:0;height:0;border-left:clamp(6px,.42em,11px) solid;border-top:clamp(4.7px,.33em,8.6px) solid transparent;border-bottom:clamp(4.7px,.33em,8.6px) solid transparent;margin-left:2px}.tiptap [data-type=details]:hover>button{color:var(--foreground)}.tiptap [data-type=details].is-open>button{transform:rotate(90deg)}.tiptap [data-type=details]>div{flex:1;min-width:0}.tiptap [data-type=details] summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 0;display:block;border-bottom:1px solid transparent;transition:border-color .15s}.tiptap [data-type=details].is-open>div>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap [data-type=details] summary[data-level="1"],.tiptap details summary[data-level="1"]{font-size:2rem;font-weight:700;line-height:1.25}.tiptap [data-type=details] summary[data-level="2"],.tiptap details summary[data-level="2"]{font-size:1.5rem;font-weight:600;line-height:1.3}.tiptap [data-type=details] summary[data-level="3"],.tiptap details summary[data-level="3"]{font-size:1.25rem;font-weight:600;line-height:1.35}.tiptap [data-type=details]:has(>div>summary[data-level="1"])>button{font-size:2rem;line-height:1.25}.tiptap [data-type=details]:has(>div>summary[data-level="2"])>button{font-size:1.5rem;line-height:1.3}.tiptap [data-type=details]:has(>div>summary[data-level="3"])>button{font-size:1.25rem;line-height:1.35}.tiptap [data-type=detailsContent]{padding:8px 8px 8px 0;border-left:none}.tiptap [data-type=detailsContent][hidden]{display:none}.tiptap details{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;transition:background .12s}.tiptap details:hover{background:var(--muted)}.tiptap details summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 26px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-bottom:1px solid transparent;position:relative;list-style:none;transition:border-color .15s}.tiptap details[open]>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap details summary::-webkit-details-marker{display:none}.tiptap details summary::marker{content:""}.tiptap details summary:before{content:"";position:absolute;left:8px;top:25px;top:calc(10px + .5lh);width:0;height:0;border-left:clamp(6px,.42em,11px) solid var(--muted-foreground);border-top:clamp(4.7px,.33em,8.6px) solid transparent;border-bottom:clamp(4.7px,.33em,8.6px) solid transparent;transform:translateY(-50%);transition:transform .2s,border-left-color .15s}.tiptap details:hover summary:before{border-left-color:var(--foreground)}.tiptap details[open]>summary:before{transform:translateY(-50%) rotate(90deg)}.tiptap details[open]>:not(summary){margin-top:8px;padding-left:26px;padding-right:8px}.tiptap table{border-collapse:collapse;margin:1em 0;table-layout:fixed;border:2px solid var(--border);max-width:100%}.tiptap .tableWrapper{overflow-x:auto;max-width:100%}.tiptap td,.tiptap th{border:1px solid var(--border);padding:.6em .8em;min-width:60px;vertical-align:middle;position:relative;box-sizing:border-box;overflow:hidden;word-break:break-word;line-height:1.5}.tiptap th{background:var(--muted);font-weight:600;text-align:left}.tiptap td{background:var(--background)}.tiptap .selectedCell:after{content:"";position:absolute;inset:0;background:var(--primary);opacity:.12;pointer-events:none;z-index:1}.tiptap .column-resize-handle{position:absolute;right:-3px;top:-1px;bottom:-1px;width:6px;background:var(--primary);opacity:0;cursor:col-resize;z-index:20;border-radius:2px;transition:opacity .15s}.tiptap table:hover .column-resize-handle{opacity:.4}.tiptap .column-resize-handle:hover{opacity:1}.tiptap.resize-cursor{cursor:col-resize}.tableWrapper{overflow-x:auto;overflow-y:hidden;margin:1em 0;max-width:100%;padding-right:4px}.tiptap table .grip-column,.tiptap table .grip-row,.tiptap table .grip-table{display:none!important}.tiptap .is-empty:before{content:attr(data-placeholder);float:left;color:var(--muted-foreground);opacity:.5;pointer-events:none;height:0}.tiptap h1.is-empty:before{font-size:2rem;font-weight:700}.tiptap h2.is-empty:before{font-size:1.5rem;font-weight:600}.tiptap h3.is-empty:before{font-size:1.25rem;font-weight:600}.ProseMirror-gapcursor{display:none;pointer-events:none;position:relative}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--foreground);animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror-dropcursor{border-top:2px solid var(--primary);margin:-1px 0}.tiptap ::-moz-selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.tiptap ::selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.ProseMirror-noderangeselection ::-moz-selection{background:transparent}.ProseMirror-noderangeselection ::selection{background:transparent}.ProseMirror-noderangeselection *{caret-color:transparent}.ProseMirror-selectednode,.ProseMirror-selectednoderange{position:relative}.ProseMirror-selectednode:not(img):not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before,.ProseMirror-selectednoderange:not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before{content:"";position:absolute;inset:-.25rem;background-color:color-mix(in srgb,var(--primary) 10%,transparent);border:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:.5rem;pointer-events:none;z-index:-1}.tiptap[contenteditable=true] [data-type=mbusVideo].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=pdfBlock].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=videoEmbed].ProseMirror-selectednode,.tiptap[contenteditable=true] img.ProseMirror-selectednode{outline:1px solid var(--primary);outline-offset:2px;border-radius:8px}.hce-table-bubble{z-index:var(--hce-menu-z,100)}.bubble-toolbar-container{position:absolute;top:0;left:0;width:-moz-max-content;width:max-content;z-index:calc(var(--hce-menu-z, 100) + 1)}.hce-toolbar:has(.absolute)~.bubble-toolbar-container,.hce-toolbar:has(.absolute)~.hce-table-bubble{display:none}.hce-menu-surface{background-color:var(--hce-menu-surface,#333)}.hce-floating-panel{background-color:color-mix(in srgb,var(--foreground) 8%,var(--popover,var(--background,#fff)));border:1px solid color-mix(in srgb,var(--foreground) 18%,var(--border));box-shadow:0 8px 24px color-mix(in srgb,var(--foreground) 16%,transparent),0 2px 6px color-mix(in srgb,var(--foreground) 10%,transparent)}.hce-floating-plus{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;border:1px solid var(--border);background:var(--background);color:var(--muted-foreground);cursor:pointer;transition:all .15s}.hce-floating-plus:hover{color:var(--foreground);border-color:var(--foreground);background:var(--muted)}.hce-drag-handle{display:flex;align-items:center;gap:2px}.hce-drag-handle__plus{display:flex;align-items:center;justify-content:center;padding:4px;border-radius:4px;border:none;background:transparent;color:var(--muted-foreground);opacity:.5;cursor:pointer;transition:opacity .15s,background-color .15s}.hce-drag-handle__plus:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip{display:flex;align-items:center;justify-content:center;padding:2px;border-radius:4px;color:var(--muted-foreground);opacity:.5;cursor:grab;transition:opacity .15s,background-color .15s}.hce-drag-handle__grip:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip:active{cursor:grabbing}.tiptap div[data-type=columns]{display:grid;gap:16px;margin:1em 0}.tiptap div[data-type=columns][data-columns="2"]{grid-template-columns:1fr 1fr}.tiptap div[data-type=columns][data-columns="3"]{grid-template-columns:1fr 1fr 1fr}.tiptap div[data-type=column]{min-width:0;padding:4px 6px;border:1px dashed var(--border);border-radius:8px}.tiptap[contenteditable=true] div[data-type=column]:focus-within{border-color:var(--primary);border-style:solid}.tiptap div[data-type=columns].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:8px}@media (max-width:640px){.tiptap div[data-type=columns]{grid-template-columns:1fr!important}}[data-type=tabs]{margin:1em 0;border:1px solid var(--border);border-radius:10px;overflow:hidden}[data-type=tabs].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent)}.hce-tabs-bar{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:5px 6px;border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--muted) 55%,transparent);-webkit-user-select:none;-moz-user-select:none;user-select:none}.hce-tab-chip{position:relative;display:inline-flex;align-items:center;gap:2px;padding-right:2px;border-radius:6px;color:var(--muted-foreground);touch-action:none}.hce-tab-chip:hover{background:color-mix(in srgb,var(--primary) 8%,transparent)}.hce-tab-chip.is-active{background:color-mix(in srgb,var(--primary) 14%,transparent);color:var(--primary)}.hce-tab-chip-label{max-width:14rem;padding:3px 8px;border:0;background:transparent;color:inherit;font:inherit;font-size:.8125rem;font-weight:500;line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.hce-tab-chip.is-active .hce-tab-chip-label{font-weight:600}.hce-tab-chip-close{display:inline-flex;visibility:hidden;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:4px;background:transparent;color:inherit;font-size:13px;line-height:1;cursor:pointer}.hce-tab-chip:hover .hce-tab-chip-close:not(.is-disabled){visibility:visible}.hce-tab-chip-close.is-disabled{cursor:default;pointer-events:none}.hce-tab-chip-close:hover{background:color-mix(in srgb,var(--foreground) 12%,transparent)}.hce-tabs-add{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--muted-foreground);font-size:15px;line-height:1;cursor:pointer}.hce-tabs-add:hover{background:color-mix(in srgb,var(--primary) 10%,transparent);color:var(--primary)}.hce-tabs-bar.is-dragging{cursor:grabbing}.hce-tab-chip.is-dragged{opacity:.45}.hce-tabs-bar.is-dragging .hce-tab-chip:hover .hce-tab-chip-close{visibility:hidden}.hce-tab-chip.is-drop-after:after,.hce-tab-chip.is-drop-before:before{content:"";position:absolute;top:2px;bottom:2px;width:2px;border-radius:1px;background:var(--primary)}.hce-tab-chip.is-drop-before:before{left:-3px}.hce-tab-chip.is-drop-after:after{right:-3px}.hce-tab-title-input{box-sizing:border-box;width:8rem;margin:2px;padding:2px 6px;border:1px solid var(--primary);border-radius:4px;background:var(--background);color:var(--foreground);font:inherit;font-size:.8125rem;outline:none}.hce-tabs-panels{padding:10px 12px}.hce-tabs-panels>[data-type=tab]{display:none}.hce-tabs-panels>[data-type=tab].hce-tab-active{display:block}[data-type=tabs]:not(.hce-tabs-live)>[data-type=tab]{display:none}[data-type=tabs]:not(.hce-tabs-live)>[data-type=tab]:first-child{display:block;padding:10px 12px}[data-type=tabs]:not(.hce-tabs-live):before{content:"";display:block;height:2rem;border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--muted) 55%,transparent)}[data-type=tab]>p:only-child:empty:before,[data-type=tab]>p:only-child:has(>br:only-child):before{content:"빈 탭입니다. 내부를 클릭하거나 블록을 넣으세요.";float:left;height:0;color:var(--muted-foreground);opacity:.5;pointer-events:none}.hce-table-btn-wrap{position:relative;display:inline-flex}.hce-table-btn-tooltip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:6px;padding:4px 8px;font-size:11px;line-height:1.2;white-space:nowrap;color:#fff;background:#1e293b;border-radius:6px;pointer-events:none;opacity:0;transition:opacity .15s;z-index:60}.hce-table-btn-wrap:hover .hce-table-btn-tooltip{opacity:1}.hce-table-btn-wrap.hce-tooltip-off:hover .hce-table-btn-tooltip{opacity:0}.tiptap math-inline,math-inline.math-node{display:inline-block;vertical-align:baseline}.tiptap math-display,math-display.math-node{display:block;margin:.9em 0;text-align:center}.math-node,.tiptap .math-node{font-size:.95em}.tiptap math-inline.math-node .katex,math-inline.math-node .katex{font-size:1.0285em}.tiptap[contenteditable=true] .math-node{cursor:pointer;border-radius:4px;transition:background-color .12s}.tiptap[contenteditable=true] .math-node:hover{background-color:color-mix(in srgb,var(--primary) 10%,transparent)}.tiptap .math-node.ProseMirror-selectednode{background-color:color-mix(in srgb,var(--primary) 18%,transparent);outline:1px solid color-mix(in srgb,var(--primary) 45%,transparent)}.tiptap .math-node.empty-math .math-placeholder{font-size:.85em;padding:0 .35em;color:var(--muted-foreground);border:1px dashed var(--border);border-radius:4px}.math-node .math-error,.tiptap .math-error{color:#dc2626;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.hce-card-frame,.tiptap [data-type=card]{position:relative}.hce-card-frame{box-sizing:border-box;width:100%;margin:12px 0;padding:26px 30px;display:flex;flex-direction:column;justify-content:center;gap:12px;overflow:hidden;border:1px solid hsla(0,0%,100%,.52);border-radius:8px;box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.28),0 8px 24px rgba(15,23,42,.08);overflow-wrap:anywhere;isolation:isolate}.hce-card-frame:before{content:"";position:absolute;inset:0;z-index:0;background:linear-gradient(90deg,hsla(0,0%,100%,.14),hsla(0,0%,100%,.04) 48%,rgba(15,23,42,.08));pointer-events:none}.hce-card-content{position:relative;z-index:1;box-sizing:border-box;width:100%;max-height:100%;min-height:0;padding:18px 20px;display:flex;flex-direction:column;gap:10px;overflow:hidden;border:1px solid hsla(0,0%,100%,.56);border-radius:8px;background:hsla(0,0%,100%,.82);color:#111827;box-shadow:0 14px 42px rgba(15,23,42,.12),inset 0 1px 0 hsla(0,0%,100%,.52);backdrop-filter:blur(18px) saturate(1.16);-webkit-backdrop-filter:blur(18px) saturate(1.16)}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.hce-card-content{background:hsla(0,0%,100%,.9)}}.hce-card-header{flex:0 0 auto}.hce-card-title{margin:0;font-size:1.65rem;font-weight:700;line-height:1.18;color:#111827}.hce-card-title[hidden]{display:none}.hce-card-title-input{box-sizing:border-box;width:100%;padding:8px 12px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.7);color:#111827;font:inherit;font-size:1.15rem;font-weight:700;outline:none}.hce-card-title-input:focus{border-color:var(--primary,#3382f2)}.hce-card-body{flex:1 1 auto;min-height:0;overflow:auto;font-size:1rem;line-height:1.55;color:#111827}.hce-card-body>p:first-child{margin-top:0}.hce-card-body>p:last-child{margin-bottom:0}.hce-card-bg-button{position:absolute;top:8px;right:8px;z-index:3;padding:4px 10px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.86);color:#111827;font-size:.8125rem;line-height:1.4;cursor:pointer}.hce-card-bg-button:hover{background:#fff}@media (max-width:640px){.hce-card-frame{padding:18px}.hce-card-content{padding:14px 16px}.hce-card-title{font-size:1.35rem}}.hce-active{background-color:color-mix(in srgb,var(--primary) 12%,transparent);color:var(--primary)}.hce-active:hover{background-color:color-mix(in srgb,var(--primary) 18%,transparent)}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-105:hover,.hover\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-red-300:hover{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-primary:focus{border-color:var(--primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}
|
|
1
|
+
.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.top-full{top:100%}.z-30{z-index:30}.z-50{z-index:50}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.\!table{display:table!important}.table{display:table}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-px{height:1px}.min-h-\[52px\]{min-height:52px}.w-10{width:2.5rem}.w-\[360px\]{width:360px}.w-\[420px\]{width:420px}.w-\[440px\]{width:440px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.min-w-\[96px\]{min-width:96px}.max-w-\[90vw\]{max-width:90vw}.flex-shrink{flex-shrink:1}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\!transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.resize{resize:both}.columns-2{-moz-columns:2;column-count:2}.columns-3{-moz-columns:3;column-count:3}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:var(--radius-md,4px)}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius-xl,8px)}.rounded-md{border-radius:var(--radius-md,6px)}.rounded-xl{border-radius:var(--radius-2xl,12px)}.rounded-t-xl{border-top-left-radius:var(--radius-2xl,12px);border-top-right-radius:var(--radius-2xl,12px)}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-border{border-color:var(--border)}.bg-background{background-color:var(--background)}.bg-black\/40{background-color:rgba(0,0,0,.4)}.bg-border{background-color:var(--border)}.bg-popover{background-color:var(--popover)}.bg-transparent{background-color:transparent}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[11px\]{font-size:11px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-destructive{color:var(--destructive)}.text-muted-foreground{color:var(--muted-foreground)}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.shadow-lg{--tw-shadow:var(--shadow-dropdown,0 10px 15px -3px rgba(0,0,0,.1));--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:var(--shadow-popup,0 20px 25px -5px rgba(0,0,0,.1));--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.hce-editor-wrapper{overflow:visible!important}.hce-color-divider{border-top:1px solid var(--border)}.bubble-toolbar-container button,.hce-editor-wrapper button,.slash-menu button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;cursor:pointer;box-sizing:border-box}.bubble-toolbar-container button:disabled,.hce-editor-wrapper button:disabled,.slash-menu button:disabled{cursor:default}.bubble-toolbar-container .hce-btn-primary,.hce-editor-wrapper .hce-btn-primary,.slash-menu .hce-btn-primary{background-color:var(--primary);color:var(--primary-foreground,#fff)}.tiptap{font-size:1.0625rem;line-height:1.8;color:var(--foreground);padding:1.5rem}.tiptap>*+*{margin-top:.25em}.tiptap [data-type=column]>:first-child,.tiptap [data-type=detailsContent]>:first-child,.tiptap blockquote>:first-child,.tiptap li>:first-child,.tiptap td>:first-child,.tiptap th>:first-child,.tiptap>:first-child{margin-top:0}.tiptap [data-type=column]>:last-child,.tiptap [data-type=detailsContent]>:last-child,.tiptap blockquote>:last-child,.tiptap li>:last-child,.tiptap td>:last-child,.tiptap th>:last-child,.tiptap>:last-child{margin-bottom:0}.tiptap p{margin:.5em 0!important;line-height:1.5}.tiptap p:first-child{margin-top:0!important}.tiptap p:last-child{margin-bottom:0!important}.tiptap p:empty,.tiptap p:has(>br:only-child){min-height:1.5em}.tiptap h1,.tiptap h2,.tiptap h3,.tiptap li,.tiptap p{white-space:pre-wrap}.tiptap h1{font-size:2rem;font-weight:700;margin:1.5em 0 .5em;line-height:1.25}.tiptap h2{font-size:1.5rem;font-weight:600;margin:1.2em 0 .4em;line-height:1.3}.tiptap h3{font-size:1.25rem;font-weight:600;margin:1em 0 .3em;line-height:1.35}.tiptap ul{list-style:disc}.tiptap ol,.tiptap ul{padding-left:1.5em;margin:.5em 0}.tiptap ol{list-style:decimal}.tiptap ul ul{list-style:circle}.tiptap ul ul ul{list-style:square}.tiptap ol ol{list-style:lower-alpha}.tiptap ol ol ol{list-style:lower-roman}.tiptap li{margin:.4em 0;line-height:1.7}.tiptap li>p{margin:0!important;line-height:inherit!important}.tiptap ul[data-type=taskList]{list-style:none;padding-left:0}.tiptap ul[data-type=taskList] li{display:flex;align-items:baseline;gap:.5rem;margin:.3em 0;line-height:1.7;list-style:none;list-style-type:none}.tiptap ul[data-type=taskList] li>label{flex-shrink:0;display:flex;align-items:center;height:1.5em}.tiptap ul[data-type=taskList] li>label input[type=checkbox]{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:1.1em;height:1.1em;margin:0;padding:0;cursor:pointer;background-color:var(--background,#fff);border:1.5px solid var(--border);border-radius:4px;transition:background-color .12s ease,border-color .12s ease,box-shadow .12s ease;display:inline-block;vertical-align:middle;flex-shrink:0}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:hover{border-color:var(--muted-foreground)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--background,#fff),0 0 0 4px var(--primary)}.tiptap ul[data-type=taskList] li>label input[type=checkbox]:checked{background-color:var(--primary);border-color:var(--primary);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' viewBox='0 0 16 16'%3E%3Cpath d='m3.5 8.5 3 3 6-6.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.tiptap ul[data-type=taskList] li>div{flex:1}.tiptap ul[data-type=taskList] li[data-checked=true]>div{text-decoration:line-through;opacity:.6}.tiptap blockquote{border-left:3px solid var(--border);padding:.5rem 1rem;margin:.75em 0;color:var(--muted-foreground);font-style:italic}.tiptap hr{border:none;border-top:2px solid color-mix(in srgb,var(--foreground) 38%,transparent);margin:1.5em 0}.tiptap code{background:var(--muted);border-radius:4px;padding:.15em .35em;font-size:.9em}.tiptap pre{background:#282c34;color:#abb2bf;border-radius:8px;padding:1em;margin:.75em 0;overflow-x:auto;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:1em;line-height:1.6}.tiptap pre code{background:none;padding:0;border-radius:0;color:#abb2bf;font-size:inherit}.tiptap pre code .hljs-keyword,.tiptap pre code .hljs-operator{color:#c678dd}.tiptap pre code .hljs-addition,.tiptap pre code .hljs-doctag,.tiptap pre code .hljs-regexp,.tiptap pre code .hljs-string{color:#98c379}.tiptap pre code .hljs-attr,.tiptap pre code .hljs-number,.tiptap pre code .hljs-selector-class,.tiptap pre code .hljs-template-variable,.tiptap pre code .hljs-type,.tiptap pre code .hljs-variable{color:#d19a66}.tiptap pre code .hljs-function,.tiptap pre code .hljs-section,.tiptap pre code .hljs-title,.tiptap pre code .hljs-title.class_{color:#61aeee}.tiptap pre code .hljs-params,.tiptap pre code .hljs-punctuation{color:#abb2bf}.tiptap pre code .hljs-comment,.tiptap pre code .hljs-quote{color:#5c6370;font-style:italic}.tiptap pre code .hljs-built_in,.tiptap pre code .hljs-formula{color:#e6c07b}.tiptap pre code .hljs-meta,.tiptap pre code .hljs-meta .hljs-keyword{color:#61aeee}.tiptap pre code .hljs-meta .hljs-string{color:#98c379}.tiptap pre code .hljs-attribute,.tiptap pre code .hljs-deletion,.tiptap pre code .hljs-name,.tiptap pre code .hljs-property,.tiptap pre code .hljs-selector-tag,.tiptap pre code .hljs-subst,.tiptap pre code .hljs-tag{color:#e06c75}.tiptap pre code .hljs-literal{color:#56b6c2}.tiptap pre code .hljs-selector-attr,.tiptap pre code .hljs-selector-id,.tiptap pre code .hljs-selector-pseudo{color:#61aeee}.tiptap pre code .hljs-link{color:#61aeee;text-decoration:underline}.tiptap pre code .hljs-bullet,.tiptap pre code .hljs-symbol{color:#61aeee}.tiptap pre code .hljs-emphasis{font-style:italic}.tiptap pre code .hljs-strong{font-weight:700}.tiptap img{max-width:100%;height:auto;border-radius:8px;margin:.75em 0;cursor:pointer;transition:box-shadow .15s}.tiptap .hce-image{position:relative;display:block;width:-moz-fit-content;width:fit-content;max-width:100%;margin:.75em 0;box-sizing:border-box}.tiptap .hce-image img{display:block;width:100%;height:auto;margin:0}.pdf-frame{position:relative;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:8px;background:var(--muted)}.pdf-frame canvas{display:block;max-width:100%;border-radius:7px}.pdf-frame:focus{outline:1px solid var(--primary);outline-offset:2px}.pdf-overlay{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .15s ease;-moz-user-select:none;user-select:none;-webkit-user-select:none}.pdf-overlay .pdf-page-input{-moz-user-select:text;user-select:text;-webkit-user-select:text}.pdf-frame:hover .pdf-overlay,.pdf-overlay:focus-within,.tiptap[contenteditable=true] [data-type=pdfBlock].ProseMirror-selectednode .pdf-overlay{opacity:1}@media (hover:none){.pdf-overlay{opacity:1}}@media (prefers-reduced-motion:reduce){.pdf-overlay{transition:none}}.pdf-cluster{position:absolute;display:flex;align-items:center;gap:2px;padding:3px 5px;border-radius:999px;background:rgba(24,24,27,.42);backdrop-filter:blur(10px) saturate(1.1);color:#fff;pointer-events:auto;max-width:calc(100% - 12px);transition:background-color .15s ease}.pdf-cluster:hover{background:rgba(24,24,27,.62)}.pdf-cluster-end{top:6px;right:8px}.pdf-cluster-page{bottom:6px;left:50%;transform:translateX(-50%)}.pdf-nav-rail{position:sticky;top:0;height:100vh;max-height:100%;pointer-events:none}.pdf-nav{position:absolute;top:50%;transform:translateY(-50%);pointer-events:auto}.pdf-nav-prev{left:12px}.pdf-nav-next{right:12px}.pdf-overlay .pdf-ctl,.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;padding:0;color:#e4e4e7;font-family:inherit;cursor:pointer;opacity:.92;transition:opacity .12s,color .12s}.pdf-overlay .pdf-ctl{width:20px;height:20px;flex:none}.pdf-overlay .pdf-ctl svg{width:14px;height:14px}.pdf-overlay .pdf-page,.pdf-overlay .pdf-preset{font-weight:500}.pdf-overlay .pdf-ctl:hover,.pdf-overlay .pdf-page:hover,.pdf-overlay .pdf-preset:hover{opacity:1;color:#fff}.pdf-overlay .pdf-ctl:disabled{opacity:.4;cursor:default}.pdf-overlay .pdf-ctl-danger:hover{opacity:1;color:#ff8f8f}.pdf-overlay .pdf-ctl:focus-visible,.pdf-overlay .pdf-page-input:focus-visible,.pdf-overlay .pdf-page:focus-visible,.pdf-overlay .pdf-preset:focus-visible{outline:2px solid hsla(0,0%,100%,.85);outline-offset:2px;border-radius:4px;opacity:1}.pdf-overlay .pdf-preset{height:18px;font-size:11px;line-height:1;font-variant-numeric:tabular-nums;flex:none}.pdf-overlay .pdf-preset.is-active,.pdf-overlay .pdf-preset.is-active:hover{opacity:1;color:#fff;font-weight:600;box-shadow:inset 0 -1px 0 0 currentColor}.pdf-overlay .pdf-fit{width:19px;height:18px;border-radius:3px}.pdf-overlay .pdf-fit svg{width:13px;height:13px}.pdf-overlay .pdf-fit.is-active,.pdf-overlay .pdf-fit.is-active:hover{opacity:1;color:#fff;box-shadow:inset 0 -1px 0 0 currentColor}.pdf-overlay [data-tip]{position:relative}.pdf-overlay [data-tip]:after{content:attr(data-tip);position:absolute;top:calc(100% + 7px);right:0;z-index:1;white-space:nowrap;font-size:11px;line-height:1.4;font-weight:400;padding:4px 8px;border-radius:5px;background:rgba(24,24,27,.94);backdrop-filter:blur(6px);color:#fff;box-shadow:0 4px 12px rgba(0,0,0,.35);opacity:0;pointer-events:none;transition:opacity .12s ease .35s}.pdf-overlay [data-tip]:focus-visible:after,.pdf-overlay [data-tip]:hover:after{opacity:1}.pdf-cluster-page [data-tip]:after{top:auto;bottom:calc(100% + 7px)}.pdf-nav-prev[data-tip]:after{right:auto;left:0}.pdf-overlay .pdf-page{height:16px;font-size:10px;line-height:1;font-variant-numeric:tabular-nums}.pdf-cluster-page{padding:2px 6px}.pdf-overlay .pdf-nav{width:30px;height:30px;padding:0;background:rgba(24,24,27,.42)}.pdf-overlay .pdf-nav:hover{background:rgba(24,24,27,.62)}.pdf-overlay .pdf-nav svg{width:18px;height:18px}.pdf-overlay .pdf-nav:disabled{opacity:.4}.pdf-divider{flex:none;width:1px;height:11px;margin:0 3px;background:hsla(0,0%,100%,.3)}.pdf-overlay .pdf-page-input{box-sizing:border-box;height:20px;width:46px;padding:0 5px;font-size:12px;text-align:center;font-variant-numeric:tabular-nums;background:rgba(24,24,27,.85);border:1px solid hsla(0,0%,100%,.5);color:#fff;border-radius:4px;font-family:inherit;outline:none}.pdf-status{display:flex;align-items:center;justify-content:center;gap:8px;padding:2.5rem 1rem;font-size:.875rem;color:var(--muted-foreground);text-align:center}.tiptap a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}.tiptap a:hover{opacity:.8}.tiptap mark{background-color:#fef08a;border-radius:2px;padding:.05em .1em}.tiptap [data-type=details]{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;display:grid;grid-template-columns:30px 1fr;align-items:start;transition:background .12s}.tiptap [data-type=details]:hover{background:var(--muted)}.tiptap [data-type=details]>button{background:none;border:none;cursor:pointer;padding:0;font:inherit;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;color:var(--muted-foreground);border-radius:4px;transition:transform .2s,color .15s,background-color .15s;flex-shrink:0;margin-top:calc(-2px + 1lh/2);margin-left:4px}.tiptap [data-type=details]>button:hover{background:color-mix(in srgb,var(--foreground) 8%,transparent)}.tiptap [data-type=details]>button:after{content:"";display:block;width:0;height:0;border-left:clamp(6px,.42em,11px) solid;border-top:clamp(4.7px,.33em,8.6px) solid transparent;border-bottom:clamp(4.7px,.33em,8.6px) solid transparent;margin-left:2px}.tiptap [data-type=details]:hover>button{color:var(--foreground)}.tiptap [data-type=details].is-open>button{transform:rotate(90deg)}.tiptap [data-type=details]>div{flex:1;min-width:0}.tiptap [data-type=details] summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 0;display:block;border-bottom:1px solid transparent;transition:border-color .15s}.tiptap [data-type=details].is-open>div>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap [data-type=details] summary[data-level="1"],.tiptap details summary[data-level="1"]{font-size:2rem;font-weight:700;line-height:1.25}.tiptap [data-type=details] summary[data-level="2"],.tiptap details summary[data-level="2"]{font-size:1.5rem;font-weight:600;line-height:1.3}.tiptap [data-type=details] summary[data-level="3"],.tiptap details summary[data-level="3"]{font-size:1.25rem;font-weight:600;line-height:1.35}.tiptap [data-type=details]:has(>div>summary[data-level="1"])>button{font-size:2rem;line-height:1.25}.tiptap [data-type=details]:has(>div>summary[data-level="2"])>button{font-size:1.5rem;line-height:1.3}.tiptap [data-type=details]:has(>div>summary[data-level="3"])>button{font-size:1.25rem;line-height:1.35}.tiptap [data-type=detailsContent]{padding:8px 8px 8px 0;border-left:none}.tiptap [data-type=detailsContent][hidden]{display:none}.tiptap details{border:none;border-radius:6px;padding:0;margin:.5em 0;background:transparent;transition:background .12s}.tiptap details:hover{background:var(--muted)}.tiptap details summary{font-weight:600;cursor:pointer;padding:10px 8px 10px 26px;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-bottom:1px solid transparent;position:relative;list-style:none;transition:border-color .15s}.tiptap details[open]>summary{border-bottom-color:var(--border,#e5e7eb)}.tiptap details summary::-webkit-details-marker{display:none}.tiptap details summary::marker{content:""}.tiptap details summary:before{content:"";position:absolute;left:8px;top:25px;top:calc(10px + .5lh);width:0;height:0;border-left:clamp(6px,.42em,11px) solid var(--muted-foreground);border-top:clamp(4.7px,.33em,8.6px) solid transparent;border-bottom:clamp(4.7px,.33em,8.6px) solid transparent;transform:translateY(-50%);transition:transform .2s,border-left-color .15s}.tiptap details:hover summary:before{border-left-color:var(--foreground)}.tiptap details[open]>summary:before{transform:translateY(-50%) rotate(90deg)}.tiptap details[open]>:not(summary){margin-top:8px;padding-left:26px;padding-right:8px}.tiptap table{border-collapse:collapse;margin:1em 0;table-layout:fixed;border:2px solid var(--border);max-width:100%}.tiptap .tableWrapper{overflow-x:auto;max-width:100%}.tiptap td,.tiptap th{border:1px solid var(--border);padding:.6em .8em;min-width:60px;vertical-align:middle;position:relative;box-sizing:border-box;overflow:hidden;word-break:break-word;line-height:1.5}.tiptap th{background:var(--muted);font-weight:600;text-align:left}.tiptap td{background:var(--background)}.tiptap .selectedCell:after{content:"";position:absolute;inset:0;background:var(--primary);opacity:.12;pointer-events:none;z-index:1}.tiptap .column-resize-handle{position:absolute;right:-3px;top:-1px;bottom:-1px;width:6px;background:var(--primary);opacity:0;cursor:col-resize;z-index:20;border-radius:2px;transition:opacity .15s}.tiptap table:hover .column-resize-handle{opacity:.4}.tiptap .column-resize-handle:hover{opacity:1}.tiptap.resize-cursor{cursor:col-resize}.tableWrapper{overflow-x:auto;overflow-y:hidden;margin:1em 0;max-width:100%;padding-right:4px}.tiptap table .grip-column,.tiptap table .grip-row,.tiptap table .grip-table{display:none!important}.tiptap .is-empty:before{content:attr(data-placeholder);float:left;color:var(--muted-foreground);opacity:.5;pointer-events:none;height:0}.tiptap h1.is-empty:before{font-size:2rem;font-weight:700}.tiptap h2.is-empty:before{font-size:1.5rem;font-weight:600}.tiptap h3.is-empty:before{font-size:1.25rem;font-weight:600}.ProseMirror-gapcursor{display:none;pointer-events:none;position:relative}.ProseMirror-gapcursor:after{content:"";display:block;position:absolute;top:-2px;width:20px;border-top:1px solid var(--foreground);animation:ProseMirror-cursor-blink 1.1s steps(2,start) infinite}@keyframes ProseMirror-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.ProseMirror-dropcursor{border-top:2px solid var(--primary);margin:-1px 0}.tiptap ::-moz-selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.tiptap ::selection{background-color:color-mix(in srgb,var(--primary) 15%,transparent)}.ProseMirror-noderangeselection ::-moz-selection{background:transparent}.ProseMirror-noderangeselection ::selection{background:transparent}.ProseMirror-noderangeselection *{caret-color:transparent}.ProseMirror-selectednode,.ProseMirror-selectednoderange{position:relative}.ProseMirror-selectednode:not(img):not([data-type=image]):not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before,.ProseMirror-selectednoderange:not([data-type=image]):not([data-type=pdfBlock]):not([data-type=mbusVideo]):not([data-type=videoEmbed]):before{content:"";position:absolute;inset:-.25rem;background-color:color-mix(in srgb,var(--primary) 10%,transparent);border:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:.5rem;pointer-events:none;z-index:-1}.tiptap[contenteditable=true] [data-type=image].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=mbusVideo].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=pdfBlock].ProseMirror-selectednode,.tiptap[contenteditable=true] [data-type=videoEmbed].ProseMirror-selectednode,.tiptap[contenteditable=true] img.ProseMirror-selectednode{outline:1px solid var(--primary);outline-offset:2px;border-radius:8px}.hce-table-bubble{z-index:var(--hce-menu-z,100)}.bubble-toolbar-container{position:absolute;top:0;left:0;width:-moz-max-content;width:max-content;z-index:calc(var(--hce-menu-z, 100) + 1)}.hce-toolbar:has(.absolute)~.bubble-toolbar-container,.hce-toolbar:has(.absolute)~.hce-table-bubble{display:none}.hce-menu-surface{background-color:var(--hce-menu-surface,#333)}.hce-floating-panel{background-color:color-mix(in srgb,var(--foreground) 8%,var(--popover,var(--background,#fff)));border:1px solid color-mix(in srgb,var(--foreground) 18%,var(--border));box-shadow:0 8px 24px color-mix(in srgb,var(--foreground) 16%,transparent),0 2px 6px color-mix(in srgb,var(--foreground) 10%,transparent)}.hce-floating-plus{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;border:1px solid var(--border);background:var(--background);color:var(--muted-foreground);cursor:pointer;transition:all .15s}.hce-floating-plus:hover{color:var(--foreground);border-color:var(--foreground);background:var(--muted)}.hce-drag-handle{display:flex;align-items:center;gap:2px}.hce-drag-handle__plus{display:flex;align-items:center;justify-content:center;padding:4px;border-radius:4px;border:none;background:transparent;color:var(--muted-foreground);opacity:.5;cursor:pointer;transition:opacity .15s,background-color .15s}.hce-drag-handle__plus:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip{display:flex;align-items:center;justify-content:center;padding:2px;border-radius:4px;color:var(--muted-foreground);opacity:.5;cursor:grab;transition:opacity .15s,background-color .15s}.hce-drag-handle__grip:hover{opacity:1;background:var(--muted)}.hce-drag-handle__grip:active{cursor:grabbing}.tiptap div[data-type=columns]{display:grid;gap:16px;margin:1em 0}.tiptap div[data-type=columns][data-columns="2"]{grid-template-columns:1fr 1fr}.tiptap div[data-type=columns][data-columns="3"]{grid-template-columns:1fr 1fr 1fr}.tiptap div[data-type=column]{min-width:0;padding:4px 6px;border:1px dashed var(--border);border-radius:8px}.tiptap[contenteditable=true] div[data-type=column]:focus-within{border-color:var(--primary);border-style:solid}.tiptap div[data-type=columns].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent);border-radius:8px}@media (max-width:640px){.tiptap div[data-type=columns]{grid-template-columns:1fr!important}}[data-type=tabs]{margin:1em 0;border:1px solid var(--border);border-radius:10px;overflow:hidden}[data-type=tabs].ProseMirror-selectednode{outline:2px solid color-mix(in srgb,var(--primary) 30%,transparent)}.hce-tabs-bar{display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:5px 6px;border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--muted) 55%,transparent);-webkit-user-select:none;-moz-user-select:none;user-select:none}.hce-tab-chip{position:relative;display:inline-flex;align-items:center;gap:2px;padding-right:2px;border-radius:6px;color:var(--muted-foreground);touch-action:none}.hce-tab-chip:hover{background:color-mix(in srgb,var(--primary) 8%,transparent)}.hce-tab-chip.is-active{background:color-mix(in srgb,var(--primary) 14%,transparent);color:var(--primary)}.hce-tab-chip-label{max-width:14rem;padding:3px 8px;border:0;background:transparent;color:inherit;font:inherit;font-size:.8125rem;font-weight:500;line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.hce-tab-chip.is-active .hce-tab-chip-label{font-weight:600}.hce-tab-chip-close{display:inline-flex;visibility:hidden;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:4px;background:transparent;color:inherit;font-size:13px;line-height:1;cursor:pointer}.hce-tab-chip:hover .hce-tab-chip-close:not(.is-disabled){visibility:visible}.hce-tab-chip-close.is-disabled{cursor:default;pointer-events:none}.hce-tab-chip-close:hover{background:color-mix(in srgb,var(--foreground) 12%,transparent)}.hce-tabs-add{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--muted-foreground);font-size:15px;line-height:1;cursor:pointer}.hce-tabs-add:hover{background:color-mix(in srgb,var(--primary) 10%,transparent);color:var(--primary)}.hce-tabs-bar.is-dragging{cursor:grabbing}.hce-tab-chip.is-dragged{opacity:.45}.hce-tabs-bar.is-dragging .hce-tab-chip:hover .hce-tab-chip-close{visibility:hidden}.hce-tab-chip.is-drop-after:after,.hce-tab-chip.is-drop-before:before{content:"";position:absolute;top:2px;bottom:2px;width:2px;border-radius:1px;background:var(--primary)}.hce-tab-chip.is-drop-before:before{left:-3px}.hce-tab-chip.is-drop-after:after{right:-3px}.hce-tab-title-input{box-sizing:border-box;width:8rem;margin:2px;padding:2px 6px;border:1px solid var(--primary);border-radius:4px;background:var(--background);color:var(--foreground);font:inherit;font-size:.8125rem;outline:none}.hce-tabs-panels{padding:10px 12px}.hce-tabs-panels>[data-type=tab]{display:none}.hce-tabs-panels>[data-type=tab].hce-tab-active{display:block}[data-type=tabs]:not(.hce-tabs-live)>[data-type=tab]{display:none}[data-type=tabs]:not(.hce-tabs-live)>[data-type=tab]:first-child{display:block;padding:10px 12px}[data-type=tabs]:not(.hce-tabs-live):before{content:"";display:block;height:2rem;border-bottom:1px solid var(--border);background:color-mix(in srgb,var(--muted) 55%,transparent)}[data-type=tab]>p:only-child:empty:before,[data-type=tab]>p:only-child:has(>br:only-child):before{content:"빈 탭입니다. 내부를 클릭하거나 블록을 넣으세요.";float:left;height:0;color:var(--muted-foreground);opacity:.5;pointer-events:none}.hce-table-btn-wrap{position:relative;display:inline-flex}.hce-table-btn-tooltip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:6px;padding:4px 8px;font-size:11px;line-height:1.2;white-space:nowrap;color:#fff;background:#1e293b;border-radius:6px;pointer-events:none;opacity:0;transition:opacity .15s;z-index:60}.hce-table-btn-wrap:hover .hce-table-btn-tooltip{opacity:1}.hce-table-btn-wrap.hce-tooltip-off:hover .hce-table-btn-tooltip{opacity:0}.tiptap math-inline,math-inline.math-node{display:inline-block;vertical-align:baseline}.tiptap math-display,math-display.math-node{display:block;margin:.9em 0;text-align:center}.math-node,.tiptap .math-node{font-size:.95em}.tiptap math-inline.math-node .katex,math-inline.math-node .katex{font-size:1.0285em}.tiptap[contenteditable=true] .math-node{cursor:pointer;border-radius:4px;transition:background-color .12s}.tiptap[contenteditable=true] .math-node:hover{background-color:color-mix(in srgb,var(--primary) 10%,transparent)}.tiptap .math-node.ProseMirror-selectednode{background-color:color-mix(in srgb,var(--primary) 18%,transparent);outline:1px solid color-mix(in srgb,var(--primary) 45%,transparent)}.tiptap .math-node.empty-math .math-placeholder{font-size:.85em;padding:0 .35em;color:var(--muted-foreground);border:1px dashed var(--border);border-radius:4px}.math-node .math-error,.tiptap .math-error{color:#dc2626;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}.hce-card-frame,.tiptap [data-type=card]{position:relative}.hce-card-frame{box-sizing:border-box;width:100%;margin:12px 0;padding:26px 30px;display:flex;flex-direction:column;justify-content:center;gap:12px;overflow:hidden;border:1px solid hsla(0,0%,100%,.52);border-radius:8px;box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.28),0 8px 24px rgba(15,23,42,.08);overflow-wrap:anywhere;isolation:isolate}.hce-card-frame:before{content:"";position:absolute;inset:0;z-index:0;background:linear-gradient(90deg,hsla(0,0%,100%,.14),hsla(0,0%,100%,.04) 48%,rgba(15,23,42,.08));pointer-events:none}.hce-card-content{position:relative;z-index:1;box-sizing:border-box;width:100%;max-height:100%;min-height:0;padding:18px 20px;display:flex;flex-direction:column;gap:10px;overflow:hidden;border:1px solid hsla(0,0%,100%,.56);border-radius:8px;background:hsla(0,0%,100%,.82);color:#111827;box-shadow:0 14px 42px rgba(15,23,42,.12),inset 0 1px 0 hsla(0,0%,100%,.52);backdrop-filter:blur(18px) saturate(1.16);-webkit-backdrop-filter:blur(18px) saturate(1.16)}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.hce-card-content{background:hsla(0,0%,100%,.9)}}.hce-card-header{flex:0 0 auto}.hce-card-title{margin:0;font-size:1.65rem;font-weight:700;line-height:1.18;color:#111827}.hce-card-title[hidden]{display:none}.hce-card-title-input{box-sizing:border-box;width:100%;padding:8px 12px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.7);color:#111827;font:inherit;font-size:1.15rem;font-weight:700;outline:none}.hce-card-title-input:focus{border-color:var(--primary,#3382f2)}.hce-card-body{flex:1 1 auto;min-height:0;overflow:auto;font-size:1rem;line-height:1.55;color:#111827}.hce-card-body>p:first-child{margin-top:0}.hce-card-body>p:last-child{margin-bottom:0}.hce-card-bg-button{position:absolute;top:8px;right:8px;z-index:3;padding:4px 10px;border:1px solid rgba(17,24,39,.12);border-radius:6px;background:hsla(0,0%,100%,.86);color:#111827;font-size:.8125rem;line-height:1.4;cursor:pointer}.hce-card-bg-button:hover{background:#fff}@media (max-width:640px){.hce-card-frame{padding:18px}.hce-card-content{padding:14px 16px}.hce-card-title{font-size:1.35rem}}.hce-active{background-color:color-mix(in srgb,var(--primary) 12%,transparent);color:var(--primary)}.hce-active:hover{background-color:color-mix(in srgb,var(--primary) 18%,transparent)}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:scale-105:hover,.hover\:scale-110:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x:1.1;--tw-scale-y:1.1}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-red-300:hover{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-primary:focus{border-color:var(--primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}
|
|
@@ -141,6 +141,17 @@ describe('sanitizeHtml', () => {
|
|
|
141
141
|
expect(result).toContain('src=');
|
|
142
142
|
expect(result).toContain('alt=');
|
|
143
143
|
});
|
|
144
|
+
/*
|
|
145
|
+
* 이미지 리사이즈(`ResizableImage`)가 폭을 **`width` 속성**으로 저장하는 근거다.
|
|
146
|
+
* 인라인 `style` 로 저장하면 여기서 조용히 지워져, 정적 렌더(`{@html}` + 살균)에서는
|
|
147
|
+
* 원래 크기로 나왔다가 에디터가 뜨는 순간 조절한 크기로 화면이 튄다.
|
|
148
|
+
*/
|
|
149
|
+
it('keeps img width but drops inline style', () => {
|
|
150
|
+
const input = '<img src="https://example.com/img.png" width="480" style="width: 480px">';
|
|
151
|
+
const result = sanitizeHtml(input);
|
|
152
|
+
expect(result).toContain('width="480"');
|
|
153
|
+
expect(result).not.toContain('style=');
|
|
154
|
+
});
|
|
144
155
|
it('preserves data-pdf-src on div', () => {
|
|
145
156
|
const input = '<div data-pdf-src="https://example.com/file.pdf" data-pdf-name="file.pdf"></div>';
|
|
146
157
|
const result = sanitizeHtml(input);
|