@caring-dev/react-notion-x 7.7.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/build/index.js ADDED
@@ -0,0 +1,3302 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
28
+
29
+ // ../../node_modules/.pnpm/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js
30
+ var require_lodash = __commonJS({
31
+ "../../node_modules/.pnpm/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js"(exports, module) {
32
+ "use strict";
33
+ var FUNC_ERROR_TEXT = "Expected a function";
34
+ var NAN = 0 / 0;
35
+ var symbolTag = "[object Symbol]";
36
+ var reTrim = /^\s+|\s+$/g;
37
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
38
+ var reIsBinary = /^0b[01]+$/i;
39
+ var reIsOctal = /^0o[0-7]+$/i;
40
+ var freeParseInt = parseInt;
41
+ var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
42
+ var freeSelf = typeof self == "object" && self && self.Object === Object && self;
43
+ var root = freeGlobal || freeSelf || Function("return this")();
44
+ var objectProto = Object.prototype;
45
+ var objectToString = objectProto.toString;
46
+ var nativeMax = Math.max;
47
+ var nativeMin = Math.min;
48
+ var now = function() {
49
+ return root.Date.now();
50
+ };
51
+ function debounce(func, wait, options) {
52
+ var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
53
+ if (typeof func != "function") {
54
+ throw new TypeError(FUNC_ERROR_TEXT);
55
+ }
56
+ wait = toNumber(wait) || 0;
57
+ if (isObject(options)) {
58
+ leading = !!options.leading;
59
+ maxing = "maxWait" in options;
60
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
61
+ trailing = "trailing" in options ? !!options.trailing : trailing;
62
+ }
63
+ function invokeFunc(time) {
64
+ var args = lastArgs, thisArg = lastThis;
65
+ lastArgs = lastThis = void 0;
66
+ lastInvokeTime = time;
67
+ result = func.apply(thisArg, args);
68
+ return result;
69
+ }
70
+ function leadingEdge(time) {
71
+ lastInvokeTime = time;
72
+ timerId = setTimeout(timerExpired, wait);
73
+ return leading ? invokeFunc(time) : result;
74
+ }
75
+ function remainingWait(time) {
76
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result2 = wait - timeSinceLastCall;
77
+ return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2;
78
+ }
79
+ function shouldInvoke(time) {
80
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
81
+ return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
82
+ }
83
+ function timerExpired() {
84
+ var time = now();
85
+ if (shouldInvoke(time)) {
86
+ return trailingEdge(time);
87
+ }
88
+ timerId = setTimeout(timerExpired, remainingWait(time));
89
+ }
90
+ function trailingEdge(time) {
91
+ timerId = void 0;
92
+ if (trailing && lastArgs) {
93
+ return invokeFunc(time);
94
+ }
95
+ lastArgs = lastThis = void 0;
96
+ return result;
97
+ }
98
+ function cancel() {
99
+ if (timerId !== void 0) {
100
+ clearTimeout(timerId);
101
+ }
102
+ lastInvokeTime = 0;
103
+ lastArgs = lastCallTime = lastThis = timerId = void 0;
104
+ }
105
+ function flush() {
106
+ return timerId === void 0 ? result : trailingEdge(now());
107
+ }
108
+ function debounced() {
109
+ var time = now(), isInvoking = shouldInvoke(time);
110
+ lastArgs = arguments;
111
+ lastThis = this;
112
+ lastCallTime = time;
113
+ if (isInvoking) {
114
+ if (timerId === void 0) {
115
+ return leadingEdge(lastCallTime);
116
+ }
117
+ if (maxing) {
118
+ timerId = setTimeout(timerExpired, wait);
119
+ return invokeFunc(lastCallTime);
120
+ }
121
+ }
122
+ if (timerId === void 0) {
123
+ timerId = setTimeout(timerExpired, wait);
124
+ }
125
+ return result;
126
+ }
127
+ debounced.cancel = cancel;
128
+ debounced.flush = flush;
129
+ return debounced;
130
+ }
131
+ function throttle3(func, wait, options) {
132
+ var leading = true, trailing = true;
133
+ if (typeof func != "function") {
134
+ throw new TypeError(FUNC_ERROR_TEXT);
135
+ }
136
+ if (isObject(options)) {
137
+ leading = "leading" in options ? !!options.leading : leading;
138
+ trailing = "trailing" in options ? !!options.trailing : trailing;
139
+ }
140
+ return debounce(func, wait, {
141
+ "leading": leading,
142
+ "maxWait": wait,
143
+ "trailing": trailing
144
+ });
145
+ }
146
+ function isObject(value) {
147
+ var type = typeof value;
148
+ return !!value && (type == "object" || type == "function");
149
+ }
150
+ function isObjectLike(value) {
151
+ return !!value && typeof value == "object";
152
+ }
153
+ function isSymbol(value) {
154
+ return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
155
+ }
156
+ function toNumber(value) {
157
+ if (typeof value == "number") {
158
+ return value;
159
+ }
160
+ if (isSymbol(value)) {
161
+ return NAN;
162
+ }
163
+ if (isObject(value)) {
164
+ var other = typeof value.valueOf == "function" ? value.valueOf() : value;
165
+ value = isObject(other) ? other + "" : other;
166
+ }
167
+ if (typeof value != "string") {
168
+ return value === 0 ? value : +value;
169
+ }
170
+ value = value.replace(reTrim, "");
171
+ var isBinary = reIsBinary.test(value);
172
+ return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
173
+ }
174
+ module.exports = throttle3;
175
+ }
176
+ });
177
+
178
+ // src/components/header.tsx
179
+ import { getPageBreadcrumbs } from "notion-utils";
180
+ import React15 from "react";
181
+ import { useHotkeys } from "react-hotkeys-hook";
182
+
183
+ // src/context.tsx
184
+ import "notion-types";
185
+ import { defaultMapImageUrl, defaultMapPageUrl } from "notion-utils";
186
+ import React10 from "react";
187
+
188
+ // src/components/asset-wrapper.tsx
189
+ import "notion-types";
190
+ import { parsePageId as parsePageId2 } from "notion-utils";
191
+
192
+ // src/utils.ts
193
+ import "notion-types";
194
+ import { formatDate, formatNotionDateTime, isUrl } from "notion-utils";
195
+ var cs = (...classes) => classes.filter((a) => !!a).join(" ");
196
+ var groupBlockContent = (blockMap) => {
197
+ var _a, _b, _c, _d;
198
+ const output = [];
199
+ let lastType;
200
+ let index = -1;
201
+ for (const id of Object.keys(blockMap)) {
202
+ const blockValue = (_a = blockMap[id]) == null ? void 0 : _a.value;
203
+ if (blockValue) {
204
+ if (blockValue.content)
205
+ for (const blockId of blockValue.content) {
206
+ const blockType = (_c = (_b = blockMap[blockId]) == null ? void 0 : _b.value) == null ? void 0 : _c.type;
207
+ if (blockType && blockType !== lastType) {
208
+ index++;
209
+ lastType = blockType;
210
+ output[index] = [];
211
+ }
212
+ if (index > -1) {
213
+ (_d = output[index]) == null ? void 0 : _d.push(blockId);
214
+ }
215
+ }
216
+ }
217
+ lastType = void 0;
218
+ }
219
+ return output;
220
+ };
221
+ var getListNumber = (blockId, blockMap) => {
222
+ var _a, _b, _c;
223
+ const groups = groupBlockContent(blockMap);
224
+ const group = groups.find((g) => g.includes(blockId));
225
+ if (!group) {
226
+ return;
227
+ }
228
+ const groupIndex = group.indexOf(blockId) + 1;
229
+ const startIndex = (_b = (_a = blockMap[blockId]) == null ? void 0 : _a.value.format) == null ? void 0 : _b.list_start_index;
230
+ return ((_c = blockMap[blockId]) == null ? void 0 : _c.value.type) === "numbered_list" ? startIndex != null ? startIndex : groupIndex : groupIndex;
231
+ };
232
+ var getListNestingLevel = (blockId, blockMap) => {
233
+ var _a, _b, _c;
234
+ let level = 0;
235
+ let currentBlockId = blockId;
236
+ while (true) {
237
+ const parentId = (_b = (_a = blockMap[currentBlockId]) == null ? void 0 : _a.value) == null ? void 0 : _b.parent_id;
238
+ if (!parentId) break;
239
+ const parentBlock = (_c = blockMap[parentId]) == null ? void 0 : _c.value;
240
+ if (!parentBlock) break;
241
+ if (parentBlock.type === "numbered_list") {
242
+ level++;
243
+ currentBlockId = parentId;
244
+ } else {
245
+ break;
246
+ }
247
+ }
248
+ return level;
249
+ };
250
+ var getListStyle = (level) => {
251
+ const styles = ["decimal", "lower-alpha", "lower-roman"];
252
+ const index = (level % styles.length + styles.length) % styles.length;
253
+ return styles[index];
254
+ };
255
+ var getHashFragmentValue = (url) => {
256
+ return url.includes("#") ? url.replace(/^.+(#.+)$/, "$1") : "";
257
+ };
258
+ var isBrowser = !!globalThis.window;
259
+ var youtubeDomains = /* @__PURE__ */ new Set([
260
+ "youtu.be",
261
+ "youtube.com",
262
+ "www.youtube.com",
263
+ "youtube-nocookie.com",
264
+ "www.youtube-nocookie.com"
265
+ ]);
266
+ var getYoutubeId = (url) => {
267
+ var _a;
268
+ try {
269
+ const { hostname } = new URL(url);
270
+ if (!youtubeDomains.has(hostname)) {
271
+ return null;
272
+ }
273
+ const regExp = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/i;
274
+ const match = url.match(regExp);
275
+ if (match && ((_a = match[2]) == null ? void 0 : _a.length) === 11) {
276
+ return match[2];
277
+ }
278
+ } catch (e) {
279
+ }
280
+ return null;
281
+ };
282
+ var getUrlParams = (url) => {
283
+ try {
284
+ const { searchParams } = new URL(url);
285
+ const result = {};
286
+ for (const [key, value] of searchParams.entries()) {
287
+ result[key] = value;
288
+ }
289
+ return result;
290
+ } catch (e) {
291
+ }
292
+ return;
293
+ };
294
+
295
+ // src/components/asset.tsx
296
+ import "notion-types";
297
+ import { getTextContent } from "notion-utils";
298
+
299
+ // src/components/lazy-image.tsx
300
+ import { normalizeUrl } from "notion-utils";
301
+ import React from "react";
302
+
303
+ // src/components/lazy-image-full.tsx
304
+ import { Component } from "react";
305
+ import { InView } from "react-intersection-observer";
306
+ import { ofType, unionize } from "unionize";
307
+ import { jsx } from "react/jsx-runtime";
308
+ var LazyImageFullState = unionize({
309
+ NotAsked: {},
310
+ Buffering: {},
311
+ // Could try to make it Promise<HTMLImageElement>,
312
+ // but we don't use the element anyway, and we cache promises
313
+ Loading: {},
314
+ LoadSuccess: {},
315
+ LoadError: ofType()
316
+ });
317
+ var Action = unionize({
318
+ ViewChanged: ofType(),
319
+ BufferingEnded: {},
320
+ // MAYBE: Load: {},
321
+ LoadSuccess: {},
322
+ LoadError: ofType()
323
+ });
324
+ var getBufferingCmd = (durationMs) => (instance) => {
325
+ const bufferingPromise = makeCancelable(delayedPromise(durationMs));
326
+ bufferingPromise.promise.then(() => instance.update(Action.BufferingEnded())).catch(
327
+ (_err) => {
328
+ }
329
+ //console.log({ isCanceled: _reason.isCanceled })
330
+ );
331
+ instance.promiseCache.buffering = bufferingPromise;
332
+ };
333
+ var getLoadingCmd = (imageProps, experimentalDecode) => (instance) => {
334
+ const loadingPromise = makeCancelable(
335
+ loadImage(imageProps, experimentalDecode)
336
+ );
337
+ loadingPromise.promise.then((_res) => instance.update(Action.LoadSuccess({}))).catch((err) => {
338
+ if (!err.isCanceled) {
339
+ instance.update(new Action.LoadError({ msg: "LoadError" }));
340
+ }
341
+ });
342
+ instance.promiseCache.loading = loadingPromise;
343
+ };
344
+ var cancelBufferingCmd = (instance) => {
345
+ var _a;
346
+ (_a = instance.promiseCache.buffering) == null ? void 0 : _a.cancel();
347
+ };
348
+ var _LazyImageFull = class _LazyImageFull extends Component {
349
+ constructor(props) {
350
+ super(props);
351
+ /** A central place to store promises.
352
+ * A bit silly, but passing promises directly in the state
353
+ * was giving me weird timing issues. This way we can keep
354
+ * the promises in check, and pick them up from the respective methods.
355
+ * FUTURE: Could pass the relevant key in Buffering and Loading, so
356
+ * that at least we know where they are from a single source.
357
+ */
358
+ __publicField(this, "promiseCache", {});
359
+ __publicField(this, "initialState", LazyImageFullState.NotAsked());
360
+ this.state = this.initialState;
361
+ this.update = this.update.bind(this);
362
+ }
363
+ /** Emit the next state based on actions.
364
+ * This is the core of the component!
365
+ */
366
+ static reducer(action, prevState, props) {
367
+ return Action.match(action, {
368
+ ViewChanged: ({ inView }) => {
369
+ if (inView === true) {
370
+ if (!props.src) {
371
+ return { nextState: LazyImageFullState.LoadSuccess() };
372
+ } else {
373
+ return LazyImageFullState.match(prevState, {
374
+ NotAsked: () => {
375
+ if (props.debounceDurationMs) {
376
+ return {
377
+ nextState: LazyImageFullState.Buffering(),
378
+ cmd: getBufferingCmd(props.debounceDurationMs)
379
+ };
380
+ } else {
381
+ return {
382
+ nextState: LazyImageFullState.Loading(),
383
+ cmd: getLoadingCmd(props, props.experimentalDecode)
384
+ };
385
+ }
386
+ },
387
+ // Do nothing in other states
388
+ default: () => ({ nextState: prevState })
389
+ });
390
+ }
391
+ } else {
392
+ return LazyImageFullState.match(prevState, {
393
+ Buffering: () => ({
394
+ nextState: LazyImageFullState.NotAsked(),
395
+ cmd: cancelBufferingCmd
396
+ }),
397
+ // Do nothing in other states
398
+ default: () => ({ nextState: prevState })
399
+ });
400
+ }
401
+ },
402
+ // Buffering has ended/succeeded, kick off request for image
403
+ BufferingEnded: () => ({
404
+ nextState: LazyImageFullState.Loading(),
405
+ cmd: getLoadingCmd(props, props.experimentalDecode)
406
+ }),
407
+ // Loading the image succeeded, simple
408
+ LoadSuccess: () => ({ nextState: LazyImageFullState.LoadSuccess() }),
409
+ //@ts-expect-error No need for changing structure
410
+ LoadError: (e) => ({ nextState: new LazyImageFullState.LoadError(e) })
411
+ });
412
+ }
413
+ update(action) {
414
+ const { nextState, cmd } = _LazyImageFull.reducer(
415
+ action,
416
+ this.state,
417
+ this.props
418
+ );
419
+ if (this.props.debugActions) {
420
+ if (false) {
421
+ console.warn(
422
+ 'You are running LazyImage with debugActions="true" in production. This might have performance implications.'
423
+ );
424
+ }
425
+ console.log({ action, prevState: this.state, nextState });
426
+ }
427
+ this.setState(nextState, () => cmd && cmd(this));
428
+ }
429
+ componentWillUnmount() {
430
+ if (this.promiseCache.loading) {
431
+ this.promiseCache.loading.cancel();
432
+ }
433
+ if (this.promiseCache.buffering) {
434
+ this.promiseCache.buffering.cancel();
435
+ }
436
+ this.promiseCache = {};
437
+ }
438
+ // Render function
439
+ render() {
440
+ const { children, loadEagerly, observerProps, ...imageProps } = this.props;
441
+ if (loadEagerly) {
442
+ return children({
443
+ // We know that the state tags and the enum match up
444
+ imageState: LazyImageFullState.LoadSuccess().tag,
445
+ imageProps
446
+ });
447
+ } else {
448
+ return /* @__PURE__ */ jsx(
449
+ InView,
450
+ {
451
+ rootMargin: "50px 0px",
452
+ threshold: 0.01,
453
+ ...observerProps,
454
+ onChange: (inView) => this.update(Action.ViewChanged({ inView })),
455
+ children: ({ ref }) => children({
456
+ // We know that the state tags and the enum match up, apart
457
+ // from Buffering not being exposed
458
+ imageState: this.state.tag === "Buffering" ? "Loading" /* Loading */ : this.state.tag,
459
+ imageProps,
460
+ ref
461
+ })
462
+ }
463
+ );
464
+ }
465
+ }
466
+ };
467
+ __publicField(_LazyImageFull, "displayName", "LazyImageFull");
468
+ var LazyImageFull = _LazyImageFull;
469
+ var loadImage = ({ src, srcSet, alt, sizes }, experimentalDecode = false) => new Promise((resolve, reject) => {
470
+ const image = new Image();
471
+ if (srcSet) {
472
+ image.srcset = srcSet;
473
+ }
474
+ if (alt) {
475
+ image.alt = alt;
476
+ }
477
+ if (sizes) {
478
+ image.sizes = sizes;
479
+ }
480
+ image.src = src;
481
+ if (experimentalDecode && "decode" in image) {
482
+ return image.decode().then(() => resolve(image)).catch((err) => reject(err));
483
+ }
484
+ image.addEventListener("load", resolve);
485
+ image.addEventListener("error", reject);
486
+ });
487
+ var delayedPromise = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
488
+ var makeCancelable = (promise) => {
489
+ let hasCanceled_ = false;
490
+ const wrappedPromise = new Promise((resolve, reject) => {
491
+ void promise.then(
492
+ (val) => hasCanceled_ ? reject({ isCanceled: true }) : resolve(val)
493
+ );
494
+ promise.catch(
495
+ (err) => hasCanceled_ ? reject({ isCanceled: true }) : reject(err)
496
+ );
497
+ });
498
+ return {
499
+ promise: wrappedPromise,
500
+ cancel() {
501
+ hasCanceled_ = true;
502
+ }
503
+ };
504
+ };
505
+
506
+ // src/components/lazy-image.tsx
507
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
508
+ function LazyImage({
509
+ src,
510
+ alt,
511
+ className,
512
+ style,
513
+ zoomable = false,
514
+ priority = false,
515
+ height,
516
+ ...rest
517
+ }) {
518
+ var _a, _b, _c;
519
+ const { recordMap, zoom, previewImages, forceCustomImages, components } = useNotionContext();
520
+ const zoomRef = React.useRef(zoom ? zoom.clone() : null);
521
+ const previewImage = previewImages ? (_c = (_a = recordMap == null ? void 0 : recordMap.preview_images) == null ? void 0 : _a[src]) != null ? _c : (_b = recordMap == null ? void 0 : recordMap.preview_images) == null ? void 0 : _b[normalizeUrl(src)] : null;
522
+ const onLoad = React.useCallback(
523
+ (e) => {
524
+ if (zoomable && (e.target.src || e.target.srcset)) {
525
+ if (zoomRef.current) {
526
+ ;
527
+ zoomRef.current.attach(e.target);
528
+ }
529
+ }
530
+ },
531
+ [zoomRef, zoomable]
532
+ );
533
+ const attachZoom = React.useCallback(
534
+ (image) => {
535
+ if (zoomRef.current && image) {
536
+ ;
537
+ zoomRef.current.attach(image);
538
+ }
539
+ },
540
+ [zoomRef]
541
+ );
542
+ const attachZoomRef = React.useMemo(
543
+ () => zoomable ? attachZoom : void 0,
544
+ [zoomable, attachZoom]
545
+ );
546
+ if (previewImage) {
547
+ const aspectRatio = previewImage.originalHeight / previewImage.originalWidth;
548
+ if (components.Image) {
549
+ return /* @__PURE__ */ jsx2(
550
+ components.Image,
551
+ {
552
+ src,
553
+ alt,
554
+ style,
555
+ className,
556
+ width: previewImage.originalWidth,
557
+ height: previewImage.originalHeight,
558
+ blurDataURL: previewImage.dataURIBase64,
559
+ placeholder: "blur",
560
+ priority,
561
+ onLoad
562
+ }
563
+ );
564
+ }
565
+ return /* @__PURE__ */ jsx2(LazyImageFull, { src, ...rest, experimentalDecode: true, children: ({ imageState, ref }) => {
566
+ const isLoaded = imageState === "LoadSuccess" /* LoadSuccess */;
567
+ const wrapperStyle = {
568
+ width: "100%"
569
+ };
570
+ const imgStyle = {};
571
+ if (height) {
572
+ wrapperStyle.height = height;
573
+ } else {
574
+ imgStyle.position = "absolute";
575
+ wrapperStyle.paddingBottom = `${aspectRatio * 100}%`;
576
+ }
577
+ return /* @__PURE__ */ jsxs(
578
+ "div",
579
+ {
580
+ className: cs(
581
+ "lazy-image-wrapper",
582
+ isLoaded && "lazy-image-loaded",
583
+ className
584
+ ),
585
+ style: wrapperStyle,
586
+ children: [
587
+ /* @__PURE__ */ jsx2(
588
+ "img",
589
+ {
590
+ className: "lazy-image-preview",
591
+ src: previewImage.dataURIBase64,
592
+ alt,
593
+ ref,
594
+ style,
595
+ decoding: "async"
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx2(
599
+ "img",
600
+ {
601
+ className: "lazy-image-real",
602
+ src,
603
+ alt,
604
+ ref: attachZoomRef,
605
+ style: {
606
+ ...style,
607
+ ...imgStyle
608
+ },
609
+ width: previewImage.originalWidth,
610
+ height: previewImage.originalHeight,
611
+ decoding: "async",
612
+ loading: "lazy"
613
+ }
614
+ )
615
+ ]
616
+ }
617
+ );
618
+ } });
619
+ } else {
620
+ if (components.Image && forceCustomImages) {
621
+ return /* @__PURE__ */ jsx2(
622
+ components.Image,
623
+ {
624
+ src,
625
+ alt,
626
+ className,
627
+ style,
628
+ width: null,
629
+ height: height || null,
630
+ priority,
631
+ onLoad
632
+ }
633
+ );
634
+ }
635
+ return /* @__PURE__ */ jsx2(
636
+ "img",
637
+ {
638
+ className,
639
+ style,
640
+ src,
641
+ alt,
642
+ ref: attachZoomRef,
643
+ loading: "lazy",
644
+ decoding: "async",
645
+ ...rest
646
+ }
647
+ );
648
+ }
649
+ }
650
+
651
+ // src/components/lite-youtube-embed.tsx
652
+ import React2 from "react";
653
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
654
+ var qs = (params) => {
655
+ return Object.keys(params).map(
656
+ (key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
657
+ ).join("&");
658
+ };
659
+ var resolutions = [120, 320, 480, 640, 1280];
660
+ var resolutionMap = {
661
+ 120: "default",
662
+ 320: "mqdefault",
663
+ 480: "hqdefault",
664
+ 640: "sddefault",
665
+ 1280: "maxresdefault"
666
+ // 2k, 4k, 8k images don't seem to be available
667
+ // Source: https://longzero.com/articles/youtube-thumbnail-sizes-url/
668
+ };
669
+ var resolutionSizes = resolutions.map((resolution) => `(max-width: ${resolution}px) ${resolution}px`).join(", ");
670
+ function getPosterUrl(id, resolution = 480, type = "jpg") {
671
+ if (type === "webp") {
672
+ return `https://i.ytimg.com/vi_webp/${id}/${resolutionMap[resolution]}.webp`;
673
+ }
674
+ return `https://i.ytimg.com/vi/${id}/${resolutionMap[resolution]}.jpg`;
675
+ }
676
+ function generateSrcSet(id, type = "jpg") {
677
+ return resolutions.map((resolution) => `${getPosterUrl(id, resolution, type)} ${resolution}w`).join(", ");
678
+ }
679
+ function LiteYouTubeEmbed({
680
+ id,
681
+ defaultPlay = false,
682
+ mute = false,
683
+ lazyImage = false,
684
+ iframeTitle = "YouTube video",
685
+ alt = "Video preview",
686
+ params = {},
687
+ adLinksPreconnect = true,
688
+ style,
689
+ className
690
+ }) {
691
+ const muteParam = mute || defaultPlay ? "1" : "0";
692
+ const queryString = React2.useMemo(
693
+ () => qs({ autoplay: "1", mute: muteParam, ...params }),
694
+ [muteParam, params]
695
+ );
696
+ const ytUrl = "https://www.youtube-nocookie.com";
697
+ const iframeSrc = `${ytUrl}/embed/${id}?${queryString}`;
698
+ const [isPreconnected, setIsPreconnected] = React2.useState(false);
699
+ const [iframeInitialized, setIframeInitialized] = React2.useState(defaultPlay);
700
+ const [isIframeLoaded, setIsIframeLoaded] = React2.useState(false);
701
+ const warmConnections = React2.useCallback(() => {
702
+ if (isPreconnected) return;
703
+ setIsPreconnected(true);
704
+ }, [isPreconnected]);
705
+ const onLoadIframe = React2.useCallback(() => {
706
+ if (iframeInitialized) return;
707
+ setIframeInitialized(true);
708
+ }, [iframeInitialized]);
709
+ const onIframeLoaded = React2.useCallback(() => {
710
+ setIsIframeLoaded(true);
711
+ }, []);
712
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
713
+ /* @__PURE__ */ jsx3(
714
+ "link",
715
+ {
716
+ rel: "preload",
717
+ as: "image",
718
+ href: getPosterUrl(id),
719
+ imageSrcSet: generateSrcSet(id, "webp"),
720
+ imageSizes: resolutionSizes
721
+ }
722
+ ),
723
+ isPreconnected && /* @__PURE__ */ jsxs2(Fragment, { children: [
724
+ /* @__PURE__ */ jsx3("link", { rel: "preconnect", href: ytUrl }),
725
+ /* @__PURE__ */ jsx3("link", { rel: "preconnect", href: "https://www.google.com" })
726
+ ] }),
727
+ isPreconnected && adLinksPreconnect && /* @__PURE__ */ jsxs2(Fragment, { children: [
728
+ /* @__PURE__ */ jsx3("link", { rel: "preconnect", href: "https://static.doubleclick.net" }),
729
+ /* @__PURE__ */ jsx3("link", { rel: "preconnect", href: "https://googleads.g.doubleclick.net" })
730
+ ] }),
731
+ /* @__PURE__ */ jsxs2(
732
+ "div",
733
+ {
734
+ onClick: onLoadIframe,
735
+ onPointerOver: warmConnections,
736
+ className: cs(
737
+ "notion-yt-lite",
738
+ isIframeLoaded && "notion-yt-loaded",
739
+ iframeInitialized && "notion-yt-initialized",
740
+ className
741
+ ),
742
+ style,
743
+ children: [
744
+ /* @__PURE__ */ jsxs2("picture", { children: [
745
+ resolutions.map((resolution) => /* @__PURE__ */ jsx3(
746
+ "source",
747
+ {
748
+ srcSet: `${getPosterUrl(id, resolution, "webp")} ${resolution}w`,
749
+ media: `(max-width: ${resolution}px)`,
750
+ type: "image/webp"
751
+ },
752
+ resolution
753
+ )),
754
+ /* @__PURE__ */ jsx3(
755
+ "img",
756
+ {
757
+ src: getPosterUrl(id),
758
+ className: "notion-yt-thumbnail",
759
+ loading: lazyImage ? "lazy" : void 0,
760
+ alt
761
+ }
762
+ )
763
+ ] }),
764
+ /* @__PURE__ */ jsx3("div", { className: "notion-yt-playbtn" }),
765
+ iframeInitialized && /* @__PURE__ */ jsx3(
766
+ "iframe",
767
+ {
768
+ width: "560",
769
+ height: "315",
770
+ frameBorder: "0",
771
+ allow: "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",
772
+ allowFullScreen: true,
773
+ title: iframeTitle,
774
+ src: iframeSrc,
775
+ onLoad: onIframeLoaded
776
+ }
777
+ )
778
+ ]
779
+ }
780
+ )
781
+ ] });
782
+ }
783
+
784
+ // src/components/asset.tsx
785
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
786
+ var isServer = !globalThis.window;
787
+ var supportedAssetTypes = /* @__PURE__ */ new Set([
788
+ "replit",
789
+ "video",
790
+ "image",
791
+ "embed",
792
+ "figma",
793
+ "typeform",
794
+ "excalidraw",
795
+ "maps",
796
+ "tweet",
797
+ "pdf",
798
+ "gist",
799
+ "codepen",
800
+ "drive"
801
+ ]);
802
+ function Asset({
803
+ block,
804
+ zoomable = true,
805
+ children
806
+ }) {
807
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
808
+ const { recordMap, mapImageUrl, components } = useNotionContext();
809
+ if (!block || !supportedAssetTypes.has(block.type)) {
810
+ return null;
811
+ }
812
+ const style = {
813
+ position: "relative",
814
+ display: "flex",
815
+ justifyContent: "center",
816
+ alignSelf: "center",
817
+ width: "100%",
818
+ maxWidth: "100%",
819
+ flexDirection: "column"
820
+ };
821
+ const assetStyle = {};
822
+ if (block.format) {
823
+ const {
824
+ block_aspect_ratio,
825
+ block_height,
826
+ block_width,
827
+ block_full_width,
828
+ block_page_width,
829
+ block_preserve_scale
830
+ } = block.format;
831
+ if (block_full_width || block_page_width) {
832
+ if (block_full_width) {
833
+ style.width = "100vw";
834
+ } else {
835
+ style.width = "100%";
836
+ }
837
+ if (block.type === "video") {
838
+ if (block_height) {
839
+ style.height = block_height;
840
+ } else if (block_aspect_ratio) {
841
+ style.paddingBottom = `${block_aspect_ratio * 100}%`;
842
+ } else if (block_preserve_scale) {
843
+ style.objectFit = "contain";
844
+ }
845
+ } else if (block_aspect_ratio && block.type !== "image") {
846
+ style.paddingBottom = `${block_aspect_ratio * 100}%`;
847
+ } else if (block_height) {
848
+ style.height = block_height;
849
+ } else if (block_preserve_scale) {
850
+ if (block.type === "image") {
851
+ style.height = "100%";
852
+ } else {
853
+ style.paddingBottom = "75%";
854
+ style.minHeight = 100;
855
+ }
856
+ }
857
+ } else {
858
+ switch ((_a = block.format) == null ? void 0 : _a.block_alignment) {
859
+ case "center":
860
+ style.alignSelf = "center";
861
+ break;
862
+ case "left":
863
+ style.alignSelf = "start";
864
+ break;
865
+ case "right":
866
+ style.alignSelf = "end";
867
+ break;
868
+ }
869
+ if (block_width) {
870
+ style.width = block_width;
871
+ }
872
+ if (block_preserve_scale && block.type !== "image") {
873
+ style.paddingBottom = "50%";
874
+ style.minHeight = 100;
875
+ } else {
876
+ if (block_height && block.type !== "image") {
877
+ style.height = block_height;
878
+ }
879
+ }
880
+ }
881
+ if (block.type === "image") {
882
+ assetStyle.objectFit = "cover";
883
+ } else if (block_preserve_scale) {
884
+ assetStyle.objectFit = "contain";
885
+ }
886
+ }
887
+ let source = ((_b = recordMap.signed_urls) == null ? void 0 : _b[block.id]) || ((_e = (_d = (_c = block.properties) == null ? void 0 : _c.source) == null ? void 0 : _d[0]) == null ? void 0 : _e[0]);
888
+ if (!source) {
889
+ return null;
890
+ }
891
+ if (block.space_id) {
892
+ const url = new URL(source);
893
+ url.searchParams.set("spaceId", block.space_id);
894
+ source = url.toString();
895
+ }
896
+ let content = null;
897
+ if (block.type === "tweet") {
898
+ const src = source;
899
+ if (!src) return null;
900
+ const id = (_g = (_f = src.split("?")) == null ? void 0 : _f[0]) == null ? void 0 : _g.split("/").pop();
901
+ if (!id) return null;
902
+ content = /* @__PURE__ */ jsx4(
903
+ "div",
904
+ {
905
+ style: {
906
+ ...assetStyle,
907
+ maxWidth: 420,
908
+ width: "100%",
909
+ marginLeft: "auto",
910
+ marginRight: "auto"
911
+ },
912
+ children: /* @__PURE__ */ jsx4(components.Tweet, { id })
913
+ }
914
+ );
915
+ } else if (block.type === "pdf") {
916
+ style.overflow = "auto";
917
+ style.background = "rgb(226, 226, 226)";
918
+ style.display = "block";
919
+ if (!style.padding) {
920
+ style.padding = "8px 16px";
921
+ }
922
+ if (!isServer) {
923
+ content = /* @__PURE__ */ jsx4(components.Pdf, { file: source });
924
+ }
925
+ } else if (block.type === "embed" || block.type === "video" || block.type === "figma" || block.type === "typeform" || block.type === "gist" || block.type === "maps" || block.type === "excalidraw" || block.type === "codepen" || block.type === "drive" || block.type === "replit") {
926
+ if (block.type === "video" && source && !source.includes("youtube") && !source.includes("youtu.be") && !source.includes("vimeo") && !source.includes("wistia") && !source.includes("loom") && !source.includes("videoask") && !source.includes("getcloudapp") && !source.includes("tella")) {
927
+ style.paddingBottom = void 0;
928
+ content = /* @__PURE__ */ jsx4(
929
+ "video",
930
+ {
931
+ playsInline: true,
932
+ controls: true,
933
+ preload: "metadata",
934
+ style: assetStyle,
935
+ src: source,
936
+ title: block.type
937
+ }
938
+ );
939
+ } else {
940
+ let src = ((_h = block.format) == null ? void 0 : _h.display_source) || source;
941
+ if (src) {
942
+ const youtubeVideoId = block.type === "video" ? getYoutubeId(src) : null;
943
+ if (youtubeVideoId) {
944
+ const params = getUrlParams(src);
945
+ content = /* @__PURE__ */ jsx4(
946
+ LiteYouTubeEmbed,
947
+ {
948
+ id: youtubeVideoId,
949
+ style: assetStyle,
950
+ className: "notion-asset-object-fit",
951
+ params
952
+ }
953
+ );
954
+ } else if (block.type === "gist") {
955
+ if (!src.endsWith(".pibb")) {
956
+ src = `${src}.pibb`;
957
+ }
958
+ assetStyle.width = "100%";
959
+ style.paddingBottom = "50%";
960
+ content = /* @__PURE__ */ jsx4(
961
+ "iframe",
962
+ {
963
+ style: assetStyle,
964
+ className: "notion-asset-object-fit",
965
+ src,
966
+ title: "GitHub Gist",
967
+ frameBorder: "0",
968
+ loading: "lazy",
969
+ scrolling: "auto"
970
+ }
971
+ );
972
+ } else {
973
+ src += block.type === "typeform" ? "&disable-auto-focus=true" : "";
974
+ content = /* @__PURE__ */ jsx4(
975
+ "iframe",
976
+ {
977
+ className: "notion-asset-object-fit",
978
+ style: assetStyle,
979
+ src,
980
+ title: `iframe ${block.type}`,
981
+ frameBorder: "0",
982
+ allowFullScreen: true,
983
+ loading: "lazy",
984
+ scrolling: "auto"
985
+ }
986
+ );
987
+ }
988
+ }
989
+ }
990
+ } else if (block.type === "image") {
991
+ if (!source.includes(".gif") && source.includes("file.notion.so")) {
992
+ source = (_k = (_j = (_i = block.properties) == null ? void 0 : _i.source) == null ? void 0 : _j[0]) == null ? void 0 : _k[0];
993
+ }
994
+ const src = mapImageUrl(source, block);
995
+ const altText = getTextContent((_l = block.properties) == null ? void 0 : _l.alt_text);
996
+ const caption = getTextContent((_m = block.properties) == null ? void 0 : _m.caption);
997
+ const alt = altText || caption || "notion image";
998
+ content = /* @__PURE__ */ jsx4(
999
+ LazyImage,
1000
+ {
1001
+ src,
1002
+ alt,
1003
+ zoomable,
1004
+ height: style.height,
1005
+ style: assetStyle
1006
+ }
1007
+ );
1008
+ }
1009
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
1010
+ /* @__PURE__ */ jsxs3("div", { style, children: [
1011
+ content,
1012
+ block.type === "image" && children
1013
+ ] }),
1014
+ block.type !== "image" && children
1015
+ ] });
1016
+ }
1017
+
1018
+ // src/components/text.tsx
1019
+ import "notion-types";
1020
+ import { parsePageId } from "notion-utils";
1021
+ import React8 from "react";
1022
+
1023
+ // src/components/eoi.tsx
1024
+ import "notion-types";
1025
+
1026
+ // src/icons/type-github.tsx
1027
+ import { jsx as jsx5 } from "react/jsx-runtime";
1028
+ function SvgTypeGitHub(props) {
1029
+ return /* @__PURE__ */ jsx5("svg", { viewBox: "0 0 260 260", ...props, children: /* @__PURE__ */ jsx5("g", { children: /* @__PURE__ */ jsx5(
1030
+ "path",
1031
+ {
1032
+ d: "M128.00106,0 C57.3172926,0 0,57.3066942 0,128.00106 C0,184.555281 36.6761997,232.535542 87.534937,249.460899 C93.9320223,250.645779 96.280588,246.684165 96.280588,243.303333 C96.280588,240.251045 96.1618878,230.167899 96.106777,219.472176 C60.4967585,227.215235 52.9826207,204.369712 52.9826207,204.369712 C47.1599584,189.574598 38.770408,185.640538 38.770408,185.640538 C27.1568785,177.696113 39.6458206,177.859325 39.6458206,177.859325 C52.4993419,178.762293 59.267365,191.04987 59.267365,191.04987 C70.6837675,210.618423 89.2115753,204.961093 96.5158685,201.690482 C97.6647155,193.417512 100.981959,187.77078 104.642583,184.574357 C76.211799,181.33766 46.324819,170.362144 46.324819,121.315702 C46.324819,107.340889 51.3250588,95.9223682 59.5132437,86.9583937 C58.1842268,83.7344152 53.8029229,70.715562 60.7532354,53.0843636 C60.7532354,53.0843636 71.5019501,49.6441813 95.9626412,66.2049595 C106.172967,63.368876 117.123047,61.9465949 128.00106,61.8978432 C138.879073,61.9465949 149.837632,63.368876 160.067033,66.2049595 C184.49805,49.6441813 195.231926,53.0843636 195.231926,53.0843636 C202.199197,70.715562 197.815773,83.7344152 196.486756,86.9583937 C204.694018,95.9223682 209.660343,107.340889 209.660343,121.315702 C209.660343,170.478725 179.716133,181.303747 151.213281,184.472614 C155.80443,188.444828 159.895342,196.234518 159.895342,208.176593 C159.895342,225.303317 159.746968,239.087361 159.746968,243.303333 C159.746968,246.709601 162.05102,250.70089 168.53925,249.443941 C219.370432,232.499507 256,184.536204 256,128.00106 C256,57.3066942 198.691187,0 128.00106,0 Z M47.9405593,182.340212 C47.6586465,182.976105 46.6581745,183.166873 45.7467277,182.730227 C44.8183235,182.312656 44.2968914,181.445722 44.5978808,180.80771 C44.8734344,180.152739 45.876026,179.97045 46.8023103,180.409216 C47.7328342,180.826786 48.2627451,181.702199 47.9405593,182.340212 Z M54.2367892,187.958254 C53.6263318,188.524199 52.4329723,188.261363 51.6232682,187.366874 C50.7860088,186.474504 50.6291553,185.281144 51.2480912,184.70672 C51.8776254,184.140775 53.0349512,184.405731 53.8743302,185.298101 C54.7115892,186.201069 54.8748019,187.38595 54.2367892,187.958254 Z M58.5562413,195.146347 C57.7719732,195.691096 56.4895886,195.180261 55.6968417,194.042013 C54.9125733,192.903764 54.9125733,191.538713 55.713799,190.991845 C56.5086651,190.444977 57.7719732,190.936735 58.5753181,192.066505 C59.3574669,193.22383 59.3574669,194.58888 58.5562413,195.146347 Z M65.8613592,203.471174 C65.1597571,204.244846 63.6654083,204.03712 62.5716717,202.981538 C61.4524999,201.94927 61.1409122,200.484596 61.8446341,199.710926 C62.5547146,198.935137 64.0575422,199.15346 65.1597571,200.200564 C66.2704506,201.230712 66.6095936,202.705984 65.8613592,203.471174 Z M75.3025151,206.281542 C74.9930474,207.284134 73.553809,207.739857 72.1039724,207.313809 C70.6562556,206.875043 69.7087748,205.700761 70.0012857,204.687571 C70.302275,203.678621 71.7478721,203.20382 73.2083069,203.659543 C74.6539041,204.09619 75.6035048,205.261994 75.3025151,206.281542 Z M86.046947,207.473627 C86.0829806,208.529209 84.8535871,209.404622 83.3316829,209.4237 C81.8013,209.457614 80.563428,208.603398 80.5464708,207.564772 C80.5464708,206.498591 81.7483088,205.631657 83.2786917,205.606221 C84.8005962,205.576546 86.046947,206.424403 86.046947,207.473627 Z M96.6021471,207.069023 C96.7844366,208.099171 95.7267341,209.156872 94.215428,209.438785 C92.7295577,209.710099 91.3539086,209.074206 91.1652603,208.052538 C90.9808515,206.996955 92.0576306,205.939253 93.5413813,205.66582 C95.054807,205.402984 96.4092596,206.021919 96.6021471,207.069023 Z",
1033
+ fill: "#161614"
1034
+ }
1035
+ ) }) });
1036
+ }
1037
+ var type_github_default = SvgTypeGitHub;
1038
+
1039
+ // src/components/mention-preview-card.tsx
1040
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1041
+ function capitalizeFirstLetter(str) {
1042
+ if (!str) return "";
1043
+ return str.charAt(0).toUpperCase() + str.slice(1);
1044
+ }
1045
+ function MentionPreviewCard({
1046
+ owner,
1047
+ lastUpdated,
1048
+ externalImage,
1049
+ title,
1050
+ domain
1051
+ }) {
1052
+ return /* @__PURE__ */ jsxs4("div", { className: "notion-external-subtitle", children: [
1053
+ externalImage && /* @__PURE__ */ jsxs4("div", { className: "notion-preview-card-domain-warp", children: [
1054
+ /* @__PURE__ */ jsx6("div", { className: "notion-preview-card-logo", children: externalImage }),
1055
+ /* @__PURE__ */ jsx6("div", { className: "notion-preview-card-domain", children: capitalizeFirstLetter(domain.split(".")[0]) })
1056
+ ] }),
1057
+ /* @__PURE__ */ jsx6("div", { className: "notion-preview-card-title", children: title }),
1058
+ owner && /* @__PURE__ */ jsxs4("div", { className: "notion-external-subtitle-item", children: [
1059
+ /* @__PURE__ */ jsx6("div", { className: "notion-external-subtitle-item-name", children: "Owner" }),
1060
+ /* @__PURE__ */ jsx6("span", { className: "notion-external-subtitle-item-desc", children: owner })
1061
+ ] }),
1062
+ lastUpdated && /* @__PURE__ */ jsxs4("div", { className: "notion-external-subtitle-item", children: [
1063
+ /* @__PURE__ */ jsx6("div", { className: "notion-external-subtitle-item-name", children: "Updated" }),
1064
+ /* @__PURE__ */ jsx6("span", { className: "notion-external-subtitle-item-desc", children: lastUpdated })
1065
+ ] }),
1066
+ domain === "github.com" && /* @__PURE__ */ jsxs4("div", { className: "notion-preview-card-github-shields", children: [
1067
+ /* @__PURE__ */ jsx6(
1068
+ "img",
1069
+ {
1070
+ src: `https://img.shields.io/github/stars/${owner}/${title}?logo=github`,
1071
+ alt: ""
1072
+ }
1073
+ ),
1074
+ /* @__PURE__ */ jsx6(
1075
+ "img",
1076
+ {
1077
+ src: `https://img.shields.io/github/last-commit/${owner}/${title}`,
1078
+ alt: ""
1079
+ }
1080
+ )
1081
+ ] })
1082
+ ] });
1083
+ }
1084
+
1085
+ // src/components/eoi.tsx
1086
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1087
+ function EOI({
1088
+ block,
1089
+ inline,
1090
+ className
1091
+ }) {
1092
+ var _a, _b, _c;
1093
+ const { components } = useNotionContext();
1094
+ const { original_url, attributes, domain } = (block == null ? void 0 : block.format) || {};
1095
+ if (!original_url || !attributes) {
1096
+ return null;
1097
+ }
1098
+ const title = (_a = attributes.find((attr) => attr.id === "title")) == null ? void 0 : _a.values[0];
1099
+ let owner = (_b = attributes.find((attr) => attr.id === "owner")) == null ? void 0 : _b.values[0];
1100
+ const lastUpdatedAt = (_c = attributes.find((attr) => attr.id === "updated_at")) == null ? void 0 : _c.values[0];
1101
+ const lastUpdated = lastUpdatedAt ? formatNotionDateTime(lastUpdatedAt) : null;
1102
+ let externalImage;
1103
+ switch (domain) {
1104
+ case "github.com":
1105
+ externalImage = /* @__PURE__ */ jsx7(type_github_default, {});
1106
+ if (owner) {
1107
+ const parts = owner.split("/");
1108
+ owner = parts.at(-1);
1109
+ }
1110
+ break;
1111
+ default:
1112
+ if (true) {
1113
+ console.log(
1114
+ `Unsupported external_object_instance domain "${domain}"`,
1115
+ JSON.stringify(block, null, 2)
1116
+ );
1117
+ }
1118
+ return null;
1119
+ }
1120
+ return /* @__PURE__ */ jsxs5(
1121
+ components.Link,
1122
+ {
1123
+ target: "_blank",
1124
+ rel: "noopener noreferrer",
1125
+ href: original_url,
1126
+ className: cs(
1127
+ "notion-external",
1128
+ inline ? "notion-external-mention" : "notion-external-block notion-row",
1129
+ className
1130
+ ),
1131
+ children: [
1132
+ externalImage && /* @__PURE__ */ jsx7("div", { className: "notion-external-image", children: externalImage }),
1133
+ /* @__PURE__ */ jsxs5("div", { className: "notion-external-description", children: [
1134
+ /* @__PURE__ */ jsx7("div", { className: "notion-external-title", children: title }),
1135
+ !inline && owner ? /* @__PURE__ */ jsxs5("div", { className: "notion-external-block-desc", children: [
1136
+ owner,
1137
+ lastUpdated && /* @__PURE__ */ jsx7("span", { children: " \u2022 " }),
1138
+ lastUpdated && `Updated ${lastUpdated}`
1139
+ ] }) : null,
1140
+ inline && (owner || lastUpdated) && /* @__PURE__ */ jsx7(
1141
+ MentionPreviewCard,
1142
+ {
1143
+ title,
1144
+ owner,
1145
+ lastUpdated,
1146
+ domain,
1147
+ externalImage
1148
+ }
1149
+ )
1150
+ ] })
1151
+ ]
1152
+ }
1153
+ );
1154
+ }
1155
+
1156
+ // src/components/graceful-image.tsx
1157
+ import "react";
1158
+ import { Img } from "react-image";
1159
+ import { jsx as jsx8 } from "react/jsx-runtime";
1160
+ function GracefulImage(props) {
1161
+ if (isBrowser) {
1162
+ return /* @__PURE__ */ jsx8(Img, { ...props });
1163
+ } else {
1164
+ return /* @__PURE__ */ jsx8("img", { ...props });
1165
+ }
1166
+ }
1167
+
1168
+ // src/components/link-mention.tsx
1169
+ import "react";
1170
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1171
+ function LinkMention({ metadata }) {
1172
+ return /* @__PURE__ */ jsxs6("span", { className: "notion-link-mention", children: [
1173
+ /* @__PURE__ */ jsx9(LinkMentionInline, { metadata }),
1174
+ /* @__PURE__ */ jsx9(LinkMentionPreview, { metadata })
1175
+ ] });
1176
+ }
1177
+ function LinkMentionInline({ metadata }) {
1178
+ return /* @__PURE__ */ jsxs6(
1179
+ "a",
1180
+ {
1181
+ href: metadata.href,
1182
+ target: "_blank",
1183
+ rel: "noopener noreferrer",
1184
+ className: "notion-link-mention-link",
1185
+ children: [
1186
+ /* @__PURE__ */ jsx9(
1187
+ "img",
1188
+ {
1189
+ className: "notion-link-mention-icon",
1190
+ src: metadata.icon_url,
1191
+ alt: metadata.link_provider
1192
+ }
1193
+ ),
1194
+ metadata.link_provider && /* @__PURE__ */ jsx9("span", { className: "notion-link-mention-provider", children: metadata.link_provider }),
1195
+ /* @__PURE__ */ jsx9("span", { className: "notion-link-mention-title", children: metadata.title })
1196
+ ]
1197
+ }
1198
+ );
1199
+ }
1200
+ function LinkMentionPreview({ metadata }) {
1201
+ return /* @__PURE__ */ jsx9("div", { className: "notion-link-mention-preview", children: /* @__PURE__ */ jsxs6("article", { className: "notion-link-mention-card", children: [
1202
+ /* @__PURE__ */ jsx9(
1203
+ "img",
1204
+ {
1205
+ className: "notion-link-mention-preview-thumbnail",
1206
+ src: metadata.thumbnail_url,
1207
+ alt: metadata.title,
1208
+ referrerPolicy: "same-origin"
1209
+ }
1210
+ ),
1211
+ /* @__PURE__ */ jsxs6("div", { className: "notion-link-mention-preview-content", children: [
1212
+ /* @__PURE__ */ jsx9("p", { className: "notion-link-mention-preview-title", children: metadata.title }),
1213
+ /* @__PURE__ */ jsx9("p", { className: "notion-link-mention-preview-description", children: metadata.description }),
1214
+ /* @__PURE__ */ jsxs6("div", { className: "notion-link-mention-preview-footer", children: [
1215
+ /* @__PURE__ */ jsx9(
1216
+ "img",
1217
+ {
1218
+ className: "notion-link-mention-preview-icon",
1219
+ src: metadata.icon_url,
1220
+ alt: metadata.link_provider,
1221
+ referrerPolicy: "same-origin"
1222
+ }
1223
+ ),
1224
+ /* @__PURE__ */ jsx9("span", { className: "notion-link-mention-preview-provider", children: metadata.link_provider })
1225
+ ] })
1226
+ ] })
1227
+ ] }) });
1228
+ }
1229
+
1230
+ // src/components/page-title.tsx
1231
+ import "notion-types";
1232
+ import { getBlockTitle as getBlockTitle2 } from "notion-utils";
1233
+ import React7 from "react";
1234
+
1235
+ // src/components/page-icon.tsx
1236
+ import "notion-types";
1237
+ import { getBlockIcon, getBlockTitle } from "notion-utils";
1238
+ import React6 from "react";
1239
+
1240
+ // src/icons/default-page-icon.tsx
1241
+ import "react";
1242
+ import { jsx as jsx10 } from "react/jsx-runtime";
1243
+ function DefaultPageIcon(props) {
1244
+ const { className, ...rest } = props;
1245
+ return /* @__PURE__ */ jsx10("svg", { className, ...rest, viewBox: "0 0 30 30", width: "16", children: /* @__PURE__ */ jsx10("path", { d: "M16,1H4v28h22V11L16,1z M16,3.828L23.172,11H16V3.828z M24,27H6V3h8v10h10V27z M8,17h14v-2H8V17z M8,21h14v-2H8V21z M8,25h14v-2H8V25z" }) });
1246
+ }
1247
+
1248
+ // src/components/page-icon.tsx
1249
+ import { jsx as jsx11 } from "react/jsx-runtime";
1250
+ var isIconBlock = (value) => {
1251
+ return value.type === "page" || value.type === "callout" || value.type === "collection_view" || value.type === "collection_view_page";
1252
+ };
1253
+ function PageIconImpl({
1254
+ block,
1255
+ className,
1256
+ inline = true,
1257
+ hideDefaultIcon = false,
1258
+ defaultIcon
1259
+ }) {
1260
+ var _a;
1261
+ const { mapImageUrl, recordMap, darkMode } = useNotionContext();
1262
+ let isImage = false;
1263
+ let content = null;
1264
+ if (isIconBlock(block)) {
1265
+ const icon = ((_a = getBlockIcon(block, recordMap)) == null ? void 0 : _a.trim()) || defaultIcon;
1266
+ const title = getBlockTitle(block, recordMap);
1267
+ if (icon && isUrl(icon)) {
1268
+ const url = mapImageUrl(icon, block);
1269
+ isImage = true;
1270
+ content = /* @__PURE__ */ jsx11(
1271
+ LazyImage,
1272
+ {
1273
+ src: url,
1274
+ alt: title || "page icon",
1275
+ className: cs(className, "notion-page-icon")
1276
+ }
1277
+ );
1278
+ } else if (icon && icon.startsWith("/icons/")) {
1279
+ const url = "https://www.notion.so" + icon + "?mode=" + (darkMode ? "dark" : "light");
1280
+ content = /* @__PURE__ */ jsx11(
1281
+ LazyImage,
1282
+ {
1283
+ src: url,
1284
+ alt: title || "page icon",
1285
+ className: cs(className, "notion-page-icon")
1286
+ }
1287
+ );
1288
+ } else if (!icon) {
1289
+ if (!hideDefaultIcon) {
1290
+ isImage = true;
1291
+ content = /* @__PURE__ */ jsx11(
1292
+ DefaultPageIcon,
1293
+ {
1294
+ className: cs(className, "notion-page-icon"),
1295
+ alt: title || "page icon"
1296
+ }
1297
+ );
1298
+ }
1299
+ } else {
1300
+ isImage = false;
1301
+ content = /* @__PURE__ */ jsx11(
1302
+ "span",
1303
+ {
1304
+ className: cs(className, "notion-page-icon"),
1305
+ role: "img",
1306
+ "aria-label": icon,
1307
+ children: icon
1308
+ }
1309
+ );
1310
+ }
1311
+ }
1312
+ if (!content) {
1313
+ return null;
1314
+ }
1315
+ return /* @__PURE__ */ jsx11(
1316
+ "div",
1317
+ {
1318
+ className: cs(
1319
+ inline ? "notion-page-icon-inline" : "notion-page-icon-hero",
1320
+ isImage ? "notion-page-icon-image" : "notion-page-icon-span"
1321
+ ),
1322
+ children: content
1323
+ }
1324
+ );
1325
+ }
1326
+ var PageIcon = React6.memo(PageIconImpl);
1327
+
1328
+ // src/components/page-title.tsx
1329
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1330
+ function PageTitleImpl({
1331
+ block,
1332
+ className,
1333
+ defaultIcon,
1334
+ ...rest
1335
+ }) {
1336
+ var _a, _b;
1337
+ const { recordMap } = useNotionContext();
1338
+ if (!block) return null;
1339
+ if (block.type === "collection_view_page" || block.type === "collection_view") {
1340
+ const title = getBlockTitle2(block, recordMap);
1341
+ if (!title) {
1342
+ return null;
1343
+ }
1344
+ const titleDecoration = [[title]];
1345
+ return /* @__PURE__ */ jsxs7("span", { className: cs("notion-page-title", className), ...rest, children: [
1346
+ /* @__PURE__ */ jsx12(
1347
+ PageIcon,
1348
+ {
1349
+ block,
1350
+ defaultIcon,
1351
+ className: "notion-page-title-icon"
1352
+ }
1353
+ ),
1354
+ /* @__PURE__ */ jsx12("span", { className: "notion-page-title-text", children: /* @__PURE__ */ jsx12(Text, { value: titleDecoration, block }) })
1355
+ ] });
1356
+ }
1357
+ if (!((_a = block.properties) == null ? void 0 : _a.title)) {
1358
+ return null;
1359
+ }
1360
+ return /* @__PURE__ */ jsxs7("span", { className: cs("notion-page-title", className), ...rest, children: [
1361
+ /* @__PURE__ */ jsx12(
1362
+ PageIcon,
1363
+ {
1364
+ block,
1365
+ defaultIcon,
1366
+ className: "notion-page-title-icon"
1367
+ }
1368
+ ),
1369
+ /* @__PURE__ */ jsx12("span", { className: "notion-page-title-text", children: /* @__PURE__ */ jsx12(Text, { value: (_b = block.properties) == null ? void 0 : _b.title, block }) })
1370
+ ] });
1371
+ }
1372
+ var PageTitle = React7.memo(PageTitleImpl);
1373
+
1374
+ // src/components/text.tsx
1375
+ import { Fragment as Fragment3, jsx as jsx13 } from "react/jsx-runtime";
1376
+ function Text({
1377
+ value,
1378
+ block,
1379
+ linkProps,
1380
+ linkProtocol
1381
+ }) {
1382
+ const { components, recordMap, mapPageUrl, mapImageUrl, rootDomain } = useNotionContext();
1383
+ return /* @__PURE__ */ jsx13(React8.Fragment, { children: value == null ? void 0 : value.map(([text, decorations], index) => {
1384
+ if (!decorations) {
1385
+ if (text === ",") {
1386
+ return /* @__PURE__ */ jsx13("span", { style: { padding: "0.5em" } }, index);
1387
+ } else {
1388
+ return /* @__PURE__ */ jsx13(React8.Fragment, { children: text }, index);
1389
+ }
1390
+ }
1391
+ const formatted = decorations.reduce(
1392
+ (element, decorator) => {
1393
+ var _a, _b, _c, _d, _e;
1394
+ switch (decorator[0]) {
1395
+ case "p": {
1396
+ const blockId = decorator[1];
1397
+ const linkedBlock = (_a = recordMap.block[blockId]) == null ? void 0 : _a.value;
1398
+ if (!linkedBlock) {
1399
+ console.log('"p" missing block', blockId);
1400
+ return null;
1401
+ }
1402
+ return /* @__PURE__ */ jsx13(
1403
+ components.PageLink,
1404
+ {
1405
+ className: "notion-link",
1406
+ href: mapPageUrl(blockId),
1407
+ children: /* @__PURE__ */ jsx13(PageTitle, { block: linkedBlock })
1408
+ }
1409
+ );
1410
+ }
1411
+ case "\u2023": {
1412
+ const linkType = decorator[1][0];
1413
+ const id = decorator[1][1];
1414
+ switch (linkType) {
1415
+ case "u": {
1416
+ const user = (_b = recordMap.notion_user[id]) == null ? void 0 : _b.value;
1417
+ if (!user) {
1418
+ console.log('"\u2023" missing user', id);
1419
+ return null;
1420
+ }
1421
+ const src = mapImageUrl(user.profile_photo, block);
1422
+ if (!src) return null;
1423
+ const name = [user.given_name, user.family_name].filter(Boolean).join(" ");
1424
+ return /* @__PURE__ */ jsx13(
1425
+ GracefulImage,
1426
+ {
1427
+ className: "notion-user",
1428
+ src,
1429
+ alt: name
1430
+ }
1431
+ );
1432
+ }
1433
+ default: {
1434
+ const linkedBlock = (_c = recordMap.block[id]) == null ? void 0 : _c.value;
1435
+ if (!linkedBlock) {
1436
+ console.log('"\u2023" missing block', linkType, id);
1437
+ return null;
1438
+ }
1439
+ return /* @__PURE__ */ jsx13(
1440
+ components.PageLink,
1441
+ {
1442
+ className: "notion-link",
1443
+ href: mapPageUrl(id),
1444
+ ...linkProps,
1445
+ target: "_blank",
1446
+ rel: "noopener noreferrer",
1447
+ children: /* @__PURE__ */ jsx13(PageTitle, { block: linkedBlock })
1448
+ }
1449
+ );
1450
+ }
1451
+ }
1452
+ }
1453
+ case "h":
1454
+ return /* @__PURE__ */ jsx13("span", { className: `notion-${decorator[1]}`, children: element });
1455
+ case "c":
1456
+ return /* @__PURE__ */ jsx13("code", { className: "notion-inline-code", children: element });
1457
+ case "b":
1458
+ return /* @__PURE__ */ jsx13("b", { children: element });
1459
+ case "i":
1460
+ return /* @__PURE__ */ jsx13("em", { children: element });
1461
+ case "s":
1462
+ return /* @__PURE__ */ jsx13("s", { children: element });
1463
+ case "_":
1464
+ return /* @__PURE__ */ jsx13("span", { className: "notion-inline-underscore", children: element });
1465
+ case "e":
1466
+ return /* @__PURE__ */ jsx13(components.Equation, { math: decorator[1], inline: true });
1467
+ case "m":
1468
+ return element;
1469
+ //still need to return the base element
1470
+ case "a": {
1471
+ const v = decorator[1];
1472
+ const pathname = v.slice(1);
1473
+ const id = parsePageId(pathname, { uuid: true });
1474
+ if (rootDomain && v.includes(rootDomain) || id && v[0] === "/") {
1475
+ const href = rootDomain && v.includes(rootDomain) ? v : `${mapPageUrl(id)}${getHashFragmentValue(v)}`;
1476
+ return /* @__PURE__ */ jsx13(
1477
+ components.PageLink,
1478
+ {
1479
+ className: "notion-link",
1480
+ href,
1481
+ ...linkProps,
1482
+ children: element
1483
+ }
1484
+ );
1485
+ } else {
1486
+ return /* @__PURE__ */ jsx13(
1487
+ components.Link,
1488
+ {
1489
+ className: "notion-link",
1490
+ href: linkProtocol ? `${linkProtocol}:${decorator[1]}` : decorator[1],
1491
+ ...linkProps,
1492
+ children: element
1493
+ }
1494
+ );
1495
+ }
1496
+ }
1497
+ case "d": {
1498
+ const v = decorator[1];
1499
+ const type = v == null ? void 0 : v.type;
1500
+ if (type === "date") {
1501
+ const startDate = v.start_date;
1502
+ return formatDate(startDate);
1503
+ } else if (type === "datetime") {
1504
+ const startDate = v.start_date;
1505
+ const startTime = v.start_time;
1506
+ return `${formatDate(startDate)} ${startTime}`;
1507
+ } else if (type === "daterange") {
1508
+ const startDate = v.start_date;
1509
+ const endDate = v.end_date;
1510
+ return `${formatDate(startDate)} \u2192 ${formatDate(endDate)}`;
1511
+ } else {
1512
+ return element;
1513
+ }
1514
+ }
1515
+ case "u": {
1516
+ const userId = decorator[1];
1517
+ const user = (_d = recordMap.notion_user[userId]) == null ? void 0 : _d.value;
1518
+ if (!user) {
1519
+ console.log("missing user", userId);
1520
+ return null;
1521
+ }
1522
+ const src = mapImageUrl(user.profile_photo, block);
1523
+ if (!src) return null;
1524
+ const name = [user.given_name, user.family_name].filter(Boolean).join(" ");
1525
+ return /* @__PURE__ */ jsx13(GracefulImage, { className: "notion-user", src, alt: name });
1526
+ }
1527
+ case "lm": {
1528
+ const metadata = decorator[1];
1529
+ return /* @__PURE__ */ jsx13(LinkMention, { metadata });
1530
+ }
1531
+ case "eoi": {
1532
+ const blockId = decorator[1];
1533
+ const externalObjectInstance = (_e = recordMap.block[blockId]) == null ? void 0 : _e.value;
1534
+ return /* @__PURE__ */ jsx13(EOI, { block: externalObjectInstance, inline: true });
1535
+ }
1536
+ case "si":
1537
+ return null;
1538
+ default:
1539
+ if (true) {
1540
+ console.log("unsupported text format", decorator);
1541
+ }
1542
+ return element;
1543
+ }
1544
+ },
1545
+ /* @__PURE__ */ jsx13(Fragment3, { children: text })
1546
+ );
1547
+ return /* @__PURE__ */ jsx13(React8.Fragment, { children: formatted }, index);
1548
+ }) });
1549
+ }
1550
+
1551
+ // src/components/asset-wrapper.tsx
1552
+ import { jsx as jsx14 } from "react/jsx-runtime";
1553
+ var urlStyle = { width: "100%" };
1554
+ function AssetWrapper({
1555
+ blockId,
1556
+ block
1557
+ }) {
1558
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1559
+ const value = block;
1560
+ const { components, mapPageUrl, rootDomain, zoom } = useNotionContext();
1561
+ let isURL = false;
1562
+ if (block.type === "image") {
1563
+ const caption = (_c = (_b = (_a = value == null ? void 0 : value.properties) == null ? void 0 : _a.caption) == null ? void 0 : _b[0]) == null ? void 0 : _c[0];
1564
+ if (caption) {
1565
+ const id = parsePageId2(caption, { uuid: true });
1566
+ const isPage = caption.charAt(0) === "/" && id;
1567
+ if (isPage || isValidURL(caption)) {
1568
+ isURL = true;
1569
+ }
1570
+ }
1571
+ }
1572
+ const figure = /* @__PURE__ */ jsx14(
1573
+ "figure",
1574
+ {
1575
+ className: cs(
1576
+ "notion-asset-wrapper",
1577
+ `notion-asset-wrapper-${block.type}`,
1578
+ ((_d = value.format) == null ? void 0 : _d.block_full_width) && "notion-asset-wrapper-full",
1579
+ blockId
1580
+ ),
1581
+ children: /* @__PURE__ */ jsx14(Asset, { block: value, zoomable: zoom && !isURL, children: ((_e = value == null ? void 0 : value.properties) == null ? void 0 : _e.caption) && !isURL && /* @__PURE__ */ jsx14("figcaption", { className: "notion-asset-caption", children: /* @__PURE__ */ jsx14(Text, { value: value.properties.caption, block }) }) })
1582
+ }
1583
+ );
1584
+ if (isURL) {
1585
+ const caption = (_h = (_g = (_f = value == null ? void 0 : value.properties) == null ? void 0 : _f.caption) == null ? void 0 : _g[0]) == null ? void 0 : _h[0];
1586
+ const id = parsePageId2(caption, { uuid: true });
1587
+ const isPage = (caption == null ? void 0 : caption.charAt(0)) === "/" && id;
1588
+ const captionHostname = extractHostname(caption);
1589
+ return /* @__PURE__ */ jsx14(
1590
+ components.PageLink,
1591
+ {
1592
+ style: urlStyle,
1593
+ href: isPage ? mapPageUrl(id) : caption,
1594
+ target: captionHostname && captionHostname !== rootDomain && !(caption == null ? void 0 : caption.startsWith("/")) ? "blank_" : null,
1595
+ children: figure
1596
+ }
1597
+ );
1598
+ }
1599
+ return figure;
1600
+ }
1601
+ function isValidURL(str) {
1602
+ const pattern = new RegExp(
1603
+ "^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$",
1604
+ "i"
1605
+ );
1606
+ return !!pattern.test(str);
1607
+ }
1608
+ function extractHostname(url) {
1609
+ try {
1610
+ const hostname = new URL(url).hostname;
1611
+ return hostname;
1612
+ } catch (e) {
1613
+ return "";
1614
+ }
1615
+ }
1616
+
1617
+ // src/icons/check.tsx
1618
+ import { jsx as jsx15 } from "react/jsx-runtime";
1619
+ function SvgCheck(props) {
1620
+ return /* @__PURE__ */ jsx15("svg", { viewBox: "0 0 14 14", ...props, children: /* @__PURE__ */ jsx15("path", { d: "M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z" }) });
1621
+ }
1622
+ var check_default = SvgCheck;
1623
+
1624
+ // src/components/checkbox.tsx
1625
+ import { jsx as jsx16 } from "react/jsx-runtime";
1626
+ function Checkbox({
1627
+ isChecked
1628
+ }) {
1629
+ let content = null;
1630
+ if (isChecked) {
1631
+ content = /* @__PURE__ */ jsx16("div", { className: "notion-property-checkbox-checked", children: /* @__PURE__ */ jsx16(check_default, {}) });
1632
+ } else {
1633
+ content = /* @__PURE__ */ jsx16("div", { className: "notion-property-checkbox-unchecked" });
1634
+ }
1635
+ return /* @__PURE__ */ jsx16("span", { className: "notion-property notion-property-checkbox", children: content });
1636
+ }
1637
+
1638
+ // src/next.tsx
1639
+ import React9 from "react";
1640
+ import isEqual from "react-fast-compare";
1641
+ import { jsx as jsx17 } from "react/jsx-runtime";
1642
+ var wrapNextImage = (NextImage) => {
1643
+ return React9.memo(function ReactNotionXNextImage({
1644
+ src,
1645
+ alt,
1646
+ width,
1647
+ height,
1648
+ className,
1649
+ fill,
1650
+ ...rest
1651
+ }) {
1652
+ if (fill === "undefined") {
1653
+ fill = !(width && height);
1654
+ }
1655
+ return /* @__PURE__ */ jsx17(
1656
+ NextImage,
1657
+ {
1658
+ className,
1659
+ src,
1660
+ alt,
1661
+ width: !fill && width && height ? width : void 0,
1662
+ height: !fill && width && height ? height : void 0,
1663
+ fill,
1664
+ ...rest
1665
+ }
1666
+ );
1667
+ }, isEqual);
1668
+ };
1669
+ var wrapNextLegacyImage = (NextLegacyImage) => {
1670
+ return React9.memo(function ReactNotionXNextLegacyImage({
1671
+ src,
1672
+ alt,
1673
+ width,
1674
+ height,
1675
+ className,
1676
+ style,
1677
+ layout,
1678
+ ...rest
1679
+ }) {
1680
+ if (!layout) {
1681
+ layout = width && height ? "intrinsic" : "fill";
1682
+ }
1683
+ return /* @__PURE__ */ jsx17(
1684
+ NextLegacyImage,
1685
+ {
1686
+ className,
1687
+ src,
1688
+ alt,
1689
+ width: layout === "intrinsic" && width,
1690
+ height: layout === "intrinsic" && height,
1691
+ objectFit: style == null ? void 0 : style.objectFit,
1692
+ objectPosition: style == null ? void 0 : style.objectPosition,
1693
+ layout,
1694
+ ...rest
1695
+ }
1696
+ );
1697
+ }, isEqual);
1698
+ };
1699
+ function wrapNextLink(NextLink) {
1700
+ return ({
1701
+ href,
1702
+ as,
1703
+ passHref,
1704
+ prefetch,
1705
+ replace,
1706
+ scroll,
1707
+ shallow,
1708
+ locale,
1709
+ ...linkProps
1710
+ }) => {
1711
+ return /* @__PURE__ */ jsx17(
1712
+ NextLink,
1713
+ {
1714
+ href,
1715
+ as,
1716
+ passHref,
1717
+ prefetch,
1718
+ replace,
1719
+ scroll,
1720
+ shallow,
1721
+ locale,
1722
+ legacyBehavior: true,
1723
+ children: /* @__PURE__ */ jsx17("a", { ...linkProps })
1724
+ }
1725
+ );
1726
+ };
1727
+ }
1728
+
1729
+ // src/context.tsx
1730
+ import { jsx as jsx18 } from "react/jsx-runtime";
1731
+ function DefaultLink(props) {
1732
+ return /* @__PURE__ */ jsx18("a", { target: "_blank", rel: "noopener noreferrer", ...props });
1733
+ }
1734
+ var DefaultLinkMemo = React10.memo(DefaultLink);
1735
+ function DefaultPageLink(props) {
1736
+ return /* @__PURE__ */ jsx18("a", { ...props });
1737
+ }
1738
+ var DefaultPageLinkMemo = React10.memo(DefaultPageLink);
1739
+ function DefaultEmbed(props) {
1740
+ return /* @__PURE__ */ jsx18(AssetWrapper, { ...props });
1741
+ }
1742
+ var DefaultHeader = Header;
1743
+ function dummyLink({ href, rel, target, title, ...rest }) {
1744
+ return /* @__PURE__ */ jsx18("span", { ...rest });
1745
+ }
1746
+ var dummyComponent = (name) => () => {
1747
+ console.warn(
1748
+ `Warning: using empty component "${name}" (you should override this in NotionRenderer.components)`
1749
+ );
1750
+ return null;
1751
+ };
1752
+ var dummyOverrideFn = (_, defaultValueFn) => defaultValueFn();
1753
+ var defaultComponents = {
1754
+ Image: null,
1755
+ // disable custom images by default
1756
+ Link: DefaultLinkMemo,
1757
+ PageLink: DefaultPageLinkMemo,
1758
+ Checkbox,
1759
+ Callout: void 0,
1760
+ // use the built-in callout rendering by default
1761
+ Code: dummyComponent("Code"),
1762
+ Equation: dummyComponent("Equation"),
1763
+ Collection: dummyComponent("Collection"),
1764
+ Property: void 0,
1765
+ // use the built-in property rendering by default
1766
+ propertyTextValue: dummyOverrideFn,
1767
+ propertySelectValue: dummyOverrideFn,
1768
+ propertyRelationValue: dummyOverrideFn,
1769
+ propertyFormulaValue: dummyOverrideFn,
1770
+ propertyTitleValue: dummyOverrideFn,
1771
+ propertyPersonValue: dummyOverrideFn,
1772
+ propertyFileValue: dummyOverrideFn,
1773
+ propertyCheckboxValue: dummyOverrideFn,
1774
+ propertyUrlValue: dummyOverrideFn,
1775
+ propertyEmailValue: dummyOverrideFn,
1776
+ propertyPhoneNumberValue: dummyOverrideFn,
1777
+ propertyNumberValue: dummyOverrideFn,
1778
+ propertyLastEditedTimeValue: dummyOverrideFn,
1779
+ propertyCreatedTimeValue: dummyOverrideFn,
1780
+ propertyDateValue: dummyOverrideFn,
1781
+ propertyAutoIncrementIdValue: dummyOverrideFn,
1782
+ Pdf: dummyComponent("Pdf"),
1783
+ Tweet: dummyComponent("Tweet"),
1784
+ Modal: dummyComponent("Modal"),
1785
+ Header: DefaultHeader,
1786
+ Embed: DefaultEmbed
1787
+ };
1788
+ var defaultNotionContext = {
1789
+ recordMap: {
1790
+ block: {},
1791
+ collection: {},
1792
+ collection_view: {},
1793
+ collection_query: {},
1794
+ notion_user: {},
1795
+ signed_urls: {}
1796
+ },
1797
+ components: defaultComponents,
1798
+ mapPageUrl: defaultMapPageUrl(),
1799
+ mapImageUrl: defaultMapImageUrl,
1800
+ searchNotion: void 0,
1801
+ isShowingSearch: false,
1802
+ onHideSearch: void 0,
1803
+ fullPage: false,
1804
+ darkMode: false,
1805
+ previewImages: false,
1806
+ forceCustomImages: false,
1807
+ showCollectionViewDropdown: true,
1808
+ linkTableTitleProperties: true,
1809
+ isLinkCollectionToUrlProperty: false,
1810
+ showTableOfContents: false,
1811
+ minTableOfContentsItems: 3,
1812
+ defaultPageIcon: null,
1813
+ defaultPageCover: null,
1814
+ defaultPageCoverPosition: 0.5,
1815
+ zoom: null
1816
+ };
1817
+ var ctx = React10.createContext(defaultNotionContext);
1818
+ function NotionContextProvider({
1819
+ components: themeComponents = {},
1820
+ children,
1821
+ mapPageUrl,
1822
+ mapImageUrl,
1823
+ rootPageId,
1824
+ ...rest
1825
+ }) {
1826
+ for (const key of Object.keys(rest)) {
1827
+ if (rest[key] === void 0) {
1828
+ delete rest[key];
1829
+ }
1830
+ }
1831
+ const wrappedThemeComponents = React10.useMemo(
1832
+ () => ({
1833
+ ...themeComponents
1834
+ }),
1835
+ [themeComponents]
1836
+ );
1837
+ if (wrappedThemeComponents.nextImage && wrappedThemeComponents.nextLegacyImage) {
1838
+ console.warn(
1839
+ "You should not pass both nextImage and nextLegacyImage. Only nextImage component will be used."
1840
+ );
1841
+ wrappedThemeComponents.Image = wrapNextImage(themeComponents.nextImage);
1842
+ } else if (wrappedThemeComponents.nextImage) {
1843
+ wrappedThemeComponents.Image = wrapNextImage(themeComponents.nextImage);
1844
+ } else if (wrappedThemeComponents.nextLegacyImage) {
1845
+ wrappedThemeComponents.Image = wrapNextLegacyImage(
1846
+ themeComponents.nextLegacyImage
1847
+ );
1848
+ }
1849
+ if (wrappedThemeComponents.nextLink) {
1850
+ wrappedThemeComponents.nextLink = wrapNextLink(themeComponents.nextLink);
1851
+ }
1852
+ for (const key of Object.keys(wrappedThemeComponents)) {
1853
+ if (!wrappedThemeComponents[key]) {
1854
+ delete wrappedThemeComponents[key];
1855
+ }
1856
+ }
1857
+ const value = React10.useMemo(
1858
+ () => ({
1859
+ ...defaultNotionContext,
1860
+ ...rest,
1861
+ rootPageId,
1862
+ mapPageUrl: mapPageUrl != null ? mapPageUrl : defaultMapPageUrl(rootPageId),
1863
+ mapImageUrl: mapImageUrl != null ? mapImageUrl : defaultMapImageUrl,
1864
+ components: { ...defaultComponents, ...wrappedThemeComponents }
1865
+ }),
1866
+ [mapImageUrl, mapPageUrl, wrappedThemeComponents, rootPageId, rest]
1867
+ );
1868
+ return /* @__PURE__ */ jsx18(ctx.Provider, { value, children });
1869
+ }
1870
+ var NotionContextConsumer = ctx.Consumer;
1871
+ var useNotionContext = () => {
1872
+ return React10.useContext(ctx);
1873
+ };
1874
+
1875
+ // src/icons/search-icon.tsx
1876
+ import "react";
1877
+ import { jsx as jsx19 } from "react/jsx-runtime";
1878
+ function SearchIcon(props) {
1879
+ const { className, ...rest } = props;
1880
+ return /* @__PURE__ */ jsx19("svg", { className: cs("notion-icon", className), viewBox: "0 0 17 17", ...rest, children: /* @__PURE__ */ jsx19("path", { d: "M6.78027 13.6729C8.24805 13.6729 9.60156 13.1982 10.709 12.4072L14.875 16.5732C15.0684 16.7666 15.3232 16.8633 15.5957 16.8633C16.167 16.8633 16.5713 16.4238 16.5713 15.8613C16.5713 15.5977 16.4834 15.3516 16.29 15.1582L12.1504 11.0098C13.0205 9.86719 13.5391 8.45215 13.5391 6.91406C13.5391 3.19629 10.498 0.155273 6.78027 0.155273C3.0625 0.155273 0.0214844 3.19629 0.0214844 6.91406C0.0214844 10.6318 3.0625 13.6729 6.78027 13.6729ZM6.78027 12.2139C3.87988 12.2139 1.48047 9.81445 1.48047 6.91406C1.48047 4.01367 3.87988 1.61426 6.78027 1.61426C9.68066 1.61426 12.0801 4.01367 12.0801 6.91406C12.0801 9.81445 9.68066 12.2139 6.78027 12.2139Z" }) });
1881
+ }
1882
+
1883
+ // src/components/search-dialog.tsx
1884
+ var import_lodash = __toESM(require_lodash(), 1);
1885
+ import { getBlockParentPage, getBlockTitle as getBlockTitle3 } from "notion-utils";
1886
+ import React14 from "react";
1887
+
1888
+ // src/icons/clear-icon.tsx
1889
+ import "react";
1890
+ import { jsx as jsx20 } from "react/jsx-runtime";
1891
+ function ClearIcon(props) {
1892
+ const { className, ...rest } = props;
1893
+ return /* @__PURE__ */ jsx20("svg", { className: cs("notion-icon", className), ...rest, viewBox: "0 0 30 30", children: /* @__PURE__ */ jsx20("path", { d: "M15,0C6.716,0,0,6.716,0,15s6.716,15,15,15s15-6.716,15-15S23.284,0,15,0z M22,20.6L20.6,22L15,16.4L9.4,22L8,20.6l5.6-5.6 L8,9.4L9.4,8l5.6,5.6L20.6,8L22,9.4L16.4,15L22,20.6z" }) });
1894
+ }
1895
+
1896
+ // src/icons/loading-icon.tsx
1897
+ import "react";
1898
+ import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
1899
+ function LoadingIcon(props) {
1900
+ const { className, ...rest } = props;
1901
+ return /* @__PURE__ */ jsxs8("svg", { className: cs("notion-icon", className), ...rest, viewBox: "0 0 24 24", children: [
1902
+ /* @__PURE__ */ jsx21("defs", { children: /* @__PURE__ */ jsxs8(
1903
+ "linearGradient",
1904
+ {
1905
+ x1: "28.1542969%",
1906
+ y1: "63.7402344%",
1907
+ x2: "74.6289062%",
1908
+ y2: "17.7832031%",
1909
+ id: "linearGradient-1",
1910
+ children: [
1911
+ /* @__PURE__ */ jsx21("stop", { stopColor: "rgba(164, 164, 164, 1)", offset: "0%" }),
1912
+ /* @__PURE__ */ jsx21(
1913
+ "stop",
1914
+ {
1915
+ stopColor: "rgba(164, 164, 164, 0)",
1916
+ stopOpacity: "0",
1917
+ offset: "100%"
1918
+ }
1919
+ )
1920
+ ]
1921
+ }
1922
+ ) }),
1923
+ /* @__PURE__ */ jsx21("g", { id: "Page-1", stroke: "none", strokeWidth: "1", fill: "none", children: /* @__PURE__ */ jsx21("g", { transform: "translate(-236.000000, -286.000000)", children: /* @__PURE__ */ jsxs8("g", { transform: "translate(238.000000, 286.000000)", children: [
1924
+ /* @__PURE__ */ jsx21(
1925
+ "circle",
1926
+ {
1927
+ id: "Oval-2",
1928
+ stroke: "url(#linearGradient-1)",
1929
+ strokeWidth: "4",
1930
+ cx: "10",
1931
+ cy: "12",
1932
+ r: "10"
1933
+ }
1934
+ ),
1935
+ /* @__PURE__ */ jsx21(
1936
+ "path",
1937
+ {
1938
+ d: "M10,2 C4.4771525,2 0,6.4771525 0,12",
1939
+ id: "Oval-2",
1940
+ stroke: "rgba(164, 164, 164, 1)",
1941
+ strokeWidth: "4"
1942
+ }
1943
+ ),
1944
+ /* @__PURE__ */ jsx21(
1945
+ "rect",
1946
+ {
1947
+ id: "Rectangle-1",
1948
+ fill: "rgba(164, 164, 164, 1)",
1949
+ x: "8",
1950
+ y: "0",
1951
+ width: "4",
1952
+ height: "4",
1953
+ rx: "8"
1954
+ }
1955
+ )
1956
+ ] }) }) })
1957
+ ] });
1958
+ }
1959
+
1960
+ // src/components/search-dialog.tsx
1961
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
1962
+ var SearchDialog = class extends React14.Component {
1963
+ constructor(props) {
1964
+ super(props);
1965
+ __publicField(this, "state", {
1966
+ isLoading: false,
1967
+ query: "",
1968
+ searchResult: null,
1969
+ searchError: null
1970
+ });
1971
+ __publicField(this, "_inputRef");
1972
+ __publicField(this, "_search");
1973
+ __publicField(this, "_onAfterOpen", () => {
1974
+ if (this._inputRef.current) {
1975
+ this._inputRef.current.focus();
1976
+ }
1977
+ });
1978
+ __publicField(this, "_onChangeQuery", (e) => {
1979
+ const query = e.target.value;
1980
+ this.setState({ query });
1981
+ if (!query.trim()) {
1982
+ this.setState({ isLoading: false, searchResult: null, searchError: null });
1983
+ return;
1984
+ } else {
1985
+ this._search();
1986
+ }
1987
+ });
1988
+ __publicField(this, "_onClearQuery", () => {
1989
+ this._onChangeQuery({ target: { value: "" } });
1990
+ });
1991
+ __publicField(this, "_warmupSearch", async () => {
1992
+ const { searchNotion, rootBlockId } = this.props;
1993
+ await searchNotion({
1994
+ query: "",
1995
+ ancestorId: rootBlockId
1996
+ });
1997
+ });
1998
+ __publicField(this, "_searchImpl", async () => {
1999
+ const { searchNotion, rootBlockId } = this.props;
2000
+ const { query } = this.state;
2001
+ if (!query.trim()) {
2002
+ this.setState({ isLoading: false, searchResult: null, searchError: null });
2003
+ return;
2004
+ }
2005
+ this.setState({ isLoading: true });
2006
+ const result = await searchNotion({
2007
+ query,
2008
+ ancestorId: rootBlockId
2009
+ });
2010
+ console.log("search", query, result);
2011
+ let searchResult = null;
2012
+ let searchError = null;
2013
+ if (result.error || result.errorId) {
2014
+ searchError = result;
2015
+ } else {
2016
+ searchResult = { ...result };
2017
+ const results = searchResult.results.map((result2) => {
2018
+ var _a, _b;
2019
+ const block = (_a = searchResult.recordMap.block[result2.id]) == null ? void 0 : _a.value;
2020
+ if (!block) return;
2021
+ const title = getBlockTitle3(block, searchResult.recordMap);
2022
+ if (!title) {
2023
+ return;
2024
+ }
2025
+ result2.title = title;
2026
+ result2.block = block;
2027
+ result2.recordMap = searchResult.recordMap;
2028
+ result2.page = getBlockParentPage(block, searchResult.recordMap, {
2029
+ inclusive: true
2030
+ }) || block;
2031
+ if (!result2.page.id) {
2032
+ return;
2033
+ }
2034
+ if ((_b = result2.highlight) == null ? void 0 : _b.text) {
2035
+ result2.highlight.html = result2.highlight.text.replaceAll(/<gzknfouu>/gi, "<b>").replaceAll(/<\/gzknfouu>/gi, "</b>");
2036
+ }
2037
+ return result2;
2038
+ }).filter(Boolean);
2039
+ const searchResultsMap = Object.fromEntries(
2040
+ results.map((result2) => [result2.page.id, result2])
2041
+ );
2042
+ searchResult.results = Object.values(searchResultsMap);
2043
+ }
2044
+ if (this.state.query === query) {
2045
+ this.setState({ isLoading: false, searchResult, searchError });
2046
+ }
2047
+ });
2048
+ this._inputRef = React14.createRef();
2049
+ }
2050
+ componentDidMount() {
2051
+ this._search = (0, import_lodash.default)(this._searchImpl.bind(this), 1e3);
2052
+ void this._warmupSearch();
2053
+ }
2054
+ render() {
2055
+ const { isOpen, onClose } = this.props;
2056
+ const { isLoading, query, searchResult, searchError } = this.state;
2057
+ const hasQuery = !!query.trim();
2058
+ return /* @__PURE__ */ jsx22(NotionContextConsumer, { children: (ctx2) => {
2059
+ const { components, defaultPageIcon, mapPageUrl } = ctx2;
2060
+ return /* @__PURE__ */ jsx22(
2061
+ components.Modal,
2062
+ {
2063
+ isOpen,
2064
+ contentLabel: "Search",
2065
+ className: "notion-search",
2066
+ overlayClassName: "notion-search-overlay",
2067
+ onRequestClose: onClose,
2068
+ onAfterOpen: this._onAfterOpen,
2069
+ children: /* @__PURE__ */ jsxs9("div", { className: "quickFindMenu", children: [
2070
+ /* @__PURE__ */ jsxs9("div", { className: "searchBar", children: [
2071
+ /* @__PURE__ */ jsx22("div", { className: "inlineIcon", children: isLoading ? /* @__PURE__ */ jsx22(LoadingIcon, { className: "loadingIcon" }) : /* @__PURE__ */ jsx22(SearchIcon, {}) }),
2072
+ /* @__PURE__ */ jsx22(
2073
+ "input",
2074
+ {
2075
+ className: "searchInput",
2076
+ placeholder: "Search",
2077
+ value: query,
2078
+ ref: this._inputRef,
2079
+ onChange: this._onChangeQuery
2080
+ }
2081
+ ),
2082
+ query && /* @__PURE__ */ jsx22(
2083
+ "div",
2084
+ {
2085
+ role: "button",
2086
+ className: "clearButton",
2087
+ onClick: this._onClearQuery,
2088
+ children: /* @__PURE__ */ jsx22(ClearIcon, { className: "clearIcon" })
2089
+ }
2090
+ )
2091
+ ] }),
2092
+ hasQuery && searchResult && /* @__PURE__ */ jsx22(Fragment4, { children: searchResult.results.length ? /* @__PURE__ */ jsxs9(
2093
+ NotionContextProvider,
2094
+ {
2095
+ ...ctx2,
2096
+ recordMap: searchResult.recordMap,
2097
+ children: [
2098
+ /* @__PURE__ */ jsx22("div", { className: "resultsPane", children: searchResult.results.map((result) => {
2099
+ var _a;
2100
+ return /* @__PURE__ */ jsxs9(
2101
+ components.PageLink,
2102
+ {
2103
+ className: cs("result", "notion-page-link"),
2104
+ href: mapPageUrl(
2105
+ result.page.id,
2106
+ // TODO
2107
+ searchResult.recordMap
2108
+ ),
2109
+ children: [
2110
+ /* @__PURE__ */ jsx22(
2111
+ PageTitle,
2112
+ {
2113
+ block: result.page,
2114
+ defaultIcon: defaultPageIcon
2115
+ }
2116
+ ),
2117
+ ((_a = result.highlight) == null ? void 0 : _a.html) && /* @__PURE__ */ jsx22(
2118
+ "div",
2119
+ {
2120
+ className: "notion-search-result-highlight",
2121
+ dangerouslySetInnerHTML: {
2122
+ __html: result.highlight.html
2123
+ }
2124
+ }
2125
+ )
2126
+ ]
2127
+ },
2128
+ result.id
2129
+ );
2130
+ }) }),
2131
+ /* @__PURE__ */ jsx22("footer", { className: "resultsFooter", children: /* @__PURE__ */ jsxs9("div", { children: [
2132
+ /* @__PURE__ */ jsx22("span", { className: "resultsCount", children: searchResult.total }),
2133
+ searchResult.total === 1 ? " result" : " results"
2134
+ ] }) })
2135
+ ]
2136
+ }
2137
+ ) : /* @__PURE__ */ jsxs9("div", { className: "noResultsPane", children: [
2138
+ /* @__PURE__ */ jsx22("div", { className: "noResults", children: "No results" }),
2139
+ /* @__PURE__ */ jsx22("div", { className: "noResultsDetail", children: "Try different search terms" })
2140
+ ] }) }),
2141
+ hasQuery && !searchResult && searchError && /* @__PURE__ */ jsx22("div", { className: "noResultsPane", children: /* @__PURE__ */ jsx22("div", { className: "noResults", children: "Search error" }) })
2142
+ ] })
2143
+ }
2144
+ );
2145
+ } });
2146
+ }
2147
+ };
2148
+
2149
+ // src/components/header.tsx
2150
+ import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
2151
+ function Header({
2152
+ block
2153
+ }) {
2154
+ return /* @__PURE__ */ jsx23("header", { className: "notion-header", children: /* @__PURE__ */ jsxs10("div", { className: "notion-nav-header", children: [
2155
+ /* @__PURE__ */ jsx23(Breadcrumbs, { block }),
2156
+ /* @__PURE__ */ jsx23(Search, { block })
2157
+ ] }) });
2158
+ }
2159
+ function Breadcrumbs({
2160
+ block,
2161
+ rootOnly = false
2162
+ }) {
2163
+ const { recordMap, mapPageUrl, components } = useNotionContext();
2164
+ const breadcrumbs = React15.useMemo(() => {
2165
+ const tempBreadcrumbs = getPageBreadcrumbs(recordMap, block.id);
2166
+ if (rootOnly) {
2167
+ return [tempBreadcrumbs == null ? void 0 : tempBreadcrumbs[0]].filter(Boolean);
2168
+ }
2169
+ return tempBreadcrumbs;
2170
+ }, [recordMap, block.id, rootOnly]);
2171
+ return /* @__PURE__ */ jsx23("div", { className: "breadcrumbs", children: breadcrumbs == null ? void 0 : breadcrumbs.map((breadcrumb, index) => {
2172
+ if (!breadcrumb) {
2173
+ return null;
2174
+ }
2175
+ const pageLinkProps = {};
2176
+ const componentMap = {
2177
+ pageLink: components.PageLink
2178
+ };
2179
+ if (breadcrumb.active) {
2180
+ componentMap.pageLink = (props) => /* @__PURE__ */ jsx23("div", { ...props });
2181
+ } else {
2182
+ pageLinkProps.href = mapPageUrl(breadcrumb.pageId);
2183
+ }
2184
+ return /* @__PURE__ */ jsxs10(React15.Fragment, { children: [
2185
+ /* @__PURE__ */ jsxs10(
2186
+ componentMap.pageLink,
2187
+ {
2188
+ className: cs("breadcrumb", breadcrumb.active && "active"),
2189
+ ...pageLinkProps,
2190
+ children: [
2191
+ breadcrumb.icon && /* @__PURE__ */ jsx23(PageIcon, { className: "icon", block: breadcrumb.block }),
2192
+ breadcrumb.title && /* @__PURE__ */ jsx23("span", { className: "title", children: breadcrumb.title })
2193
+ ]
2194
+ }
2195
+ ),
2196
+ index < breadcrumbs.length - 1 && /* @__PURE__ */ jsx23("span", { className: "spacer", children: "/" })
2197
+ ] }, breadcrumb.pageId);
2198
+ }) }, "breadcrumbs");
2199
+ }
2200
+ function Search({
2201
+ block,
2202
+ search,
2203
+ title = "Search"
2204
+ }) {
2205
+ const { searchNotion, rootPageId, isShowingSearch, onHideSearch } = useNotionContext();
2206
+ const onSearchNotion = search || searchNotion;
2207
+ const [isSearchOpen, setIsSearchOpen] = React15.useState(isShowingSearch);
2208
+ React15.useEffect(() => {
2209
+ setIsSearchOpen(isShowingSearch);
2210
+ }, [isShowingSearch]);
2211
+ const onOpenSearch = React15.useCallback(() => {
2212
+ setIsSearchOpen(true);
2213
+ }, []);
2214
+ const onCloseSearch = React15.useCallback(() => {
2215
+ setIsSearchOpen(false);
2216
+ if (onHideSearch) {
2217
+ onHideSearch();
2218
+ }
2219
+ }, [onHideSearch]);
2220
+ useHotkeys("cmd+p", (event) => {
2221
+ onOpenSearch();
2222
+ event.preventDefault();
2223
+ event.stopPropagation();
2224
+ });
2225
+ useHotkeys("cmd+k", (event) => {
2226
+ onOpenSearch();
2227
+ event.preventDefault();
2228
+ event.stopPropagation();
2229
+ });
2230
+ const hasSearch = !!onSearchNotion;
2231
+ return /* @__PURE__ */ jsxs10(Fragment5, { children: [
2232
+ hasSearch && /* @__PURE__ */ jsxs10(
2233
+ "div",
2234
+ {
2235
+ role: "button",
2236
+ className: cs("breadcrumb", "button", "notion-search-button"),
2237
+ onClick: onOpenSearch,
2238
+ children: [
2239
+ /* @__PURE__ */ jsx23(SearchIcon, { className: "searchIcon" }),
2240
+ title && /* @__PURE__ */ jsx23("span", { className: "title", children: title })
2241
+ ]
2242
+ }
2243
+ ),
2244
+ isSearchOpen && hasSearch && /* @__PURE__ */ jsx23(
2245
+ SearchDialog,
2246
+ {
2247
+ isOpen: isSearchOpen,
2248
+ rootBlockId: rootPageId || (block == null ? void 0 : block.id),
2249
+ onClose: onCloseSearch,
2250
+ searchNotion: onSearchNotion
2251
+ }
2252
+ )
2253
+ ] });
2254
+ }
2255
+
2256
+ // src/renderer.tsx
2257
+ import mediumZoom from "@fisch0920/medium-zoom";
2258
+ import "notion-types";
2259
+ import * as React20 from "react";
2260
+
2261
+ // src/block.tsx
2262
+ import {
2263
+ getBlockCollectionId,
2264
+ getBlockIcon as getBlockIcon2,
2265
+ getBlockParentPage as getBlockParentPage2,
2266
+ getPageTableOfContents,
2267
+ getTextContent as getTextContent2,
2268
+ uuidToId as uuidToId2
2269
+ } from "notion-utils";
2270
+ import React19 from "react";
2271
+
2272
+ // src/components/audio.tsx
2273
+ import "notion-types";
2274
+ import { jsx as jsx24 } from "react/jsx-runtime";
2275
+ function Audio({
2276
+ block,
2277
+ className
2278
+ }) {
2279
+ var _a, _b, _c;
2280
+ const { recordMap } = useNotionContext();
2281
+ let source = recordMap.signed_urls[block.id] || ((_c = (_b = (_a = block.properties) == null ? void 0 : _a.source) == null ? void 0 : _b[0]) == null ? void 0 : _c[0]);
2282
+ if (!source) {
2283
+ return null;
2284
+ }
2285
+ if (block.space_id) {
2286
+ const url = new URL(source);
2287
+ url.searchParams.set("spaceId", block.space_id);
2288
+ source = url.toString();
2289
+ }
2290
+ return /* @__PURE__ */ jsx24("div", { className: cs("notion-audio", className), children: /* @__PURE__ */ jsx24("audio", { controls: true, preload: "none", src: source }) });
2291
+ }
2292
+
2293
+ // src/components/file.tsx
2294
+ import "notion-types";
2295
+
2296
+ // src/icons/file-icon.tsx
2297
+ import "react";
2298
+ import { jsx as jsx25 } from "react/jsx-runtime";
2299
+ function FileIcon(props) {
2300
+ const { className, ...rest } = props;
2301
+ return /* @__PURE__ */ jsx25("svg", { className, ...rest, viewBox: "0 0 30 30", children: /* @__PURE__ */ jsx25("path", { d: "M22,8v12c0,3.866-3.134,7-7,7s-7-3.134-7-7V8c0-2.762,2.238-5,5-5s5,2.238,5,5v12c0,1.657-1.343,3-3,3s-3-1.343-3-3V8h-2v12c0,2.762,2.238,5,5,5s5-2.238,5-5V8c0-3.866-3.134-7-7-7S6,4.134,6,8v12c0,4.971,4.029,9,9,9s9-4.029,9-9V8H22z" }) });
2302
+ }
2303
+
2304
+ // src/components/file.tsx
2305
+ import { jsx as jsx26, jsxs as jsxs11 } from "react/jsx-runtime";
2306
+ function File({
2307
+ block,
2308
+ className
2309
+ }) {
2310
+ var _a, _b, _c, _d, _e;
2311
+ const { components, recordMap } = useNotionContext();
2312
+ let source = recordMap.signed_urls[block.id] || ((_c = (_b = (_a = block.properties) == null ? void 0 : _a.source) == null ? void 0 : _b[0]) == null ? void 0 : _c[0]);
2313
+ if (!source) {
2314
+ return null;
2315
+ }
2316
+ if (block.space_id) {
2317
+ const url = new URL(source);
2318
+ url.searchParams.set("spaceId", block.space_id);
2319
+ source = url.toString();
2320
+ }
2321
+ return /* @__PURE__ */ jsx26("div", { className: cs("notion-file", className), children: /* @__PURE__ */ jsxs11(
2322
+ components.Link,
2323
+ {
2324
+ className: "notion-file-link",
2325
+ href: source,
2326
+ target: "_blank",
2327
+ rel: "noopener noreferrer",
2328
+ children: [
2329
+ /* @__PURE__ */ jsx26(FileIcon, { className: "notion-file-icon" }),
2330
+ /* @__PURE__ */ jsxs11("div", { className: "notion-file-info", children: [
2331
+ /* @__PURE__ */ jsx26("div", { className: "notion-file-title", children: /* @__PURE__ */ jsx26(Text, { value: ((_d = block.properties) == null ? void 0 : _d.title) || [["File"]], block }) }),
2332
+ ((_e = block.properties) == null ? void 0 : _e.size) && /* @__PURE__ */ jsx26("div", { className: "notion-file-size", children: /* @__PURE__ */ jsx26(Text, { value: block.properties.size, block }) })
2333
+ ] })
2334
+ ]
2335
+ }
2336
+ ) });
2337
+ }
2338
+
2339
+ // src/components/google-drive.tsx
2340
+ import "notion-types";
2341
+ import { jsx as jsx27, jsxs as jsxs12 } from "react/jsx-runtime";
2342
+ function GoogleDrive({
2343
+ block,
2344
+ className
2345
+ }) {
2346
+ var _a;
2347
+ const { components, mapImageUrl } = useNotionContext();
2348
+ const properties = (_a = block.format) == null ? void 0 : _a.drive_properties;
2349
+ if (!properties) return null;
2350
+ let domain;
2351
+ try {
2352
+ const url = new URL(properties.url);
2353
+ domain = url.hostname;
2354
+ } catch (e) {
2355
+ }
2356
+ return /* @__PURE__ */ jsx27("div", { className: cs("notion-google-drive", className), children: /* @__PURE__ */ jsxs12(
2357
+ components.Link,
2358
+ {
2359
+ className: "notion-google-drive-link",
2360
+ href: properties.url,
2361
+ target: "_blank",
2362
+ rel: "noopener noreferrer",
2363
+ children: [
2364
+ /* @__PURE__ */ jsx27("div", { className: "notion-google-drive-preview", children: /* @__PURE__ */ jsx27(
2365
+ GracefulImage,
2366
+ {
2367
+ src: mapImageUrl(properties.thumbnail, block),
2368
+ alt: properties.title || "Google Drive Document",
2369
+ loading: "lazy"
2370
+ }
2371
+ ) }),
2372
+ /* @__PURE__ */ jsxs12("div", { className: "notion-google-drive-body", children: [
2373
+ properties.title && /* @__PURE__ */ jsx27("div", { className: "notion-google-drive-body-title", children: properties.title }),
2374
+ properties.icon && domain && /* @__PURE__ */ jsxs12("div", { className: "notion-google-drive-body-source", children: [
2375
+ properties.icon && /* @__PURE__ */ jsx27(
2376
+ "div",
2377
+ {
2378
+ className: "notion-google-drive-body-source-icon",
2379
+ style: {
2380
+ backgroundImage: `url(${properties.icon})`
2381
+ }
2382
+ }
2383
+ ),
2384
+ domain && /* @__PURE__ */ jsx27("div", { className: "notion-google-drive-body-source-domain", children: domain })
2385
+ ] })
2386
+ ] })
2387
+ ]
2388
+ }
2389
+ ) });
2390
+ }
2391
+
2392
+ // src/components/page-aside.tsx
2393
+ var import_lodash2 = __toESM(require_lodash(), 1);
2394
+ import { uuidToId } from "notion-utils";
2395
+ import React17 from "react";
2396
+ import { jsx as jsx28, jsxs as jsxs13 } from "react/jsx-runtime";
2397
+ function PageAside({
2398
+ toc,
2399
+ activeSection,
2400
+ setActiveSection,
2401
+ pageAside,
2402
+ hasToc,
2403
+ hasAside,
2404
+ className
2405
+ }) {
2406
+ const throttleMs = 100;
2407
+ const actionSectionScrollSpy = React17.useMemo(
2408
+ () => (0, import_lodash2.default)(() => {
2409
+ const sections = document.getElementsByClassName("notion-h");
2410
+ let prevBBox = null;
2411
+ let currentSectionId = activeSection;
2412
+ for (const section of sections) {
2413
+ if (!section || !(section instanceof Element)) continue;
2414
+ if (!currentSectionId) {
2415
+ currentSectionId = section.dataset.id;
2416
+ }
2417
+ const bbox = section.getBoundingClientRect();
2418
+ const prevHeight = prevBBox ? bbox.top - prevBBox.bottom : 0;
2419
+ const offset = Math.max(150, prevHeight / 4);
2420
+ if (bbox.top - offset < 0) {
2421
+ currentSectionId = section.dataset.id;
2422
+ prevBBox = bbox;
2423
+ continue;
2424
+ }
2425
+ break;
2426
+ }
2427
+ setActiveSection(currentSectionId);
2428
+ }, throttleMs),
2429
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2430
+ [
2431
+ // explicitly not taking a dependency on activeSection
2432
+ setActiveSection
2433
+ ]
2434
+ );
2435
+ React17.useEffect(() => {
2436
+ if (!hasToc) {
2437
+ return;
2438
+ }
2439
+ window.addEventListener("scroll", actionSectionScrollSpy);
2440
+ actionSectionScrollSpy();
2441
+ return () => {
2442
+ window.removeEventListener("scroll", actionSectionScrollSpy);
2443
+ };
2444
+ }, [hasToc, actionSectionScrollSpy]);
2445
+ if (!hasAside) {
2446
+ return null;
2447
+ }
2448
+ return /* @__PURE__ */ jsxs13("aside", { className: cs("notion-aside", className), children: [
2449
+ hasToc && /* @__PURE__ */ jsxs13("div", { className: "notion-aside-table-of-contents", children: [
2450
+ /* @__PURE__ */ jsx28("div", { className: "notion-aside-table-of-contents-header", children: "Table of Contents" }),
2451
+ /* @__PURE__ */ jsx28("nav", { className: "notion-table-of-contents", children: toc.map((tocItem) => {
2452
+ const id = uuidToId(tocItem.id);
2453
+ return /* @__PURE__ */ jsx28(
2454
+ "a",
2455
+ {
2456
+ href: `#${id}`,
2457
+ className: cs(
2458
+ "notion-table-of-contents-item",
2459
+ `notion-table-of-contents-item-indent-level-${tocItem.indentLevel}`,
2460
+ activeSection === id && "notion-table-of-contents-active-item"
2461
+ ),
2462
+ children: /* @__PURE__ */ jsx28(
2463
+ "span",
2464
+ {
2465
+ className: "notion-table-of-contents-item-body",
2466
+ style: {
2467
+ display: "inline-block",
2468
+ marginLeft: tocItem.indentLevel * 16
2469
+ },
2470
+ children: tocItem.text
2471
+ }
2472
+ )
2473
+ },
2474
+ id
2475
+ );
2476
+ }) })
2477
+ ] }),
2478
+ pageAside
2479
+ ] });
2480
+ }
2481
+
2482
+ // src/components/sync-pointer-block.tsx
2483
+ import "notion-types";
2484
+ import { jsx as jsx29 } from "react/jsx-runtime";
2485
+ function SyncPointerBlock({
2486
+ block,
2487
+ level
2488
+ }) {
2489
+ var _a, _b;
2490
+ if (!block) {
2491
+ if (true) {
2492
+ console.warn("missing sync pointer block");
2493
+ }
2494
+ return null;
2495
+ }
2496
+ const syncPointerBlock = block;
2497
+ const referencePointerId = (_b = (_a = syncPointerBlock == null ? void 0 : syncPointerBlock.format) == null ? void 0 : _a.transclusion_reference_pointer) == null ? void 0 : _b.id;
2498
+ if (!referencePointerId) {
2499
+ return null;
2500
+ }
2501
+ return /* @__PURE__ */ jsx29(
2502
+ NotionBlockRenderer,
2503
+ {
2504
+ level,
2505
+ blockId: referencePointerId
2506
+ },
2507
+ referencePointerId
2508
+ );
2509
+ }
2510
+
2511
+ // src/icons/link-icon.tsx
2512
+ import "react";
2513
+ import { jsx as jsx30 } from "react/jsx-runtime";
2514
+ function LinkIcon(props) {
2515
+ const { className, ...rest } = props;
2516
+ return /* @__PURE__ */ jsx30(
2517
+ "svg",
2518
+ {
2519
+ className,
2520
+ ...rest,
2521
+ viewBox: "0 0 16 16",
2522
+ width: "16",
2523
+ height: "16",
2524
+ children: /* @__PURE__ */ jsx30(
2525
+ "path",
2526
+ {
2527
+ fillRule: "evenodd",
2528
+ d: "M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"
2529
+ }
2530
+ )
2531
+ }
2532
+ );
2533
+ }
2534
+
2535
+ // src/block.tsx
2536
+ import { Fragment as Fragment6, jsx as jsx31, jsxs as jsxs14 } from "react/jsx-runtime";
2537
+ var tocIndentLevelCache = {};
2538
+ var pageCoverStyleCache = {};
2539
+ function Block(props) {
2540
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T;
2541
+ const ctx2 = useNotionContext();
2542
+ const {
2543
+ components,
2544
+ fullPage,
2545
+ darkMode,
2546
+ recordMap,
2547
+ mapPageUrl,
2548
+ mapImageUrl,
2549
+ showTableOfContents,
2550
+ minTableOfContentsItems,
2551
+ defaultPageIcon,
2552
+ defaultPageCover,
2553
+ defaultPageCoverPosition
2554
+ } = ctx2;
2555
+ const [activeSection, setActiveSection] = React19.useState(null);
2556
+ const {
2557
+ block,
2558
+ children,
2559
+ level,
2560
+ className,
2561
+ bodyClassName,
2562
+ header,
2563
+ footer,
2564
+ pageHeader,
2565
+ pageFooter,
2566
+ pageTitle,
2567
+ pageAside,
2568
+ pageCover,
2569
+ hideBlockId,
2570
+ disableHeader
2571
+ } = props;
2572
+ if (!block) {
2573
+ return null;
2574
+ }
2575
+ if (level === 0 && block.type === "collection_view") {
2576
+ ;
2577
+ block.type = "collection_view_page";
2578
+ }
2579
+ const blockId = hideBlockId ? "notion-block" : `notion-block-${uuidToId2(block.id)}`;
2580
+ switch (block.type) {
2581
+ case "collection_view_page":
2582
+ // fallthrough
2583
+ case "page":
2584
+ if (level === 0) {
2585
+ const {
2586
+ page_icon = defaultPageIcon,
2587
+ page_cover = defaultPageCover,
2588
+ page_cover_position = defaultPageCoverPosition,
2589
+ page_full_width,
2590
+ page_small_text
2591
+ } = block.format || {};
2592
+ if (fullPage) {
2593
+ const properties = block.type === "page" ? block.properties : {
2594
+ title: (_b = (_a = recordMap.collection[getBlockCollectionId(block, recordMap)]) == null ? void 0 : _a.value) == null ? void 0 : _b.name
2595
+ };
2596
+ const coverPosition = (1 - (page_cover_position || 0.5)) * 100;
2597
+ const pageCoverObjectPosition = `center ${coverPosition}%`;
2598
+ let pageCoverStyle = pageCoverStyleCache[pageCoverObjectPosition];
2599
+ if (!pageCoverStyle) {
2600
+ pageCoverStyle = pageCoverStyleCache[pageCoverObjectPosition] = {
2601
+ objectPosition: pageCoverObjectPosition
2602
+ };
2603
+ }
2604
+ const pageIcon = (_c = getBlockIcon2(block, recordMap)) != null ? _c : defaultPageIcon;
2605
+ const isPageIconUrl = pageIcon && isUrl(pageIcon);
2606
+ const toc = getPageTableOfContents(
2607
+ block,
2608
+ recordMap
2609
+ );
2610
+ const hasToc = showTableOfContents && toc.length >= minTableOfContentsItems;
2611
+ const hasAside = !!((hasToc || pageAside) && !page_full_width);
2612
+ const hasPageCover = !!(pageCover || page_cover);
2613
+ return /* @__PURE__ */ jsxs14(
2614
+ "div",
2615
+ {
2616
+ className: cs(
2617
+ "notion",
2618
+ "notion-app",
2619
+ darkMode ? "dark-mode" : "light-mode",
2620
+ blockId,
2621
+ className
2622
+ ),
2623
+ children: [
2624
+ /* @__PURE__ */ jsx31("div", { className: "notion-viewport" }),
2625
+ /* @__PURE__ */ jsxs14("div", { className: "notion-frame", children: [
2626
+ !disableHeader && /* @__PURE__ */ jsx31(components.Header, { block }),
2627
+ header,
2628
+ /* @__PURE__ */ jsxs14("div", { className: "notion-page-scroller", children: [
2629
+ hasPageCover && (pageCover != null ? pageCover : /* @__PURE__ */ jsx31("div", { className: "notion-page-cover-wrapper", children: /* @__PURE__ */ jsx31(
2630
+ LazyImage,
2631
+ {
2632
+ src: mapImageUrl(page_cover, block),
2633
+ alt: getTextContent2(properties == null ? void 0 : properties.title),
2634
+ priority: true,
2635
+ className: "notion-page-cover",
2636
+ style: pageCoverStyle
2637
+ }
2638
+ ) })),
2639
+ /* @__PURE__ */ jsxs14(
2640
+ "main",
2641
+ {
2642
+ className: cs(
2643
+ "notion-page",
2644
+ hasPageCover ? "notion-page-has-cover" : "notion-page-no-cover",
2645
+ page_icon ? "notion-page-has-icon" : "notion-page-no-icon",
2646
+ isPageIconUrl ? "notion-page-has-image-icon" : "notion-page-has-text-icon",
2647
+ "notion-full-page",
2648
+ page_full_width && "notion-full-width",
2649
+ page_small_text && "notion-small-text",
2650
+ bodyClassName
2651
+ ),
2652
+ children: [
2653
+ page_icon && /* @__PURE__ */ jsx31(
2654
+ PageIcon,
2655
+ {
2656
+ block,
2657
+ defaultIcon: defaultPageIcon,
2658
+ inline: false
2659
+ }
2660
+ ),
2661
+ pageHeader,
2662
+ /* @__PURE__ */ jsx31("h1", { className: "notion-title", children: pageTitle != null ? pageTitle : /* @__PURE__ */ jsx31(Text, { value: properties == null ? void 0 : properties.title, block }) }),
2663
+ (block.type === "collection_view_page" || block.type === "page" && block.parent_table === "collection") && /* @__PURE__ */ jsx31(components.Collection, { block, ctx: ctx2 }),
2664
+ block.type !== "collection_view_page" && /* @__PURE__ */ jsxs14(
2665
+ "div",
2666
+ {
2667
+ className: cs(
2668
+ "notion-page-content",
2669
+ hasAside && "notion-page-content-has-aside",
2670
+ hasToc && "notion-page-content-has-toc"
2671
+ ),
2672
+ children: [
2673
+ /* @__PURE__ */ jsx31("article", { className: "notion-page-content-inner", children }),
2674
+ hasAside && /* @__PURE__ */ jsx31(
2675
+ PageAside,
2676
+ {
2677
+ toc,
2678
+ activeSection,
2679
+ setActiveSection,
2680
+ hasToc,
2681
+ hasAside,
2682
+ pageAside
2683
+ }
2684
+ )
2685
+ ]
2686
+ }
2687
+ ),
2688
+ pageFooter
2689
+ ]
2690
+ }
2691
+ ),
2692
+ footer
2693
+ ] })
2694
+ ] })
2695
+ ]
2696
+ }
2697
+ );
2698
+ } else {
2699
+ return /* @__PURE__ */ jsxs14(
2700
+ "main",
2701
+ {
2702
+ className: cs(
2703
+ "notion",
2704
+ darkMode ? "dark-mode" : "light-mode",
2705
+ "notion-page",
2706
+ page_full_width && "notion-full-width",
2707
+ page_small_text && "notion-small-text",
2708
+ blockId,
2709
+ className,
2710
+ bodyClassName
2711
+ ),
2712
+ children: [
2713
+ /* @__PURE__ */ jsx31("div", { className: "notion-viewport" }),
2714
+ pageHeader,
2715
+ (block.type === "collection_view_page" || block.type === "page" && block.parent_table === "collection") && /* @__PURE__ */ jsx31(components.Collection, { block, ctx: ctx2 }),
2716
+ block.type !== "collection_view_page" && children,
2717
+ pageFooter
2718
+ ]
2719
+ }
2720
+ );
2721
+ }
2722
+ } else {
2723
+ const blockColor = (_d = block.format) == null ? void 0 : _d.block_color;
2724
+ return /* @__PURE__ */ jsx31(
2725
+ components.PageLink,
2726
+ {
2727
+ className: cs(
2728
+ "notion-page-link",
2729
+ blockColor && `notion-${blockColor}`,
2730
+ blockId
2731
+ ),
2732
+ href: mapPageUrl(block.id),
2733
+ children: /* @__PURE__ */ jsx31(PageTitle, { block })
2734
+ }
2735
+ );
2736
+ }
2737
+ case "header":
2738
+ // fallthrough
2739
+ case "sub_header":
2740
+ // fallthrough
2741
+ case "sub_sub_header": {
2742
+ if (!block.properties) return null;
2743
+ const blockColor = (_e = block.format) == null ? void 0 : _e.block_color;
2744
+ const id = uuidToId2(block.id);
2745
+ const title = getTextContent2(block.properties.title) || `Notion Header ${id}`;
2746
+ let indentLevel = tocIndentLevelCache[block.id];
2747
+ let indentLevelClass;
2748
+ if (indentLevel === void 0) {
2749
+ const page = getBlockParentPage2(block, recordMap);
2750
+ if (page) {
2751
+ const toc = getPageTableOfContents(page, recordMap);
2752
+ const tocItem = toc.find((tocItem2) => tocItem2.id === block.id);
2753
+ if (tocItem) {
2754
+ indentLevel = tocItem.indentLevel;
2755
+ tocIndentLevelCache[block.id] = indentLevel;
2756
+ }
2757
+ }
2758
+ }
2759
+ if (indentLevel !== void 0) {
2760
+ indentLevelClass = `notion-h-indent-${indentLevel}`;
2761
+ }
2762
+ const isH1 = block.type === "header";
2763
+ const isH2 = block.type === "sub_header";
2764
+ const isH3 = block.type === "sub_sub_header";
2765
+ const classNameStr = cs(
2766
+ isH1 && "notion-h notion-h1",
2767
+ isH2 && "notion-h notion-h2",
2768
+ isH3 && "notion-h notion-h3",
2769
+ blockColor && `notion-${blockColor}`,
2770
+ indentLevelClass,
2771
+ blockId
2772
+ );
2773
+ const innerHeader = /* @__PURE__ */ jsxs14("span", { children: [
2774
+ /* @__PURE__ */ jsx31("div", { id, className: "notion-header-anchor" }),
2775
+ !((_f = block.format) == null ? void 0 : _f.toggleable) && /* @__PURE__ */ jsx31("a", { className: "notion-hash-link", href: `#${id}`, title, children: /* @__PURE__ */ jsx31(LinkIcon, {}) }),
2776
+ /* @__PURE__ */ jsx31("span", { className: "notion-h-title", children: /* @__PURE__ */ jsx31(Text, { value: block.properties.title, block }) })
2777
+ ] });
2778
+ let headerBlock = null;
2779
+ if (isH1) {
2780
+ headerBlock = /* @__PURE__ */ jsx31("h2", { className: classNameStr, "data-id": id, children: innerHeader });
2781
+ } else if (isH2) {
2782
+ headerBlock = /* @__PURE__ */ jsx31("h3", { className: classNameStr, "data-id": id, children: innerHeader });
2783
+ } else {
2784
+ headerBlock = /* @__PURE__ */ jsx31("h4", { className: classNameStr, "data-id": id, children: innerHeader });
2785
+ }
2786
+ if ((_g = block.format) == null ? void 0 : _g.toggleable) {
2787
+ return /* @__PURE__ */ jsxs14("details", { className: cs("notion-toggle", blockId), children: [
2788
+ /* @__PURE__ */ jsx31("summary", { children: headerBlock }),
2789
+ /* @__PURE__ */ jsx31("div", { children })
2790
+ ] });
2791
+ } else {
2792
+ return headerBlock;
2793
+ }
2794
+ }
2795
+ case "divider":
2796
+ return /* @__PURE__ */ jsx31("hr", { className: cs("notion-hr", blockId) });
2797
+ case "text": {
2798
+ if (!block.properties && !((_h = block.content) == null ? void 0 : _h.length)) {
2799
+ return /* @__PURE__ */ jsx31("div", { className: cs("notion-blank", blockId), children: "\xA0" });
2800
+ }
2801
+ const blockColor = (_i = block.format) == null ? void 0 : _i.block_color;
2802
+ return /* @__PURE__ */ jsxs14(
2803
+ "div",
2804
+ {
2805
+ className: cs(
2806
+ "notion-text",
2807
+ blockColor && `notion-${blockColor}`,
2808
+ blockId
2809
+ ),
2810
+ children: [
2811
+ ((_j = block.properties) == null ? void 0 : _j.title) && /* @__PURE__ */ jsx31(Text, { value: block.properties.title, block }),
2812
+ children && /* @__PURE__ */ jsx31("div", { className: "notion-text-children", children })
2813
+ ]
2814
+ }
2815
+ );
2816
+ }
2817
+ case "bulleted_list":
2818
+ // fallthrough
2819
+ case "numbered_list": {
2820
+ const wrapList = (content, start2) => block.type === "bulleted_list" ? /* @__PURE__ */ jsx31("ul", { className: cs("notion-list", "notion-list-disc", blockId), children: content }) : /* @__PURE__ */ jsx31(
2821
+ "ol",
2822
+ {
2823
+ start: start2,
2824
+ className: cs("notion-list", "notion-list-numbered", blockId),
2825
+ style: block.type === "numbered_list" ? {
2826
+ listStyleType: getListStyle(
2827
+ getListNestingLevel(block.id, recordMap.block)
2828
+ )
2829
+ } : void 0,
2830
+ children: content
2831
+ }
2832
+ );
2833
+ let output = null;
2834
+ const isTopLevel = block.type !== ((_l = (_k = recordMap.block[block.parent_id]) == null ? void 0 : _k.value) == null ? void 0 : _l.type);
2835
+ const start = getListNumber(block.id, recordMap.block);
2836
+ if (block.content) {
2837
+ const listItem = block.properties ? /* @__PURE__ */ jsx31("li", { children: /* @__PURE__ */ jsx31(Text, { value: block.properties.title, block }) }) : null;
2838
+ if (block.type === "bulleted_list") {
2839
+ output = /* @__PURE__ */ jsxs14(Fragment6, { children: [
2840
+ listItem,
2841
+ /* @__PURE__ */ jsx31("ul", { className: cs("notion-list", "notion-list-disc", blockId), children })
2842
+ ] });
2843
+ } else {
2844
+ const nestingLevel = getListNestingLevel(block.id, recordMap.block);
2845
+ output = /* @__PURE__ */ jsxs14(Fragment6, { children: [
2846
+ listItem,
2847
+ /* @__PURE__ */ jsx31(
2848
+ "ol",
2849
+ {
2850
+ className: cs("notion-list", "notion-list-numbered", blockId),
2851
+ style: {
2852
+ listStyleType: getListStyle(nestingLevel + 1)
2853
+ },
2854
+ children
2855
+ }
2856
+ )
2857
+ ] });
2858
+ }
2859
+ } else {
2860
+ output = block.properties ? /* @__PURE__ */ jsx31("li", { children: /* @__PURE__ */ jsx31(Text, { value: block.properties.title, block }) }) : null;
2861
+ }
2862
+ return isTopLevel ? wrapList(output, start) : output;
2863
+ }
2864
+ case "embed":
2865
+ return /* @__PURE__ */ jsx31(components.Embed, { blockId, block });
2866
+ case "replit":
2867
+ // fallthrough
2868
+ case "tweet":
2869
+ // fallthrough
2870
+ case "maps":
2871
+ // fallthrough
2872
+ case "pdf":
2873
+ // fallthrough
2874
+ case "figma":
2875
+ // fallthrough
2876
+ case "typeform":
2877
+ // fallthrough
2878
+ case "codepen":
2879
+ // fallthrough
2880
+ case "excalidraw":
2881
+ // fallthrough
2882
+ case "image":
2883
+ // fallthrough
2884
+ case "gist":
2885
+ // fallthrough
2886
+ case "video":
2887
+ return /* @__PURE__ */ jsx31(AssetWrapper, { blockId, block });
2888
+ case "drive": {
2889
+ const properties = (_m = block.format) == null ? void 0 : _m.drive_properties;
2890
+ if (!properties) {
2891
+ if ((_n = block.format) == null ? void 0 : _n.display_source) {
2892
+ return /* @__PURE__ */ jsx31(AssetWrapper, { blockId, block });
2893
+ }
2894
+ }
2895
+ return /* @__PURE__ */ jsx31(
2896
+ GoogleDrive,
2897
+ {
2898
+ block,
2899
+ className: blockId
2900
+ }
2901
+ );
2902
+ }
2903
+ case "audio":
2904
+ return /* @__PURE__ */ jsx31(Audio, { block, className: blockId });
2905
+ case "file":
2906
+ return /* @__PURE__ */ jsx31(File, { block, className: blockId });
2907
+ case "equation":
2908
+ return /* @__PURE__ */ jsx31(
2909
+ components.Equation,
2910
+ {
2911
+ block,
2912
+ inline: false,
2913
+ className: blockId
2914
+ }
2915
+ );
2916
+ case "code":
2917
+ return /* @__PURE__ */ jsx31(components.Code, { block });
2918
+ case "column_list":
2919
+ return /* @__PURE__ */ jsx31("div", { className: cs("notion-row", blockId), children });
2920
+ case "column": {
2921
+ const spacerWidth = `min(32px, 4vw)`;
2922
+ const ratio = ((_o = block.format) == null ? void 0 : _o.column_ratio) || 0.5;
2923
+ const parent = (_p = recordMap.block[block.parent_id]) == null ? void 0 : _p.value;
2924
+ const columns = ((_q = parent == null ? void 0 : parent.content) == null ? void 0 : _q.length) || Math.max(2, Math.ceil(1 / ratio));
2925
+ const width = `calc((100% - (${columns - 1} * ${spacerWidth})) * ${ratio})`;
2926
+ const style = { width };
2927
+ return /* @__PURE__ */ jsxs14(Fragment6, { children: [
2928
+ /* @__PURE__ */ jsx31("div", { className: cs("notion-column", blockId), style, children }),
2929
+ /* @__PURE__ */ jsx31("div", { className: "notion-spacer" })
2930
+ ] });
2931
+ }
2932
+ case "quote": {
2933
+ if (!block.properties) return null;
2934
+ const blockColor = (_r = block.format) == null ? void 0 : _r.block_color;
2935
+ return /* @__PURE__ */ jsxs14(
2936
+ "blockquote",
2937
+ {
2938
+ className: cs(
2939
+ "notion-quote",
2940
+ blockColor && `notion-${blockColor}`,
2941
+ blockId
2942
+ ),
2943
+ children: [
2944
+ /* @__PURE__ */ jsx31("div", { children: /* @__PURE__ */ jsx31(Text, { value: block.properties.title, block }) }),
2945
+ children
2946
+ ]
2947
+ }
2948
+ );
2949
+ }
2950
+ case "collection_view":
2951
+ return /* @__PURE__ */ jsx31(components.Collection, { block, className: blockId, ctx: ctx2 });
2952
+ case "callout":
2953
+ if (components.Callout) {
2954
+ return /* @__PURE__ */ jsx31(components.Callout, { block, className: blockId });
2955
+ } else {
2956
+ return /* @__PURE__ */ jsxs14(
2957
+ "div",
2958
+ {
2959
+ className: cs(
2960
+ "notion-callout",
2961
+ ((_s = block.format) == null ? void 0 : _s.block_color) && `notion-${(_t = block.format) == null ? void 0 : _t.block_color}_co`,
2962
+ blockId
2963
+ ),
2964
+ children: [
2965
+ /* @__PURE__ */ jsx31(PageIcon, { block, hideDefaultIcon: true }),
2966
+ /* @__PURE__ */ jsxs14("div", { className: "notion-callout-text", children: [
2967
+ /* @__PURE__ */ jsx31(Text, { value: (_u = block.properties) == null ? void 0 : _u.title, block }),
2968
+ children
2969
+ ] })
2970
+ ]
2971
+ }
2972
+ );
2973
+ }
2974
+ case "bookmark": {
2975
+ if (!block.properties) return null;
2976
+ const link = block.properties.link;
2977
+ if (!link || !((_v = link[0]) == null ? void 0 : _v[0])) return null;
2978
+ let title = getTextContent2(block.properties.title);
2979
+ if (!title) {
2980
+ title = getTextContent2(link);
2981
+ }
2982
+ if (title) {
2983
+ if (title.startsWith("http")) {
2984
+ try {
2985
+ const url = new URL(title);
2986
+ title = url.hostname;
2987
+ } catch (e) {
2988
+ }
2989
+ }
2990
+ }
2991
+ return /* @__PURE__ */ jsx31("div", { className: "notion-row", children: /* @__PURE__ */ jsxs14(
2992
+ components.Link,
2993
+ {
2994
+ target: "_blank",
2995
+ rel: "noopener noreferrer",
2996
+ className: cs(
2997
+ "notion-bookmark",
2998
+ ((_w = block.format) == null ? void 0 : _w.block_color) && `notion-${block.format.block_color}`,
2999
+ blockId
3000
+ ),
3001
+ href: link[0][0],
3002
+ children: [
3003
+ /* @__PURE__ */ jsxs14("div", { children: [
3004
+ title && /* @__PURE__ */ jsx31("div", { className: "notion-bookmark-title", children: /* @__PURE__ */ jsx31(Text, { value: [[title]], block }) }),
3005
+ ((_x = block.properties) == null ? void 0 : _x.description) && /* @__PURE__ */ jsx31("div", { className: "notion-bookmark-description", children: /* @__PURE__ */ jsx31(Text, { value: (_y = block.properties) == null ? void 0 : _y.description, block }) }),
3006
+ /* @__PURE__ */ jsxs14("div", { className: "notion-bookmark-link", children: [
3007
+ ((_z = block.format) == null ? void 0 : _z.bookmark_icon) && /* @__PURE__ */ jsx31("div", { className: "notion-bookmark-link-icon", children: /* @__PURE__ */ jsx31(
3008
+ LazyImage,
3009
+ {
3010
+ src: mapImageUrl((_A = block.format) == null ? void 0 : _A.bookmark_icon, block),
3011
+ alt: title
3012
+ }
3013
+ ) }),
3014
+ /* @__PURE__ */ jsx31("div", { className: "notion-bookmark-link-text", children: /* @__PURE__ */ jsx31(Text, { value: link, block }) })
3015
+ ] })
3016
+ ] }),
3017
+ ((_B = block.format) == null ? void 0 : _B.bookmark_cover) && /* @__PURE__ */ jsx31("div", { className: "notion-bookmark-image", children: /* @__PURE__ */ jsx31(
3018
+ LazyImage,
3019
+ {
3020
+ src: mapImageUrl((_C = block.format) == null ? void 0 : _C.bookmark_cover, block),
3021
+ alt: getTextContent2((_D = block.properties) == null ? void 0 : _D.title),
3022
+ style: {
3023
+ objectFit: "cover"
3024
+ }
3025
+ }
3026
+ ) })
3027
+ ]
3028
+ }
3029
+ ) });
3030
+ }
3031
+ case "toggle":
3032
+ return /* @__PURE__ */ jsxs14("details", { className: cs("notion-toggle", blockId), children: [
3033
+ /* @__PURE__ */ jsx31("summary", { children: /* @__PURE__ */ jsx31(Text, { value: (_E = block.properties) == null ? void 0 : _E.title, block }) }),
3034
+ /* @__PURE__ */ jsx31("div", { children })
3035
+ ] });
3036
+ case "table_of_contents": {
3037
+ const page = getBlockParentPage2(block, recordMap);
3038
+ if (!page) return null;
3039
+ const toc = getPageTableOfContents(page, recordMap);
3040
+ const blockColor = (_F = block.format) == null ? void 0 : _F.block_color;
3041
+ return /* @__PURE__ */ jsx31(
3042
+ "div",
3043
+ {
3044
+ className: cs(
3045
+ "notion-table-of-contents",
3046
+ blockColor && `notion-${blockColor}`,
3047
+ blockId
3048
+ ),
3049
+ children: toc.map((tocItem) => /* @__PURE__ */ jsx31(
3050
+ "a",
3051
+ {
3052
+ href: `#${uuidToId2(tocItem.id)}`,
3053
+ className: "notion-table-of-contents-item",
3054
+ children: /* @__PURE__ */ jsx31(
3055
+ "span",
3056
+ {
3057
+ className: "notion-table-of-contents-item-body",
3058
+ style: {
3059
+ display: "inline-block",
3060
+ marginLeft: tocItem.indentLevel * 24
3061
+ },
3062
+ children: tocItem.text
3063
+ }
3064
+ )
3065
+ },
3066
+ tocItem.id
3067
+ ))
3068
+ }
3069
+ );
3070
+ }
3071
+ case "to_do": {
3072
+ const isChecked = ((_I = (_H = (_G = block.properties) == null ? void 0 : _G.checked) == null ? void 0 : _H[0]) == null ? void 0 : _I[0]) === "Yes";
3073
+ return /* @__PURE__ */ jsxs14("div", { className: cs("notion-to-do", blockId), children: [
3074
+ /* @__PURE__ */ jsxs14("div", { className: "notion-to-do-item", children: [
3075
+ /* @__PURE__ */ jsx31(components.Checkbox, { blockId, isChecked }),
3076
+ /* @__PURE__ */ jsx31(
3077
+ "div",
3078
+ {
3079
+ className: cs(
3080
+ "notion-to-do-body",
3081
+ isChecked && `notion-to-do-checked`
3082
+ ),
3083
+ children: /* @__PURE__ */ jsx31(Text, { value: (_J = block.properties) == null ? void 0 : _J.title, block })
3084
+ }
3085
+ )
3086
+ ] }),
3087
+ /* @__PURE__ */ jsx31("div", { className: "notion-to-do-children", children })
3088
+ ] });
3089
+ }
3090
+ case "transclusion_container":
3091
+ return /* @__PURE__ */ jsx31("div", { className: cs("notion-sync-block", blockId), children });
3092
+ case "transclusion_reference":
3093
+ return /* @__PURE__ */ jsx31(SyncPointerBlock, { ...props, level: level + 1 });
3094
+ case "alias": {
3095
+ const blockPointerId = (_L = (_K = block == null ? void 0 : block.format) == null ? void 0 : _K.alias_pointer) == null ? void 0 : _L.id;
3096
+ const linkedBlock = (_M = recordMap.block[blockPointerId]) == null ? void 0 : _M.value;
3097
+ if (!linkedBlock) {
3098
+ console.log('"alias" missing block', blockPointerId);
3099
+ return null;
3100
+ }
3101
+ return /* @__PURE__ */ jsx31(
3102
+ components.PageLink,
3103
+ {
3104
+ className: cs("notion-page-link", blockPointerId),
3105
+ href: mapPageUrl(blockPointerId),
3106
+ children: /* @__PURE__ */ jsx31(PageTitle, { block: linkedBlock })
3107
+ }
3108
+ );
3109
+ }
3110
+ case "table":
3111
+ return /* @__PURE__ */ jsx31("table", { className: cs("notion-simple-table", blockId), children: /* @__PURE__ */ jsx31("tbody", { children }) });
3112
+ case "table_row": {
3113
+ const tableBlock = (_N = recordMap.block[block.parent_id]) == null ? void 0 : _N.value;
3114
+ const order = (_O = tableBlock.format) == null ? void 0 : _O.table_block_column_order;
3115
+ const formatMap = (_P = tableBlock.format) == null ? void 0 : _P.table_block_column_format;
3116
+ const backgroundColor = (_Q = block.format) == null ? void 0 : _Q.block_color;
3117
+ const hasRowHeader = ((_R = tableBlock.format) == null ? void 0 : _R.table_block_column_header) === true;
3118
+ const hasColumnHeader = ((_S = tableBlock.format) == null ? void 0 : _S.table_block_row_header) === true;
3119
+ const isHeaderRow = hasRowHeader && ((_T = tableBlock.content) == null ? void 0 : _T[0]) === block.id;
3120
+ if (!tableBlock || !order) {
3121
+ return null;
3122
+ }
3123
+ return /* @__PURE__ */ jsx31(
3124
+ "tr",
3125
+ {
3126
+ className: cs(
3127
+ "notion-simple-table-row",
3128
+ backgroundColor && `notion-${backgroundColor}`,
3129
+ isHeaderRow && "notion-simple-table-header-row",
3130
+ blockId
3131
+ ),
3132
+ children: order.map((column, columnIndex) => {
3133
+ var _a2, _b2, _c2;
3134
+ const color = (_a2 = formatMap == null ? void 0 : formatMap[column]) == null ? void 0 : _a2.color;
3135
+ const isHeaderColumn = hasColumnHeader && columnIndex === 0;
3136
+ return /* @__PURE__ */ jsx31(
3137
+ "td",
3138
+ {
3139
+ className: cs(
3140
+ color ? `notion-${color}` : "",
3141
+ isHeaderColumn && "notion-simple-table-header-cell"
3142
+ ),
3143
+ style: {
3144
+ width: ((_b2 = formatMap == null ? void 0 : formatMap[column]) == null ? void 0 : _b2.width) || 120
3145
+ },
3146
+ children: /* @__PURE__ */ jsx31("div", { className: "notion-simple-table-cell", children: /* @__PURE__ */ jsx31(
3147
+ Text,
3148
+ {
3149
+ value: ((_c2 = block.properties) == null ? void 0 : _c2[column]) || [["\u3164"]],
3150
+ block
3151
+ }
3152
+ ) })
3153
+ },
3154
+ column
3155
+ );
3156
+ })
3157
+ }
3158
+ );
3159
+ }
3160
+ case "external_object_instance":
3161
+ return /* @__PURE__ */ jsx31(EOI, { block, className: blockId });
3162
+ default:
3163
+ if (true) {
3164
+ console.log(
3165
+ "Unsupported block type " + block.type,
3166
+ JSON.stringify(block, null, 2)
3167
+ );
3168
+ }
3169
+ return /* @__PURE__ */ jsx31("div", {});
3170
+ }
3171
+ }
3172
+
3173
+ // src/renderer.tsx
3174
+ import { jsx as jsx32 } from "react/jsx-runtime";
3175
+ function NotionRenderer({
3176
+ components,
3177
+ recordMap,
3178
+ mapPageUrl,
3179
+ mapImageUrl,
3180
+ searchNotion,
3181
+ isShowingSearch,
3182
+ onHideSearch,
3183
+ fullPage,
3184
+ rootPageId,
3185
+ rootDomain,
3186
+ darkMode,
3187
+ previewImages,
3188
+ forceCustomImages,
3189
+ showCollectionViewDropdown,
3190
+ linkTableTitleProperties,
3191
+ isLinkCollectionToUrlProperty,
3192
+ isImageZoomable = true,
3193
+ showTableOfContents,
3194
+ minTableOfContentsItems,
3195
+ defaultPageIcon,
3196
+ defaultPageCover,
3197
+ defaultPageCoverPosition,
3198
+ ...rest
3199
+ }) {
3200
+ const zoom = React20.useMemo(
3201
+ () => !!globalThis.window && mediumZoom({
3202
+ background: "rgba(0, 0, 0, 0.8)",
3203
+ minZoomScale: 2,
3204
+ margin: getMediumZoomMargin()
3205
+ }),
3206
+ []
3207
+ );
3208
+ return /* @__PURE__ */ jsx32(
3209
+ NotionContextProvider,
3210
+ {
3211
+ components,
3212
+ recordMap,
3213
+ mapPageUrl,
3214
+ mapImageUrl,
3215
+ searchNotion,
3216
+ isShowingSearch,
3217
+ onHideSearch,
3218
+ fullPage,
3219
+ rootPageId,
3220
+ rootDomain,
3221
+ darkMode,
3222
+ previewImages,
3223
+ forceCustomImages,
3224
+ showCollectionViewDropdown,
3225
+ linkTableTitleProperties,
3226
+ isLinkCollectionToUrlProperty,
3227
+ showTableOfContents,
3228
+ minTableOfContentsItems,
3229
+ defaultPageIcon,
3230
+ defaultPageCover,
3231
+ defaultPageCoverPosition,
3232
+ zoom: isImageZoomable ? zoom : null,
3233
+ children: /* @__PURE__ */ jsx32(NotionBlockRenderer, { ...rest })
3234
+ }
3235
+ );
3236
+ }
3237
+ function NotionBlockRenderer({
3238
+ level = 0,
3239
+ blockId,
3240
+ ...props
3241
+ }) {
3242
+ var _a, _b;
3243
+ const { recordMap } = useNotionContext();
3244
+ const id = blockId || Object.keys(recordMap.block)[0];
3245
+ const block = (_a = recordMap.block[id]) == null ? void 0 : _a.value;
3246
+ if (!block) {
3247
+ if (true) {
3248
+ console.warn("missing block", blockId);
3249
+ }
3250
+ return null;
3251
+ }
3252
+ return /* @__PURE__ */ jsx32(Block, { level, block, ...props, children: (_b = block == null ? void 0 : block.content) == null ? void 0 : _b.map((contentBlockId) => /* @__PURE__ */ jsx32(
3253
+ NotionBlockRenderer,
3254
+ {
3255
+ blockId: contentBlockId,
3256
+ level: level + 1,
3257
+ ...props
3258
+ },
3259
+ contentBlockId
3260
+ )) }, id);
3261
+ }
3262
+ function getMediumZoomMargin() {
3263
+ const width = window.innerWidth;
3264
+ if (width < 500) {
3265
+ return 8;
3266
+ } else if (width < 800) {
3267
+ return 20;
3268
+ } else if (width < 1280) {
3269
+ return 30;
3270
+ } else if (width < 1600) {
3271
+ return 40;
3272
+ } else if (width < 1920) {
3273
+ return 48;
3274
+ } else {
3275
+ return 72;
3276
+ }
3277
+ }
3278
+ export {
3279
+ Breadcrumbs,
3280
+ Header,
3281
+ NotionContextConsumer,
3282
+ NotionContextProvider,
3283
+ NotionRenderer,
3284
+ PageIcon,
3285
+ PageIconImpl,
3286
+ Search,
3287
+ Text,
3288
+ cs,
3289
+ dummyLink,
3290
+ formatDate,
3291
+ formatNotionDateTime,
3292
+ getHashFragmentValue,
3293
+ getListNestingLevel,
3294
+ getListNumber,
3295
+ getListStyle,
3296
+ getUrlParams,
3297
+ getYoutubeId,
3298
+ isBrowser,
3299
+ isUrl,
3300
+ useNotionContext
3301
+ };
3302
+ //# sourceMappingURL=index.js.map