-
wordpress的每日60秒一堆不靠谱的
刚刚去下载了一个发现各种报错,而且拿回来的图片1MB多,对带宽小的服务器来说是致命打击。 接口就不提供了,自己找一找吧,这个网上很多免费的。 发现有个bug,直接往 $wpdb->posts 写记录,绕过了 WordPress 的发布流程,因此 没有触发 wp_insert_post() 等钩子 会导致明明发布了却显示404 重新改了一下: <?php /** * 获取每天60秒读懂世界的内容并发布到WordPress * 修复了数组访问和文件处理的错误 */ // 获取API数据 $content = curl_get('API接口'); // 调试:输出原始返回内容 if ($content === false) { die('cURL请求失败,无法获取API数据'); } // 调试:检查返回内容 if (empty($content)) { die('API返回内容为空'); } $data = json_decode($content, true); // 调试:检查JSON解析 if (json_last_error() !== JSON_ERROR_NONE) { die('JSON解析失败: ' . json_last_error_msg() . ',原始内容: ' . substr($content, 0, 500)); } // 检查数据是否有效 if (!$data || !is_array($data)) { die('API返回数据格式无效,原始内容: ' . substr($content, 0, 500)); } // 检查是否有必要的字段 if (!isset($data['code'])) { die('API返回数据格式错误:缺少code字段'); } // 调试:输出code值和类型 // echo 'API返回的code值: ' . $data['code'] . ',类型: ' . gettype($data['code']) . '<br>'; // 检查API返回状态 if ($data['code'] !== 200 && $data['code'] !== '200') { // API返回错误或数据未更新 echo 'API返回错误或数据未更新,状态码:' . $data['code']; if (isset($data['msg'])) { echo ',错误信息:' . $data['msg']; } } else { // 验证必要字段是否存在 if (!isset($data['image']) || !isset($data['title']) || !isset($data['data'])) { die('API返回数据格式错误:缺少必要字段'); } $head_img = $data['image']; // 检查图片URL是否有效 if (empty($head_img) || !filter_var($head_img, FILTER_VALIDATE_URL)) { die('图片URL无效'); } $ext = pathinfo($head_img, PATHINFO_EXTENSION); // 如果无法获取扩展名,使用默认扩展名 if (empty($ext)) { $ext = 'jpg'; } $rand_name = date("Ymd") . '.' . $ext; if (is_dir('60s') == false) { mkdir('60s', 0777, true); } // 获取图片内容并检查是否成功 $image_content = file_get_contents($head_img); if ($image_content === false) { die('无法下载图片'); } // 压缩图片以减少文件大小和带宽消耗 $compressed_image = compress_image($image_content, $ext); if ($compressed_image…... -
吾今有世家存档修改器 Python版本
内容已失效,年代久远,后续没再继续玩了。 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 吾今有世家游戏存档修改器 用于修改GameData.es3文件中的游戏数据 作者: SnowZ 版本: 2.3.1 日期: 2025 """ import json import tkinter as tk from tkinter import ttk, filedialog, messagebox, scrolledtext import os import shutil from datetime import datetime class SaveEditor: """ 游戏存档修改器主类 提供图形界面来修改ES3格式的存档文件 """ def __init__(self): """ 初始化修改器界面和数据 """ self.root = tk.Tk() self.root.title("吾今有世家 - 游戏存档修改器 v2.3.1") self.root.geometry("1200x800") self.root.resizable(True, True) # 存档数据 self.game_data = None self.save_file_path = "" # 创建界面 self.create_widgets() # 尝试自动加载当前目录的GameData.es3 default_save = os.path.join(os.getcwd(), "GameData.es3") if os.path.exists(default_save): self.load_save_file(default_save) def create_widgets(self): """ 创建主界面组件 """ # 创建菜单栏 self.create_menu() # 创建主框架 main_frame = ttk.Frame(self.root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) # 创建选项卡控件 self.notebook = ttk.Notebook(main_frame) self.notebook.pack(fill=tk.BOTH, expand=True) # 创建各个功能选项卡 self.create_character_tab() # 人物信息 self.create_family_tab() # 家族信息 self.create_noble_tab() # 世家信息 self.create_fief_tab() # 封地信息 self.create_military_tab() # 军事信息 self.create_economy_tab() # 经济信息 self.create_raw_data_tab() # 原始数据 # 状态栏 self.status_var = tk.StringVar() self.status_var.set("就绪 - 请加载存档文件") status_bar = ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN) status_bar.pack(side=tk.BOTTOM, fill=tk.X, pady=(5, 0)) def create_menu(self): """ 创建菜单栏 """ menubar = tk.Menu(self.root) self.root.config(menu=menubar) # 文件菜单 file_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="文件(F)", menu=file_menu) file_menu.add_command(label="打开存档(O)", command=self.open_save_file, accelerator="Ctrl+O") file_menu.add_command(label="保存存档(S)", command=self.save_file, accelerator="Ctrl+S") file_menu.add_command(label="另存为(A)", command=self.save_as_file, accelerator="Ctrl+Shift+S") file_menu.add_separator() file_menu.add_command(label="备份存档(B)", command=self.backup_save_file) file_menu.add_separator() file_menu.add_command(label="退出(X)", command=self.root.quit) # 工具菜单 tools_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="工具(T)", menu=tools_menu) tools_menu.add_command(label="验证数据完整性", command=self.validate_data) tools_menu.add_command(label="重置所有修改", command=self.reset_all_changes) # 帮助菜单 help_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="帮助(H)", menu=help_menu) help_menu.add_command(label="使用说明", command=self.show_help) help_menu.add_command(label="关于", command=self.show_about)…... -
jsdelivr npm CDN 国内加速节点
jsdelivr 节点:常用于加速 GitHub/npm 项目,可通过更改节点改善项目在国内的可用性。 gcore.jsdelivr.netGcore 节点可用性高testingcf.jsdelivr.netCloudflare 节点可用性高quantil.jsdelivr.netQuantil 节点可用性尚可fastly.jsdelivr.netFastly 节点可用性尚可originfastly.jsdelivr.netFastly 节点可用性低test1.jsdelivr.netCloudflare 节点可用性低cdn.jsdelivr.net通用节点可用性低 第三方提供的 jsdelivr 节点 jsd.cdn.zzko.cn国内 CDNjsd.onmicrosoft.cn国内 CDNjsdelivr.b-cdn.net台湾 CDNcdn.jsdelivr.usAnycast 这两个节点国内速度很快,不清楚稳定性。 npm 节点:unpkg.com 国内几乎不可用,可用下方国内 cdn 节点。 npm.elemecdn.com饿了么同步快,缺的多npm.onmicrosoft.cn公益需准确的版本号unpkg.zhimg.com知乎同步慢npm.akass.cn公益需准确的版本号cdn.chuqis.com/npm/公益需准确的版本号code.bdstatic.com/npm百度仅同步热门包... -
umami mysql版本更新到2.18 check-db报错解决
升级到 2.18.0 后,Umami 由于 09_update_hostname_region 迁移失败而无法启动。 在 DB 容器内的 SQL shell 中使用以下 SQL 命令: UPDATE _prisma_migrations SET finished_at = NOW(), logs = NULL, applied_steps_count = 1 WHERE migration_name = '09_update_hostname_region'; Prisma 迁移过程中可能因数据库权限、表结构冲突或版本兼容性问题导致状态卡住。... -
如何在宝塔面板中更新 SearXNG(Python 项目)
我个人其实不喜欢使用docker的方式部署项目,万不得已需要非常多的依赖环境的时候,会优先选择使用docker,网上搜来搜去全是部署的教程,一概没有提到如何更新的。这里安装的步骤就不说了,我只记录更新的步骤,之前是记得的,最近去忙别的项目太久了,以至于忘了,所以在这里记录一下。 本文将详细介绍如何在宝塔面板中非 Docker 部署的环境下,更新 SearXNG 项目。适用于使用 uWSGI、Nginx 或 Apache 部署的 Python 项目。 前提条件 已通过宝塔面板部署 SearXNG 项目。 熟悉宝塔面板基本操作(如启动/停止服务)。 具备基础 Linux 命令行操作能力。 更新步骤 1. 停止 SearXNG 服务 在宝塔面板中: 进入「网站」→ 选择你的 SearXNG 项目 → 点击「停止」。 2. 备份重要文件 cd /www/wwwroot/your_searxng_path # 替换为实际路径 # 备份配置文件 cp settings.yml settings.yml.bak # 备份虚拟环境(可选) cp -r venv venv.bak 3. 拉取最新代码 # 添加安全目录(若首次出现权限警告) git config --global --add safe.directory /www/searxng # 获取最新代码 git pull origin master 到这步基本上结束了,你在Python项目的终端里退出,重启一下Python项目就可以看到更新了已经。如果报错的,可以看看下面的步骤。 20250802这个版本需要从gunicorn启动项目,以后应该不支持uwsgi 4. 更新 Python 依赖 # 升级 pip 并安装依赖 pip install -U pip pip install -U -r requirements.txt # 退出虚拟环境 deactivate 5. 更新前端资源 cd searx/static/themes/simple # 安装 Node.js 依赖 npm install # 编译前端资源 npm run build 6. 检查并修改配置文件 如果 settings.yml 有变更,手动合并 settings.yml.bak 和新版本的配置。 确保数据库、端口等配置正确。 7. 重启服务 在宝塔面板中: 进入「网站」→ 选择你的 SearXNG 项目 → 点击「启动」。 或通过修改 uwsgi 配置触发重启: touch uwsgi.ini # 修改时间戳以重启服务 验证更新 访问你的 SearXNG 站点(如 http://yourdomain.com)。 检查页面底部是否显示新版本号(如 SearXNG vX.Y.Z)。 测试搜索功能是否正常。 注意事项 定期备份:更新前务必备份 settings.yml 和虚拟环境。 官方文档:参考 SearXNG 官方更新日志 了解新版本变更。 权限问题:确保宝塔用户对项目目录有读写权限。 通过以上步骤,您可以安全地在宝塔面板中更新 SearXNG 项目。如遇问题,可通过备份快速回滚。... -
MaxKB 迁移教程(基于宝塔面板 Docker 环境)
一、迁移前准备工作 确保新旧服务器都已安装宝塔面板和 Docker :在新旧服务器上分别登录宝塔面板,检查 Docker 是否正常运行。可通过宝塔面板的 Docker 管理模块查看服务状态。 记录原始 MaxKB 配置信息 :包括容器名称、端口号(默认为 8080)、数据卷挂载路径(默认为 /root/.maxkb 和 /root/.python-packages)等,便于在新服务器上恢复原有配置。 二、在旧服务器上备份数据 进入旧服务器的宝塔面板,停止 MaxKB 容器 :在宝塔面板的 Docker 容器列表中找到 MaxKB 容器,点击 “停止” 按钮。 使用命令打包数据目录 : 打开旧服务器的终端,执行以下命令将 /root/.maxkb 和 /root/.python-packages 目录打包压缩: tar -czvf maxkb_backup.tar.gz /root/.maxkb /root/.python-packages 将打包好的 maxkb_backup.tar.gz 文件从旧服务器下载到本地,可通过宝塔面板的文件管理功能或使用 scp 命令进行传输。 三、在新服务器上准备环境 上传备份文件到新服务器 :将本地的 maxkb_backup.tar.gz 文件上传到新服务器的 /root 目录下,可使用宝塔面板的文件上传功能或 scp 命令,例如: scp /path/on/local/maxkb_backup.tar.gz root@新服务器IP:/root 解压备份文件 :在新服务器的终端中,执行以下命令解压备份文件: tar -xzvf maxkb_backup.tar.gz -C /root 这会将备份的数据解压到 /root/.maxkb 和 /root/.python-packages 目录下。 四、在新服务器上拉取 MaxKB 镜像并运行 拉取 MaxKB 官方镜像 :在新服务器的终端中,执行以下命令拉取最新的 MaxKB 镜像: docker pull registry.fit2cloud.com/maxkb/maxkb 运行 MaxKB 容器 :根据需要设置端口号(可修改为原本的端口或其他端口),执行以下命令启动 MaxKB 容器: docker run -d --name=maxkb --restart=always -p <新端口号>:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb 例如,若要使用原本的 8080 端口,命令为: docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb 五、验证迁移是否成功 在宝塔面板查看 MaxKB 容器状态 :登录新服务器的宝塔面板,进入 Docker 容器列表,检查 MaxKB 容器是否处于 “运行中” 状态。 通过浏览器访问 MaxKB 服务 :在浏览器中输入新服务器的 IP 地址和设置的端口号,例如 http://新服务器IP:8080,测试是否能正常访问 MaxKB 系统,登录后检查数据是否完整迁移。 六、注意事项 在迁移过程中,确保新旧服务器的网络连接正常,避免数据传输中断。 若需要修改 MaxKB 的配置文件(如端口号等),可在解压备份文件后,进入 /root/.maxkb 目录下查找相关配置文件进行修改,但需谨慎操作,修改完成后再启动容器。 迁移完成后,建议在旧服务器上清理已停止的 MaxKB 容器及相关镜像,以释放资源。可使用以下命令: docker stop maxkb docker rm maxkb docker rmi registry.fit2cloud.com/maxkb/maxkb 以上就是基于宝塔面板 Docker 环境的 MaxKB 迁移教程,按照步骤操作即可完成数据的迁移和新环境的搭建。... -
Docker 迁移 Gitea 到新的服务器
一、迁移前的准备 在新服务器上安装 Docker 和 Docker Compose: # 安装 Dockercurl -fsSL https://get.docker.com | sh# 安装 Docker Composesudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose 二、备份现有的 Gitea 数据 在旧服务器上备份 Gitea 数据(假设容器名 gitea,数据挂载在 /mnt/gitea): # 停止 Gitea 容器docker stop gitea# 备份数据卷mkdir ~/gitea_backupdocker cp gitea:/data ~/gitea_backup/# 压缩备份数据tar -czf ~/gitea_backup.tar.gz ~/gitea_backup 三、导出 Docker 镜像 导出 Gitea 镜像: # 查看镜像 IDdocker images# 导出镜像docker save -o ~/gitea_image.tar <gitea_image_id> 四、迁移到新服务器 将备份数据和镜像传输到新服务器: # 使用 scp 传输(替换相应 IP 和路径)scp ~/gitea_backup.tar.gz <new_server_ip>:/path/to/scp ~/gitea_image.tar <new_server_ip>:/path/to/ 五、在新服务器上恢复 Gitea 加载镜像并创建运行环境: # 加载镜像docker load -i /path/to/gitea_image.tar# 创建数据目录mkdir -p /mnt/gitea# 解压备份数据tar -xzf /path/to/gitea_backup.tar.gz -C ~/mv ~/gitea_backup/data/* /mnt/gitea/# 创建 docker-compose.ymlcat <<EOF > ~/docker-compose.ymlversion: '3'services: gitea: image: <your_gitea_image>:<tag> container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 volumes: - /mnt/gitea:/data ports: - "3000:3000" - "22:22" restart: alwaysEOF 启动 Gitea: cd ~docker-compose up -d 六、验证迁移结果 在浏览器访问新服务器的 IP 地址(如 http://<new_server_ip>:3000),确认 Gitea 正常运行。 七、结尾 通过以上步骤,您可以成功地将 Gitea 从旧服务器迁移到新服务器。在整个迁移过程中,确保备份数据的完整性和安全性至关重要。根据需要,您还可以调整 docker-compose.yml 文件中的配置参数,以优化 Gitea 的性能和可用性。 如果使用的MySQL是容器外的,记得给数据库上一个可以访问的权限,或开放3306端口。... -
苹果CMS一些数据处理记录
前几日因为删除了某一个分类,数据是已经删掉了,但是本地的图片数据还存在的,但是又不想把所有的图片全删了重建图片,于是想了个办法。 从数据库里把所有的封面图数据全部取出来,打印在一个txt文本里,然后跟图片目录下的图片文件做一个匹配筛选,如果不匹配则删除,这样就不会影响内容还在的图片内容。 使用的Python处理,直接把SQL下载到本地处理即可。 Python代码: import os import re import urllib.parse import configparser import argparse # 默认配置信息 DEFAULT_CONFIG = { 'SQL_FILE_PATH': 'f:\\code\\新建文件夹\\xxxx.sql', # SQL文件路径 'LOCAL_IMAGE_ROOT': 'f:\\code\\新建文件夹\\vod', # 本地图片根目录 'OUTPUT_TXT_PATH': 'f:\\code\\新建文件夹\\image_urls.txt', # 输出的TXT文件路径 'URL_DOMAIN': '123.com', # URL域名 'URL_PREFIX': 'mac://', # URL前缀 'URL_PATH_PREFIX': '/upload/vod/', # URL路径前缀 'LOCAL_PATH_PREFIX': '/vod' # 本地路径前缀 } # 全局配置变量 CONFIG = {} def load_config(config_file=None): """ 加载配置文件,如果配置文件不存在,则使用默认配置 """ global CONFIG CONFIG = DEFAULT_CONFIG.copy() if config_file and os.path.exists(config_file): try: parser = configparser.ConfigParser() parser.read(config_file, encoding='utf-8') if 'Settings' in parser: for key in DEFAULT_CONFIG: if key in parser['Settings']: CONFIG[key] = parser['Settings'][key] print(f"已从配置文件加载配置: {config_file}") except Exception as e: print(f"加载配置文件失败: {e},将使用默认配置") else: print("未指定配置文件或配置文件不存在,将使用默认配置") # 打印当前配置 print("当前配置:") for key, value in CONFIG.items(): print(f" {key}: {value}") def create_default_config(config_file): """ 创建默认配置文件 """ try: parser = configparser.ConfigParser() parser['Settings'] = DEFAULT_CONFIG with open(config_file, 'w', encoding='utf-8') as f: parser.write(f) print(f"已创建默认配置文件: {config_file}") return True except Exception as e: print(f"创建默认配置文件失败: {e}") return False def extract_urls_from_sql_file(): """ 从SQL文件中提取图片URL数据 """ urls = [] try: sql_file_path = CONFIG['SQL_FILE_PATH'] url_domain = CONFIG['URL_DOMAIN'] url_prefix = CONFIG['URL_PREFIX'] url_path_prefix = CONFIG['URL_PATH_PREFIX'] print(f"开始解析SQL文件: {sql_file_path}") # 使用正则表达式直接查找所有符合特定格式的URL # 动态构建正则表达式,使用配置中的域名和路径前缀 domain_escaped = url_domain.replace('.', '\\.') pattern = f"{url_prefix}{domain_escaped}{url_path_prefix}[^'\"]+" with open(sql_file_path, 'r', encoding='utf-8', errors='ignore') as file: content = file.read() matches = re.findall(pattern, content) for match in matches: # 将URL前缀替换为http://以便后续处理 url = match.replace(url_prefix, 'http://') urls.append(url) print(f"从SQL文件提取到…... -
Cloudflare 自选 IP 教程:配置 CDN 加速网站访问
前言 本文介绍如何通过 Cloudflare 自选 IP 节点来加速网站访问。虽然 Cloudflare CDN 提供丰富的免费资源,但在中国大陆访问速度较慢,甚至部分区域无法访问。通过选择合适的 CDN 节点,可以有效提升访问速度。此方法需满足以下条件: 启用 Cloudflare for SaaS,需使用信用卡(支持银联)或 PayPal 验证。 至少需要两个域名:一个加速域名(供用户访问),一个回源域名(解析到源服务器 IP,建议保密)。 加速域名建议接入支持分运营商解析的 DNS 服务商,如阿里云、DNSPOD、华为云等;回源域名接入 Cloudflare。 Cloudflare 添加回源域名 添加回源域名并配置 DNS 在 Cloudflare 账户中添加回源域名,采用 NS 接入。 生效后,进入域名设置 > DNS > 添加记录,按以下格式填写: 名称:根据需求填写子域名或留空(表示主域名)。 类型:选择 A 记录(IPv4 地址)。 内容:输入源服务器的 IP 地址。 代理状态:可选择开启或关闭 Cloudflare 代理,开启代理可隐藏源服务器 IP,增强安全性。 TTL:选择自动或自定义,自动模式下 Cloudflare 会根据缓存策略自动调整。 保存配置。 启用 Cloudflare for SaaS 点击左侧菜单中的 SSL/TLS > 自定义主机名,点击启用 Cloudflare For SaaS。 添加支付信息并开通。 在回退源中输入刚才解析的回源域名。 等待几十秒,配置显示回退源状态有效即可。 添加自定义主机名 点击“添加自定义主机名”,输入加速域名,其他选项保持默认。 确定添加。 配置加速域名的 DNS 解析 回到加速域名的 DNS 服务商,添加两条 TXT 解析记录。 名称和记录值按 Cloudflare 的要求填写(添加名称时需去掉 CF 提供名称后面的主域名)。 添加完成后等待几分钟刷新,当 Cloudflare 的证书和主机名状态变为有效即可。 Cloudflare 自选 IP 节点 选择最佳 CF 节点 IP 使用以下工具找到面向国内访问最佳的 Cloudflare 节点 IP,并定期检查自选 IP 是否可用: Cloudflare ST:功能强大,需下载对应系统和架构的可执行文件,分别使用不同网络测试。 Better Cloudflare IP:基于 bat 和 bash,简单通用,需分别使用不同网络测试。 CloudFlare 优质 IP 自动切换:每 15 分钟刷新针对三网不同线路的优质 Cloudflare IP。 配置加速域名解析记录 回到加速域名,添加解析记录: 默认请求来源:通过 CNAME 指向回源域名。 其他运营商:通过 A 记录解析到对应的 Cloudflare 节点 IP。 注意事项 源站应使用主域名的 SSL 证书,而非回源域名的 SSL 证书。 定期检查自选 IP 是否可用,若某个运营商的 IP 不可用,使用该运营商网络的用户将无法访问网站。 省流版: 准备两个域名:1.com 和 2.com 1.com需要在dnspod等平台解析。 2.com需要在cloudflare里使用。 在聚合DNS里面添加1.com做CF优选IP 将2.com解析到服务器IP 在CF里找到SSL/TLS自定义主机名,添加一个自定义主机名:1.com 然后在回退源里添加2.com即可... -
宝塔面板 Nginx启用Brotli
如果要让 Nginx 支持 Brotli 压缩 ,首先需要安装 [ngx_brotli 模块],具体方式如下: cd /www/servergit clone --recurse-submodules -j8 https://github.com/google/ngx_brotli 添加 ngx_brotli 编译参数 echo "--add-module=/www/server/ngx_brotli" > /www/server/panel/install/nginx_configure.pl 以上添加方式适合所有 Nginx 版本安装,且包括未来升级或切换 Nginx 版本无需再另行添加。 在宝塔面板软件商店中选择 Nginx 1.25 并点击编译安装即可。 配置 Brotli 压缩 在宝塔面板中,点开 Nginx 设置 > 配置修改,并搜索 gzip_disable 。 在这一行的下方插入以下内容: brotli on;brotli_comp_level 6; #压缩等级,默认6,最高11,高的压缩等级需要更多的CPUbrotli_buffers 16 8k; #请求缓冲区的数量和大小brotli_min_length 20; #指定压缩数据的最小字节数,只有大于或等于最小长度才会对其压缩。brotli_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml text/html application/json image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl image/x-icon image/jpeg image/gif image/png image/bmp application/vnd.api+json; #指定允许进行压缩类型brotli_static always; #是否允许查找预处理好的、以.br结尾的压缩文件,可选值为on、off、alwaysbrotli_window 512k; #窗口值,默认值为512k 保存并重启 Nginx 即可。 经过以上配置后,Nginx 将支持 Gzip 与 Brotli,浏览器支持 Brotli 的情况下,会默认启用 Brotli 压缩。...



