Compare commits

..
62 Commits
Author SHA1 Message Date
eoao e5479b5f26 新增公告弹窗和无人收件开关 2025-08-03 21:18:54 +08:00
eoao 8c20ccb608 新增规则触发人机验证和加载失败提示 2025-07-30 12:56:12 +08:00
eoao 2df3e19d48 修复无法自适应浏览器语言 2025-07-29 14:09:29 +08:00
eoao 83d7817442 新增权限域名限制和链接背景上传 2025-07-27 15:26:06 +08:00
Abner e16da38bb2 修复 wrangler 配置文件占位符替换时序问题 (#57)
- 移除 telemetry 命令的配置文件参数避免在替换前读取配置
- 重新组织工作流步骤,确保配置文件占位符替换在所有 wrangler 命令之前执行
- 添加调试信息显示 R2_BUCKET_NAME 值和配置文件内容
- 修复 R2 bucket name 验证错误
- 调整数据库初始化等待时间从 10 秒增加到 15 秒
2025-07-27 10:23:21 +08:00
eoao d4d52aa2c4 修改文档和版本号 2025-07-24 18:05:00 +08:00
eoao 798321f7d5 修复注册码权限无效bug 2025-07-22 23:33:46 +08:00
eoao f6e60d6d7f 新增中英文切换 2025-07-22 22:02:23 +08:00
eoao 5d15a500f9 修改注册密码长度限制 2025-07-18 21:18:12 +08:00
eoao 635fd7737b 修改版本号 2025-07-18 01:16:44 +08:00
eoao 7b8aed4623 修复请求响应过慢 2025-07-16 20:07:39 +08:00
eoao fa542c437c 修复可选注册码报错
(cherry picked from commit b40c62f94d6e33814db1498534d585b5b8d4303f)
2025-07-16 20:38:00 +08:00
eoao 4f65ff0d34 修复注册密码提示问题 2025-07-16 20:30:00 +08:00
eoao 06291b4c86 新增注册码、草稿箱、权限拦截邮件、发件菜单隐藏 2025-07-15 20:09:56 +08:00
eoao 28905e369d 修复gmail附件和回复编辑器图片不显示 2025-07-10 09:00:14 +08:00
Abner aa827c0d33 fix 部署描述及action部署在未配置变量时输出成功提示 2025-07-09 19:26:36 +08:00
eoaoandAbner 3c33536812 新增 GitHub Actions 自动化部署
Co-authored-by: Abner <[email protected]>
2025-07-09 16:35:01 +08:00
eoao 452f134314 修复邮件图片移动端无法自适应 2025-07-07 22:43:57 +08:00
eoao a07cd2de12 修复收件内嵌图片只能显示一张 2025-07-07 22:38:56 +08:00
eoao 02076bf550 优化移动端404图片大小 2025-07-05 23:28:17 +08:00
eoao 8fcecf7645 修复邮件列表截取文字加载图片导致大量爆红 2025-07-04 21:11:41 +08:00
eoao 957bb04039 删除配置 2025-07-04 20:22:59 +08:00
eoao eb0819135f 修改版本号 2025-07-04 20:16:33 +08:00
MengNianxiaoyao fc45478707 修正错误文本
(cherry picked from commit 773f0cdcbb05eb27eeeb73e86d18a4f8e44cdb57)
2025-07-04 18:55:01 +08:00
eoao 263edb43b8 优化登录身份缓存机制 2025-07-04 20:02:00 +08:00
eoao dba5d1da63 截取邮箱名做发件名防止出现空名 2025-06-30 22:44:30 +08:00
eoao 2f87c0e6af 修复星标邮件列表不同步和图表空数据不为0 2025-06-30 15:27:59 +08:00
eoao 60f5e9a701 调整移动动端空状态大小、加载时标题改成空 2025-06-29 22:01:39 +08:00
eoao 2865e3aeb4 修复邮件列表发件无法搜索和不显示邮箱 2025-06-29 14:25:39 +08:00
eoao 689bc3a72e 邮件详情样式优化和查询优化 2025-06-29 11:57:53 +08:00
eoao 1c1e6dc458 修复纯文本邮件文字不会自动行 2025-06-28 22:01:42 +08:00
eoao 58ebf2bffb 修改版本号 2025-06-28 21:43:24 +08:00
eoao 9b1ecd084f 修复某些情况取消星标不同步 2025-06-28 21:35:43 +08:00
eoao 345d96ae55 新增点击复制邮箱功能 2025-06-28 20:22:52 +08:00
eoao 35749f6127 新增tg和第三方邮件转发 2025-06-28 13:35:37 +08:00
eoao f2a108a9b9 优化编辑器表情底部空白和table不显示线 2025-06-25 19:30:07 +08:00
eoao 7d8195dd5c 饼状图不再统计空名 2025-06-25 11:46:34 +08:00
eoao 970985cd10 新增无人收件和支持一些字符邮箱 2025-06-25 10:39:21 +08:00
eoao f65e174e7f 修复富文本居中图片后内容页还是靠左 2025-06-21 08:36:41 +08:00
eoao 2d123310e5 修复数据可视化最后一天为0 2025-06-20 00:52:17 +08:00
eoao affa62a0cb 新增打包文件 2025-06-17 09:23:00 +08:00
eoao 0cd976c3b1 设置柱状图默认值 2025-06-17 09:23:00 +08:00
eoao 65aeb6a2de 修改版本号 2025-06-17 09:21:00 +08:00
eoao 174248156c 新增邮件群发和数据可视化 2025-06-17 09:20:00 +08:00
eoao 9d8bff65fc 修改图片压缩规则,优化样式 2025-06-06 19:20:59 +08:00
eoao 80c649a013 修复透明度覆盖影响设置问题,优化样式 2025-06-06 00:23:31 +08:00
eoao 0184a276c5 修复星标不能查看,附件等多个bug,优化样式 2025-06-05 23:09:05 +08:00
eoao 024daaeecc 修复邮件正文不是utc+8时间 2025-06-05 15:02:57 +08:00
eoao b5271f1925 修改文档和修改项目错字 2025-06-05 08:53:24 +08:00
eoao 532a47406d 修复无法接收邮件问题 2025-06-04 22:12:54 +08:00
eoao 043e01fde2 修改登录页面 2025-06-04 00:20:53 +08:00
eoao a2e26d3b55 修复自动刷新问题 2025-06-03 13:29:52 +08:00
eoao 0d3e45a47f 修复人机验证不显示问题 2025-06-03 12:58:33 +08:00
eoao 16c4b3b738 修复内容显示问题 2025-06-03 07:53:22 +08:00
eoao 87bbfcbd9f 新增邮件发送和管理员功能 2025-05-29 17:38:50 +08:00
eoao 6be8c9c580 添加教程,更新打包文件
删除描述
2025-04-29 04:49:33 +08:00
eoao 4a0e46e1cf 修复a标签变成黑色问题 2025-04-27 17:19:37 +08:00
eoao 298a21a3ee 修改错字 2025-04-27 11:47:53 +08:00
eoao 41d786ef49 修改配置 2025-04-27 09:32:25 +08:00
eoao b2b489c828 添加说明和MIT 2025-04-27 09:09:43 +08:00
eoao 1136617dd9 添加打包文件 2025-04-26 17:33:50 +08:00
eoao 2f2434ca5c 保存 2025-04-26 17:24:39 +08:00
361 changed files with 21378 additions and 20344 deletions
-10
View File
@@ -1,10 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[Bug] "
labels: bug
assignees: ''
---
-10
View File
@@ -1,10 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[Feature request] "
labels: enhancement
assignees: ''
---
-10
View File
@@ -1,10 +0,0 @@
---
name: Need Help
about: Create a issue to find help
title: "[Help] "
labels: help wanted
assignees: ''
---
+85 -226
View File
@@ -14,258 +14,117 @@ jobs:
runs-on: ubuntu-latest
env:
NAME: ${{ secrets.NAME || vars.NAME || 'cloud-mail' }}
CUSTOM_DOMAIN: ${{ secrets.CUSTOM_DOMAIN || vars.CUSTOM_DOMAIN }}
DOMAIN: ${{ secrets.DOMAIN || vars.DOMAIN }}
ADMIN: ${{ secrets.ADMIN || vars.ADMIN }}
JWT_SECRET: ${{ secrets.JWT_SECRET || vars.JWT_SECRET }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN || vars.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || vars.CLOUDFLARE_ACCOUNT_ID }}
D1_DATABASE_ID: ${{ secrets.D1_DATABASE_ID || vars.D1_DATABASE_ID }}
KV_NAMESPACE_ID: ${{ secrets.KV_NAMESPACE_ID || vars.KV_NAMESPACE_ID }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME || vars.R2_BUCKET_NAME }}
PROJECT_LINK: ${{ secrets.PROJECT_LINK || vars.PROJECT_LINK }}
AI_MODEL: ${{ secrets.AI_MODEL || vars.AI_MODEL || '@cf/meta/llama-3.1-8b-instruct' }}
CLOUDFLARE_EMAIL: ${{ secrets.CF_EMAIL || vars.CF_EMAIL || false }}
ANALYSIS_CACHE: ${{ secrets.ANALYSIS_CACHE || vars.ANALYSIS_CACHE || false }}
LINUXDO_CLIENT_ID: ${{ secrets.LINUXDO_CLIENT_ID || vars.LINUXDO_CLIENT_ID }}
LINUXDO_CLIENT_SECRET: ${{ secrets.LINUXDO_CLIENT_SECRET || vars.LINUXDO_CLIENT_SECRET }}
LINUXDO_CALLBACK_URL: ${{ secrets.LINUXDO_CALLBACK_URL || vars.LINUXDO_CALLBACK_URL }}
LINUXDO_SWITCH: ${{ secrets.LINUXDO_SWITCH || vars.LINUXDO_SWITCH }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
D1_DATABASE_ID: ${{ secrets.D1_DATABASE_ID }}
KV_NAMESPACE_ID: ${{ secrets.KV_NAMESPACE_ID }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
DOMAIN: ${{ secrets.DOMAIN }}
ADMIN: ${{ secrets.ADMIN }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
INIT_URL: ${{ secrets.INIT_URL }}
outputs:
worker_url: ${{ steps.deploy.outputs.worker_url }}
deployment_skipped: ${{ steps.deploy.outputs.deployment_skipped }}
steps:
- name: 🚚 检出代码仓库 / Checkout repository
- name: ➡️ Checkout repository
uses: actions/checkout@v4
- name: ⚙ 设置 pnpm / Set up pnpm
uses: pnpm/[email protected]
with:
version: 9
- name: ⚙ 设置 Node.js / Set up Node.js
- name: 📦 Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "./mail-worker/pnpm-lock.yaml"
node-version: "20"
cache: "npm"
cache-dependency-path: "./mail-worker/package-lock.json"
- name: 📦 安装依赖 / Install dependencies
run: pnpm install --frozen-lockfile
- name: 📥 Install dependencies
run: npm ci
working-directory: ./mail-worker
- name: 📡 禁用 Wrangler 遥测 / Disable wrangler telemetry
- name: 📡 Disable wrangler telemetry
working-directory: ./mail-worker
run: pnpm wrangler telemetry disable
run: npx wrangler telemetry disable
- name: 🛠️ 设置环境 / Set up environment
working-directory: ./mail-worker
run: |
echo "🔐 Starting environment setup..."
if [ -z "$JWT_SECRET" ] || grep -q '[?%#/\\]' <<< "$JWT_SECRET"; then
echo "❌ JWT_SECRET variable is empty or contains invalid characters (?, %, #, /, \\)."
exit 1
fi
if ! jq -e 'type == "array"' <<< "$DOMAIN" ; then
echo "❌ DOMAIN variable must be a JSON array (e.g., [\"example.com\"])."
exit 1
fi
if [ -z "$ADMIN" ]; then
echo "❌ ADMIN variable cannot be empty."
exit 1
fi
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then
echo "❌ CLOUDFLARE_ACCOUNT_ID variable cannot be empty."
exit 1
fi
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "❌ CLOUDFLARE_API_TOKEN variable cannot be empty."
exit 1
fi
if [ -z "$CUSTOM_DOMAIN" ]; then
echo "::warning:: CUSTOM_DOMAIN variable is not set."
fi
CONFIG_FILE="wrangler-action.toml"
if [ -z "$R2_BUCKET_NAME" ]; then
sed -i '/\[\[r2_buckets\]\]/,/^$/d' "$CONFIG_FILE"
fi
if [ -z "$PROJECT_LINK" ]; then
sed -i '/^project_link = /d' "$CONFIG_FILE"
fi
if [ -z "$LINUXDO_CLIENT_ID" ] || [ -z "$LINUXDO_CLIENT_SECRET" ]; then
sed -i '/^linuxdo_client_id = /,/^linuxdo_switch = /d' "$CONFIG_FILE"
fi
if [ -z "$CUSTOM_DOMAIN" ]; then
sed -i '/\[\[routes\]\]/,/^$/d' "$CONFIG_FILE"
fi
if [ "$(printf '%s' "$CLOUDFLARE_EMAIL" | tr '[:upper:]' '[:lower:]')" = "true" ]; then
cat >> "$CONFIG_FILE" <<'EOF'
[[send_email]]
name = "email"
EOF
fi
sed -i "s|\${NAME}|${NAME}|g" "$CONFIG_FILE"
sed -i "s|\${CUSTOM_DOMAIN}|${CUSTOM_DOMAIN}|g" "$CONFIG_FILE"
sed -i "s|\"\${DOMAIN}\"|${DOMAIN}|g" "$CONFIG_FILE"
sed -i "s|\${ADMIN}|${ADMIN}|g" "$CONFIG_FILE"
sed -i "s|\${JWT_SECRET}|${JWT_SECRET}|g" "$CONFIG_FILE"
sed -i "s|\${R2_BUCKET_NAME}|${R2_BUCKET_NAME}|g" "$CONFIG_FILE"
sed -i "s|\${PROJECT_LINK}|${PROJECT_LINK}|g" "$CONFIG_FILE"
sed -i "s|\${ANALYSIS_CACHE}|${ANALYSIS_CACHE}|g" "$CONFIG_FILE"
sed -i "s|\${AI_MODEL}|${AI_MODEL}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CLIENT_ID}|${LINUXDO_CLIENT_ID}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CLIENT_SECRET}|${LINUXDO_CLIENT_SECRET}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_CALLBACK_URL}|${LINUXDO_CALLBACK_URL}|g" "$CONFIG_FILE"
sed -i "s|\${LINUXDO_SWITCH}|${LINUXDO_SWITCH}|g" "$CONFIG_FILE"
echo "✅ Environment setup completed."
- name: ⚡ 设置KV数据库 / Set up KV database
working-directory: ./mail-worker
run: |
CONFIG_FILE="wrangler-action.toml"
if [ -n "$KV_NAMESPACE_ID" ]; then
sed -i "s|\${KV_NAMESPACE_ID}|${KV_NAMESPACE_ID}|g" "$CONFIG_FILE"
echo "✅ Using the database from environment variables."
exit 0
fi
echo "🔍 Checking if the database exists..."
set +e
KV_LIST=$(pnpm wrangler kv namespace list 2>&1)
STATUS=$?
set -e
if [ $STATUS -ne 0 ]; then
echo "$KV_LIST"
exit 1
fi
if echo "$KV_LIST" | jq -e ".[] | select(.title == \"$NAME\")" >/dev/null; then
echo "✅ Database $NAME already exists."
KV_ID=$(echo "$KV_LIST" | jq -r ".[] | select(.title == \"$NAME\") | .id")
echo "KV_NAMESPACE_ID: $KV_ID"
else
echo "⚠️ Database $NAME does not exist. Starting creation..."
pnpm wrangler kv namespace create $NAME
KV_LIST=$(pnpm wrangler kv namespace list)
KV_ID=$(echo "$KV_LIST" | jq -r ".[] | select(.title == \"$NAME\") | .id")
fi
sed -i "s|\${KV_NAMESPACE_ID}|$KV_ID|g" "$CONFIG_FILE"
echo "✅ Setup completed."
- name: 🐬 设置D1数据库 / Set up D1 database
working-directory: ./mail-worker
run: |
CONFIG_FILE="wrangler-action.toml"
if [ -n "$D1_DATABASE_ID" ]; then
sed -i "s|\${D1_DATABASE_ID}|${D1_DATABASE_ID}|g" "$CONFIG_FILE"
echo "✅ Using the database from environment variables."
exit 0
fi
echo "🔍 Checking if the database exists..."
set +e
DB_LIST=$(pnpm wrangler d1 list --json 2>&1)
STATUS=$?
set -e
if [ $STATUS -ne 0 ]; then
echo "$DB_LIST"
exit 1
fi
if echo "$DB_LIST" | jq -e ".[] | select(.name == \"$NAME\")" >/dev/null; then
echo "✅ Database $NAME already exists."
D1_ID=$(echo "$DB_LIST" | jq -r ".[] | select(.name == \"$NAME\") | .uuid")
echo "D1_DATABASE_ID: $D1_ID"
else
echo "⚠️ Database $NAME does not exist. Starting creation..."
pnpm wrangler d1 create $NAME
DB_LIST=$(pnpm wrangler d1 list --json)
D1_ID=$(echo "$DB_LIST" | jq -r ".[] | select(.name == \"$NAME\") | .uuid")
fi
sed -i "s|\${D1_DATABASE_ID}|$D1_ID|g" "$CONFIG_FILE"
echo "✅ Setup completed."
- name: 🚀 开始部署 / Start deployment
- name: 🛠️ Prepare Config, Set Secrets and Deploy
id: deploy
working-directory: ./mail-worker
run: |
echo "🚀 Starting deployment..."
pnpm wrangler deploy -c wrangler-action.toml 2>&1 \
| tee deploy.log \
| grep -v "https://.*\.workers\.dev" \
| sed -E 's/env\.domain .*/env.domain (***)/' \
|| true
DEPLOY_EXIT_CODE=${PIPESTATUS[0]}
if [ $DEPLOY_EXIT_CODE -ne 0 ]; then
exit 1
if [ -z "$D1_DATABASE_ID" ] || [ -z "$KV_NAMESPACE_ID" ] || [ -z "$R2_BUCKET_NAME" ]; then
echo "⚠️ Required secrets (D1_DATABASE_ID, KV_NAMESPACE_ID, or R2_BUCKET_NAME) are not set."
echo "🟡 Skipping deployment."
echo "deployment_skipped=true" >> $GITHUB_OUTPUT
exit 0
fi
WORKER_URL=$(grep -o "https://.*\.workers\.dev" deploy.log || echo "")
if [ -n "$WORKER_URL" ]; then
echo "::add-mask::$WORKER_URL"
fi
echo "worker_url=$WORKER_URL" >> $GITHUB_OUTPUT
echo "✅ Setup completed."
echo "deployment_skipped=false" >> $GITHUB_OUTPUT
CONFIG_FILE="wrangler-action.toml"
echo "⚙️ Dynamically updating '$CONFIG_FILE' with binding IDs..."
- name: ♻️ 初始化数据库 / Initialize database
sed -i "s|\${D1_DATABASE_ID}|${D1_DATABASE_ID}|g" "$CONFIG_FILE"
sed -i "s|\${KV_NAMESPACE_ID}|${KV_NAMESPACE_ID}|g" "$CONFIG_FILE"
sed -i "s|\${R2_BUCKET_NAME}|${R2_BUCKET_NAME}|g" "$CONFIG_FILE"
echo "🔍 Debug: Checking configuration after replacement..."
echo "R2_BUCKET_NAME value: '$R2_BUCKET_NAME'"
echo "R2 bucket configuration in $CONFIG_FILE:"
grep -A 2 -B 2 "bucket_name" "$CONFIG_FILE" || true
echo "🔒 Setting Worker secrets..."
WORKER_NAME="cloud-mail"
for VAR in DOMAIN ADMIN JWT_SECRET; do
if [ -n "${!VAR}" ]; then
VAR_LOWER=$(echo "$VAR" | tr '[:upper:]' '[:lower:]')
echo ">> Processing secret: '$VAR_LOWER'"
(echo "${!VAR}" | npx wrangler secret put "$VAR_LOWER" --name "$WORKER_NAME" -c "$CONFIG_FILE") || true
else
echo "⚠️ Warning: GitHub Secret '$VAR' is not set. Skipping."
fi
done
echo "🚀 Configuration updated. Starting deployment..."
npx wrangler deploy -c "$CONFIG_FILE" | grep -v "https://.*\.workers\.dev" || true
echo "✅ Deployment command executed."
- name: 🗄️ Initialize Database (if INIT_URL is set)
if: ${{ steps.deploy.outputs.deployment_skipped == 'false' }}
run: |
echo "🛠️ Starting database initialization..."
if [ -z "$INIT_URL" ]; then
echo "✅ Deployment successful. INIT_URL not set, skipping initialization."
exit 0
fi
echo "⏳ Waiting 15 秒之前 before checking initialization status..."
sleep 15
WORKER_URL="${CUSTOM_DOMAIN:+https://$CUSTOM_DOMAIN}"
WORKER_URL="${WORKER_URL:-${{ steps.deploy.outputs.worker_url }}}"
if [ -z "$WORKER_URL" ]; then
echo "❌ Preview URL not available. Please set CUSTOM_DOMAIN."
exit 1
fi
HTTP_CODE=$(curl -sL -w "%{http_code}" -o response.txt "$WORKER_URL/api/init/${JWT_SECRET}")
HTTP_CODE=$(curl -s -w "%{http_code}" -o response.txt "$INIT_URL")
RESPONSE_BODY=$(cat response.txt)
echo "🔎 Checking response... (Status: $HTTP_CODE)"
if [ "$RESPONSE_BODY" = "success" ]; then
echo "✅ Setup completed."
if [ "$HTTP_CODE" = "200" ] && [ "$RESPONSE_BODY" = "初始化成功" ]; then
echo "🎉Fresh initialization successful!"
elif [ "$HTTP_CODE" = "200" ]; then
echo "✅ Database is already initialized or in a stable state. Response: $RESPONSE_BODY"
else
echo "❌ Failed. HTTP: $HTTP_CODE, Response: $RESPONSE_BODY"
exit 1
echo "⚠️ Database initialization check failed with HTTP status: $HTTP_CODE. Please check your worker logs."
fi
- name: 🗑️ 删除运行记录 / Delete workflow runs
- name: 📣 Notify Final Status
if: always()
run: |
if [ "${{ job.status }}" == "success" ]; then
if [ "${{ steps.deploy.outputs.deployment_skipped }}" == "true" ]; then
echo "🟡 Deployment was skipped due to missing configuration."
else
echo "🎉🎉🎉 Hooray! Deployment completed successfully! 🎉🎉🎉"
fi
else
echo "❌❌❌ Oh no! The deployment failed. Please check the logs above for errors. ❌❌❌"
fi
- name: Delete workflow runs
uses: GitRML/delete-workflow-runs@main
continue-on-error: true
with:
retain_days: '1'
retain_days: '3'
keep_minimum_runs: '0'
+1 -2
View File
@@ -9,7 +9,6 @@ lerna-debug.log*
node_modules
dist-ssr
*.local
dist
.vscode/*
!.vscode/extensions.json
@@ -24,4 +23,4 @@ dist
mail-vue/node_modules
mail-vue/dist
.wrangler
.venv
.venv
+124 -91
View File
@@ -1,143 +1,176 @@
<p align="center">
<img src="doc/demo/logo.png" width="80px" />
<h1 align="center">Cloud Mail</h1>
<p align="center">A simple, responsive email service designed to run on Cloudflare Workers 🎉</p>
<p align="center">
<a href="/README.md" style="margin-left: 5px">简体中文</a> | English
</p>
<p align="center">
<a href="https://github.com/maillab/cloud-mail/tree/main?tab=MIT-1-ov-file" target="_blank" >
<img src="https://img.shields.io/badge/license-MIT-green" />
</a>
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank" >
<img src="https://img.shields.io/github/v/release/maillab/cloud-mail" alt="releases" />
</a>
<a href="https://github.com/maillab/cloud-mail/issues" >
<img src="https://img.shields.io/github/issues/maillab/cloud-mail" alt="issues" />
</a>
<a href="https://github.com/maillab/cloud-mail/stargazers" target="_blank">
<img src="https://img.shields.io/github/stars/maillab/cloud-mail" alt="stargazers" />
</a>
<a href="https://github.com/maillab/cloud-mail/forks" target="_blank" >
<img src="https://img.shields.io/github/forks/maillab/cloud-mail" alt="forks" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/20459" target="_blank" >
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" >
</a>
</p>
<img src="doc/demo/logo.png" width="80px" />
</p>
## Description
With only one domain, you can create multiple different email addresses, similar to major email platforms. This project can be deployed on Cloudflare Workers to reduce server costs and build your own email service.
<div align="center">
<h1>Cloud Mail</h1>
</div>
<div align="center">
<h4>A responsive email service built with Vue 3 that supports email sending and can be deployed on Cloudflare. 🎉</h4>
</div>
## Project Showcase
- [Live Demo](https://skymail.ink)<br>
- [Deployment Guide](https://doc.skymail.ink/en/)<br>
[**👉 Online Demo**](https://skymail.ink)
[**👉 Beginners Guide UI Deployment**](https://doc.skymail.ink)
| ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) |
|--------------------------|--------------------------|
|--------------------------|---------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
| ![](/doc/demo/demo5.png) | ![](/doc/demo/demo6.png) |
| ![](/doc/demo/demo7.png) | ![](/doc/demo/demo8.png) |
## Features
- **💰 Low-Cost Usage**: No server required — deploy to Cloudflare Workers to reduce costs.
- **💻 Responsive Design**: Automatically adapts to both desktop and most mobile browsers.
- **📧 Email Sending**: Integrated with Resend, supporting bulk email sending and attachments.
- **📧 Email Sending**: Integrated with Resend for bulk email sending, embedded images, attachments, and status tracking.
- **🛡️ Admin Features**: Admin controls for user and email management with RBAC-based access control.
- **🛡️ Admin Features**: Admins can manage users and emails, with RBAC permission control to limit access to features and resources.
- **🔀 Multiple Accounts**: Users can add multiple email accounts.
- **📦 Attachment Support**: Send and receive attachments, stored and downloaded via R2 object storage.
- **🔔 Email Push**: Forward received emails to Telegram bots or other email providers.
- **📡 Open API**: Supports batch user creation via API and multi-condition email queries
- **📈 Data Visualization**: Use Echarts to visualize system data, including user email growth.
- **🔢 Verification Code Recognition**: Auto-detect codes via Workers AI
- **📈 Data Visualization**: Use ECharts to visualize system data, including user email growth.
- **⭐ Starred Emails**: Mark important emails for quick access.
- **🎨 Personalization**: Customize website title, login background, and transparency.
- **⚙️ Feature Settings**: Toggle on or off features like registration, email sending, and more, with the option to make the site private.
- **🤖 CAPTCHA**: Integrated with Turnstile CAPTCHA to prevent automated registration.
- **📜 More Features**: Under development...
## Tech Stack
- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **Framework**: [Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/)
- **Web Framework**: [Hono](https://hono.dev/)
- **ORM**: [Drizzle](https://orm.drizzle.team/)
- **Frontend Framework**: [Vue3](https://vuejs.org/)
- **UI Framework**: [Element Plus](https://element-plus.org/)
- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **Email Service**: [Resend](https://resend.com/)
- **Cache**: [Cloudflare KV](https://developers.cloudflare.com/kv/)
- **Caching**: [Cloudflare KV](https://developers.cloudflare.com/kv/)
- **Database**: [Cloudflare D1](https://developers.cloudflare.com/d1/)
- **File Storage**: [Cloudflare R2](https://developers.cloudflare.com/r2/)
## Project Structure
## Setup Guide
```
cloud-mail
├── mail-worker # Backend worker project
│ ├── src
│ │ ├── api # API layer
│ │ ├── const # Project constants
│ │ ├── dao # Data access layer
│ │ ├── email # Email processing and handling
│ │ ├── entity # Database entities
│ │ ├── error # Custom exceptions
│ │ ├── hono # Web framework, middleware, error handling
│ │ ├── i18n # Internationalization
│ │ ├── init # Database and cache initialization
│ │ ├── model # Response data models
│ │ ├── security # Authentication and authorization
│ │ ├── service # Business logic layer
│ │ ├── template # Message templates
│ │ ├── utils # Utility functions
│ │ └── index.js # Entry point
│ ├── package.json # Project dependencies
│ └── wrangler.toml # Project configuration
├─ mail-vue # Frontend Vue project
│ ├── src
│ │ ├── axios # Axios configuration
│ │ ├── components # Custom components
│ │ ├── echarts # ECharts integration
│ │ ├── i18n # Internationalization
│ │ ├── init # Startup initialization
│ │ ├── layout # Main layout components
│ │ ├── perm # Permissions and access control
│ │ ├── request # API request layer
│ │ ├── router # Router configuration
│ │ ├── store # Global state management
│ │ ├── utils # Utility functions
│ │ ├── views # Page components
│ │ ├── app.vue # Root component
│ │ ├── main.js # Entry JS file
│ │ └── style.css # Global styles
│ ├── package.json # Project dependencies
└── └── env.release # Environment configuration
### System Requirements
Nodejs v18.20 +
Cloudflare account (with a bound domain)
**Clone the project to your local machine:**
``` shell
git clone https://github.com/eoao/cloud-mail
cd cloud-mail/mail-worker
```
## Sponsor
**Install Dependencies:**
```shell
npm i
```
<a href="https://doc.skymail.ink/support.html">
**Configure the Project**
mail-worker/wrangler.toml
```toml
[[d1_databases]]
binding = "db" # Default binding name for D1 database, cannot be changed
database_name = "" # Database name
database_id = "" # Database ID
[[kv_namespaces]]
binding = "kv" # Default binding name for KV storage, cannot be changed
id = "" # KV namespace ID
[[r2_buckets]]
binding = "r2" # Default binding name for R2 storage, cannot be changed
bucket_name = "" # R2 bucket name
[assets]
binding = "assets" # Static asset binding name, cannot be changed
directory = "./dist" # Directory for frontend Vue project build, default: dist
[vars]
orm_log = false
domain = [] # Configure email domains, example: ["example1.com", "example2.com"]
admin = "" # Admin email, example: "[email protected]"
jwt_secret = "" # JWT secret for login tokens, choose a random string
```
**Deploy Remotely**
1. Create KV, D1 database, and R2 object storage in Cloudflare Console.
2. In the project directory `mail-worker/wrangler.toml`, configure the environment variables and database IDs/names.
3. Run the deployment command:
```shell
npm run deploy
```
4. In Cloudflare → Account Home → Your Domain → Email → Email Routing → Route Rules → Catch-all Address, edit and route to the worker.
5. In your browser, visit `https://your-project-domain/api/init/your-jwt-secret` to initialize or update the D1 and KV databases.
6. After deployment, log in to the site with the admin account to configure R2 domains, Turnstile keys, and more.
**Run Locally**
1. Run locally. Databases and object storage will automatically be set up, no manual creation needed. Data is stored in the `mail-worker/.wrangler` folder.
```shell
npm run dev
```
2. In your browser, visit `http://127.0.0.1:8787/api/init/your-jwt-secret` to initialize D1 and KV databases.
3. For local testing, you can set the R2 domain to `http://127.0.0.1:8787/api/file`.
**Email Sending**
1. Register on Resend, then click on “Domains” to add and verify your domain. Wait for verification.
2. Go to "API Keys" to create an API key, then copy the token and paste it in the project website settings.
3. Go to "Webhooks" and add a callback URL `https://your-project-domain/api/webhooks`.
Select the following events: ✅ (email.bounced, email.complained, email.delivered, email.delivery_delayed).
**Project Update**
After the update, run `https://your-project-domain/api/init/your-jwt-secret` to synchronize the database schema.
## Support
<a href="https://support.skymail.ink">
<img width="170px" src="./doc/images/support.png" alt="">
</a>
</a><br><br>
**Special Sponsors**
[DartNode](https://dartnode.com)Providing cloud computing service resource support
[![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
## License
+143 -94
View File
@@ -1,90 +1,75 @@
<p align="center">
<img src="doc/demo/logo.png" width="80px" />
<h1 align="center">Cloud Mail</h1>
<p align="center">基于 Cloudflare 的简约响应式邮箱服务,支持邮件发送、附件收发 🎉</p>
<p align="center">
简体中文 | <a href="/README-en.md" style="margin-left: 5px">English </a>
</p>
<p align="center">
<a href="https://github.com/maillab/cloud-mail/tree/main?tab=MIT-1-ov-file" target="_blank" >
<img src="https://img.shields.io/badge/license-MIT-green" />
</a>
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank" >
<img src="https://img.shields.io/github/v/release/maillab/cloud-mail" alt="releases" />
</a>
<a href="https://github.com/maillab/cloud-mail/issues" >
<img src="https://img.shields.io/github/issues/maillab/cloud-mail" alt="issues" />
</a>
<a href="https://github.com/maillab/cloud-mail/stargazers" target="_blank">
<img src="https://img.shields.io/github/stars/maillab/cloud-mail" alt="stargazers" />
</a>
<a href="https://github.com/maillab/cloud-mail/forks" target="_blank" >
<img src="https://img.shields.io/github/forks/maillab/cloud-mail" alt="forks" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/20459" target="_blank" >
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" >
</a>
</p>
<img src="doc/demo/logo.png" width="80px" />
</p>
<div align="center">
<h1>Cloud Mail</h1>
</div>
<div align="center">
<h4>使用Vue3开发的响应式简约邮箱服务,支持邮件发送附件收发,可以部署到Cloudflare云平台实现免费白嫖🎉</h4>
</div>
<div align="center">
<span>简体中文 | <a href="/README-en.md" style="margin-left: 5px">English </a></span>
</div>
## 项目简介
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台,本项目支持署到 Cloudflare Workers ,降低服务器成本,搭建自己的邮箱服务
只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台 QQ邮箱,谷歌邮箱等,本项目使用Cloud flare部署,Resend推送邮件,无需服务器费用,搭建属于自己的邮箱服务
## 项目展示
## 项目展示
- [在线演示](https://skymail.ink)<br>
- [部署文档](https://doc.skymail.ink)<br>
[**👉 在线演示**](https://skymail.ink)
[**👉 小白保姆教程-界面部署**](https://doc.skymail.ink)
| ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) |
|-----------------------|-----------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
|--------------------------|---------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
| ![](/doc/demo/demo5.png) | ![](/doc/demo/demo6.png) |
| ![](/doc/demo/demo7.png) | ![](/doc/demo/demo8.png) |
## 功能介绍
- **💰 低成本使用**部署到 Cloudflare Workers 降低服务器成本
- **💰免费白嫖**:无需服务器,部署到Cloudflare Workers 免费使用,不要钱
- **💻 响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
- **💻响应式设计**:响应式布局自动适配PC和大部分手机端浏览器
- **📧 邮件发送**:集成Resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
- **📧邮件发送**:集成resend发送邮件,支持群发,内嵌图片和附件发送,发送状态查看
- **🛡️ 管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
- **🛡️管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制
- **📦 附件收发**:支持收发附件,使用R2对象存储保存和下载文件
- **🔀多号模式**:开启后一个用户可以添加多个邮箱,默认一用户一邮箱,类似各大邮箱平台
- **🔔 邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
- **📦附件收发**:支持收发附件,使用R2对象存储保存和下载文件
- **📡 开放API**:支持使用API批量生成用户,多条件查询邮件
- **🔔邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱
- **🔢 验证码识别**:使用Workers AI,自动识别邮件验证码
- **📈数据可视化**:使用echarts对系统数据详情,用户邮件增长可视化显示
- **📈 数据可视化**:使用ECharts对系统数据详情,用户邮件增长可视化显示
- **⭐星标邮件**:标记重要邮件,以便快速查阅
- **🎨 个性化设置**:可以自定义网站标题,登录背景,透明度
- **🎨个性化设置**:可以自定义网站标题,登录背景,透明度
- **🤖 人机验证**:集成Turnstile人机验证,防止人机批量注册
- **⚙️功能设置**:可以对注册,邮件发送,添加等功能关闭和开启,设为私人站点
- **📜 更多功能**:正在开发中...
- **🤖人机验证**:集成Turnstile人机验证,防止人机批量注册
- **📜更多功能**:正在开发中...
## 技术栈
- **平台**[Cloudflare Workers](https://developers.cloudflare.com/workers/)
- **框架**[Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/)
- **Web框架**[Hono](https://hono.dev/)
- **ORM**[Drizzle](https://orm.drizzle.team/)
- **前端框架**[Vue3](https://vuejs.org/)
- **UI框架**[Element Plus](https://element-plus.org/)
- **平台:** [Cloudflare workers](https://developers.cloudflare.com/workers/)
- **邮件推送:** [Resend](https://resend.com/)
@@ -94,56 +79,120 @@
- **文件存储**[Cloudflare R2](https://developers.cloudflare.com/r2/)
## 目录结构
## 使用教程
### 环境要求
Nodejs v18.20 +
Cloudflare 账号 (需要绑定域名)
**克隆项目到本地**
``` shell
git clone https://github.com/eoao/cloud-mail #拉取代码
cd cloud-mail/mail-worker #进入worker目录
```
**安装依赖**
```shell
npm i
```
**项目配置**
mail-worker/wrangler.toml
```toml
[[d1_databases]]
binding = "db" #d1数据库绑定名默认不可修改
database_name = "" #d1数据库名字
database_id = "" #d1数据库id
[[kv_namespaces]]
binding = "kv" #kv绑定名默认不可修改
id = "" #kv数据库id
[[r2_buckets]]
binding = "r2" #r2对象存储绑定名默认不可修改
bucket_name = "" #r2对象存储桶的名字
[assets]
binding = "assets" #静态资源绑定名默认不可修改
directory = "./dist" #前端vue项目打包的静态资源存放位置,默认dist
[vars]
orm_log = false
domain = [] #邮件域名可以配置多个示例: ["example1.com","example2.com"]
admin = "" #管理员的邮箱 示例: "[email protected]"
jwt_secret = "" #登录身份令牌的密钥,随便填一串字符串
```
cloud-mail
├── mail-worker # worker后端项目
│ ├── src
│ │ ├── api # api接口层
│ │ ├── const # 项目常量
│ │ ├── dao # 数据访问层
│ │ ├── email # 邮件处理接收
│ │ ├── entity # 数据库实体
│ │ ├── error # 自定义异常
│ │ ├── hono # web框架配置、拦截器、全局异常等
│ │ ├── i18n # 语言国际化
│ │ ├── init # 数据库缓存初始化
│ │ ├── model # 响应体数据封装
│ │ ├── security # 身份权限认证
│ │ ├── service # 业务服务层
│ │ ├── template # 消息模板
│ │ ├── utils # 工具类
│ │ └── index.js # 入口文件
│ ├── pageckge.json # 项目依赖
│ └── wrangler.toml # 项目配置
├── mail-vue # vue前端项目
│ ├── src
│ │ ├── axios # axios配置
│ │ ├── components # 自定义组件
│ │ ├── echarts # echarts组件导入
│ │ ├── i18n # 语言国际化
│ │ ├── init # 入站初始化
│ │ ├── layout # 主体布局组件
│ │ ├── perm # 权限认证
│ │ ├── request # api接口
│ │ ├── router # 路由配置
│ │ ├── store # 全局状态管理
│ │ ├── utils # 工具类
│ │ ├── views # 页面组件
│ │ ├── app.vue # 入口组件
│ │ ├── main.js # 入口js
│ │ └── style.css # 全局css
│ ├── package.json # 项目依赖
└── └── env.release # 项目配置
```
**远程部署**
1. 在 Cloudflare 控制台创建KVD1数据库,R2对象存储
2. 在项目目录 `mail-worker/wrangler.toml` 配置文件中配置对应环境变量,以及创建的数据库id和名称
3. 执行远程部署命令
```shell
npm run deploy
```
4. 在Cloudflare→账户主页→你的域名→电子邮件→电子邮件路由→路由规则→Catch-all地址,编辑发送到worker
5. 浏览器输入 `https://你的项目域名/api/init/你的jwt_secret` 初始化或更新 d1和kv数据库
6. 部署完成登录网站,使用管理员账号可以在设置页面添加配置 R2域名 Turnstile密钥 等
[👉 使用 Github Action 部署](/doc/github-action.md)
**本地运行**
1. 本地运行,数据库,对象存储会自动安装,无需创建,数据库数据保存在 `mail-worker/.wrangler` 文件夹
```shell
npm run dev
```
2. 浏览器输入 `http://127.0.0.1:8787/api/init/你的jwt_secret` 初始化d1和kv数据库
3. 本地运行项目设置页面r2域名可设置为 `http://127.0.0.1:8787/api/file`
**邮件发送**
1. 在 resend 官网注册后,点击左侧 Domains 添加并验证你的域名,等待验证完成
2. 点击左侧 Api Keys 创建立api key 复制token回到项目网站设置页面添加 resend token
3. 点击左侧 Webhooks 添加回调地址 `https://你的项目域名/api/webhooks`
勾选✅ (email.bounced email.complained email.delivered email.delivery_delayed)
**项目更新**
更新后需要执行 `https://你的项目域名/api/init/你的jwt_secret` 来同步数据库结构
## 赞助
<a href="https://doc.skymail.ink/support.html" >
<a href="https://support.skymail.ink" >
<img width="170px" src="./doc/images/support.png" alt="">
</a>
</a><br><br>
**特别赞助商**
[DartNode](https://dartnode.com):提供云计算服务资源支持
[![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source")
## 许可证
Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 64 KiB

+1 -2
View File
@@ -1,4 +1,3 @@
NODE_ENV = 'dev'
VITE_APP_TITLE = '开发环境'
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
VITE_PWA_NAME = 'Cloud Mail'
VITE_BASE_URL = 'http://127.0.0.1:8787/api'
+1 -3
View File
@@ -1,5 +1,3 @@
NODE_ENV = 'release'
VITE_APP_TITLE = '发布环境'
VITE_BASE_URL = '/api'
VITE_PWA_NAME = 'Cloud Mail'
VITE_OUT_DIR = ../mail-worker/dist
VITE_BASE_URL = '/api'
+1 -2
View File
@@ -1,4 +1,3 @@
NODE_ENV = 'remote'
VITE_APP_TITLE = '远程环境'
VITE_BASE_URL = 'https://skymail.ink/api'
VITE_PWA_NAME = 'Cloud Mail'
VITE_BASE_URL = 'https://mornglow.top/api'
+87 -129
View File
@@ -1,139 +1,97 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="theme-color" content="#F1F1F1" id="theme-color-meta">
<meta name="description" content="Cloud Mail 是一个 Serverless 响应式邮箱服务,支持邮件发送,可部署到 Cloudflare 平台,降低服务器成本。Cloud Mail is a serverless responsive email service that supports email sending and can be deployed on Cloudflare to reduce server costs.">
<title>Cloud Mail</title>
<link rel="icon" href="/public/mail.png" type="image/png">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script>
const uiStoreStr = localStorage.getItem('ui')
if (uiStoreStr) {
const uiStore = JSON.parse(uiStoreStr)
const root = document.documentElement
root.setAttribute('class', uiStore.dark ? 'dark' : '');
const metaTag = document.getElementById('theme-color-meta');
const isMobile = !window.matchMedia("(pointer: fine) and (hover: hover)").matches;
metaTag.setAttribute('content', uiStore.dark ? (isMobile ? '#141414' : '#000000') : (isMobile ? '#FFFFFF' : '#F1F1F1'));
}
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title></title>
<link rel="icon" href="./src/assets/favicon.svg" type="image/svg+xml">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<style>
html {
background: #FFFFFF;
}
.dark {
background: #141414;
}
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 500;
background: var(--el-bg-color);
}
.loading-hide {
pointer-events: none;
opacity: 0;
}
.loading-icon {
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
}
.loading-image {
width: 70px;
height: 70px;
object-fit: contain;
}
.loading-progress {
position: relative;
width: 64px;
height: 4px;
overflow: hidden;
border-radius: 999px;
background: rgba(64, 158, 255, 0.18);
}
.loading-progress::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: inherit;
background: #409EFF;
transform: scaleX(0);
transform-origin: left center;
animation: loading-progress-grow 2.4s linear forwards;
}
.loading-progress::after {
content: "";
position: absolute;
top: 0;
width: 24px;
height: 100%;
border-radius: inherit;
background: rgba(64, 158, 255, 0.45);
filter: blur(4px);
transform: translateX(-24px);
animation: loading-progress-peg 2.4s linear forwards;
}
.loading-complete .loading-progress::before {
animation: none;
transform: scaleX(1);
transition: transform 200ms linear;
}
.loading-complete .loading-progress::after {
animation: none;
transform: translateX(60px);
transition: transform 200ms linear;
}
@keyframes loading-progress-grow {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
@keyframes loading-progress-peg {
0% {
transform: translateX(-24px);
}
100% {
transform: translateX(60px);
}
}
</style>
<body>
<div id="loading-first" >
<div class="loading-icon">
<img class="loading-image" src="/mail-pwa.png" alt="Cloud Mail">
<div class="loading-progress" aria-hidden="true"></div>
</div>
<div id="loading-first">
<div class="loading-icon">
<svg class="circular" viewBox="0 0 20 20">
<g class="loading-path">
<circle r="3.375" class="dot1" rx="0" ry="0" />
<circle r="3.375" class="dot2" rx="0" ry="0" />
<circle r="3.375" class="dot4" rx="0" ry="0" />
<circle r="3.375" class="dot3" rx="0" ry="0" />
</g>
</svg>
</div>
</div>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<style>
#loading-first {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
z-index: 500;
}
.loading-icon {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.circular {
height: 30px;
width: 30px;
animation: loading-rotate 1s linear infinite;
}
.loading-path .dot1 {
transform: translate(3.75px, 3.75px);
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
}
.loading-path .dot2 {
transform: translate(calc(100% - 3.75px), 3.75px);
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.4s;
}
.loading-path .dot3 {
transform: translate(3.75px, calc(100% - 3.75px));
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 1.2s;
}
.loading-path .dot4 {
transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
fill: #409EFF;
animation: custom-spin-move 1s infinite linear alternate;
opacity: 0.3;
animation-delay: 0.8s;
}
@keyframes loading-rotate {
to {
transform: rotate(360deg);
}
}
@keyframes custom-spin-move {
to {
opacity: 1;
}
}
</style>
-8
View File
@@ -1,8 +0,0 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}
+3899
View File
File diff suppressed because it is too large Load Diff
+3 -8
View File
@@ -7,23 +7,19 @@
"dev": "vite --mode dev",
"remote": "vite --mode remote",
"build": "vite build --mode release",
"eo": "vite build --mode eo",
"preview": "vite preview"
},
"dependencies": {
"@iconify/vue": "^4.3.0",
"@simplewebauthn/browser": "^13.3.0",
"@vueuse/components": "^14.1.0",
"@vueuse/core": "^12.0.0",
"axios": "1.15.2",
"axios": "^1.7.8",
"compressorjs": "^1.2.1",
"date-time-format-timezone": "^1.0.22",
"dayjs": "^1.11.13",
"dexie": "^4.0.11",
"echarts": "^5.6.0",
"element-plus": "^2.13.1",
"element-plus": "^2.9.11",
"lodash-es": "^4.17.21",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.2.0",
@@ -38,7 +34,6 @@
"terser": "^5.39.0",
"unplugin-auto-import": "^19.3.0",
"unplugin-vue-components": "^28.7.0",
"vite": "7.1.5",
"vite-plugin-pwa": "^1.0.3"
"vite": "6.3.4"
}
}
-5244
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -1,6 +0,0 @@
/assets/*
Cache-Control: public, max-age=31556952, immutable
/tinymce/*
Cache-Control: public, max-age=604800, immutable
/image/*
Cache-Control: public, max-age=604800, immutable
Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

-55
View File
@@ -1,55 +0,0 @@
.tox-dialog__body-content {
margin: 0 !important;
}
img {
max-width: 100% !important;
height: auto !important;
}
p {
margin: 0 !important;
}
a {
text-decoration: none;
color: #0E70DF;
}
body {
margin: 10px 8px 0 5px !important;
font-size: 14px;
}
:root {
--scrollbar-thumb-color: #FFFFFF;
--scrollbar-track-color: #A8ABB2;
}
.mceNonEditable {
color: #303133;
background: #FFFFFF;
}
@media (pointer: fine) and (hover: hover) {
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: var(--scrollbar-track-color);
}
::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb-color);
border-radius: 10px;
cursor: pointer;
}
}
.mce-item-table:not([border]), .mce-item-table:not([border]) caption, .mce-item-table:not([border]) td, .mce-item-table:not([border]) th, .mce-item-table[border="0"], .mce-item-table[border="0"] caption, .mce-item-table[border="0"] td, .mce-item-table[border="0"] th, table[style*="border-width: 0px"], table[style*="border-width: 0px"] caption, table[style*="border-width: 0px"] td, table[style*="border-width: 0px"] th {
border: none;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-21
View File
@@ -1,21 +0,0 @@
Below is a list of third party libraries that this software uses:
----------------------------------------------------------------
dompurify - Patched by Tiny
owner: Mario Heiderich
repo: https://github.com/cure53/DOMPurify
version: 3.2.4
license: MPL-2.0 OR Apache-2.0
prismjs
owner: Lea Verou
repo: https://github.com/PrismJS/prism
version: 1.25.0
license: MIT
prism-themes
owner: Lea Verou
repo: https://github.com/PrismJS/prism-themes
version: 1.9.0
license: MIT
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -1 +1,4 @@
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:"OL"===l?3:4,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,disc,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);class o{constructor(t,e){this.tag=t,this.value=e}static some(t){return new o(!0,t)}static none(){return o.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?o.some(t(this.value)):o.none()}bind(t){return this.tag?t(this.value):o.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:o.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?o.some(t):o.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}o.singletonNone=new o(!1);const a=Array.prototype.indexOf,u=Object.keys;var d=tinymce.util.Tools.resolve("tinymce.util.Tools");const c=t=>e=>i(e)&&t.test(e.nodeName),h=c(/^(OL|UL|DL)$/),g=c(/^(TH|TD)$/),p=t=>l(t)||"default"===t?"":t,m=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;e<n;e++){const n=t[e];if(h(r=n)&&!/\btox\-/.test(r.className))return o.some(n);if(s(n,e))break}var r;return o.none()})(e,0,g).exists((e=>e.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)||!t.selection.isEditable()})(t,n))})(t,r.parents))),v=(t,s,r,n,l,i)=>{const c={"lower-latin":"lower-alpha","upper-latin":"upper-alpha","lower-alpha":"lower-latin","upper-alpha":"upper-latin"},h=(g=t=>{return e=i,s=t,a.call(e,s)>-1;var e,s},((t,e)=>{const s={};return((t,e)=>{const s=u(t);for(let r=0,n=s.length;r<n;r++){const n=s[r];e(t[n],n)}})(t,((t,r)=>{const n=e(t,r);s[n.k]=n.v})),s})(c,((t,e)=>({k:e,v:g(t)}))));var g;t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(d.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=p(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return o.from(s)})(t);return s.exists((t=>e===t||c[t]===e&&!h[e]))},onSetup:m(t,l)})},y=(t,s,r,n,l,i)=>{i.length>1?v(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:m(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,p(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{y(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),y(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the List Styles plugin.")}))}();
+3
View File
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>e.options.get("allow_html_in_named_anchor");const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}();
+4 -1
View File
@@ -1 +1,4 @@
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e);const n=e=>undefined===e;const o=e=>!(e=>null==e)(e),r=Object.hasOwnProperty,a=e=>"\ufeff"===e,s=e=>t=>t.options.get(e),l=s("autolink_pattern"),i=s("link_default_target"),c=s("link_default_protocol"),d=s("allow_unsafe_link_target");var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!a(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=l(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),r.call(t,n))||"false"===i.getContentEditable(e)||null!==i.getParent(e,"a[href]");var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return P="www.",(b=t).length>=4&&b.substr(0,4)===P?t=c(e)+"://"+t:((e,t,o=0,r)=>{const a=e.indexOf(t,o);return-1!==a&&(!!n(r)||a+t.length<=r)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,P;return null},k=(e,n)=>{const{dom:o,selection:r}=e,{rng:a,url:s}=n,l=r.getBookmark();r.setRng(a);const c="createlink",u={command:c,ui:!1,value:s};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(c,!1,s),e.dispatch("ExecCommand",u);const n=i(e);if(t(n)){const t=r.getNode();o.setAttrib(t,"target",n),"_blank"!==n||d(e)||o.setAttrib(t,"rel","noopener")}}r.moveToBookmark(l),e.nodeChanged()},p=e=>{const t=m(e,-1);o(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);o(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e);const l=e=>undefined===e;const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]")||e.mode.isReadOnly())return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=4&&b.substr(0,4)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),n=o("min_height"),s=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),g=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},l=(e,t,o,n)=>{var s;const i=parseInt(null!==(s=e.getStyle(t,o,n))&&void 0!==s?s:"",10);return isNaN(i)?0:i},a=(e,o,r,c)=>{var d;const u=e.dom,h=e.getDoc();if(!h)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void g(e,!0);const m=h.documentElement,f=c?c():i(e),p=null!==(d=n(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=l(u,m,"margin-top",!0),v=l(u,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+f;C<0&&(C=0);const H=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+H>p&&(y=C+H);const b=s(e);b&&y>b?(y=b,g(e,!0)):g(e,!1);const w=o.get();if(w.set&&(e.dom.setStyles(e.getDoc().documentElement,{"min-height":0}),e.dom.setStyles(e.getBody(),{"min-height":"inherit"})),y!==w.totalHeight&&(C-f!==w.contentHeight||!w.set)){const n=y-w.totalHeight;if(u.setStyle(e.getContainer(),"height",y+"px"),o.set({totalHeight:y,contentHeight:C,set:!0}),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&n<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(()=>{let e={totalHeight:0,contentHeight:0,set:!1};return{get:()=>e,set:t=>{e=t}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{const n=()=>r(e);e.on("init",(s=>{const r=i(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,s,n)})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{a(e,o,t,n)}))})(e,o)}}))}();
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t);const r=t=>undefined===t;var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},y=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},g=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{const r=()=>f(t)&&!t.mode.isReadOnly();e.setEnabled(r());const o=()=>e.setEnabled(r());return t.on("StoreDraft RestoreDraft RemoveDraft",o),()=>t.off("StoreDraft RestoreDraft RemoveDraft",o)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{y(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{g(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&g(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>y(t),restoreDraft:()=>g(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}();
File diff suppressed because one or more lines are too long
+3
View File
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}();
File diff suppressed because one or more lines are too long
@@ -1 +1,4 @@
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,r=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(n=String).prototype.isPrototypeOf(r)||(null===(i=o.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var r,o,n,i})(t),o=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1),Array.prototype.slice;const u=(t,e)=>{for(let r=0,o=t.length;r<o;r++)e(t[r],r)};i(Array.from)&&Array.from;const c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const r=t.dom;if(1!==r.nodeType)return!1;{const t=r;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}},m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=t=>d(t.dom.host),p=(t,e)=>{t.dom.removeAttribute(e)},w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const r=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(r=e)&&n(r.dom.host)?a.some(e):a.none();var r})(d(e)).fold((()=>r.body.contains(e)),(o=w,i=y,t=>o(i(t))));var o,i},b=t=>"rtl"===((t,e)=>{const r=t.dom,o=window.getComputedStyle(r).getPropertyValue(e);return""!==o||w(t)?o:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(r,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const r=[];for(let o=0,n=t.length;o<n;o++){const n=t[o];e(n,o)&&r.push(n)}return r})(((t,e)=>{const r=t.length,o=new Array(r);for(let n=0;n<r;n++){const r=t[n];o[n]=e(r,n)}return o})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(r=t,o="ol,ul",((t,e,r)=>{let n=t.dom;const s=i(r)?r:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,o))return a.some(t);if(s(t))break}return a.none()})(r,0,n)):a.some(t)).getOr(t);var r,o,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?p(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(r(n)||o(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{p(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>r=>{const o=o=>{const n=d(o.element);r.setActive(b(n)===e),r.setEnabled(t.selection.isEditable())};return t.on("NodeChange",o),r.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",o)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=()=>false;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o<r;o++)e(t[o],o)},c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},p=t=>d(t.dom.host),w=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=(t=>d(t.dom.getRootNode()))(t);return v(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=w,i=p,t=>r(i(t))));var r,i},b=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||w(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",S=(t,e)=>(t=>((t,e)=>{const o=[];for(let r=0,n=t.length;r<n;r++){const n=t[r];e(n,r)&&o.push(n)}return o})(((t,e)=>{const o=t.length,r=new Array(o);for(let n=0;n<o;n++){const o=t[n];r[n]=e(o,n)}return r})(t.dom.childNodes,d),(t=>h(t,e))))(t),N=t=>g(t)&&"li"===t.dom.nodeName.toLowerCase();const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?y(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{y(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(b(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -1 +1,4 @@
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=e=>"function"==typeof e;Array.prototype.slice;const c=Array.prototype.push;n(Array.from)&&Array.from;var i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),l=tinymce.util.Tools.resolve("tinymce.EditorManager"),a=tinymce.util.Tools.resolve("tinymce.Env"),p=tinymce.util.Tools.resolve("tinymce.util.Tools");const u=e=>t=>t.options.get(e),m=u("importcss_merge_classes"),f=u("importcss_exclusive"),y=u("importcss_selector_converter"),d=u("importcss_selector_filter"),h=u("importcss_groups"),g=u("importcss_append"),_=u("importcss_file_filter"),v=u("skin"),b=u("skin_url"),x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=p.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),m(e)?s.classes=n:s.attributes={class:n},s},A=(e,t)=>null===t||f(e),k=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s<r;++s){if(!o(e[s]))throw new Error("Arr.flatten item "+s+" was not an array, input: "+e);c.apply(t,e[s])}return t})(((e,t)=>{const s=e.length,r=new Array(s);for(let o=0;o<s;o++){const s=e[o];r[o]=t(s,o)}return r})(r,n))).concat(e);var r,n}}})(),r={},n=T(d(e)),u=(e=>p.map(e,(e=>p.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(h(e)),m=(t,s)=>{if(((e,t,s,r)=>!(A(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{A(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=y(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||i.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};p.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let i,u=t.href;if(u=(e=>{const t=a.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=v(e);if(s){const r=b(e),o=r?e.documentBaseURI.toAbsolute(r):l.baseURL+"/skins/ui/"+s,n=l.baseURL+"/skins/content/",c=e.editorManager.suffix;return t===o+"/content"+(e.inline?".inline":"")+`${c}.css`||-1!==t.indexOf(n)}return!1})(e,u)){p.each(t.imports,(e=>{c(e,!0)}));try{i=t.cssRules||t.rules}catch(e){}p.each(i,(e=>{e.styleSheet&&e.styleSheet?c(e.styleSheet,!0):e.selectorText&&p.each(e.selectorText.split(","),(e=>{o.push(p.trim(e))}))}))}};p.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{p.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>p.grep(e,(e=>!e.filter||e.filter(t))))(u,e);if(s.length>0)p.each(s,(s=>{const r=m(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=m(e,null);s&&t.addItem(s)}}}));const f=t.toFormats();e.dispatch("addStyleModifications",{items:f,replace:!g(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),k(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=e=>"function"==typeof e;var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),g=p("importcss_file_filter"),_=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),M=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s<r;++s){if(!o(e[s]))throw new Error("Arr.flatten item "+s+" was not an array, input: "+e);b.apply(t,e[s])}return t})(((e,t)=>{const s=e.length,r=new Array(s);for(let o=0;o<s;o++){const s=e[o];r[o]=t(s,o)}return r})(r,n))).concat(e);var r,n}}})(),r={},n=T(y(e)),p=(e=>a.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=_(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/",c=e.editorManager.suffix;return t===o+"/content"+(e.inline?".inline":"")+`${c}.css`||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet&&e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(g(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),M(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),n=t("insertdatetime_timeformat"),r=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length<t)for(let a=0;a<t-e.length;a++)e="0"+e;return e},d=(e,t,a=new Date)=>(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)&&e.selection.isEditable()){const a=d(e,t);let n;n=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const r=e.dom.getParent(e.selection.getStart(),"time");r?((e,t,a,n)=>{const r=e.dom.create("time",{datetime:a},n);e.dom.replace(r,t),e.selection.select(r,!0),e.selection.collapse(!1)})(e,r,n,a):e.insertContent('<time datetime="'+n+'">'+a+"</time>")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");const g=e=>t=>{const a=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",a),a(),()=>{e.off("NodeChange",a)}};e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,n)=>{u(e,null!=n?n:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:n(e))}))})(e),(e=>{const t=r(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=r(e);return t.length>0?t[0]:n(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)},onSetup:g(e)});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)}))),onSetup:g(e)})})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=n=>e=>typeof e===n,o=e("boolean"),a=e("number"),t=n=>e=>e.options.get(n),i=t("nonbreaking_force_tab"),s=t("nonbreaking_wrap"),r=(n,e)=>{let o="";for(let a=0;a<e;a++)o+=n;return o},c=(n,e)=>{const o=s(n)||n.plugins.visualchars?`<span class="${(n=>!!n.plugins.visualchars&&n.plugins.visualchars.isEnabled())(n)?"mce-nbsp-wrap mce-nbsp":"mce-nbsp-wrap"}" contenteditable="false">${r("&nbsp;",e)}</span>`:r("&nbsp;",e);n.undoManager.transact((()=>n.insertContent(o)))};var l=tinymce.util.Tools.resolve("tinymce.util.VK");const u=n=>e=>{const o=()=>{e.setEnabled(n.selection.isEditable())};return n.on("NodeChange",o),o(),()=>{n.off("NodeChange",o)}};n.add("nonbreaking",(n=>{(n=>{const e=n.options.register;e("nonbreaking_force_tab",{processor:n=>o(n)?{value:n?3:0,valid:!0}:a(n)?{value:n,valid:!0}:{valid:!1,message:"Must be a boolean or number."},default:!1}),e("nonbreaking_wrap",{processor:"boolean",default:!0})})(n),(n=>{n.addCommand("mceNonBreaking",(()=>{c(n,1)}))})(n),(n=>{const e=()=>n.execCommand("mceNonBreaking");n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:e,onSetup:u(n)}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:e,onSetup:u(n)})})(n),(n=>{const e=i(n);e>0&&n.on("keydown",(o=>{if(o.keyCode===l.TAB&&!o.isDefaultPrevented()){if(o.shiftKey)return;o.preventDefault(),o.stopImmediatePropagation(),c(n,e)}}))})(n)}))}();
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env");const t=e=>a=>a.options.get(e),n=t("pagebreak_separator"),o=t("pagebreak_split_block"),r="mce-pagebreak",s=e=>{const t=`<img src="${a.transparentSrc}" class="${r}" data-mce-resize="false" data-mce-placeholder />`;return e?`<p>${t}</p>`:t},c=e=>a=>{const t=()=>{a.setEnabled(e.selection.isEditable())};return e.on("NodeChange",t),t(),()=>{e.off("NodeChange",t)}};e.add("pagebreak",(e=>{(e=>{const a=e.options.register;a("pagebreak_separator",{processor:"string",default:"\x3c!-- pagebreak --\x3e"}),a("pagebreak_split_block",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mcePageBreak",(()=>{e.insertContent(s(o(e)))}))})(e),(e=>{const a=()=>e.execCommand("mcePageBreak");e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:a,onSetup:c(e)}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:a,onSetup:c(e)})})(e),(e=>{const a=n(e),t=()=>o(e),c=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,(e=>"\\"+e)),"gi");e.on("BeforeSetContent",(e=>{e.content=e.content.replace(c,s(t()))})),e.on("PreInit",(()=>{e.serializer.addNodeFilter("img",(n=>{let o,s,c=n.length;for(;c--;)if(o=n[c],s=o.attr("class"),s&&-1!==s.indexOf(r)){const n=o.parent;if(n&&e.schema.getBlockElements()[n.name]&&t()){n.type=3,n.value=a,n.raw=!0,o.remove();continue}o.type=3,o.value=a,o.raw=!0}}))}))})(e),(e=>{e.on("ResolveName",(a=>{"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,r)&&(a.name="pagebreak")}))})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3
View File
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const o=e=>"function"==typeof e;var t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),n=tinymce.util.Tools.resolve("tinymce.util.Tools");const a=e=>o=>o.options.get(e),c=a("save_enablewhendirty"),i=a("save_onsavecallback"),s=a("save_oncancelcallback"),r=(e,o)=>{e.notificationManager.open({text:o,type:"error"})},l=e=>o=>{const t=()=>{o.setEnabled(!c(e)||e.isDirty())};return t(),e.on("NodeChange dirty",t),()=>e.off("NodeChange dirty",t)};e.add("save",(e=>{(e=>{const o=e.options.register;o("save_enablewhendirty",{processor:"boolean",default:!0}),o("save_onsavecallback",{processor:"function"}),o("save_oncancelcallback",{processor:"function"})})(e),(e=>{e.ui.registry.addButton("save",{icon:"save",tooltip:"Save",enabled:!1,onAction:()=>e.execCommand("mceSave"),onSetup:l(e),shortcut:"Meta+S"}),e.ui.registry.addButton("cancel",{icon:"cancel",tooltip:"Cancel",enabled:!1,onAction:()=>e.execCommand("mceCancel"),onSetup:l(e)}),e.addShortcut("Meta+S","","mceSave")})(e),(e=>{e.addCommand("mceSave",(()=>{(e=>{const n=t.DOM.getParent(e.id,"form");if(c(e)&&!e.isDirty())return;e.save();const a=i(e);if(o(a))return a.call(e,e),void e.nodeChanged();n?(e.setDirty(!1),n.onsubmit&&!n.onsubmit()||("function"==typeof n.submit?n.submit():r(e,"Error: Form submit field collision.")),e.nodeChanged()):r(e,"Error: No form element found.")})(e)})),e.addCommand("mceCancel",(()=>{(e=>{const t=n.trim(e.startContent),a=s(e);o(a)?a.call(e,e):e.resetContent(t)})(e)}))})(e)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1,4 @@
/**
* TinyMCE version 7.8.0 (TBD)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const o=(t,o,e)=>{t.dom.toggleClass(t.getBody(),"mce-visualblocks"),e.set(!e.get()),((t,o)=>{t.dispatch("VisualBlocks",{state:o})})(t,e.get())},e=t=>t.options.get("visualblocks_default_state");const s=(t,o)=>e=>{e.setActive(o.get());const s=t=>e.setActive(t.state);return t.on("VisualBlocks",s),()=>t.off("VisualBlocks",s)};t.add("visualblocks",((t,l)=>{(t=>{(0,t.options.register)("visualblocks_default_state",{processor:"boolean",default:!1})})(t);const a=(()=>{let t=!1;return{get:()=>t,set:o=>{t=o}}})();((t,e,s)=>{t.addCommand("mceVisualBlocks",(()=>{o(t,0,s)}))})(t,0,a),((t,o)=>{const e=()=>t.execCommand("mceVisualBlocks");t.ui.registry.addToggleButton("visualblocks",{icon:"visualblocks",tooltip:"Show blocks",onAction:e,onSetup:s(t,o),context:"any"}),t.ui.registry.addToggleMenuItem("visualblocks",{text:"Show blocks",icon:"visualblocks",onAction:e,onSetup:s(t,o),context:"any"})})(t,a),((t,s,l)=>{t.on("PreviewFormats AfterPreviewFormats",(o=>{l.get()&&t.dom.toggleClass(t.getBody(),"mce-visualblocks","afterpreviewformats"===o.type)})),t.on("init",(()=>{e(t)&&o(t,0,l)}))})(t,0,a)}))}();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/dark/content.css', `body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}`)
+1 -10
View File
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{background-color: #141414;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/default/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/document/content.css', `@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/tinymce-5-dark/content.css', `body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}`)
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/tinymce-5/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
tinymce.Resource.add('content/writer/content.css', `body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}`)
@@ -1,10 +1 @@
/* This file is bundled with the code from the following third party libraries */
/**
* http://prismjs.com/
* Dracula Theme originally by Zeno Rocha [@zenorocha]
* https://draculatheme.com/
*
* Ported for PrismJS by Albert Vallverdu [@byverdu]
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More