// ==UserScript==
// @name ▲V2EX Polish - 体验更现代化的 V2EX 🟢
// @namespace https://v2p.app
// @version 1.9.19
// @description 一款专为 V2EX 用户设计的浏览器插件,提供了丰富的扩展功能,让原生页面焕然一新!✨
// @author LeoKu(https://leoku.dev)
// @match https://*.v2ex.com/*
// @match https://v2ex.com/*
// @icon https://v2p.app/favicon.svg
// @run-at document-start
// @grant GM_addStyle
// @license MIT
// @downloadURL none
// ==/UserScript==
"use strict";
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
// src/constants.ts
var EXTENSION_NAME, biliEmojiLink, emoticons, READABLE_CONTENT_HEIGHT, MAX_CONTENT_HEIGHT, READING_CONTENT_LIMIT, dataExpiryTime, imgurClientIdPool, defaultOptions;
var init_constants = __esm({
"src/constants.ts"() {
"use strict";
EXTENSION_NAME = "V2EX_Polish";
biliEmojiLink = {
["[\u8131\u5355doge]" /* 脱单doge */]: "https://i.imgur.com/L62ZP7V.png",
["[doge]" /* doge */]: "https://i.imgur.com/agAJ0Rd.png",
["[\u8FA3\u773C\u775B]" /* 辣眼睛 */]: "https://i.imgur.com/n119Wvk.png",
["[\u7591\u60D1]" /* 疑惑 */]: "https://i.imgur.com/U3hKhrT.png",
["[\u6342\u8138]" /* 捂脸 */]: "https://i.imgur.com/14cwgsI.png",
["[\u54E6\u547C]" /* 哦呼 */]: "https://i.imgur.com/km62MY2.png",
["[\u50B2\u5A07]" /* 傲娇 */]: "https://i.imgur.com/TkdeN49.png",
["[\u601D\u8003]" /* 思考 */]: "https://i.imgur.com/MAyk5GN.png",
["[\u5403\u74DC]" /* 吃瓜 */]: "https://i.imgur.com/Ug1iMq4.png",
["[\u65E0\u8BED]" /* 无语 */]: "https://i.imgur.com/e1q9ScT.png",
["[\u5927\u54ED]" /* 大哭 */]: "https://i.imgur.com/YGIx7lh.png",
["[\u9178\u4E86]" /* 酸了 */]: "https://i.imgur.com/5FDsp6L.png",
["[\u6253call]" /* 打call */]: "https://i.imgur.com/pmNOo2w.png",
["[\u6B6A\u5634]" /* 歪嘴 */]: "https://i.imgur.com/XzEYBoY.png",
["[\u661F\u661F\u773C]" /* 星星眼 */]: "https://i.imgur.com/2spsghH.png",
["[OK]" /* OK */]: "https://i.imgur.com/6DMydmQ.png",
["[\u8DEA\u4E86]" /* 跪了 */]: "https://i.imgur.com/TYtySHv.png",
["[\u54CD\u6307]" /* 响指 */]: "https://i.imgur.com/Ac88cMm.png",
["[\u54ED\u60F9R]" /* 哭惹 */]: "https://i.imgur.com/HgxsUD2.png",
["[\u54C7R]" /* 哇 */]: "https://i.imgur.com/OZySWIG.png",
["[\u6C57\u989CR]" /* 汗颜 */]: "https://i.imgur.com/jrVZoLi.png",
["[\u5BB3\u7F9ER]" /* 害羞 */]: "https://i.imgur.com/OVQjxIr.png",
["[\u840C\u840C\u54D2R]" /* 萌萌哒 */]: "https://i.imgur.com/Ue1kikn.png",
["[\u5077\u7B11R]" /* 偷笑 */]: "https://i.imgur.com/aF7QiE5.png"
};
emoticons = [
{
title: "\u6D41\u884C",
list: [
"[\u8131\u5355doge]" /* 脱单doge */,
"[doge]" /* doge */,
"[\u6253call]" /* 打call */,
"[\u661F\u661F\u773C]" /* 星星眼 */,
"[\u5403\u74DC]" /* 吃瓜 */,
"[OK]" /* OK */,
"[\u54E6\u547C]" /* 哦呼 */,
"[\u601D\u8003]" /* 思考 */,
"[\u7591\u60D1]" /* 疑惑 */,
"[\u8FA3\u773C\u775B]" /* 辣眼睛 */,
"[\u50B2\u5A07]" /* 傲娇 */,
"[\u6342\u8138]" /* 捂脸 */,
"[\u65E0\u8BED]" /* 无语 */,
"[\u5927\u54ED]" /* 大哭 */,
"[\u9178\u4E86]" /* 酸了 */,
"[\u6B6A\u5634]" /* 歪嘴 */,
"[\u8DEA\u4E86]" /* 跪了 */,
"[\u54CD\u6307]" /* 响指 */,
"[\u54C7R]" /* 哇 */,
"[\u840C\u840C\u54D2R]" /* 萌萌哒 */,
"[\u5BB3\u7F9ER]" /* 害羞 */,
"[\u5077\u7B11R]" /* 偷笑 */,
"[\u54ED\u60F9R]" /* 哭惹 */,
"[\u6C57\u989CR]" /* 汗颜 */
]
},
{
title: "\u5C0F\u9EC4\u8138",
list: [
"\u{1F600}",
"\u{1F601}",
"\u{1F602}",
"\u{1F923}",
"\u{1F605}",
"\u{1F60A}",
"\u{1F60B}",
"\u{1F618}",
"\u{1F970}",
"\u{1F617}",
"\u{1F929}",
"\u{1F914}",
"\u{1F928}",
"\u{1F610}",
"\u{1F611}",
"\u{1F644}",
"\u{1F60F}",
"\u{1F62A}",
"\u{1F62B}",
"\u{1F971}",
"\u{1F61C}",
"\u{1F612}",
"\u{1F614}",
"\u{1F628}",
"\u{1F630}",
"\u{1F631}",
"\u{1F975}",
"\u{1F621}",
"\u{1F973}",
"\u{1F97A}",
"\u{1F92D}",
"\u{1F9D0}",
"\u{1F60E}",
"\u{1F913}",
"\u{1F62D}",
"\u{1F911}",
"\u{1F92E}"
]
},
{
title: "\u624B\u52BF",
list: [
"\u{1F64B}",
"\u{1F64E}",
"\u{1F645}",
"\u{1F647}",
"\u{1F937}",
"\u{1F90F}",
"\u{1F449}",
"\u270C\uFE0F",
"\u{1F918}",
"\u{1F919}",
"\u{1F44C}",
"\u{1F90C}",
"\u{1F44D}",
"\u{1F44E}",
"\u{1F44B}",
"\u{1F91D}",
"\u{1F64F}",
"\u{1F44F}"
]
},
{
title: "\u5E86\u795D",
list: ["\u2728", "\u{1F389}", "\u{1F38A}"]
},
{
title: "\u5176\u4ED6",
list: ["\u{1F47B}", "\u{1F921}", "\u{1F414}", "\u{1F440}", "\u{1F4A9}", "\u{1F434}", "\u{1F984}", "\u{1F427}", "\u{1F436}", "\u{1F412}", "\u{1F648}", "\u{1F649}", "\u{1F64A}", "\u{1F435}"]
}
];
READABLE_CONTENT_HEIGHT = 250;
MAX_CONTENT_HEIGHT = 550;
READING_CONTENT_LIMIT = 150;
dataExpiryTime = 60 * 60 * 1e3;
imgurClientIdPool = [
"3107b9ef8b316f3",
// 以下 Client ID 来自「V2EX Plus」
"442b04f26eefc8a",
"59cfebe717c09e4",
"60605aad4a62882",
"6c65ab1d3f5452a",
"83e123737849aa9",
"9311f6be1c10160",
"c4a4a563f698595",
"81be04b9e4a08ce"
];
defaultOptions = {
openInNewTab: false,
autoCheckIn: {
enabled: true
},
theme: {
autoSwitch: false
},
reply: {
preload: "off"
},
replyContent: {
autoFold: true,
hideReplyTime: true,
hideRefName: true
},
nestedReply: {
display: "indent",
multipleInsideOne: "nested"
},
userTag: {
display: "inline"
}
};
}
});
// src/icons.ts
var iconLoading, iconLogo, iconGitHub;
var init_icons = __esm({
"src/icons.ts"() {
"use strict";
iconLoading = `
`;
iconLogo = `
`;
iconGitHub = `
`;
}
});
// src/utils.ts
function getOS() {
const userAgent = window.navigator.userAgent.toLowerCase();
const macosPlatforms = /(macintosh|macintel|macppc|mac68k|macos)/i;
const windowsPlatforms = /(win32|win64|windows|wince)/i;
const iosPlatforms = /(iphone|ipad|ipod)/i;
let os = null;
if (macosPlatforms.test(userAgent)) {
os = "macos";
} else if (iosPlatforms.test(userAgent)) {
os = "ios";
} else if (windowsPlatforms.test(userAgent)) {
os = "windows";
} else if (userAgent.includes("android")) {
os = "android";
} else if (userAgent.includes("linux")) {
os = "linux";
}
return os;
}
function formatTimestamp(timestamp, { format = "YMD" } = {}) {
const date = new Date(timestamp.toString().length === 10 ? timestamp * 1e3 : timestamp);
const year = date.getFullYear().toString();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
const YMD = `${year}-${month}-${day}`;
if (format === "YMDHMS") {
const hour = date.getHours().toString().padStart(2, "0");
const minute = date.getMinutes().toString().padStart(2, "0");
const second = date.getSeconds().toString().padStart(2, "0");
return `${YMD} ${hour}:${minute}:${second}`;
}
return YMD;
}
function isSameDay(timestamp1, timestamp2) {
const date1 = new Date(timestamp1);
const date2 = new Date(timestamp2);
return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate();
}
function isObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function deepMerge(target, source) {
const result = {};
for (const key in target) {
const targetProp = target[key];
const sourceProp = source[key];
if (isObject(targetProp) && isObject(sourceProp)) {
result[key] = deepMerge(targetProp, sourceProp);
} else if (Reflect.has(source, key)) {
result[key] = sourceProp;
} else {
result[key] = targetProp;
}
}
for (const key in source) {
if (!Reflect.has(target, key)) {
result[key] = source[key];
}
}
return result;
}
function getRunEnv() {
if (typeof chrome === "object" && typeof chrome.extension !== "undefined") {
return "chrome";
}
if (typeof browser === "object" && typeof browser.extension !== "undefined") {
return "web-ext";
}
return null;
}
function escapeHTML(htmlString) {
return htmlString.replace(/[<>&"'']/g, (match) => {
switch (match) {
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
case '"':
return """;
case "'":
return "'";
default:
return match;
}
});
}
function injectScript(scriptSrc) {
const script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", scriptSrc);
document.body.appendChild(script);
}
function isValidSettings(settings) {
return !!settings && typeof settings === "object" && "options" /* Options */ in settings;
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function getV2P_Settings() {
let noteId;
{
const res = await fetch(`${"https://www.v2ex.com" /* Origin */}/notes`);
const htmlText = await res.text();
const $page = $(htmlText);
const $note = $page.find('.note_item > .note_item_title > a[href^="/notes"]');
$note.each((_, dom) => {
const $dom = $(dom);
if ($dom.text().startsWith(mark)) {
const href = $dom.attr("href");
if (typeof href === "string") {
const id = href.split("/").at(2);
noteId = id;
}
return false;
}
});
}
if (noteId) {
const res = await fetch(`${"https://www.v2ex.com" /* Origin */}/notes/edit/${noteId}`);
const htmlText = await res.text();
const $editor = $(htmlText).find("#note_content.note_editor");
const value = $editor.val();
if (typeof value === "string") {
const syncSettings = JSON.parse(value.replace(mark, ""));
if (isValidSettings(syncSettings)) {
return { noteId, config: syncSettings };
}
}
}
}
async function setV2P_Settings(storageSettings, signal) {
const data = await getV2P_Settings();
const updating = !!data;
const formData = new FormData();
const syncVersion = updating ? data.config["settings-sync" /* SyncInfo */].version + 1 : 1;
const syncInfo = {
version: syncVersion,
lastSyncTime: Date.now()
};
formData.append(
"content",
mark + JSON.stringify({ ...storageSettings, ["settings-sync" /* SyncInfo */]: syncInfo })
);
formData.append("syntax", "0");
if (updating) {
const { noteId } = data;
await fetch(`${"https://www.v2ex.com" /* Origin */}/notes/edit/${noteId}`, {
method: "POST",
body: formData,
signal
});
} else {
formData.append("parent_id", "0");
await fetch(`${"https://www.v2ex.com" /* Origin */}/notes/new`, {
method: "POST",
body: formData,
signal
});
}
await setStorage("settings-sync" /* SyncInfo */, syncInfo);
return syncInfo;
}
function getStorage(useCache = true) {
return new Promise((resolve, reject) => {
if (useCache) {
if (window.__V2P_StorageCache) {
resolve(window.__V2P_StorageCache);
}
}
const runEnv = getRunEnv();
if (!(runEnv === "chrome" || runEnv === "web-ext")) {
const data = { ["options" /* Options */]: defaultOptions };
if (typeof window !== "undefined") {
window.__V2P_StorageCache = data;
}
resolve(data);
} else {
chrome.storage.sync.get().then((items) => {
let data;
const options = items["options" /* Options */];
if (options) {
data = { ...items, ["options" /* Options */]: deepMerge(defaultOptions, options) };
} else {
data = { ...items, ["options" /* Options */]: defaultOptions };
}
if (typeof window !== "undefined") {
window.__V2P_StorageCache = data;
}
resolve(data);
}).catch((err) => {
reject(err);
});
}
});
}
function getStorageSync() {
const storage = window.__V2P_StorageCache;
if (!storage) {
throw new Error(`${EXTENSION_NAME}: \u65E0\u53EF\u7528\u7684 Storage \u7F13\u5B58\u6570\u636E`);
}
return storage;
}
async function setStorage(storageKey, storageItem) {
switch (storageKey) {
case "options" /* Options */:
case "api" /* API */:
case "daily" /* Daily */:
case "member-tag" /* MemberTag */:
case "settings-sync" /* SyncInfo */:
case "reading-list" /* ReadingList */:
try {
await chrome.storage.sync.set({ [storageKey]: storageItem });
if (storageKey !== "api" /* API */ && storageKey !== "settings-sync" /* SyncInfo */ && typeof $ !== "undefined") {
const settings = await getStorage(false);
if (controller) {
controller.abort();
}
controller = new AbortController();
setV2P_Settings(settings, controller.signal);
}
} catch (err) {
if (String(err).includes("QUOTA_BYTES_PER_ITEM quota exceeded")) {
console.error(
`${EXTENSION_NAME}: \u65E0\u6CD5\u8BBE\u7F6E ${storageKey}\uFF0C \u5355\u4E2A item \u4E0D\u80FD\u8D85\u51FA 8 KB\uFF0C\u8BE6\u60C5\u67E5\u770B\uFF1Ahttps://developer.chrome.com/docs/extensions/reference/storage/#storage-areas`
);
}
throw new Error(`\u274C \u65E0\u6CD5\u8BBE\u7F6E\uFF1A${storageKey}`);
}
break;
default:
throw new Error(`\u672A\u77E5\u7684 storageKey\uFF1A ${storageKey}`);
}
}
var mark, controller;
var init_utils = __esm({
"src/utils.ts"() {
"use strict";
init_constants();
mark = `${EXTENSION_NAME}_settings`;
controller = null;
}
});
// src/contents/globals.ts
function updateCommentCells() {
$commentCells = $commentBox.find('.cell[id^="r_"]');
$commentTableRows = $commentCells.find("> table > tbody > tr");
}
var $wrapper, $wrapperContent, $main, $topicList, $topicContentBox, $topicHeader, $commentBox, $commentCells, $commentTableRows, $replyBox, $replyForm, $replyTextArea, replyTextArea, loginName, topicOwnerName, topicId;
var init_globals = __esm({
"src/contents/globals.ts"() {
"use strict";
$wrapper = $("#Wrapper");
$wrapperContent = $wrapper.find("> .content");
$main = $("#Main");
$topicList = $(
"#Main #Tabs ~ .cell.item, #Main #TopicsNode > .cell, #Main .cell.item:has(.item_title > .topic-link)"
);
$topicContentBox = $("#Main .box:has(.topic_buttons)");
$topicHeader = $topicContentBox.find(".header");
$commentBox = $('#Main .box:has(.cell[id^="r_"])');
$commentCells = $commentBox.find('.cell[id^="r_"]');
$commentTableRows = $commentCells.find("> table > tbody > tr");
$replyBox = $("#reply-box");
$replyForm = $replyBox.find('form[action^="/t"]');
$replyTextArea = $("#reply_content");
replyTextArea = document.querySelector("#reply_content");
loginName = $('#Top .tools > a[href^="/member"]').text();
topicOwnerName = $topicHeader.find('> small > a[href^="/member"]').text();
topicId = window.location.pathname.match(/\/t\/(\d+)/)?.at(1);
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/createElement.js
var createElement, createElement$1;
var init_createElement = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/createElement.js"() {
"use strict";
createElement = (tag, attrs, children = []) => {
const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
Object.keys(attrs).forEach((name) => {
element.setAttribute(name, String(attrs[name]));
});
if (children.length) {
children.forEach((child) => {
const childElement = createElement(...child);
element.appendChild(childElement);
});
}
return element;
};
createElement$1 = ([tag, attrs, children]) => createElement(tag, attrs, children);
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/replaceElement.js
var getAttrs, getClassNames, combineClassNames, toPascalCase, replaceElement;
var init_replaceElement = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/replaceElement.js"() {
"use strict";
init_createElement();
getAttrs = (element) => Array.from(element.attributes).reduce((attrs, attr) => {
attrs[attr.name] = attr.value;
return attrs;
}, {});
getClassNames = (attrs) => {
if (typeof attrs === "string")
return attrs;
if (!attrs || !attrs.class)
return "";
if (attrs.class && typeof attrs.class === "string") {
return attrs.class.split(" ");
}
if (attrs.class && Array.isArray(attrs.class)) {
return attrs.class;
}
return "";
};
combineClassNames = (arrayOfClassnames) => {
const classNameArray = arrayOfClassnames.flatMap(getClassNames);
return classNameArray.map((classItem) => classItem.trim()).filter(Boolean).filter((value, index, self) => self.indexOf(value) === index).join(" ");
};
toPascalCase = (string) => string.replace(/(\w)(\w*)(_|-|\s*)/g, (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase());
replaceElement = (element, { nameAttr, icons, attrs }) => {
const iconName = element.getAttribute(nameAttr);
if (iconName == null)
return;
const ComponentName = toPascalCase(iconName);
const iconNode = icons[ComponentName];
if (!iconNode) {
return console.warn(
`${element.outerHTML} icon name was not found in the provided icons object.`
);
}
const elementAttrs = getAttrs(element);
const [tag, iconAttributes, children] = iconNode;
const iconAttrs = {
...iconAttributes,
"data-lucide": iconName,
...attrs,
...elementAttrs
};
const classNames = combineClassNames(["lucide", `lucide-${iconName}`, elementAttrs, attrs]);
if (classNames) {
Object.assign(iconAttrs, {
class: classNames
});
}
const svgElement = createElement$1([tag, iconAttrs, children]);
return element.parentNode?.replaceChild(svgElement, element);
};
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/defaultAttributes.js
var defaultAttributes;
var init_defaultAttributes = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/defaultAttributes.js"() {
"use strict";
defaultAttributes = {
xmlns: "http://www.w3.org/2000/svg",
width: 24,
height: 24,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
"stroke-width": 2,
"stroke-linecap": "round",
"stroke-linejoin": "round"
};
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/arrow-up-right-square.js
var ArrowUpRightSquare;
var init_arrow_up_right_square = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/arrow-up-right-square.js"() {
"use strict";
init_defaultAttributes();
ArrowUpRightSquare = [
"svg",
defaultAttributes,
[
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }],
["path", { d: "M8 8h8v8" }],
["path", { d: "m8 16 8-8" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/book-open-check.js
var BookOpenCheck;
var init_book_open_check = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/book-open-check.js"() {
"use strict";
init_defaultAttributes();
BookOpenCheck = [
"svg",
defaultAttributes,
[
["path", { d: "M8 3H2v15h7c1.7 0 3 1.3 3 3V7c0-2.2-1.8-4-4-4Z" }],
["path", { d: "m16 12 2 2 4-4" }],
["path", { d: "M22 6V3h-6c-2.2 0-4 1.8-4 4v14c0-1.7 1.3-3 3-3h7v-2.3" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/chevron-down.js
var ChevronDown;
var init_chevron_down = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/chevron-down.js"() {
"use strict";
init_defaultAttributes();
ChevronDown = ["svg", defaultAttributes, [["path", { d: "m6 9 6 6 6-6" }]]];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/chevrons-up.js
var ChevronsUp;
var init_chevrons_up = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/chevrons-up.js"() {
"use strict";
init_defaultAttributes();
ChevronsUp = [
"svg",
defaultAttributes,
[
["path", { d: "m17 11-5-5-5 5" }],
["path", { d: "m17 18-5-5-5 5" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/eye-off.js
var EyeOff;
var init_eye_off = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/eye-off.js"() {
"use strict";
init_defaultAttributes();
EyeOff = [
"svg",
defaultAttributes,
[
["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }],
["path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }],
["path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }],
["line", { x1: "2", x2: "22", y1: "2", y2: "22" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/heart.js
var Heart;
var init_heart = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/heart.js"() {
"use strict";
init_defaultAttributes();
Heart = [
"svg",
defaultAttributes,
[
[
"path",
{
d: "M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"
}
]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/message-square-plus.js
var MessageSquarePlus;
var init_message_square_plus = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/message-square-plus.js"() {
"use strict";
init_defaultAttributes();
MessageSquarePlus = [
"svg",
defaultAttributes,
[
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }],
["path", { d: "M12 7v6" }],
["path", { d: "M9 10h6" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/message-square.js
var MessageSquare;
var init_message_square = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/message-square.js"() {
"use strict";
init_defaultAttributes();
MessageSquare = [
"svg",
defaultAttributes,
[["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }]]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/moon.js
var Moon;
var init_moon = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/moon.js"() {
"use strict";
init_defaultAttributes();
Moon = [
"svg",
defaultAttributes,
[["path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }]]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/package-plus.js
var PackagePlus;
var init_package_plus = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/package-plus.js"() {
"use strict";
init_defaultAttributes();
PackagePlus = [
"svg",
defaultAttributes,
[
["path", { d: "M16 16h6" }],
["path", { d: "M19 13v6" }],
[
"path",
{
d: "M21 10V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l2-1.14"
}
],
["path", { d: "m7.5 4.27 9 5.15" }],
["polyline", { points: "3.29 7 12 12 20.71 7" }],
["line", { x1: "12", x2: "12", y1: "22", y2: "12" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/panel-right.js
var PanelRight;
var init_panel_right = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/panel-right.js"() {
"use strict";
init_defaultAttributes();
PanelRight = [
"svg",
defaultAttributes,
[
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }],
["path", { d: "M15 3v18" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/panel-top.js
var PanelTop;
var init_panel_top = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/panel-top.js"() {
"use strict";
init_defaultAttributes();
PanelTop = [
"svg",
defaultAttributes,
[
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }],
["path", { d: "M3 9h18" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/smile.js
var Smile;
var init_smile = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/smile.js"() {
"use strict";
init_defaultAttributes();
Smile = [
"svg",
defaultAttributes,
[
["circle", { cx: "12", cy: "12", r: "10" }],
["path", { d: "M8 14s1.5 2 4 2 4-2 4-2" }],
["line", { x1: "9", x2: "9.01", y1: "9", y2: "9" }],
["line", { x1: "15", x2: "15.01", y1: "9", y2: "9" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/star.js
var Star;
var init_star = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/star.js"() {
"use strict";
init_defaultAttributes();
Star = [
"svg",
defaultAttributes,
[
[
"polygon",
{
points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
}
]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/sun.js
var Sun;
var init_sun = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/sun.js"() {
"use strict";
init_defaultAttributes();
Sun = [
"svg",
defaultAttributes,
[
["circle", { cx: "12", cy: "12", r: "4" }],
["path", { d: "M12 2v2" }],
["path", { d: "M12 20v2" }],
["path", { d: "m4.93 4.93 1.41 1.41" }],
["path", { d: "m17.66 17.66 1.41 1.41" }],
["path", { d: "M2 12h2" }],
["path", { d: "M20 12h2" }],
["path", { d: "m6.34 17.66-1.41 1.41" }],
["path", { d: "m19.07 4.93-1.41 1.41" }]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/twitter.js
var Twitter;
var init_twitter = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/icons/twitter.js"() {
"use strict";
init_defaultAttributes();
Twitter = [
"svg",
defaultAttributes,
[
[
"path",
{
d: "M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z"
}
]
]
];
}
});
// node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/lucide.js
var createIcons;
var init_lucide = __esm({
"node_modules/.pnpm/lucide@0.316.0/node_modules/lucide/dist/esm/lucide.js"() {
"use strict";
init_replaceElement();
init_createElement();
init_arrow_up_right_square();
init_book_open_check();
init_chevron_down();
init_chevrons_up();
init_eye_off();
init_heart();
init_message_square_plus();
init_message_square();
init_moon();
init_package_plus();
init_panel_right();
init_panel_top();
init_smile();
init_star();
init_sun();
init_twitter();
createIcons = ({ icons = {}, nameAttr = "data-lucide", attrs = {} } = {}) => {
if (!Object.values(icons).length) {
throw new Error(
"Please provide an icons object.\nIf you want to use all the icons you can import it like:\n `import { createIcons, icons } from 'lucide';\nlucide.createIcons({icons});`"
);
}
if (typeof document === "undefined") {
throw new Error("`createIcons()` only works in a browser environment.");
}
const elementsToReplace = document.querySelectorAll(`[${nameAttr}]`);
Array.from(elementsToReplace).forEach(
(element) => replaceElement(element, { nameAttr, icons, attrs })
);
if (nameAttr === "data-lucide") {
const deprecatedElements = document.querySelectorAll("[icon-name]");
if (deprecatedElements.length > 0) {
console.warn(
"[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide"
);
Array.from(deprecatedElements).forEach(
(element) => replaceElement(element, { nameAttr: "icon-name", icons, attrs })
);
}
}
};
}
});
// src/components/toast.ts
function createToast(props) {
const { message, duration = 3e3 } = props;
const $existTosat = $(".v2p-toast");
if ($existTosat.length > 0) {
$existTosat.remove();
}
const $toast = $(`
${message}
`).hide();
$(document.body).append($toast);
$toast.fadeIn("fast");
if (duration !== 0) {
setTimeout(() => {
$toast.fadeOut("fast", () => {
$toast.remove();
});
}, duration);
}
return {
clear() {
$toast.remove();
}
};
}
var init_toast = __esm({
"src/components/toast.ts"() {
"use strict";
}
});
// src/contents/helpers.ts
function isV2EX_RequestError(error) {
if ("cause" in error) {
const cause = error["cause"];
if ("success" in cause && "message" in cause) {
return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
typeof cause["success"] === "boolean" && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
!cause["success"] && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
typeof cause["message"] === "string"
);
}
}
return false;
}
function focusReplyInput() {
if (replyTextArea instanceof HTMLTextAreaElement) {
replyTextArea.focus();
}
}
function insertTextToReplyInput(text) {
if (replyTextArea instanceof HTMLTextAreaElement) {
const startPos = replyTextArea.selectionStart;
const endPos = replyTextArea.selectionEnd;
const valueToStart = replyTextArea.value.substring(0, startPos);
const valueFromEnd = replyTextArea.value.substring(endPos, replyTextArea.value.length);
replyTextArea.value = `${valueToStart}${text}${valueFromEnd}`;
focusReplyInput();
replyTextArea.selectionStart = replyTextArea.selectionEnd = startPos + text.length;
}
}
async function setMemberTags(params) {
const { memberName, memberAvatar, tags } = params;
const storage = await getStorage(false);
const tagData = storage["member-tag" /* MemberTag */];
const runEnv = getRunEnv();
if (!(runEnv === "chrome" || runEnv === "web-ext")) {
return;
}
if (tags && tags.length > 0) {
const newTagData = {
...tagData,
[memberName]: { tags, avatar: memberAvatar || tagData?.[memberName]?.avatar }
};
await setStorage("member-tag" /* MemberTag */, newTagData);
} else {
if (tagData && Reflect.has(tagData, memberName)) {
delete tagData[memberName];
await setStorage("member-tag" /* MemberTag */, tagData);
}
}
}
async function addToReadingList(params) {
const { url, title, content } = params;
if (!(typeof url === "string" || typeof title === "string" || typeof content === "string")) {
const message = "\u65E0\u6CD5\u8BC6\u522B\u5C06\u8BE5\u4E3B\u9898\u7684\u5143\u6570\u636E";
createToast({ message });
throw new Error(message);
}
const storage = await getStorage();
const currentData = storage["reading-list" /* ReadingList */]?.data || [];
const exist = currentData.findIndex((it) => it.url === url) !== -1;
if (exist) {
createToast({ message: "\u8BE5\u4E3B\u9898\u5DF2\u5B58\u5728\u4E8E\u7A0D\u540E\u9605\u8BFB" });
} else {
if (window.__V2P_AddingReading !== true) {
window.__V2P_AddingReading = true;
try {
await setStorage("reading-list" /* ReadingList */, {
data: [
{
url,
title: title.replace(" - V2EX", ""),
content: content.length > READING_CONTENT_LIMIT ? content.substring(0, READING_CONTENT_LIMIT) + "..." : content,
addedTime: Date.now()
},
...currentData
]
});
createToast({ message: "\u2705 \u5DF2\u6DFB\u52A0\u8FDB\u7A0D\u540E\u9605\u8BFB" });
await sleep(500);
} finally {
window.__V2P_AddingReading = false;
}
}
}
}
function decodeBase64TopicPage() {
const dataTitle = "\u70B9\u51FB\u590D\u5236";
if (window.__V2P_DecodeStatus === "decodeed") {
createToast({ message: "\u5DF2\u89E3\u6790\u5B8C\u672C\u9875\u6240\u6709\u7684 Base64 \u5B57\u7B26\u4E32" });
} else {
const $topicContentBox2 = $("#Main .box:has(.topic_content)");
const $commentBox2 = $('#Main .box:has(.cell[id^="r_"])');
const $commentCells2 = $commentBox2.find('.cell[id^="r_"]');
let count = 0;
const excludeList = [
"boss",
"bilibili",
"Bilibili",
"Encrypto",
"encrypto",
"Window10",
"airpords",
"Windows7"
];
const convertHTMLText = (text, excludeTextList) => {
if (text.length % 4 !== 0 || text.length <= 8) {
return text;
}
if (excludeList.includes(text)) {
return text;
}
if (text.includes("=")) {
const paddingIndex = text.indexOf("=");
if (paddingIndex !== text.length - 1 && paddingIndex !== text.length - 2) {
return text;
}
}
if (excludeTextList?.some((excludeText) => excludeText.includes(text))) {
return text;
}
try {
const decodedStr = decodeURIComponent(window.atob(text));
count += 1;
return `${text}(${decodedStr})`;
} catch (err) {
if (err instanceof Error) {
console.error(`\u89E3\u6790 Base64 \u51FA\u9519\uFF1A${err.message}`);
}
return text;
}
};
const base64regex = /[A-z0-9+/=]+/g;
const contentHandler = (_, content) => {
const excludeTextList = [
...content.getElementsByTagName("a"),
...content.getElementsByTagName("img")
].map((ele) => ele.outerHTML);
content.innerHTML = content.innerHTML.replace(
base64regex,
(htmlText) => convertHTMLText(htmlText, excludeTextList)
);
};
$commentCells2.find(".reply_content").each(contentHandler);
$topicContentBox2.find(".topic_content").each(contentHandler);
if (count === 0) {
createToast({ message: "\u672C\u9875\u672A\u53D1\u73B0 Base64 \u5B57\u7B26\u4E32" });
} else {
window.__V2P_DecodeStatus = "decodeed";
createToast({ message: `\u2705 \u5DF2\u89E3\u6790\u672C\u9875\u6240\u6709\u7684 Base64 \u5B57\u7B26\u4E32\uFF0C\u5171 ${count} \u6761` });
}
$(".v2p-decode").on("click", (ev) => {
const text = ev.target.innerText;
void navigator.clipboard.writeText(text).then(() => {
ev.target.dataset.title = "\u2705 \u5DF2\u590D\u5236";
setTimeout(() => {
ev.target.dataset.title = dataTitle;
}, 1e3);
});
});
}
}
function postTask(expression, callback) {
const runEnv = getRunEnv();
if (!runEnv) {
const result = Function(`"use strict"; ${expression}`)();
callback?.(result);
} else {
if (callback) {
if (window.__V2P_Tasks) {
window.__V2P_Tasks.set(Date.now(), callback);
} else {
window.__V2P_Tasks = /* @__PURE__ */ new Map([[Date.now(), callback]]);
}
}
const messageData = {
from: 0 /* Content */,
payload: { task: { id: Date.now(), expression } }
};
window.postMessage(messageData);
}
}
function loadIcons() {
setTimeout(() => {
createIcons({
attrs: {
width: "100%",
height: "100%"
},
icons: {
MessageSquarePlus,
MessageSquare,
BookOpenCheck,
ChevronsUp,
Heart,
EyeOff,
Sun,
Moon,
Smile,
PackagePlus,
Star,
Twitter,
ChevronDown,
ArrowUpRightSquare
}
});
}, 0);
}
function transformEmoji(textValue) {
return textValue.replace(/\[[^\]]+\]/g, (x) => {
const emojiLink = biliEmojiLink[x];
if (typeof emojiLink === "string") {
return `${emojiLink} `;
}
return x;
});
}
var init_helpers = __esm({
"src/contents/helpers.ts"() {
"use strict";
init_lucide();
init_toast();
init_constants();
init_utils();
init_globals();
}
});
// src/contents/common.ts
var common_exports = {};
var init_common = __esm({
"src/contents/common.ts"() {
"use strict";
init_constants();
init_icons();
init_utils();
init_globals();
init_helpers();
if ($("#site-header").length > 0) {
$(document.body).addClass("v2p-mobile");
}
void (async () => {
const storage = await getStorage();
const options = storage["options" /* Options */];
const $toggle = $("#Rightbar .light-toggle").addClass("v2p-color-mode-toggle");
if (options.theme.autoSwitch) {
const perfersDark = window.matchMedia("(prefers-color-scheme: dark)");
const toggleTheme = (preferDark) => {
const shouldSync = preferDark && !$wrapper.hasClass("Night") || !preferDark && $wrapper.hasClass("Night");
if (shouldSync) {
const href = $toggle.attr("href");
if (typeof href === "string") {
fetch(href);
}
if (preferDark) {
$toggle.prop("title", "\u4F7F\u7528\u6D45\u8272\u4E3B\u9898");
$toggle.html('');
} else {
$toggle.prop("title", "\u4F7F\u7528\u6DF1\u8272\u4E3B\u9898");
$toggle.html('');
}
loadIcons();
}
if (preferDark) {
$(document.body).addClass("v2p-theme-dark");
$wrapper.addClass("Night");
} else {
$(document.body).removeClass("v2p-theme-dark");
$wrapper.removeClass("Night");
}
};
toggleTheme(perfersDark.matches);
perfersDark.addEventListener("change", ({ matches }) => {
toggleTheme(matches);
});
$toggle.on("click", () => {
void setStorage("options" /* Options */, deepMerge(options, { theme: { autoSwitch: false } }));
});
}
const syncInfo = storage["settings-sync" /* SyncInfo */];
if (syncInfo) {
const lastCheckTime = syncInfo.lastCheckTime;
const twoHours = 2 * 60 * 1e3 * 60;
const neverChecked = !lastCheckTime;
if (lastCheckTime && Date.now() - lastCheckTime >= twoHours || neverChecked) {
const isSignInPage = window.location.href.includes("/signin");
if (!isSignInPage) {
void getV2P_Settings().then(async (res) => {
const settings = res?.config;
const remoteSyncInfo = settings?.["settings-sync" /* SyncInfo */];
if (settings && remoteSyncInfo) {
if (syncInfo.version < remoteSyncInfo.version || neverChecked) {
await chrome.storage.sync.set(
deepMerge(storage, {
...settings,
["settings-sync" /* SyncInfo */]: {
...settings["settings-sync" /* SyncInfo */],
lastCheckTime: Date.now()
}
})
);
}
}
});
}
}
}
{
const $toggleImg = $toggle.find("> img");
const alt = $toggleImg.prop("alt");
if (alt === "Light") {
$toggle.prop("title", "\u4F7F\u7528\u6DF1\u8272\u4E3B\u9898");
$toggleImg.replaceWith('');
} else if (alt === "Dark") {
$toggle.prop("title", "\u4F7F\u7528\u6D45\u8272\u4E3B\u9898");
$toggleImg.replaceWith('');
}
}
{
$("#Top .site-nav .tools > .top").addClass("v2p-hover-btn");
}
{
const runEnv = getRunEnv();
if (runEnv === "chrome" || runEnv === "web-ext") {
injectScript(chrome.runtime.getURL("scripts/web_accessible_resources.min.js"));
window.addEventListener("message", (ev) => {
if (ev.data.from === 1 /* Web */) {
const payload = ev.data.payload;
const task = payload?.task;
if (payload?.status === "ready") {
postTask('if (typeof window.once === "string") { return window.once; }', (result) => {
if (typeof result === "string") {
window.once = result;
}
});
}
if (task) {
window.__V2P_Tasks?.get(task.id)?.(task.result);
}
}
});
}
}
{
const $extraFooter = $(`
`);
$(``).prependTo($extraFooter);
$("#Bottom .content").append($extraFooter);
}
})();
}
});
// node_modules/.pnpm/@floating-ui+utils@0.1.6/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === "function" ? value(param) : value;
}
function getSide(placement) {
return placement.split("-")[0];
}
function getAlignment(placement) {
return placement.split("-")[1];
}
function getOppositeAxis(axis) {
return axis === "x" ? "y" : "x";
}
function getAxisLength(axis) {
return axis === "y" ? "height" : "width";
}
function getSideAxis(placement) {
return ["top", "bottom"].includes(getSide(placement)) ? "y" : "x";
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
}
function getSideList(side, isStart, rtl) {
const lr = ["left", "right"];
const rl = ["right", "left"];
const tb = ["top", "bottom"];
const bt = ["bottom", "top"];
switch (side) {
case "top":
case "bottom":
if (rtl)
return isStart ? rl : lr;
return isStart ? lr : rl;
case "left":
case "right":
return isStart ? tb : bt;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === "start", rtl);
if (alignment) {
list = list.map((side) => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== "number" ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
return {
...rect,
top: rect.y,
left: rect.x,
right: rect.x + rect.width,
bottom: rect.y + rect.height
};
}
var min, max, oppositeSideMap, oppositeAlignmentMap;
var init_floating_ui_utils = __esm({
"node_modules/.pnpm/@floating-ui+utils@0.1.6/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs"() {
"use strict";
min = Math.min;
max = Math.max;
oppositeSideMap = {
left: "right",
right: "left",
bottom: "top",
top: "bottom"
};
oppositeAlignmentMap = {
start: "end",
end: "start"
};
}
});
// node_modules/.pnpm/@floating-ui+core@1.5.2/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
function computeCoordsFromPlacement(_ref, placement, rtl) {
let {
reference,
floating
} = _ref;
const sideAxis = getSideAxis(placement);
const alignmentAxis = getAlignmentAxis(placement);
const alignLength = getAxisLength(alignmentAxis);
const side = getSide(placement);
const isVertical = sideAxis === "y";
const commonX = reference.x + reference.width / 2 - floating.width / 2;
const commonY = reference.y + reference.height / 2 - floating.height / 2;
const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
let coords;
switch (side) {
case "top":
coords = {
x: commonX,
y: reference.y - floating.height
};
break;
case "bottom":
coords = {
x: commonX,
y: reference.y + reference.height
};
break;
case "right":
coords = {
x: reference.x + reference.width,
y: commonY
};
break;
case "left":
coords = {
x: reference.x - floating.width,
y: commonY
};
break;
default:
coords = {
x: reference.x,
y: reference.y
};
}
switch (getAlignment(placement)) {
case "start":
coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
break;
case "end":
coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
break;
}
return coords;
}
async function detectOverflow(state, options) {
var _await$platform$isEle;
if (options === void 0) {
options = {};
}
const {
x,
y,
platform: platform2,
rects,
elements,
strategy
} = state;
const {
boundary = "clippingAncestors",
rootBoundary = "viewport",
elementContext = "floating",
altBoundary = false,
padding = 0
} = evaluate(options, state);
const paddingObject = getPaddingObject(padding);
const altContext = elementContext === "floating" ? "reference" : "floating";
const element = elements[altBoundary ? altContext : elementContext];
const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
boundary,
rootBoundary,
strategy
}));
const rect = elementContext === "floating" ? {
...rects.floating,
x,
y
} : rects.reference;
const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
x: 1,
y: 1
} : {
x: 1,
y: 1
};
const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
rect,
offsetParent,
strategy
}) : rect);
return {
top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
};
}
async function convertValueToCoords(state, options) {
const {
placement,
platform: platform2,
elements
} = state;
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
const side = getSide(placement);
const alignment = getAlignment(placement);
const isVertical = getSideAxis(placement) === "y";
const mainAxisMulti = ["left", "top"].includes(side) ? -1 : 1;
const crossAxisMulti = rtl && isVertical ? -1 : 1;
const rawValue = evaluate(options, state);
let {
mainAxis,
crossAxis,
alignmentAxis
} = typeof rawValue === "number" ? {
mainAxis: rawValue,
crossAxis: 0,
alignmentAxis: null
} : {
mainAxis: 0,
crossAxis: 0,
alignmentAxis: null,
...rawValue
};
if (alignment && typeof alignmentAxis === "number") {
crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
}
return isVertical ? {
x: crossAxis * crossAxisMulti,
y: mainAxis * mainAxisMulti
} : {
x: mainAxis * mainAxisMulti,
y: crossAxis * crossAxisMulti
};
}
var computePosition, flip, offset, shift;
var init_floating_ui_core = __esm({
"node_modules/.pnpm/@floating-ui+core@1.5.2/node_modules/@floating-ui/core/dist/floating-ui.core.mjs"() {
"use strict";
init_floating_ui_utils();
init_floating_ui_utils();
computePosition = async (reference, floating, config) => {
const {
placement = "bottom",
strategy = "absolute",
middleware = [],
platform: platform2
} = config;
const validMiddleware = middleware.filter(Boolean);
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
let rects = await platform2.getElementRects({
reference,
floating,
strategy
});
let {
x,
y
} = computeCoordsFromPlacement(rects, placement, rtl);
let statefulPlacement = placement;
let middlewareData = {};
let resetCount = 0;
for (let i = 0; i < validMiddleware.length; i++) {
const {
name,
fn
} = validMiddleware[i];
const {
x: nextX,
y: nextY,
data,
reset
} = await fn({
x,
y,
initialPlacement: placement,
placement: statefulPlacement,
strategy,
middlewareData,
rects,
platform: platform2,
elements: {
reference,
floating
}
});
x = nextX != null ? nextX : x;
y = nextY != null ? nextY : y;
middlewareData = {
...middlewareData,
[name]: {
...middlewareData[name],
...data
}
};
if (reset && resetCount <= 50) {
resetCount++;
if (typeof reset === "object") {
if (reset.placement) {
statefulPlacement = reset.placement;
}
if (reset.rects) {
rects = reset.rects === true ? await platform2.getElementRects({
reference,
floating,
strategy
}) : reset.rects;
}
({
x,
y
} = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
}
i = -1;
continue;
}
}
return {
x,
y,
placement: statefulPlacement,
strategy,
middlewareData
};
};
flip = function(options) {
if (options === void 0) {
options = {};
}
return {
name: "flip",
options,
async fn(state) {
var _middlewareData$arrow, _middlewareData$flip;
const {
placement,
middlewareData,
rects,
initialPlacement,
platform: platform2,
elements
} = state;
const {
mainAxis: checkMainAxis = true,
crossAxis: checkCrossAxis = true,
fallbackPlacements: specifiedFallbackPlacements,
fallbackStrategy = "bestFit",
fallbackAxisSideDirection = "none",
flipAlignment = true,
...detectOverflowOptions
} = evaluate(options, state);
if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
return {};
}
const side = getSide(placement);
const isBasePlacement = getSide(initialPlacement) === initialPlacement;
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
if (!specifiedFallbackPlacements && fallbackAxisSideDirection !== "none") {
fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
}
const placements2 = [initialPlacement, ...fallbackPlacements];
const overflow = await detectOverflow(state, detectOverflowOptions);
const overflows = [];
let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
if (checkMainAxis) {
overflows.push(overflow[side]);
}
if (checkCrossAxis) {
const sides2 = getAlignmentSides(placement, rects, rtl);
overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
}
overflowsData = [...overflowsData, {
placement,
overflows
}];
if (!overflows.every((side2) => side2 <= 0)) {
var _middlewareData$flip2, _overflowsData$filter;
const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
const nextPlacement = placements2[nextIndex];
if (nextPlacement) {
return {
data: {
index: nextIndex,
overflows: overflowsData
},
reset: {
placement: nextPlacement
}
};
}
let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
if (!resetPlacement) {
switch (fallbackStrategy) {
case "bestFit": {
var _overflowsData$map$so;
const placement2 = (_overflowsData$map$so = overflowsData.map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0];
if (placement2) {
resetPlacement = placement2;
}
break;
}
case "initialPlacement":
resetPlacement = initialPlacement;
break;
}
}
if (placement !== resetPlacement) {
return {
reset: {
placement: resetPlacement
}
};
}
}
return {};
}
};
};
offset = function(options) {
if (options === void 0) {
options = 0;
}
return {
name: "offset",
options,
async fn(state) {
var _middlewareData$offse, _middlewareData$arrow;
const {
x,
y,
placement,
middlewareData
} = state;
const diffCoords = await convertValueToCoords(state, options);
if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
return {};
}
return {
x: x + diffCoords.x,
y: y + diffCoords.y,
data: {
...diffCoords,
placement
}
};
}
};
};
shift = function(options) {
if (options === void 0) {
options = {};
}
return {
name: "shift",
options,
async fn(state) {
const {
x,
y,
placement
} = state;
const {
mainAxis: checkMainAxis = true,
crossAxis: checkCrossAxis = false,
limiter = {
fn: (_ref) => {
let {
x: x2,
y: y2
} = _ref;
return {
x: x2,
y: y2
};
}
},
...detectOverflowOptions
} = evaluate(options, state);
const coords = {
x,
y
};
const overflow = await detectOverflow(state, detectOverflowOptions);
const crossAxis = getSideAxis(getSide(placement));
const mainAxis = getOppositeAxis(crossAxis);
let mainAxisCoord = coords[mainAxis];
let crossAxisCoord = coords[crossAxis];
if (checkMainAxis) {
const minSide = mainAxis === "y" ? "top" : "left";
const maxSide = mainAxis === "y" ? "bottom" : "right";
const min3 = mainAxisCoord + overflow[minSide];
const max3 = mainAxisCoord - overflow[maxSide];
mainAxisCoord = clamp(min3, mainAxisCoord, max3);
}
if (checkCrossAxis) {
const minSide = crossAxis === "y" ? "top" : "left";
const maxSide = crossAxis === "y" ? "bottom" : "right";
const min3 = crossAxisCoord + overflow[minSide];
const max3 = crossAxisCoord - overflow[maxSide];
crossAxisCoord = clamp(min3, crossAxisCoord, max3);
}
const limitedCoords = limiter.fn({
...state,
[mainAxis]: mainAxisCoord,
[crossAxis]: crossAxisCoord
});
return {
...limitedCoords,
data: {
x: limitedCoords.x - x,
y: limitedCoords.y - y
}
};
}
};
};
}
});
// node_modules/.pnpm/@floating-ui+dom@1.4.5/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
function getWindow(node) {
var _node$ownerDocument;
return (node == null ? void 0 : (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getComputedStyle$1(element) {
return getWindow(element).getComputedStyle(element);
}
function isNode(value) {
return value instanceof getWindow(value).Node;
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || "").toLowerCase();
}
return "#document";
}
function isHTMLElement(value) {
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(node) {
if (typeof ShadowRoot === "undefined") {
return false;
}
return node instanceof getWindow(node).ShadowRoot || node instanceof ShadowRoot;
}
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle$1(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !["inline", "contents"].includes(display);
}
function isTableElement(element) {
return ["table", "td", "th"].includes(getNodeName(element));
}
function isContainingBlock(element) {
const safari = isSafari();
const css = getComputedStyle$1(element);
return css.transform !== "none" || css.perspective !== "none" || (css.containerType ? css.containerType !== "normal" : false) || !safari && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !safari && (css.filter ? css.filter !== "none" : false) || ["transform", "perspective", "filter"].some((value) => (css.willChange || "").includes(value)) || ["paint", "layout", "strict", "content"].some((value) => (css.contain || "").includes(value));
}
function isSafari() {
if (typeof CSS === "undefined" || !CSS.supports)
return false;
return CSS.supports("-webkit-backdrop-filter", "none");
}
function isLastTraversableNode(node) {
return ["html", "body", "#document"].includes(getNodeName(node));
}
function getCssDimensions(element) {
const css = getComputedStyle$1(element);
let width = parseFloat(css.width) || 0;
let height = parseFloat(css.height) || 0;
const hasOffset = isHTMLElement(element);
const offsetWidth = hasOffset ? element.offsetWidth : width;
const offsetHeight = hasOffset ? element.offsetHeight : height;
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
if (shouldFallback) {
width = offsetWidth;
height = offsetHeight;
}
return {
width,
height,
$: shouldFallback
};
}
function isElement(value) {
return value instanceof Element || value instanceof getWindow(value).Element;
}
function unwrapElement(element) {
return !isElement(element) ? element.contextElement : element;
}
function getScale(element) {
const domElement = unwrapElement(element);
if (!isHTMLElement(domElement)) {
return createCoords(1);
}
const rect = domElement.getBoundingClientRect();
const {
width,
height,
$: $2
} = getCssDimensions(domElement);
let x = ($2 ? round(rect.width) : rect.width) / width;
let y = ($2 ? round(rect.height) : rect.height) / height;
if (!x || !Number.isFinite(x)) {
x = 1;
}
if (!y || !Number.isFinite(y)) {
y = 1;
}
return {
x,
y
};
}
function getVisualOffsets(element) {
const win = getWindow(element);
if (!isSafari() || !win.visualViewport) {
return noOffsets;
}
return {
x: win.visualViewport.offsetLeft,
y: win.visualViewport.offsetTop
};
}
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
if (isFixed === void 0) {
isFixed = false;
}
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
return false;
}
return isFixed;
}
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
const clientRect = element.getBoundingClientRect();
const domElement = unwrapElement(element);
let scale = createCoords(1);
if (includeScale) {
if (offsetParent) {
if (isElement(offsetParent)) {
scale = getScale(offsetParent);
}
} else {
scale = getScale(element);
}
}
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
let x = (clientRect.left + visualOffsets.x) / scale.x;
let y = (clientRect.top + visualOffsets.y) / scale.y;
let width = clientRect.width / scale.x;
let height = clientRect.height / scale.y;
if (domElement) {
const win = getWindow(domElement);
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
let currentIFrame = win.frameElement;
while (currentIFrame && offsetParent && offsetWin !== win) {
const iframeScale = getScale(currentIFrame);
const iframeRect = currentIFrame.getBoundingClientRect();
const css = getComputedStyle(currentIFrame);
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
x *= iframeScale.x;
y *= iframeScale.y;
width *= iframeScale.x;
height *= iframeScale.y;
x += left;
y += top;
currentIFrame = getWindow(currentIFrame).frameElement;
}
}
return rectToClientRect({
width,
height,
x,
y
});
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.pageXOffset,
scrollTop: element.pageYOffset
};
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
let {
rect,
offsetParent,
strategy
} = _ref;
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
if (offsetParent === documentElement) {
return rect;
}
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
let scale = createCoords(1);
const offsets = createCoords(0);
if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== "fixed") {
if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isHTMLElement(offsetParent)) {
const offsetRect = getBoundingClientRect(offsetParent);
scale = getScale(offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
}
}
return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y
};
}
function getClientRects(element) {
return Array.from(element.getClientRects());
}
function getWindowScrollBarX(element) {
return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
}
function getDocumentRect(element) {
const html = getDocumentElement(element);
const scroll = getNodeScroll(element);
const body = element.ownerDocument.body;
const width = max2(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
const height = max2(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
const y = -scroll.scrollTop;
if (getComputedStyle$1(body).direction === "rtl") {
x += max2(html.clientWidth, body.clientWidth) - width;
}
return {
width,
height,
x,
y
};
}
function getParentNode(node) {
if (getNodeName(node) === "html") {
return node;
}
const result = (
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot || // DOM Element detected.
node.parentNode || // ShadowRoot detected.
isShadowRoot(node) && node.host || // Fallback.
getDocumentElement(node)
);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list) {
var _node$ownerDocument;
if (list === void 0) {
list = [];
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []);
}
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor));
}
function getViewportRect(element, strategy) {
const win = getWindow(element);
const html = getDocumentElement(element);
const visualViewport = win.visualViewport;
let width = html.clientWidth;
let height = html.clientHeight;
let x = 0;
let y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
const visualViewportBased = isSafari();
if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
return {
width,
height,
x,
y
};
}
function getInnerBoundingClientRect(element, strategy) {
const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
const top = clientRect.top + element.clientTop;
const left = clientRect.left + element.clientLeft;
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
const width = element.clientWidth * scale.x;
const height = element.clientHeight * scale.y;
const x = left * scale.x;
const y = top * scale.y;
return {
width,
height,
x,
y
};
}
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
let rect;
if (clippingAncestor === "viewport") {
rect = getViewportRect(element, strategy);
} else if (clippingAncestor === "document") {
rect = getDocumentRect(getDocumentElement(element));
} else if (isElement(clippingAncestor)) {
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
} else {
const visualOffsets = getVisualOffsets(element);
rect = {
...clippingAncestor,
x: clippingAncestor.x - visualOffsets.x,
y: clippingAncestor.y - visualOffsets.y
};
}
return rectToClientRect(rect);
}
function hasFixedPositionAncestor(element, stopNode) {
const parentNode = getParentNode(element);
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
return false;
}
return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
}
function getClippingElementAncestors(element, cache) {
const cachedResult = cache.get(element);
if (cachedResult) {
return cachedResult;
}
let result = getOverflowAncestors(element).filter((el) => isElement(el) && getNodeName(el) !== "body");
let currentContainingBlockComputedStyle = null;
const elementIsFixed = getComputedStyle$1(element).position === "fixed";
let currentNode = elementIsFixed ? getParentNode(element) : element;
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
const computedStyle = getComputedStyle$1(currentNode);
const currentNodeIsContaining = isContainingBlock(currentNode);
if (!currentNodeIsContaining && computedStyle.position === "fixed") {
currentContainingBlockComputedStyle = null;
}
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && ["absolute", "fixed"].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
if (shouldDropCurrentNode) {
result = result.filter((ancestor) => ancestor !== currentNode);
} else {
currentContainingBlockComputedStyle = computedStyle;
}
currentNode = getParentNode(currentNode);
}
cache.set(element, result);
return result;
}
function getClippingRect(_ref) {
let {
element,
boundary,
rootBoundary,
strategy
} = _ref;
const elementClippingAncestors = boundary === "clippingAncestors" ? getClippingElementAncestors(element, this._c) : [].concat(boundary);
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
const firstClippingAncestor = clippingAncestors[0];
const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
accRect.top = max2(rect.top, accRect.top);
accRect.right = min2(rect.right, accRect.right);
accRect.bottom = min2(rect.bottom, accRect.bottom);
accRect.left = max2(rect.left, accRect.left);
return accRect;
}, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
return {
width: clippingRect.right - clippingRect.left,
height: clippingRect.bottom - clippingRect.top,
x: clippingRect.left,
y: clippingRect.top
};
}
function getDimensions(element) {
return getCssDimensions(element);
}
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
const isOffsetParentAnElement = isHTMLElement(offsetParent);
const documentElement = getDocumentElement(offsetParent);
const isFixed = strategy === "fixed";
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
let scroll = {
scrollLeft: 0,
scrollTop: 0
};
const offsets = createCoords(0);
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isHTMLElement(offsetParent)) {
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
offsets.x = offsetRect.x + offsetParent.clientLeft;
offsets.y = offsetRect.y + offsetParent.clientTop;
} else if (documentElement) {
offsets.x = getWindowScrollBarX(documentElement);
}
}
return {
x: rect.left + scroll.scrollLeft - offsets.x,
y: rect.top + scroll.scrollTop - offsets.y,
width: rect.width,
height: rect.height
};
}
function getTrueOffsetParent(element, polyfill) {
if (!isHTMLElement(element) || getComputedStyle$1(element).position === "fixed") {
return null;
}
if (polyfill) {
return polyfill(element);
}
return element.offsetParent;
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else {
currentNode = getParentNode(currentNode);
}
}
return null;
}
function getOffsetParent(element, polyfill) {
const window2 = getWindow(element);
if (!isHTMLElement(element)) {
return window2;
}
let offsetParent = getTrueOffsetParent(element, polyfill);
while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === "static") {
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
}
if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle$1(offsetParent).position === "static" && !isContainingBlock(offsetParent))) {
return window2;
}
return offsetParent || getContainingBlock(element) || window2;
}
function isRTL(element) {
return getComputedStyle(element).direction === "rtl";
}
var min2, max2, round, createCoords, noOffsets, getElementRects, platform, computePosition2;
var init_floating_ui_dom = __esm({
"node_modules/.pnpm/@floating-ui+dom@1.4.5/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs"() {
"use strict";
init_floating_ui_core();
init_floating_ui_core();
min2 = Math.min;
max2 = Math.max;
round = Math.round;
createCoords = (v) => ({
x: v,
y: v
});
noOffsets = /* @__PURE__ */ createCoords(0);
getElementRects = async function(_ref) {
let {
reference,
floating,
strategy
} = _ref;
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
const getDimensionsFn = this.getDimensions;
return {
reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy),
floating: {
x: 0,
y: 0,
...await getDimensionsFn(floating)
}
};
};
platform = {
convertOffsetParentRelativeRectToViewportRelativeRect,
getDocumentElement,
getClippingRect,
getOffsetParent,
getElementRects,
getClientRects,
getDimensions,
getScale,
isElement,
isRTL
};
computePosition2 = (reference, floating, options) => {
const cache = /* @__PURE__ */ new Map();
const mergedOptions = {
platform,
...options
};
const platformWithCache = {
...mergedOptions.platform,
_c: cache
};
return computePosition(reference, floating, {
...mergedOptions,
platform: platformWithCache
});
};
}
});
// src/components/popup.ts
function createPopup(props) {
const {
root,
trigger,
triggerType = "click",
content,
options,
onOpen,
onClose,
placement = "bottom-start",
offsetOptions = { mainAxis: 5, crossAxis: 5 }
} = props;
const $popupContent = $('