diff --git a/.gitignore b/.gitignore index fe04a06..b17a0e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ node_modules .s .DS_Store +src/code/filemgr +src/code/filemgr.zip nas \ No newline at end of file diff --git a/.signore b/.signore new file mode 100644 index 0000000..00a9acc --- /dev/null +++ b/.signore @@ -0,0 +1,10 @@ +.git +.github +hook + +src/nas +nas + +src/code/images +src/code/filemgr +src/code/filemgr.zip diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..804452c --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +include src/code/images/Makefile \ No newline at end of file diff --git a/publish-api.yaml b/publish-api.yaml deleted file mode 100644 index 702f8a6..0000000 --- a/publish-api.yaml +++ /dev/null @@ -1,131 +0,0 @@ -Type: Application -Name: fc-stable-diffusion-api -Provider: - - 阿里云 -Version: dev -Description: 使用serverless devs将stable-diffusion-api部署到阿里云函数计算上 -HomePage: https://github.com/OhYee/fc-stable-diffuson -Tags: #标签详情 - - 部署函数 -Category: Web框架 -Parameters: - type: object - additionalProperties: false # 不允许增加其他属性 - required: # 必填项 - - region - - serviceName - - functionName - - type - - nasEnabled - - webuiEnabled - - apiEnabled - - roleArn - - enableCollect - properties: - region: - title: 地域 - type: string - default: - description: 创建应用所在的地区。由于当前模板涉及 Github 以及 HuggingFace 等网站访问,国内部分地区可能无法直接使用,推荐您选择海外地区进行部署 - enum: - - cn-hangzhou - - ap-northeast-1 - - ap-southeast-1 - - cn-beijing - - cn-shanghai - - cn-shenzhen - serviceName: - title: 服务名 - type: string - default: fc-stable-diffusion-api - pattern: "^[a-zA-Z_][a-zA-Z0-9-_:/.]{0,127}$" - description: 您可以根据需要设置不同的服务名,同一个服务会共享部分第三方云产品资源 - functionName: - title: 函数名 - type: string - default: sd - pattern: "^[a-zA-Z_][a-zA-Z0-9-_:/.]{0,127}$" - description: 您可以根据需要多次创建该应用,通过函数名来区分出不同的镜像地址 - type: - title: 绘图类型 - type: string - default: 动漫风格 - description: |+ - 根据不同的绘图风格,将会自动为您选择不同的社区镜像以供测试。 - 注意: - 函数计算是 Serverless 架构形式的计算平台,所有的容器镜像、代码、参考示例、开源信息均为用户自行所有,不作为函数计算本身提供的服务; - 当前应用仅为案例,供使用者参考和学习使用,如果有生产使用需要,需要使用者自行完善和优化; - 当前应用会消耗 GPU 资源,购买 GPU 资源包可以降低您的使用成本。 - enum: - - SD1.5 - - 动漫风格 - - 真人风格 - - 轻量版 - nasEnabled: - title: 启用 NAS - type: boolean - default: true - description: |+ - 启用 NAS 将允许您上传自定义的模型、插件,提升 Stable Diffusion 自由度及可定制性。 - 启用 NAS 后将会为您自动创建 NAS 实例,并挂载至 /mnt/auto 目录,这可能会导致额外的费用。 - 与函数计算 Serverless 模式不同,NAS 属于存储产品,即使未读取仍然需要收取文件存储费用,建议搭配 NAS 资源包使用。 - - webuiEnabled: - title: 启用 WebUI 模式 - type: boolean - default: false - description: |+ - 将开启 webui 页面,您可以通过网页生成图片 - webuiAuth: - title: WebUI 鉴权 - type: string - pattern: "^([^:,]+:[^:,]+(,[^:,]+:[^:,]+)*)*$" - description: |+ - WebUI 鉴权,访问页面时需要进行鉴权操作,只有通过鉴权后才能进入界面,避免链接泄漏后导致额外费用。格式:“用户名:密码”,多个用户使用英文逗号分隔。留空不开启鉴权 - - apiEnabled: - title: 启用 API 模式 - type: boolean - default: true - description: |+ - 将开启 api 模式,可在 /docs 目录查看所有接口文档,并通过接口生成图片。 - apiAuth: - title: API 鉴权 - type: string - pattern: "^([^:,]+:[^:,]+(,[^:,]+:[^:,]+)*)*$" - description: |+ - API 鉴权,只有通过鉴权才能调用接口,避免链接泄漏后导致额外费用。格式:“用户名:密码”,多个用户使用英文逗号分隔。留空不开启鉴权 - - extraArgs: - title: Stable Diffusion 参数 - type: string - description: |+ - 您可以根据需要添加额外的 Stable Diffusion 参数。全部参数见 https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Command-Line-Arguments-and-Settings - - filemgrToken: - title: "FC 文件管理器密钥" - type: string - description: 用于管理 NAS 文件的文件管理器,配置密钥可以避免被恶意访问。留空则不进行鉴权。' - - roleArn: - title: RAM 角色 ARN - type: string - default: '' - pattern: '^acs:ram::[0-9]*:role/.*$' - description: | - 函数计算访问云服务时使用的服务角色,需要填写具体的角色ARN,格式为acs:ram::$account-id>:role/$role-name。例如:acs:ram::14310000000:role/aliyunfcdefaultrole。 - 如果您没有特殊要求,可以使用函数计算提供的默认的服务角色,即AliyunFCDefaultRole, 并增加 AliyunFCFullAccess 权限。如果您首次使用函数计算,可以访问 https://fcnext.console.aliyun.com 进行授权。 - 详细文档参考 https://help.aliyun.com/document_detail/181589.html#section-o93-dbr-z6o" - required: true - x-role: - name: fcdeployrole - service: fc - authorities: - - AliyunFCDefaultRolePolicy - - AliyunFCFullAccess - enableCollect: - title: 协助改善体验 - type: boolean - default: true - description: |+ - 通过开启该功能,可以将您的非敏感操作共享给我们,以便优化和改善应用。非敏感操作指 Stable Diffusion 使用、报错信息,不涉及提示词、参数、生成出的图片等敏感数据。 \ No newline at end of file diff --git a/publish-plus.yaml b/publish-plus.yaml deleted file mode 100644 index 4458d7a..0000000 --- a/publish-plus.yaml +++ /dev/null @@ -1,131 +0,0 @@ -Type: Application -Name: fc-stable-diffusion-plus -Provider: - - 阿里云 -Version: dev -Description: 使用serverless devs将stable-diffusion-plus部署到阿里云函数计算上 -HomePage: https://github.com/OhYee/fc-stable-diffuson -Tags: #标签详情 - - 部署函数 -Category: Web框架 -Parameters: - type: object - additionalProperties: false # 不允许增加其他属性 - required: # 必填项 - - region - - serviceName - - functionName - - type - - nasEnabled - - webuiEnabled - - apiEnabled - - roleArn - - enableCollect - properties: - region: - title: 地域 - type: string - default: - description: 创建应用所在的地区。由于当前模板涉及 Github 以及 HuggingFace 等网站访问,国内部分地区可能无法直接使用,推荐您选择海外地区进行部署 - enum: - - cn-hangzhou - - ap-northeast-1 - - ap-southeast-1 - - cn-beijing - - cn-shanghai - - cn-shenzhen - serviceName: - title: 服务名 - type: string - default: fc-stable-diffusion-plus - pattern: "^[a-zA-Z_][a-zA-Z0-9-_:/.]{0,127}$" - description: 您可以根据需要设置不同的服务名,同一个服务会共享部分第三方云产品资源 - functionName: - title: 函数名 - type: string - default: sd - pattern: "^[a-zA-Z_][a-zA-Z0-9-_:/.]{0,127}$" - description: 您可以根据需要多次创建该应用,通过函数名来区分出不同的镜像地址 - type: - title: 绘图类型 - type: string - default: 动漫风格 - description: |+ - 根据不同的绘图风格,将会自动为您选择不同的社区镜像以供测试。 - 注意: - 函数计算是 Serverless 架构形式的计算平台,所有的容器镜像、代码、参考示例、开源信息均为用户自行所有,不作为函数计算本身提供的服务; - 当前应用仅为案例,供使用者参考和学习使用,如果有生产使用需要,需要使用者自行完善和优化; - 当前应用会消耗 GPU 资源,购买 GPU 资源包可以降低您的使用成本。 - enum: - - SD1.5 - - 动漫风格 - - 真人风格 - - 轻量版 - nasEnabled: - title: 启用 NAS - type: boolean - default: true - description: |+ - 启用 NAS 将允许您上传自定义的模型、插件,提升 Stable Diffusion 自由度及可定制性。 - 启用 NAS 后将会为您自动创建 NAS 实例,并挂载至 /mnt/auto 目录,这可能会导致额外的费用。 - 与函数计算 Serverless 模式不同,NAS 属于存储产品,即使未读取仍然需要收取文件存储费用,建议搭配 NAS 资源包使用。 - - webuiEnabled: - title: 启用 WebUI 模式 - type: boolean - default: true - description: |+ - 将开启 webui 页面,您可以通过网页生成图片 - webuiAuth: - title: WebUI 鉴权 - type: string - pattern: "^([^:,]+:[^:,]+(,[^:,]+:[^:,]+)*)*$" - description: |+ - WebUI 鉴权,访问页面时需要进行鉴权操作,只有通过鉴权后才能进入界面,避免链接泄漏后导致额外费用。格式:“用户名:密码”,多个用户使用英文逗号分隔。留空不开启鉴权 - - apiEnabled: - title: 启用 API 模式 - type: boolean - default: false - description: |+ - 将开启 api 模式,可在 /docs 目录查看所有接口文档,并通过接口生成图片。 - apiAuth: - title: API 鉴权 - type: string - pattern: "^([^:,]+:[^:,]+(,[^:,]+:[^:,]+)*)*$" - description: |+ - API 鉴权,只有通过鉴权才能调用接口,避免链接泄漏后导致额外费用。格式:“用户名:密码”,多个用户使用英文逗号分隔。留空不开启鉴权 - - extraArgs: - title: Stable Diffusion 参数 - type: string - description: |+ - 您可以根据需要添加额外的 Stable Diffusion 参数。全部参数见 https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Command-Line-Arguments-and-Settings - - filemgrToken: - title: "FC 文件管理器密钥" - type: string - description: 用于管理 NAS 文件的文件管理器,配置密钥可以避免被恶意访问。留空则不进行鉴权。' - - roleArn: - title: RAM 角色 ARN - type: string - default: '' - pattern: '^acs:ram::[0-9]*:role/.*$' - description: | - 函数计算访问云服务时使用的服务角色,需要填写具体的角色ARN,格式为acs:ram::$account-id>:role/$role-name。例如:acs:ram::14310000000:role/aliyunfcdefaultrole。 - 如果您没有特殊要求,可以使用函数计算提供的默认的服务角色,即AliyunFCDefaultRole, 并增加 AliyunFCFullAccess 权限。如果您首次使用函数计算,可以访问 https://fcnext.console.aliyun.com 进行授权。 - 详细文档参考 https://help.aliyun.com/document_detail/181589.html#section-o93-dbr-z6o" - required: true - x-role: - name: fcdeployrole - service: fc - authorities: - - AliyunFCDefaultRolePolicy - - AliyunFCFullAccess - enableCollect: - title: 协助改善体验 - type: boolean - default: true - description: |+ - 通过开启该功能,可以将您的非敏感操作共享给我们,以便优化和改善应用。非敏感操作指 Stable Diffusion 使用、报错信息,不涉及提示词、参数、生成出的图片等敏感数据。 \ No newline at end of file diff --git a/publish.yaml b/publish.yaml index a7c0c59..9351ccd 100644 --- a/publish.yaml +++ b/publish.yaml @@ -1,19 +1,28 @@ -Type: Application -Name: fc-stable-diffusion +Edition: 3.0.0 +Type: Project +Name: fc-stable-diffusion-v3 Provider: - - 阿里云 -Version: dev + - 阿里云 +Version: 3.0.9 +# Version: dev Description: 使用serverless devs将stable-diffusion部署到阿里云函数计算上 -HomePage: https://github.com/OhYee/fc-stable-diffuson -Tags: #标签详情 +HomePage: https://github.com/devsapp/fc-stable-diffuson +Tags: - 部署函数 -Category: Web框架 +Organization: 阿里云函数计算(FC) +Category: 人工智能 +Service: + 函数计算: + Runtime: custom + Authorities: + - 创建函数 +Effective: Public Parameters: type: object additionalProperties: false # 不允许增加其他属性 required: # 必填项 - region - - serviceName + - namespace - functionName - type - enableCollect @@ -21,31 +30,29 @@ Parameters: region: title: 地域 type: string - default: - description: 创建应用所在的地区。由于当前模板涉及 Github 以及 HuggingFace 等网站访问,国内部分地区可能无法直接使用,推荐您选择海外地区进行部署 + default: cn-hangzhou + description: 创建应用所在的地区。由于当前模板涉及 Github 以及 HuggingFace 等网站访问,国内部分地区可能无法直接使用 enum: - cn-hangzhou - - ap-northeast-1 - - ap-southeast-1 - - cn-beijing - cn-shanghai - - cn-shenzhen - serviceName: - title: 服务名 + - ap-northeast-1 + # - us-east-1 + namespace: + title: 命名空间 type: string - default: fc-stable-diffusion - description: 您可以根据需要设置不同的服务名,同一个服务会共享部分第三方云产品资源 + default: sd-${default-suffix} + description: 命名空间将作为函数名的前缀,用以区分不同的 sd 应用,默认挂载的 nas 目录也取决于命名空间。 functionName: title: 函数名 type: string default: sd description: 您可以根据需要多次创建该应用,通过函数名来区分出不同的镜像地址 type: - title: 绘图类型 + title: 镜像选择 type: string - default: 动漫风格 + default: SD1.5 description: |+ - 根据不同的绘图风格,将会自动为您选择不同的社区镜像以供测试。 + 不同的镜像将内置不同的模型与插件,请选择您希望的模型插件组合。 注意: 函数计算是 Serverless 架构形式的计算平台,所有的容器镜像、代码、参考示例、开源信息均为用户自行所有,不作为函数计算本身提供的服务; 当前应用仅为案例,供使用者参考和学习使用,如果有生产使用需要,需要使用者自行完善和优化; @@ -55,9 +62,27 @@ Parameters: - 动漫风格 - 真人风格 - 轻量版 + - TensorRT + - 艺术字 enableCollect: title: 协助改善体验 type: boolean default: true description: |+ - 通过开启该功能,可以将您的非敏感操作共享给我们,以便优化和改善应用。非敏感操作指 Stable Diffusion 使用、报错信息,不涉及提示词、参数、生成出的图片等敏感数据。 \ No newline at end of file + 通过开启该功能,可以将您的非敏感操作共享给我们,以便优化和改善应用。非敏感操作指 Stable Diffusion 使用、报错信息,不涉及提示词、参数、生成出的图片等敏感数据。 + roleArn: + title: RAM 角色 ARN + type: string + default: '' + pattern: '^acs:ram::[0-9]*:role/.*$' + description: | + 函数计算访问云服务时使用的服务角色,需要填写具体的角色ARN,格式为acs:ram::$account-id>:role/$role-name。例如:acs:ram::14310000000:role/aliyunfcdefaultrole。 + 如果您没有特殊要求,可以使用函数计算提供的默认的服务角色,即AliyunFCDefaultRole, 并增加 AliyunFCFullAccess 权限。如果您首次使用函数计算,可以访问 https://fcnext.console.aliyun.com 进行授权。 + 详细文档参考 https://help.aliyun.com/document_detail/181589.html#section-o93-dbr-z6o" + required: true + x-role: + name: fcdeployrole + service: fc + authorities: + - AliyunFCDefaultRolePolicy + - AliyunFCFullAccess \ No newline at end of file diff --git a/readme-api.md b/readme-api.md deleted file mode 100644 index e21fa08..0000000 --- a/readme-api.md +++ /dev/null @@ -1,187 +0,0 @@ -> 注:当前项目为 Serverless Devs -> 应用,由于应用中会存在需要初始化才可运行的变量(例如应用部署地区、服务名、函数名等等),所以**不推荐**直接 Clone 本仓库到本地进行部署或直接复制 -> s.yaml 使用,**强烈推荐**通过 `s init` 的方法或应用中心进行初始化,详情可参考[部署 & 体验](#部署--体验) 。 - -# fc-stable-diffusion-api 帮助文档 - -

- - - - - - - - - -

- - - -使用serverless devs将stable-diffusion 的api服务部署到阿里云函数计算上,支持自定义模型,可以共享已有的stable-diffusion服务 - - - - - -- [:smiley_cat: 代码](https://github.com/devsapp/fc-stable-diffuson) - - - - - - -## 前期准备 - -使用该项目,您需要有开通以下服务: - - - -| 服务 | 备注 | -| ------- | -- | -| 函数计算 FC | | -| 文件存储 NAS | | - - - -推荐您拥有以下的产品权限 / 策略: - - - -## 应用介绍文档 -### 应用详情 -本应用旨在帮助开发者实现将[stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 开源应用部署到阿里云函数计算,保留其api服务,并且提供动态管理模型插件等能力 - - - -## 使用文档 -### 本地部署方案 - - - - 安装 [Serverless Devs Cli](https://www.serverless-devs.com/serverless-devs/install) 开发者工具`npm install @serverless-devs/s -g` - ,并进行[授权信息配置](https://docs.serverless-devs.com/fc/config) ; - - 初始化项目:`s init fc-stable-diffusion-api -d fc-stable-diffusion-api` - - 进入项目,并进行项目部署:`cd fc-stable-diffusion-api && s deploy - y` -本地部署成功后使用部分参考应用中心部署方案配置管理后台系列操作 - - -### 应用中心部署方案 -### ![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683461638633-942efd24-2edf-41bd-8654-89f115e348ae.png#clientId=u03391672-5bf6-4&from=paste&height=895&id=u334249e9&originHeight=1790&originWidth=3548&originalType=binary&ratio=2&rotation=0&showTitle=false&size=2234309&status=done&style=none&taskId=u76368d40-2f09-4f3b-a3e4-de7f5e8485b&title=&width=1774) -通过模版创建应用-> 人工智能选项卡-> AI数字绘画stable-diffusion api服务->立即创建 -### 填写表单项 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683461803985-e41d7585-5290-415f-aaf6-272cfea79c5b.png#clientId=u03391672-5bf6-4&from=paste&height=932&id=u8bafe9d1&originHeight=1864&originWidth=3386&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1934288&status=done&style=none&taskId=u02aec15c-b0cc-4c02-abc4-96700bc4faa&title=&width=1693) -选择直接部署-> 杭州/北京/上海/深圳地域 -> 复制开发者准备好的容器镜像 - 杭州region: registry.cn-hangzhou.aliyuncs.com/serverlessdevshanxie/sd-auto-nas:apionly - 北京region: registry.cn-beijing.aliyuncs.com/serverlessdevshanxie/sd-auto-nas:apionly - 深圳region: registry.cn-shenzhen.aliyuncs.com/serverlessdevshanxie/sd-auto-nas:apionly - 上海region: registry.cn-shanghai.aliyuncs.com/serverlessdevshanxie/sd-auto-nas:apionly -点击创建并部署默认环境 -### 应用部署 -接下来什么都不需要操作,等待应用部署即可,约花费5-10分钟, 如果你是技术同学,可以展开看看我们提供的部署日志,观察部署过程 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683461882180-9c03225c-6083-48dc-9d41-c4d250a4078f.png#clientId=u03391672-5bf6-4&from=paste&height=763&id=u3eafadd6&originHeight=1526&originWidth=2974&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1679012&status=done&style=none&taskId=u903b7e84-f059-4236-b21c-221e450f505&title=&width=1487) - -### 配置管理后台 -部署成功后得到两个域名 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462322986-6dd3cc6c-de40-4f0f-aa9f-a08781fcec4d.png#clientId=u03391672-5bf6-4&from=paste&height=255&id=ua83aae53&originHeight=510&originWidth=1648&originalType=binary&ratio=2&rotation=0&showTitle=false&size=340481&status=done&style=none&taskId=ud1417aee-7314-4cfa-a4b6-83794124dae&title=&width=824) -其中sd开头的是主服务 -admin开头的是我们的管理后台,您可以选择直接访问sd服务,我们提前为您准备了默认的sd1.5基础模型,也可以通过管理后台添加更多的模型和扩展,登录管理后台以及上传模型教程如下 - -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462407669-d8321fe2-e5c3-4858-84be-e27fc51449fa.png#clientId=u03391672-5bf6-4&from=paste&height=923&id=uf26f0147&originHeight=1846&originWidth=3522&originalType=binary&ratio=2&rotation=0&showTitle=false&size=5431845&status=done&style=none&taskId=u2ade747c-a250-4d08-82d4-af7043ff905&title=&width=1761) -管理后台使用的是 可道云提供的 kod-box,对于你而言一路点点点,就可以 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462449802-e95a58af-2aef-4908-a047-4e0a24a85b97.png#clientId=u03391672-5bf6-4&from=paste&height=620&id=u5de0c684&originHeight=1240&originWidth=1698&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1362726&status=done&style=none&taskId=u9b5f01bd-4296-408e-9bc7-5827c044b22&title=&width=849) -等初始化好之后,设置自己的登录账号和密码 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462492174-aff0e298-c20a-42a2-8c26-7aceb3f89be2.png#clientId=u03391672-5bf6-4&from=paste&height=825&id=uec11eb95&originHeight=1650&originWidth=2722&originalType=binary&ratio=2&rotation=0&showTitle=false&size=3978912&status=done&style=none&taskId=ubb7da915-9392-48de-b946-3ce287ffc41&title=&width=1361) -之后进行登录 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462570237-b92cd673-b0a8-4990-a2b0-6000e3c52f33.png#clientId=u03391672-5bf6-4&from=paste&height=604&id=u0cee9d6b&originHeight=1208&originWidth=1158&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1292053&status=done&style=none&taskId=uf04dc207-be0d-4fde-8218-0270a2fbf00&title=&width=579) -登录后在路径输入 /mnt/auto/sd -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462657365-fbeffad5-959e-4146-93fc-7fc7870acba5.png#clientId=u03391672-5bf6-4&from=paste&height=877&id=u5bdf6be3&originHeight=1754&originWidth=3546&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1801931&status=done&style=none&taskId=u9f5ca6e2-c5c5-4681-a2fe-a921b95de25&title=&width=1773) -如果你熟悉sd-webui的目录的话,你可以看到对应的目录 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462697869-704c768f-8081-40de-b9f8-695947d510a9.png#clientId=u03391672-5bf6-4&from=paste&height=722&id=u3075dff9&originHeight=1444&originWidth=3472&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1676917&status=done&style=none&taskId=ua4e68371-f843-439d-9049-bf2c8e8f6db&title=&width=1736) -接下来我们打开/mnt/auto/sd/models/Stable-diffusion/ ,然后点击上传->离线下载 -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683462759753-fcb5f1f7-12b8-44c9-9386-ebdf6d8ca78f.png#clientId=u03391672-5bf6-4&from=paste&height=890&id=ud0edb1b4&originHeight=1780&originWidth=3564&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1855469&status=done&style=none&taskId=u990255b9-b49a-4a1e-833f-2399b066f98&title=&width=1782) - - -你也可以输入已经外部网站的模型地址,或者您先上传到阿里云OSS,通过同地域的内网地址进行下载,除了下载,你也可以把本地的模型直接拖拽上传。 -因为模型较大,下载时间预计花费5-15分钟,可以休息等待一下(如果提升出错可以忽略) -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683465959658-c672bd36-cde0-4d83-bef5-1e47f9c601ee.png#clientId=u03391672-5bf6-4&from=paste&height=795&id=u65ee50e7&originHeight=1590&originWidth=3524&originalType=binary&ratio=2&rotation=0&showTitle=false&size=1670748&status=done&style=none&taskId=u1fa844fb-df6f-4672-982b-3f6d9406807&title=&width=1762) - - - - - - - -## 源码定制 -如果您觉得我们提供的镜像能力不能满足您的需求,您可以通过社区开发者开放的构建[镜像源码](https://github.com/ai-app-with-serverless/fc-stable-diffusion-image/tree/apionly)进行重新构建 - - -定制好自己的镜像之后可以替换上面流程中需要填写的镜像部分即可,注意对应好地域。 - - -### 常见问题 - -#### 1. 冷启动时间较长如何优化? - -因为本身sd的模型较大,打包镜像后依然达到10G,函数计算拉起镜像冷启动时间会比较长,大概2-5分钟,我们提供了预加载界面,避免您长时间的白屏等待。 - -#### 2.镜像加速 - -为了提升冷启动时间,我们提供了镜像加速服务,请关注控制台上的镜像加速状态,只有在ready才真正可用。 - -#### 3. 刚进去输入提示词构建偶尔会失败 - -这个可能是因为模型本身还未加载,请注意查看左上角选择框里面包含模型内容,之后再操作。出图的时候会有一定的等待时间,这个是正常现象,耐心等待即可 - -#### 4 资费消耗 - -GPU本身对算力资源消耗较大,我们默认提供的是按量付费的模式,当您不用的时候会自动释放资源,这样可以帮您减少资费消耗 - -#### 5 模型及插件扩展 - -需要自己上传 - -可以在进入admin后台管理地址之后在路径输入框输入 -/mnt/auto/sd -然后进入models/Stable-diffusion 点击文件上传,选择”离线下载“并输入 -https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt - -等带下载完成后需要修改文件名称,只保留sd-v1-5-inpainting.ckpt - -#### 6 如何构建并使用stable-diffusion-webui 镜像 - -- 使用[stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker) - 镜像本地镜像构建 -- 将构建好的本地镜像托管到 - 阿里云[容器镜像服务](https://help.aliyun.com/document_detail/257112.html?spm=a2c4g.410107.0.0.5b4036b9BUO0T5)服务, - 注意选择镜像服务的地域要跟函数计算部署的地域保持一致 - - - - - -## 开发者社区 - -您如果有关于错误的反馈或者未来的期待,您可以在 -[Serverless Devs repo Issues](https://github.com/serverless-devs/serverless-devs/issues) -中进行反馈和交流。如果您想要加入我们的讨论组或者了解 FC 组件的最新动态,您可以通过以下渠道进行: - -

- -| | | | -| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -|

微信公众号:`serverless`
|
微信小助手:`xiaojiangwh`
|
钉钉交流群:`33947367`
| - -

-
- -## 免责声明 - - - -1.应用中心仅为您提供应用的逻辑关系,不为您托管任何资源。如果您部署的应用中,存在一定的资源收费现象,请参考对应产品的收费标准;如果您应用所使用的某些产品或者服务因为产品规划等原因发生了不兼容变更,建议您直接咨询对应的产品或者服务; -2.应用中心为您提供的默认流水线功能是免费的,如果您需要手动切换到自定义流水线可能涉及到资源使用费用,具体的收费标准需要参考函数计算的计费文档; -3.应用中心部署的部分应用会为您分配“devsapp.cn”的测试域名,这个测试域名并非阿里云官方域名,是 CNCF Sandbox 项目 Serverless -Devs 所提供的测试域名,我们不保证该域名的使用时效性,推荐您只在测试的时候使用,或者绑定自己的自定义域名进行使用; -4.应用部署过程中,如果提示“当前应用模板由社区贡献,非阿里云官方提供,推荐您在使用当前应用模板前仔细阅读应用详情,以确保应用的安全,稳定等”则表示该应用并非阿里云官方所提供的应用,我们仅作为收录和展示,如果您继续部署该应用,推荐您联系应用的作者,并与作者协商应用使用的相关协议等; - - \ No newline at end of file diff --git a/readme-plus.md b/readme-plus.md deleted file mode 100644 index 69c211c..0000000 --- a/readme-plus.md +++ /dev/null @@ -1,182 +0,0 @@ - -> 注:当前项目为 Serverless Devs 应用,由于应用中会存在需要初始化才可运行的变量(例如应用部署地区、服务名、函数名等等),所以**不推荐**直接 Clone 本仓库到本地进行部署或直接复制 s.yaml 使用,**强烈推荐**通过 `s init ` 的方法或应用中心进行初始化,详情可参考[部署 & 体验](#部署--体验) 。 - -# fc-stable-diffusion-plus 帮助文档 -

- - - - - - - - - -

- - - -使用serverless devs将stable-diffusion部署到阿里云函数计算上,支持模型自定义 - - - - - -- [:smiley_cat: 代码](https://github.com/devsapp/fc-stable-diffuson) - - - - - - - - - -## 前期准备 - -使用该项目,您需要有开通以下服务: - - - - - -| 服务 | 备注 | -| --- | --- | -| 函数计算 FC | 对AIGC进行GPU推理计算,新用户请先领取 试用资源包 | - - - -推荐您拥有以下的产品权限 / 策略: - - - - - -您还需要注意: -1.本项目支持自定义模型,并且提前预置了sd1.5的基础模型,自定义模型需要通过kodbox管理后台进行上传 -2.项目依赖阿里云函数计算和阿里云文件存储Nas,这两款产品都会产生资费,请关注您的资源包使用情况和费用情况 -3.项目部署成功之后确保模型加载完毕(左上角选择框有模型显示)再开始推理 -4.项目初始启动有大约1分钟的白屏时间,这是服务完全冷启动的状态,请耐心等待 -5.项目里面的插件安装推荐下载到本地再通过kodbox管理后台上传,因为网络关系,在线安装有失败的情况 - - - - - -免责声明: -1. 该项目的构建镜像及应用模板完全开源,由社区开发者贡献,阿里云仅提供了算力支持; -2. 项目使用的sd-webui镜像内容同步自开源社区,如遇软件使用问题可以去社区查看问题答案 - - - -## 部署 & 体验 - - - -- :fire: 通过 [Serverless 应用中心](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion-plus) , - [![Deploy with Severless Devs](https://img.alicdn.com/imgextra/i1/O1CN01w5RFbX1v45s8TIXPz_!!6000000006118-55-tps-95-28.svg)](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion-plus) 该应用。 - - - - -- 通过 [Serverless Devs Cli](https://www.serverless-devs.com/serverless-devs/install) 进行部署: - - [安装 Serverless Devs Cli 开发者工具](https://www.serverless-devs.com/serverless-devs/install) ,并进行[授权信息配置](https://docs.serverless-devs.com/fc/config) ; - - 初始化项目:`s init fc-stable-diffusion-plus -d fc-stable-diffusion-plus ` - - 进入项目,并进行项目部署:`cd fc-stable-diffusion-plus && s deploy - y` - - - -## 应用详情 - - - -## 前期准备 - -使用该项目,您需要有开通以下服务: - - -| 服务 | 备注 | -| ------- | -- | -| 函数计算 FC | | - - -推荐您拥有以下的产品权限 / 策略: - -## 应用介绍文档 -### 应用详情 -本应用旨在帮助开发者实现将[stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 开源应用部署到阿里云函数计算,并且提供动态管理模型插件等能力 - -## 使用文档 -### 本地部署方案 - - 安装 [Serverless Devs Cli](https://www.serverless-devs.com/serverless-devs/install) 开发者工具`npm install @serverless-devs/s -g` - ,并进行[授权信息配置](https://docs.serverless-devs.com/fc/config) ; - - 初始化项目:`s init fc-stable-diffusion-plus -d fc-stable-diffusion-plus` - - 进入项目,并进行项目部署:`cd fc-stable-diffusion-plus && s deploy - y` -本地部署成功后使用部分参考应用中心部署方案配置管理后台系列操作 - -### 应用中心部署方案 - -![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2023/png/13970/1683461638633-942efd24-2edf-41bd-8654-89f115e348ae.png#clientId=u03391672-5bf6-4&from=paste&height=895&id=u334249e9&originHeight=1790&originWidth=3548&originalType=binary&ratio=2&rotation=0&showTitle=false&size=2234309&status=done&style=none&taskId=u76368d40-2f09-4f3b-a3e4-de7f5e8485b&title=&width=1774) -通过模版创建应用-> 人工智能选项卡-> AI数字绘画stable-diffusion自定义模板->立即创建 - - - -## 使用文档 - - - -## 源码定制 -如果您是一名开发同学,可以构建自己的镜像 -基于[https://github.com/AbdBarho/stable-diffusion-webui-docker/tree/master/services/AUTOMATIC1111](https://github.com/AbdBarho/stable-diffusion-webui-docker/tree/master/services/AUTOMATIC1111)这个项目, - -社区准备了优化好的镜像, -+ 增加deforum扩展的镜像: https://github.com/ai-app-with-serverless/fc-stable-diffusion-image/tree/master -+ 仅包含api服务的镜像:https://github.com/ai-app-with-serverless/fc-stable-diffusion-image/tree/apionly - -### 常见问题 - -#### 1. 冷启动时间较长如何优化? - -因为本身sd的模型较大,打包镜像后依然达到10G,函数计算拉起镜像冷启动时间会比较长,大概2-5分钟,我们提供了预加载界面,避免您长时间的白屏等待。 - -#### 2. 刚进去输入提示词构建偶尔会失败 - -这个可能是因为模型本身还未加载,请注意查看左上角选择框里面包含模型内容,之后再操作。出图的时候会有一定的等待时间,这个是正常现象,耐心等待即可 - -#### 3 资费消耗 - -GPU本身对算力资源消耗较大,我们默认提供的是按量付费的模式,当您不用的时候会自动释放资源,这样可以帮您减少资费消耗 - -#### 4 模型及插件扩展 - -需要自己上传 - -可以在进入admin后台管理地址之后在路径输入框输入 -/mnt/auto/sd -然后进入models/Stable-diffusion 点击文件上传,选择”离线下载“并输入您的模型地址 - -#### 6 如何构建并使用stable-diffusion-webui 镜像 - -- 使用[stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker) - 镜像本地镜像构建 -- 将构建好的本地镜像托管到 - 阿里云[容器镜像服务](https://help.aliyun.com/document_detail/257112.html?spm=a2c4g.410107.0.0.5b4036b9BUO0T5)服务, - 注意选择镜像服务的地域要跟函数计算部署的地域保持一致 - - - - - - - -## 开发者社区 - -您如果有关于错误的反馈或者未来的期待,您可以在 [Serverless Devs repo Issues](https://github.com/serverless-devs/serverless-devs/issues) 中进行反馈和交流。如果您想要加入我们的讨论组或者了解 FC 组件的最新动态,您可以通过以下渠道进行: - -

- -| | | | -| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -|

微信公众号:`serverless`
|
微信小助手:`xiaojiangwh`
|
钉钉交流群:`33947367`
| -

-
diff --git a/readme.md b/readme.md index 3f4cd7b..c0dfee0 100644 --- a/readme.md +++ b/readme.md @@ -1,16 +1,16 @@ -> 注:当前项目为 Serverless Devs 应用,由于应用中会存在需要初始化才可运行的变量(例如应用部署地区、服务名、函数名等等),所以**不推荐**直接 Clone 本仓库到本地进行部署或直接复制 s.yaml 使用,**强烈推荐**通过 `s init ` 的方法或应用中心进行初始化,详情可参考[部署 & 体验](#部署--体验) 。 +> 注:当前项目为 Serverless Devs 应用,由于应用中会存在需要初始化才可运行的变量(例如应用部署地区、函数名等等),所以**不推荐**直接 Clone 本仓库到本地进行部署或直接复制 s.yaml 使用,**强烈推荐**通过 `s init ${模版名称}` 的方法或应用中心进行初始化,详情可参考[部署 & 体验](#部署--体验) 。 -# fc-stable-diffusion 帮助文档 +# fc-stable-diffusion-v3 帮助文档

- + - - + + - - + +

@@ -22,7 +22,7 @@ -- [:smiley_cat: 代码](https://github.com/devsapp/fc-stable-diffuson) + @@ -34,35 +34,27 @@ ## 前期准备 -使用该项目,您需要有开通以下服务: +使用该项目,您需要有开通以下服务并拥有对应权限: -| 服务 | 备注 | -| --- | --- | -| 函数计算 FC | +| 服务/业务 | 权限 | 相关文档 | +| --- | --- | --- | +| 函数计算 | 创建函数 | [帮助文档](https://help.aliyun.com/product/2508973.html) [计费文档](https://help.aliyun.com/document_detail/2512928.html) | -推荐您拥有以下的产品权限 / 策略: - - - -您还需要注意: -1. 项目依赖阿里云函数计算,这会产生资费,请关注您的资源包使用情况和费用情况 -2. 项目里面的插件安装推荐下载到本地再通过kodbox管理后台上传,因为网络关系,在线安装有失败的情况 + -免责声明: -该项目的构建镜像及应用模板完全开源,由社区开发者贡献,阿里云仅提供了算力支持; -项目使用的sd-webui镜像内容同步自开源社区,如遇软件使用问题可以去社区查看问题答案 + @@ -70,78 +62,59 @@ -- :fire: 通过 [Serverless 应用中心](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion) , - [![Deploy with Severless Devs](https://img.alicdn.com/imgextra/i1/O1CN01w5RFbX1v45s8TIXPz_!!6000000006118-55-tps-95-28.svg)](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion) 该应用。 +- :fire: 通过 [Serverless 应用中心](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion-v3) , + [![Deploy with Severless Devs](https://img.alicdn.com/imgextra/i1/O1CN01w5RFbX1v45s8TIXPz_!!6000000006118-55-tps-95-28.svg)](https://fcnext.console.aliyun.com/applications/create?template=fc-stable-diffusion-v3) 该应用。 - 通过 [Serverless Devs Cli](https://www.serverless-devs.com/serverless-devs/install) 进行部署: - [安装 Serverless Devs Cli 开发者工具](https://www.serverless-devs.com/serverless-devs/install) ,并进行[授权信息配置](https://docs.serverless-devs.com/fc/config) ; - - 初始化项目:`s init fc-stable-diffusion -d fc-stable-diffusion ` - - 进入项目,并进行项目部署:`cd fc-stable-diffusion && s deploy - y` + - 初始化项目:`s init fc-stable-diffusion-v3 -d fc-stable-diffusion-v3` + - 进入项目,并进行项目部署:`cd fc-stable-diffusion-v3 && s deploy -y` -## 应用详情 +## 案例介绍 - - -## 使用文档 - - -### 内置模型 +本案例将 [Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui),这一火热的 AIGC 项目快速创建并部署到阿里云函数计算 FC。快速体验强大的 AI 图片生成能力,实现文生图、图生图等多种功能。 -#### 基础模型 -共包含三种类型的基础模型预构建镜像 +Stable Diffusion 是一款开源的扩散模型,由 CompVis、Stability AI 和 LAION 的研究人员和工程师创建。由于 Stable Diffusion 开源、扩展性强的特点,其受到了全球众多 AIGC 爱好者的追捧。根据模型网站 Civital 统计,目前最热门的模型已经超过 100 万次下载,超过 10 万次下载的模型 70 余个,各种风格、不同功能的模型超过 12 万。Stable Diffusion WebUI 在国内也很火热,通过 Stable Diffusion WebUI 进行文生图的教程在国内各大平台多次登入热搜榜、排行榜,引领了一波又一波的浪潮。 -##### sd1.5 -内置 `sd-v1-5-inpainting.ckpt` 镜像,绘制能力较强,可以根据描述词得到不同形式的图像 +Stable Diffusion WebUI 需要通过 GPU 算力进行运算,且部署存在一定的门槛要求。因此借助于 Serverless 开发平台,用户可以简单、方便地将 Stable Diffusion WebUI 部署至函数计算,快速感受 AIGC 的魅力。同时,开发平台还集成了包括热门模型库、云上文件管理、Serverless API 等多种定制化能力,方便不同的用户更好地使用 Stable Diffusion WebUI。 -##### 动漫风格 - -内置 `mixProV4.Cqhm.safetensors` 镜像,支持绘制出动漫风格的图像 -(建议配合 VAE 模型 `cIF8Anime2.43ol.ckpt` 提升色彩表现能力) - -[模型来源地址](https://civitai.com/models/7241/mix-pro-v4) - - -##### 真人风格 + -内置 `chilloutmix_NiPrunedFp16Fix.safetensors` 镜像,支持绘制出真人风格的图像 +## 使用流程 -[模型来源地址](https://huggingface.co/samle/sd-webui-models/) + -搭配了对应 Lora 模型 +部署完成后,点击 WebUI 域名,进入 Stable Diffusion WebUI 页面 +![进入 WebUI](https://img.alicdn.com/imgextra/i1/O1CN017nVu2A21J6kEkXGHo_!!6000000006963-0-tps-750-424.jpg) -- `ChinaDollLikeness.safetensors` -- `KoreanDollLikeness.safetensors` -- `JapaneseDollLikeness.safetensors` -#### Lora & VAE 模型 +点击页面右侧的生成,即可生成您的第一张图片 +![出图](https://img.alicdn.com/imgextra/i3/O1CN01DRInqG1UacZJgzUXs_!!6000000002534-0-tps-750-203.jpg) -|名称|类型|地址|介绍| -|:---:|:---:|:---:|:---:| -|`milkingMachine_v11.safetensors`|Lora|[模型来源](https://civitai.com/models/17516/abyssorangemix3-6-milk-cow-girl-2-milkingmachine-lora-by-racycats)|动漫风渲染| -|`blingdbox_v1_mix.safetensors`|Lora|[模型来源](https://civitai.com/models/25995/blindbox?modelVersionId=32988)|盲盒画风| -|`GachaSpliash4.safetensors`|Lora|[模型来源](https://civitai.com/models/13090/gacha-splash-lora)|带背景立绘风格| -|`Colorwater_v4.safetensors`|Lora|[模型来源](https://civitai.com/models/16055/colorwater)|水墨风渲染| -|`cIF8Anime2.43ol.ckpt`|VAE|[模型来源](https://civitai.com/models/7241/mix-pro-v4)|提升色彩表现| +Stable Diffusion WebUI 使用可参考任意平台的热门教程,也可以参考 Stable Diffusion 文档:https://alidocs.dingtalk.com/i/p/x9JOGOjr65om4QLAdy0mV8B0gpkodz89 + -### 内置插件 +## 注意事项 -- [stable-diffusion-webui-chinese](https://github.com/VinsonLaro/stable-diffusion-webui-chinese) WebUI 汉化 -- [sd-prompt-translator](https://github.com/studyzy/sd-prompt-translator) 中文提示词自动翻译 -- [sdweb-easy-prompt-selector](https://github.com/blue-pen5805/sdweb-easy-prompt-selector) 提示词选择,[@路过银河​](https://zhuanlan.zhihu.com/p/630518048) 提供汉化 + +- Stable Diffusion 及 Stable Diffusion WebUI 为开源项目,代码由开源社区维护,对项目存在疑问可以前往社区寻求帮助; +- 如果您在使用中,对于第三方插件存在疑问,可以在插件社区寻求帮助; +- 函数计算为 Serverless 产品,数据存储在文件管理 NAS 中。如果您开启了模型管理管理功能,将会为您自动开启 NAS 服务,NAS 将根据存储的文件大小进行计费; +- 为保证 Stable Diffusion 运行质量,默认创建的 NAS 为通用性能型 NAS,费用为标准通用型 NAS 的 5.4 倍(具体折算比例请参考 NAS 文档)。 - + diff --git a/src/.gitignore b/src/.gitignore index 48e80d0..6ee1ce8 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,2 +1,3 @@ __pycache__ -.s \ No newline at end of file +.s +.env \ No newline at end of file diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 64c0b5f..0000000 --- a/src/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -.PHONY: help \ - build \ - test \ - push-beijing \ - push-shanghai \ - push-shenzhen \ - push-hangzhou \ - push - -help: ## 帮助文件 - @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-40s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) - - -NAMESPACE=aliyun-fc -REPO=fc-stable-diffusion -BASE_TAG=basev8 - -SD15_VERSION=v12 -ANIME_VERSION=v12 -REALMAN_VERSION=v12 -LITE_VERSION=v4 - - -push: push-jp push-beijing push-shanghai push-shenzhen push-hangzhou ## push 镜像到所有 registry - - -build-base: ## 构建基础镜像 - DOCKER_BUILDKIT=1 docker build -f code/images/Dockerfile --target base -t registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} code/images - -build-sd1.5: ## 构建 sd 1.5 - DOCKER_BUILDKIT=1 docker build -f code/images/Dockerfile --target sd1.5 --build-arg IMAGE_TAG=sd1.5-${SD15_VERSION} -t stable-diffusion:sd1.5-${SD15_VERSION} code/images/ - -build-anime: ## 构建动漫风格 - DOCKER_BUILDKIT=1 docker build -f code/images/Dockerfile --target anime --build-arg IMAGE_TAG=anime-${ANIME_VERSION} -t stable-diffusion:anime-${ANIME_VERSION} code/images/ - -build-realman: ## 构建真人风格 - DOCKER_BUILDKIT=1 docker build -f code/images/Dockerfile --target realman --build-arg IMAGE_TAG=realman-${REALMAN_VERSION} -t stable-diffusion:realman-${REALMAN_VERSION} code/images/ - -build-lite: ## 构建 Lite 版本 - DOCKER_BUILDKIT=1 docker build -f code/images/Dockerfile --target lite --build-arg IMAGE_TAG=lite-${LITE_VERSION} -t stable-diffusion:lite-${LITE_VERSION} code/images/ - -build: build-sd1.5 build-anime build-realman build-lite # 构建全部镜像 - - - - -push-base: ## 推送基础镜像 - docker push registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} - -push-beijing: ## push 镜像到北京 - IMAGE=registry.cn-beijing.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-shanghai: ## push 镜像到上海 - IMAGE=registry.cn-shanghai.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-shenzhen: ## push 镜像到深圳 - IMAGE=registry.cn-shenzhen.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-hangzhou: ## push 镜像到杭州 - IMAGE=registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-ap: build ## push 镜像到新加坡 - IMAGE=registry-vpc.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-jp: - IMAGE=registry.ap-northeast-1.aliyuncs.com/${NAMESPACE}/${REPO} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - docker tag stable-diffusion:$$tag $$IMAGE:$$tag && \ - docker push $$IMAGE:$$tag; \ - done - -push-base-ap: build ## push 镜像到新加坡 - docker tag registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} registry-vpc.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} && \ - docker push registry-vpc.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} - -sync-from-ap: ## 同步新加坡镜像到其他 region - docker pull registry.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} && \ - docker tag registry.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} && \ - docker push registry.cn-hangzhou.aliyuncs.com/${NAMESPACE}/${REPO}:${BASE_TAG} && \ - for tag in "sd1.5-${SD15_VERSION}" "anime-${ANIME_VERSION}" "realman-${REALMAN_VERSION}" "lite-${LITE_VERSION}"; do \ - for region in "cn-hangzhou" "cn-beijing" "cn-shanghai" "cn-shenzhen" "ap-northeast-1"; do \ - docker pull registry.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:$${tag} && \ - docker tag registry.ap-southeast-1.aliyuncs.com/${NAMESPACE}/${REPO}:$${tag} registry.$${region}.aliyuncs.com/${NAMESPACE}/${REPO}:$${tag} && \ - docker push registry.$${region}.aliyuncs.com/${NAMESPACE}/${REPO}:$${tag} && continue; break; \ - done; \ - done - - -push: push-beijing push-shanghai push-hangzhou push-shenzhen push-jp - -all-ap: build-base build push-base-ap push-ap - -all: all-ap push push-base - -dev: build-anime ## 使用动漫风格进行测试 - docker run --rm -it --name=sd --net=host -v ${shell pwd}/nas:/mnt/auto stable-diffusion:anime-${ANIME_VERSION} - -exec: ## 登入容器实例 - docker exec -it sd /bin/bash diff --git a/src/code/.gitignore b/src/code/.gitignore new file mode 100644 index 0000000..c322d04 --- /dev/null +++ b/src/code/.gitignore @@ -0,0 +1,3 @@ +filemgr.zip +filemgr +s.yaml \ No newline at end of file diff --git a/src/code/images/Dockerfile b/src/code/images/Dockerfile index 709b85c..6055c9f 100644 --- a/src/code/images/Dockerfile +++ b/src/code/images/Dockerfile @@ -1,117 +1,123 @@ -# syntax = docker/dockerfile:experimental - -# # WebUI 基础镜像 -# # 包含 WebUI、相关依赖、插件、Lora、VAE - - - -ARG ROOT="/stable-diffusion-webui" -ARG SD_BUILTIN="/built-in" - ############################# -# 依赖的仓库下载 # +# 基础 python 依赖环境 # ############################# +FROM python:3.10.9-slim AS deps -FROM alpine/git:2.36.2 as repositories +RUN --mount=type=cache,target=/root/.cache/pip \ + python3 -m venv /venv && \ + . /venv/bin/activate && \ + pip install \ + torch==2.1.2 torchvision==0.16.2 --extra-index-url https://download.pytorch.org/whl/cu121 -COPY clone.sh /clone.sh +# 安装 rust 环境 +RUN --mount=type=cache,target=/var/cache/apt \ + apt update && \ + apt install -y curl gcc g++ build-essential +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y +ENV PATH="/root/.cargo/bin:$PATH" -# RUN . /clone.sh taming-transformers https://github.com/CompVis/taming-transformers.git 3ba01b241669f5ade541ce990f7650a3b8f65318 \ -# && rm -rf data assets **/*.ipynb +RUN --mount=type=cache,target=/root/.cache/pip \ + . /venv/bin/activate && \ + export PATH="/root/.cargo/bin:$PATH" && \ + pip install transformers==4.30.2 -RUN . /clone.sh /repositories/stable-diffusion-stability-ai https://github.com/Stability-AI/stablediffusion.git cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf \ - && rm -rf assets data/**/*.png data/**/*.jpg data/**/*.gif +# find . -type f -name "requirements.txt" | xargs -I {} cat {} | tr -d '\r' | sed 's/>/=/g' | sort -u | awk -F '==' '! /^(#|-|\s*$)/ {sub(/^[ \t]+|[ \t]+$/, "", $0); if (!seen[$1]++) print}' | xargs +RUN --mount=type=cache,target=/root/.cache/pip \ + . /venv/bin/activate && \ + pip install \ + GitPython==3.1.32 Pillow==9.5.0 accelerate==0.21.0 addict albumentations==0.4.3 blendmodes \ + clean-fid==0.1.35 dctorch diskcache==5.6.3 einops==0.4.1 facexlib==0.3.0 fairscale==0.4.4 \ + setuptools==69.5.1 fastapi==0.94.0 future gdown timm==0.4.12 gradio==3.41.2 \ + imageio-ffmpeg==0.4.2 imageio==2.27.0 inflection==0.5.1 invisible-watermark==0.1.5 \ + jsonmerge==1.8.0 kornia==0.6.7 lark==1.1.2 lmdb lpips numpy==1.26.2 omegaconf==2.2.3 \ + opencv-python piexif==1.1.3 pillow-avif-plugin==1.4.3 psutil==5.9.5 pudb==2019.2 \ + pycocoevalcap httpcore==0.15 pyyaml requests resize-right==0.0.2 safetensors==0.4.2 \ + scikit-image==0.21.0 scipy streamlit-drawable-canvas==0.8.0 streamlit==0.73.1 \ + tb-nightly spandrel==0.1.6 test-tube==0.7.5 tomesd==0.1.3 torch torchdiffeq tqdm \ + wandb webdataset==0.2.5 yapf httpx==0.24.1 -RUN . /clone.sh /repositories/generative-models https://github.com/Stability-AI/generative-models.git 45c443b316737a4ab6e40413d7794a7f5657c19f \ - && rm -rf assets data/**/*.png data/**/*.jpg data/**/*.gif +RUN --mount=type=cache,target=/root/.cache/pip \ + . /venv/bin/activate && \ + pip install \ + clip-anytorch open-clip-torch==2.20.0 pytorch_lightning==1.9.4 torchmetrics==0.7.0 \ + torchsde==0.2.6 torchdiffeq==0.2.3 -RUN . /clone.sh /repositories/CodeFormer https://github.com/sczhou/CodeFormer.git c5b4593074ba6214284d6acd5f1719b6c5d739af \ - && rm -rf assets inputs -RUN . /clone.sh /repositories/BLIP https://github.com/salesforce/BLIP.git 48211a1594f1321b00f14c9f7a5b4813144b2fb9 -RUN . /clone.sh /repositories/k-diffusion https://github.com/crowsonkb/k-diffusion.git ab527a9a6d347f364e3d185ba6d714e22d80cb3c -RUN . /clone.sh /repositories/clip-interrogator https://github.com/pharmapsychotic/clip-interrogator 2486589f24165c8e3b303f84e9dbbea318df83e8 +# 重新安装一次 pytorch,确保最终使用的版本符合 sd webui 预期 +RUN --mount=type=cache,target=/root/.cache/pip \ + . /venv/bin/activate && \ + pip install \ + torch==2.1.2 torchvision==0.16.2 xformers --index-url https://download.pytorch.org/whl/cu121 ############################# -# 内置的插件下载 # +# sdwebui 仓库 # ############################# +FROM alpine/git:2.36.2 AS repos -FROM alpine/git:2.36.2 as extensions +ARG SHA=82a973c0 +RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /code && \ + cd /code && \ + git reset --hard ${SHA} -COPY clone.sh /clone.sh +RUN git clone https://github.com/Stability-AI/stablediffusion.git /code/repositories/stable-diffusion-stability-ai && \ + cd /code/repositories/stable-diffusion-stability-ai && \ + git reset --hard cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf -# adetailer 人脸修复插件 -RUN . /clone.sh /extensions/adetailer https://github.com/Bing-su/adetailer.git v23.9.3 && \ - cd /extensions/adetailer && \ - rm -rf .github .vscode *.md .gitignore +RUN git clone https://github.com/Stability-AI/generative-models.git /code/repositories/generative-models && \ + cd /code/repositories/generative-models && \ + git reset --hard fbdc58cab9f4ee2be7a5e1f2e2787ecd9311942f -# sd-prompt-translator 中文提示词支持 -RUN . /clone.sh /extensions/sd-prompt-translator https://github.com/studyzy/sd-prompt-translator.git bfe88c39ff020f22ef3e81b317862cdbe6e0f8af && \ - cd /extensions/sd-prompt-translator && \ - rm -rf UI.png *.md .gitignore +RUN git clone https://github.com/sczhou/CodeFormer.git /code/repositories/CodeFormer && \ + cd /code/repositories/CodeFormer && \ + git reset --hard 8392d0334956108ab53d9439c4b9fc9c4af0d66d -# sd-webui-controlnet -RUN . /clone.sh /extensions/sd-webui-controlnet https://github.com/Mikubill/sd-webui-controlnet.git 7a4805c8ea3256a0eab3512280bd4f84ca0c8182 && \ - cd /extensions/sd-webui-controlnet && \ - rm -rf .github example tests web_tests *.md .gitignore +RUN git clone https://github.com/salesforce/BLIP.git /code/repositories/BLIP && \ + cd /code/repositories/BLIP && \ + git reset --hard 3a29b7410476bf5f2ba0955827390eb6ea1f4f9d -# sd-webui-deforum 全息视频 -RUN . /clone.sh /extensions/sd-webui-deforum https://github.com/deforum-art/sd-webui-deforum.git 368ffb01121b0cbf4c316318bfc1ebe6666e74bd && \ - cd /extensions/sd-webui-deforum && \ - rm -rf .github tests *.md .gitignore +RUN git clone https://github.com/crowsonkb/k-diffusion.git /code/repositories/k-diffusion && \ + cd /code/repositories/k-diffusion && \ + git reset --hard 21d12c91ad4550e8fcf3308ff9fe7116b3f19a08 -# sd-webui-llul 细节增强 -RUN . /clone.sh /extensions/sd-webui-llul https://github.com/hnmr293/sd-webui-llul.git aa47b3eeb45c53f0d6ccaae59abf36e8ed6731f5 && \ - cd /extensions/sd-webui-llul && \ - rm -rf images *.md .gitignore +RUN git clone https://github.com/pharmapsychotic/clip-interrogator /code/repositories/clip-interrogator && \ + cd /code/repositories/clip-interrogator && \ + git reset --hard bc07ce62c179d3aab3053a623d96a071101d11cb -# sd-webui-prompt-all-in-one 提示词增强 -RUN . /clone.sh /extensions/sd-webui-prompt-all-in-one https://github.com/Physton/sd-webui-prompt-all-in-one.git 6e06fb051ab67cd587a9961132c37047b5e6d06d && \ - cd /extensions/sd-webui-prompt-all-in-one && \ - rm -rf .github tests *.MD .gitignore && \ - sed -n -i '1,21p' scripts/physton_prompt/translator/amazon_translator.py && \ - sed -i '16d' scripts/physton_prompt/packages.py -# sd-webui-roop 换脸 -RUN . /clone.sh /extensions/sd-webui-roop https://github.com/s0md3v/sd-webui-roop.git 3176d477d77830f06b83573d07aeeae1a7046f6e && \ - cd /extensions/sd-webui-roop && \ - rm -rf example *.md .gitignore +RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui-assets /code/repositories/stable-diffusion-webui-assets && \ + cd /code/repositories/stable-diffusion-webui-assets && \ + git reset --hard 6f7db241d2f8ba7457bac5ca9753331f0c266917 -# stable-diffusion-webui-chinese 中文翻译 -RUN . /clone.sh /extensions/stable-diffusion-webui-chinese https://github.com/VinsonLaro/stable-diffusion-webui-chinese.git 304061b791599807afec20221438e8c74d94a89f && \ - cd /extensions/stable-diffusion-webui-chinese && \ - rm -rf *.md -# stable-diffusion-webui-dataset-tag-editor 训练打标 -RUN . /clone.sh /extensions/stable-diffusion-webui-dataset-tag-editor https://github.com/toshiaki1729/stable-diffusion-webui-dataset-tag-editor.git v0.2.0 && \ - cd /extensions/stable-diffusion-webui-dataset-tag-editor && \ - rm -rf .github pic *.md .gitignore *.png -# stable-diffusion-webui-images-browser 图片浏览器 -RUN . /clone.sh /extensions/stable-diffusion-webui-images-browser https://github.com/yfszzx/stable-diffusion-webui-images-browser.git v1.0.0 && \ - cd /extensions/stable-diffusion-webui-images-browser && \ - rm -rf .DS_Store *.md .gitignore +############################# +# sdwebui 需要的 hf 模型 # +############################# +FROM python:3.10.9-slim AS download_huggingface -# stable-diffusion-webui-rembg 移除背景 -RUN . /clone.sh /extensions/stable-diffusion-webui-rembg https://github.com/AUTOMATIC1111/stable-diffusion-webui-rembg.git 3d9eedbbf0d585207f97d5b21e42f32c0042df70 && \ - cd /extensions/stable-diffusion-webui-rembg && \ - rm -rf *.md .gitignore *.png +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install transformers[sentencepiece] sentencepiece && \ + pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 -# stable-diffusion-webui-wd14-tagger 图片反推提示词 -RUN . /clone.sh /extensions/stable-diffusion-webui-wd14-tagger https://github.com/picobyte/stable-diffusion-webui-wd14-tagger.git v1.2.0 && \ - cd /extensions/stable-diffusion-webui-wd14-tagger && \ - rm -rf docs *.md .gitignore +COPY ./init /init +RUN mkdir -p /sd-prompt-translator && python /init/sd-prompt-translator.py /sd-prompt-translator +RUN mkdir -p /bert-base-uncased-cache && python /init/bert-base-uncased.py /bert-base-uncased-cache +RUN mkdir -p /clip-vit-large-patch14 && python /init/clip-vit-large-patch14.py /clip-vit-large-patch14 +RUN mkdir -p /models--Bingsu--adetailer && python /init/bingsu-adetailer.py /models--Bingsu--adetailer -# sdweb-easy-prompt-selector 提示词选择 -COPY ./sd-resource/extensions/sdweb-easy-prompt-selector /extensions/sdweb-easy-prompt-selector +RUN --mount=type=cache,target=/var/cache/apt \ + apt update && \ + apt install -y tar + +RUN tar -C /init -xvf /init/models--google--t5-v1_1-xxl.tar.gz ############################# # sdwebui 需要的模型 # ############################# -FROM python:3.10.9-slim as download_sdwebui +FROM python:3.10.9-slim AS download_sdwebui RUN apt update && apt install -y aria2 @@ -122,260 +128,102 @@ RUN aria2c -x 8 --dir "/" --out "detection_Resnet50_Final.pth" "https://github.c RUN aria2c -x 8 --dir "/" --out "parsing_parsenet.pth" "https://github.com/sczhou/CodeFormer/releases/download/v0.1.0/parsing_parsenet.pth" RUN aria2c -x 8 --dir "/" --out "model_base_caption_capfilt_large.pth" "https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_caption_capfilt_large.pth" RUN aria2c -x 8 --dir "/" --out "model-resnet_custom_v3.pt" "https://github.com/AUTOMATIC1111/TorchDeepDanbooru/releases/download/v1/model-resnet_custom_v3.pt" +RUN aria2c -x 8 --dir "/" --out "clip_l.safetensors" "https://huggingface.co/AUTOMATIC/stable-diffusion-3-medium-text-encoders/resolve/main/clip_l.safetensors" +RUN aria2c -x 8 --dir "/" --out "clip_g.safetensors" "https://huggingface.co/AUTOMATIC/stable-diffusion-3-medium-text-encoders/resolve/main/clip_g.safetensors" -############################# -# 内置插件需要的模型 # -############################# - -FROM python:3.10.9-slim as download_extensions - -RUN apt update && apt install -y aria2 - -RUN aria2c -x 8 --dir "/" --out "inswapper_128.onnx" "https://huggingface.co/ezioruan/inswapper_128.onnx/resolve/main/inswapper_128.onnx" -RUN aria2c -x 8 --dir "/" --out "detector.onnx" "https://huggingface.co/s0md3v/nudity-checker/resolve/main/detector.onnx" -RUN aria2c -x 8 --dir "/" --out "control_v11p_sd15_scribble.pth" "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.pth" -RUN aria2c -x 8 --dir "/" --out "control_v11p_sd15_scribble.yaml" "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_scribble.yaml" -RUN aria2c -x 8 --dir "/" --out "control_v1p_sd15_illumination.safetensors" "https://huggingface.co/ioclab/ioc-controlnet/resolve/main/models/control_v1p_sd15_illumination.safetensors" -RUN aria2c -x 8 --dir "/" --out "buffalo_l.zip" "https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_l.zip" ############################# -# 内置模型 # +# serverless api # ############################# -FROM python:3.10.9-slim as download_models - -RUN apt update && apt install -y aria2 +FROM golang:1.21 AS serverless-stable-diffusion-api -RUN aria2c -x 16 --dir "/" --out "sd-v1-5-inpainting.ckpt" "https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt" +RUN go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest -RUN aria2c -x 16 --dir "/" --out "mixProV4.Cqhm.safetensors" "https://civitai.com/api/download/models/34559?type=Model&format=SafeTensor&size=full&fp=fp16" +RUN mkdir -p /code && \ + git clone https://github.com/devsapp/serverless-stable-diffusion-api.git /code && \ + cd /code && \ + git checkout 0a3be77d477092e3c6c1f31ebc504232c1a5f6ed -RUN aria2c -x 16 --dir "/" --out "ChinaDollLikeness.safetensors" "https://civitai.com/api/download/models/66172?type=Model&format=SafeTensor" -RUN aria2c -x 16 --dir "/" --out "KoreanDollLikeness.safetensors" "https://civitai.com/api/download/models/31284?type=Model&format=SafeTensor&size=full&fp=fp16" -RUN aria2c -x 16 --dir "/" --out "JapaneseDollLikeness.safetensors" "https://civitai.com/api/download/models/34562?type=Model&format=SafeTensor&size=full&fp=fp16" -RUN aria2c -x 16 --dir "/" --out "chilloutmix_NiPrunedFp16Fix.safetensors" "https://huggingface.co/samle/sd-webui-models/resolve/main/chilloutmix_NiPrunedFp16Fix.safetensors" +WORKDIR /code +RUN go get ./... && \ + go get github.com/oapi-codegen/runtime && \ + go get github.com/getkin/kin-openapi/openapi3 && \ + go get golang.org/x/text/language -RUN aria2c -x 16 --dir "/" --out "cIF8Anime2.43ol.ckpt" "https://civitai.com/api/download/models/28569" -RUN aria2c -x 16 --dir "/" --out "vae-ft-mse-840000-ema-pruned.safetensors" "https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors" +# /code/build/agent/agentServer +RUN make build-agent -RUN aria2c -x 16 --dir "/" --out "moxin.safetensors" "https://civitai.com/api/download/models/14856?type=Model&format=SafeTensor&size=full&fp=fp16" -RUN aria2c -x 16 --dir "/" --out "milkingMachine_v11.safetensors" "https://huggingface.co/samle/sd-webui-models/resolve/main/milkingMachine_v11.safetensors" -RUN aria2c -x 16 --dir "/" --out "blingdbox_v1_mix.safetensors" "https://civitai.com/api/download/models/32988?type=Model&format=SafeTensor&size=full&fp=fp16" -RUN aria2c -x 16 --dir "/" --out "GachaSpliash4.safetensors" "https://civitai.com/api/download/models/38884?type=Model&format=SafeTensor" -RUN aria2c -x 16 --dir "/" --out "Colorwater_v4.safetensors" "https://civitai.com/api/download/models/21173?type=Model&format=SafeTensor&size=full&fp=fp16" +# /code/build/proxy/proxyServer +RUN make build-proxy -############################# -# 插件从 hf 下载的模型 # -############################# -FROM python:3.10.9-slim as download_huggingface - -RUN --mount=type=cache,target=/root/.cache/pip \ - pip install transformers[sentencepiece] sentencepiece && \ - pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 - -COPY ./init /init -RUN mkdir -p /sd-prompt-translator && python /init/sd-prompt-translator.py /sd-prompt-translator -RUN mkdir -p /bert-base-uncased-cache && python /init/bert-base-uncased.py /bert-base-uncased-cache -RUN mkdir -p /clip-vit-large-patch14 && python /init/clip-vit-large-patch14.py /clip-vit-large-patch14 -RUN mkdir -p /models--Bingsu--adetailer && python /init/bingsu-adetailer.py /models--Bingsu--adetailer ############################# -# 基础 sd 镜像 # +# 基础镜像 # ############################# +FROM python:3.10.9-slim AS base -FROM python:3.10.9-slim as sdwebui - - -ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1 - -ARG ROOT -ARG SD_BUILTIN -ENV ROOT="${ROOT}" -ENV SD_BUILTIN="${SD_BUILTIN}" +ENV BUILTIN="/built-in" +ENV SD_DIR="/stable-diffusion-webui" +ENV NAS_DIR="/mnt/auto/sd" +ENV VIRTUAL_NAS="/virtual_nas" RUN --mount=type=cache,target=/var/cache/apt \ apt update && \ - apt install -y --no-install-recommends \ - wget git fonts-dejavu-core rsync git jq moreutils aria2 \ - ffmpeg libglfw3-dev libgles2-mesa-dev pkg-config libcairo2 libcairo2-dev \ - libpython3.9-dev gcc g++ procps unzip curl - -ENV SHA=v1.6.0 -RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git /stable-diffusion-webui && \ - cd stable-diffusion-webui && \ - git reset --hard ${SHA} + apt install -y \ + rsync vim git curl wget jq ffmpeg \ + gcc g++ unzip build-essential \ + fonts-dejavu-core moreutils aria2 libglfw3-dev libgles2-mesa-dev pkg-config \ + libcairo2 libcairo2-dev procps libpython3-dev -RUN --mount=type=bind,from=repositories,source=/repositories,target=/repositories \ - mkdir -p ${ROOT}/repositories/ && \ - cp -R /repositories/* ${ROOT}/repositories/ +# 从依赖镜像获取所需的依赖文件,并映射至 /mnt/auto/sd +RUN --mount=type=bind,from=deps,source=/venv,target=/mnt/venv \ + mkdir -p /venv && \ + cp -R /mnt/venv/* /venv -# 其他必备的依赖 -RUN --mount=type=cache,target=/root/.cache/pip \ - pip install --upgrade pip && \ - pip install -r ${ROOT}/requirements_versions.txt && \ - find ${ROOT}/repositories -name requirements.txt | xargs -I {} pip install -r {} || echo "failed" && \ - pip install rich==13.4.2 numexpr matplotlib pandas av pims imageio_ffmpeg gdown mediapipe==0.10.2 \ - ultralytics==8.0.145 py-cpuinfo protobuf==3.20 rembg==2.0.38 \ - deepdanbooru onnxruntime-gpu jsonschema opencv_contrib_python opencv_python opencv_python_headless packaging Pillow tqdm \ - chardet PyExecJS lxml pathos cryptography openai aliyun-python-sdk-core aliyun-python-sdk-alimt send2trash \ - insightface==0.7.3 tensorflow ifnude && \ - pip install xformers==0.0.20 taming-transformers-rom1504 && \ - pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 +# 获取 Stable Diffusion 代码 +RUN --mount=type=bind,from=repos,source=/code,target=/code \ + mkdir -p ${SD_DIR} && \ + find /code -maxdepth 1 | xargs -I {} cp -r {} "${SD_DIR}" -# fix using lora in only api mode -# COPY ./fix.diff ${ROOT}/fix.diff -# RUN cd ${ROOT} && git apply --whitespace=fix fix.diff +# 使用 venv 环境 +ENV VIRTUAL_ENV="/venv" +ENV PATH="${VIRTUAL_ENV}/bin:$PATH" -FROM sdwebui as base # 启动的时候会下载这个 -COPY --from=download_huggingface /clip-vit-large-patch14 ${SD_BUILTIN}/root/.cache/huggingface/hub/ +COPY --from=download_huggingface /clip-vit-large-patch14 ${BUILTIN}/root/.cache/huggingface/hub/ +RUN --mount=type=bind,from=download_huggingface,source=/init,target=/init \ + mkdir -p ${BUILTIN}/root/.cache/huggingface/hub/ && \ + cp -R /init/models--google--t5-v1_1-xxl ${BUILTIN}/root/.cache/huggingface/hub/ # 面部修复 + 高分辨率修复 359M + 104M + 81.4M -COPY --from=download_sdwebui /codeformer-v0.1.0.pth ${SD_BUILTIN}/models/Codeformer/codeformer-v0.1.0.pth -COPY --from=download_sdwebui /detection_Resnet50_Final.pth ${SD_BUILTIN}/repositories/CodeFormer/weights/facelib/detection_Resnet50_Final.pth -COPY --from=download_sdwebui /parsing_parsenet.pth ${SD_BUILTIN}/repositories/CodeFormer/weights/facelib/parsing_parsenet.pth +COPY --from=download_sdwebui /codeformer-v0.1.0.pth ${BUILTIN}/models/Codeformer/codeformer-v0.1.0.pth +COPY --from=download_sdwebui /detection_Resnet50_Final.pth ${BUILTIN}/repositories/CodeFormer/weights/facelib/detection_Resnet50_Final.pth +COPY --from=download_sdwebui /parsing_parsenet.pth ${BUILTIN}/repositories/CodeFormer/weights/facelib/parsing_parsenet.pth # DeepBooru 反向推导提示词 614M -COPY --from=download_sdwebui /model-resnet_custom_v3.pt ${SD_BUILTIN}/models/torch_deepdanbooru/model-resnet_custom_v3.pt - -ENTRYPOINT ["/docker/entrypoint.sh"] -EXPOSE 7860 - -WORKDIR ${ROOT} - -ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility -ENV NVIDIA_VISIBLE_DEVICES=all - -############################# -# 执行部分文件 # -############################# - -FROM python:3.10.9-slim as execute - -ARG ROOT -ARG SD_BUILTIN -ENV ROOT="${ROOT}" -ENV SD_BUILTIN="${SD_BUILTIN}" - -ARG IMAGE_TAG="" -RUN echo -n ${IMAGE_TAG} > /IMAGE_TAG - - -COPY ./sd-resource ${SD_BUILTIN} - -RUN --mount=type=bind,from=sdwebui,source=/,target=/sdwebui \ - cp -R /sdwebui/${ROOT}/scripts ${SD_BUILTIN}/scripts && \ - cp -R /sdwebui/${ROOT}/extensions-builtin/* ${SD_BUILTIN}/extensions-builtin/ - -RUN sed -i ${SD_BUILTIN}/ui-config.json -e 's@"txt2img/Prompt/value": ""@"txt2img/Prompt/value": "masterpiece, best quality, very detailed, extremely detailed beautiful, super detailed, tousled hair, illustration, dynamic angles, girly, fashion clothing, standing, mannequin, looking at viewer, interview, beach, beautiful detailed eyes, exquisitely beautiful face, floating, high saturation, beautiful and detailed light and shadow"@' -RUN sed -i ${SD_BUILTIN}/ui-config.json -e 's@"txt2img/Negative prompt/value": ""@"txt2img/Negative prompt/value": "loli,nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly"@' - -COPY ./config.json ./entrypoint.sh ./info.py ./sd-agent /docker/ -RUN chmod 777 /docker/sd-agent - -############################# -# 最小可运行版本 # -############################# - -FROM base as lite - -RUN --mount=type=bind,from=execute,source=/,target=/execute \ - cp -R /execute/${SD_BUILTIN}/* ${SD_BUILTIN} && \ - cp -R /execute/docker/ /docker && \ - cp /execute/IMAGE_TAG /IMAGE_TAG - -############################# -# 内置模型 # -############################# - -FROM base as model-base - -# 内置插件 -RUN --mount=type=bind,from=extensions,source=/extensions,target=/extensions \ - mkdir -p ${SD_BUILTIN}/extensions/ && \ - cp -R /extensions/* ${SD_BUILTIN}/extensions/ - -# 中文提示词翻译 299M -COPY --from=download_huggingface /sd-prompt-translator ${SD_BUILTIN}/extensions/sd-prompt-translator/scripts/models -# COPY --from=repositories /bert-base-uncased-cache/* ${SD_BUILTIN}/root/.cache/huggingface/hub/ - -# CLIP 反向推导提示词 614M? 890M? -# https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/10574 -# COPY --from=download_extensions /model_base_caption_capfilt_large.pth ${SD_BUILTIN}/models/BLIP/model_base_caption_capfilt_large.pth - -# roop 554M + -# COPY --from=download_extensions /inswapper_128.onnx ${SD_BUILTIN}/models/roop/inswapper_128.onnx -# COPY --from=download_extensions /detector.onnx ${SD_BUILTIN}/root/.ifnude/detector.onnx -# RUN --mount=type=bind,from=download_extensions,source=/buffalo_l.zip,target=/buffalo_l.zip \ -# mkdir -p ${SD_BUILTIN}/root/.insightface/models && \ -# unzip /buffalo_l.zip -d ${SD_BUILTIN}/root/.insightface/models - -# controlnet -# COPY --from=download_extensions /control_v11p_sd15_scribble.pth ${SD_BUILTIN}/models/ControlNet/control_v11p_sd15_scribble.pth -# COPY --from=download_extensions /control_v11p_sd15_scribble.yaml ${SD_BUILTIN}/models/ControlNet/control_v11p_sd15_scribble.yaml -COPY --from=download_extensions /control_v1p_sd15_illumination.safetensors ${SD_BUILTIN}/models/ControlNet/control_v1p_sd15_illumination.safetensors - -# adetailer -COPY --from=download_huggingface /models--Bingsu--adetailer ${SD_BUILTIN}/root/.cache/huggingface/hub/ - -# 内置模型 -COPY --from=download_models /cIF8Anime2.43ol.ckpt ${SD_BUILTIN}/models/VAE/cIF8Anime2.43ol.ckpt - -# COPY --from=download_models /moxin.safetensors ${SD_BUILTIN}/models/Lora/moxin.safetensors -COPY --from=download_models /milkingMachine_v11.safetensors ${SD_BUILTIN}/models/Lora/milkingMachine_v11.safetensors -COPY --from=download_models /blingdbox_v1_mix.safetensors ${SD_BUILTIN}/models/Lora/blingdbox_v1_mix.safetensors -COPY --from=download_models /GachaSpliash4.safetensors ${SD_BUILTIN}/models/Lora/GachaSpliash4.safetensors -COPY --from=download_models /Colorwater_v4.safetensors ${SD_BUILTIN}/models/Lora/Colorwater_v4.safetensors - - -############################# -# sd1.5 版本 # -############################# - -FROM model-base as sd1.5 - -COPY --from=download_models /sd-v1-5-inpainting.ckpt ${SD_BUILTIN}/models/Stable-diffusion/sd-v1-5-inpainting.ckpt - -RUN --mount=type=bind,from=execute,source=/,target=/execute \ - cp -R /execute/${SD_BUILTIN}/* ${SD_BUILTIN} && \ - cp -R /execute/docker/ /docker && \ - cp /execute/IMAGE_TAG /IMAGE_TAG - -############################# -# 动漫版本 # -############################# - -FROM model-base as anime +COPY --from=download_sdwebui /model-resnet_custom_v3.pt ${BUILTIN}/models/torch_deepdanbooru/model-resnet_custom_v3.pt -COPY --from=download_models /mixProV4.Cqhm.safetensors ${SD_BUILTIN}/models/Stable-diffusion/mixProV4.Cqhm.safetensors +COPY --from=download_sdwebui /clip_g.safetensors ${BUILTIN}/models/CLIP/clip_g.safetensors +COPY --from=download_sdwebui /clip_l.safetensors ${BUILTIN}/models/CLIP/clip_l.safetensors +WORKDIR ${SD_DIR} -RUN --mount=type=bind,from=execute,source=/,target=/execute \ - cp -R /execute/${SD_BUILTIN}/* ${SD_BUILTIN} && \ - cp -R /execute/docker/ /docker && \ - cp /execute/IMAGE_TAG /IMAGE_TAG +ENTRYPOINT [ "/docker/entrypoint.bash" ] -RUN sed -i ${SD_BUILTIN}/config.json -e 's/sd-v1-5-inpainting.ckpt \[c6bbc15e32\]/mixProV4.Cqhm.safetensors \[61e23e57ea\]/' -RUN sed -i ${SD_BUILTIN}/config.json -e 's/c6bbc15e3224e6973459ba78de4998b80b50112b0ae5b5c67113d56b4e366b19/61e23e57ea13765152435b42d55e7062de188ca3234edb82d751cf52f7667d4f/' -RUN sed -i ${SD_BUILTIN}/config.json -e 's/Automatic/cIF8Anime2.43ol.ckpt/' ############################# -# 真人版本 # +# lite 轻量版镜像 # ############################# +FROM base AS lite -FROM model-base as realman +ARG IMAGE_TAG="${IMAGE_TAG}" +ENV IMAGE_TAG=${IMAGE_TAG} -COPY --from=download_models /ChinaDollLikeness.safetensors ${SD_BUILTIN}/models/Lora/ChinaDollLikeness.safetensors -COPY --from=download_models /KoreanDollLikeness.safetensors ${SD_BUILTIN}/models/Lora/KoreanDollLikeness.safetensors -COPY --from=download_models /JapaneseDollLikeness.safetensors ${SD_BUILTIN}/models/Lora/JapaneseDollLikeness.safetensors -COPY --from=download_models /chilloutmix_NiPrunedFp16Fix.safetensors ${SD_BUILTIN}/models/Stable-diffusion/chilloutmix_NiPrunedFp16Fix.safetensors +RUN --mount=type=bind,from=serverless-stable-diffusion-api,source=/code,target=/serverless-api \ + --mount=type=bind,source=/sd-resource,target=/ctx \ + bash /ctx/init.bash -RUN --mount=type=bind,from=execute,source=/,target=/execute \ - cp -R /execute/${SD_BUILTIN}/* ${SD_BUILTIN} && \ - cp -R /execute/docker/ /docker && \ - cp /execute/IMAGE_TAG /IMAGE_TAG -RUN sed -i ${SD_BUILTIN}/config.json -e 's@sd-v1-5-inpainting.ckpt \[c6bbc15e32\]@chilloutmix_NiPrunedFp16Fix.safetensors \[59ffe2243a\]@' -RUN sed -i ${SD_BUILTIN}/config.json -e 's@c6bbc15e3224e6973459ba78de4998b80b50112b0ae5b5c67113d56b4e366b19@59ffe2243a25c9fe137d590eb3c5c3d3273f1b4c86252da11bbdc9568773da0c@' diff --git a/src/code/images/Dockerfile.patch b/src/code/images/Dockerfile.patch deleted file mode 100644 index 6c53924..0000000 --- a/src/code/images/Dockerfile.patch +++ /dev/null @@ -1,5 +0,0 @@ -FROM stable-diffusion:anime-v9 - -RUN pip list | awk '/cu12/ { print $1 }' | sed 's/cu12/cu11/g' | grep -v nvidia-nvjitlink-cu11 | xargs pip install && \ - pip list | awk '/cu12/ { print $1 }' | xargs pip uninstall -y && \ - rm -rf ${SD_BUILTIN}/root/.cache/huggingface/hub/ diff --git a/src/code/images/Dockerfile.sd1.5 b/src/code/images/Dockerfile.sd1.5 new file mode 100644 index 0000000..3597f15 --- /dev/null +++ b/src/code/images/Dockerfile.sd1.5 @@ -0,0 +1,36 @@ +ARG BASE_IMAGE + +############################# +# 内置的模型 # +############################# +FROM python:3.10.9-slim AS models + +RUN apt update && apt install -y aria2 + +RUN aria2c -x 16 --dir "/models" --out "sd-v1-5-inpainting.ckpt" "https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt" + +############################# +# 内置 sd1.5 模型 # +############################# +ARG BASE_IMAGE +FROM "$BASE_IMAGE" AS sd1.5 + +# 内置模型放置到 builtin 目录 +RUN --mount=type=bind,from=models,source=/models,target=/models \ + mkdir -p ${BUILTIN}/models/Stable-diffusion && \ + cp -R /models/* ${BUILTIN}/models/Stable-diffusion/ + +# 提前挂载模型到虚拟 NAS 中 +RUN ln -s ${BUILTIN}/models/Stable-diffusion/sd-v1-5-inpainting.ckpt ${VIRTUAL_NAS}/models/Stable-diffusion/sd-v1-5-inpainting.ckpt + +# 修改默认的提示词 +RUN sed -i "$BUILTIN/ui-config.json" -e 's@"txt2img/Prompt/value": ""@"txt2img/Prompt/value": "masterpiece, best quality, very detailed, extremely detailed beautiful, super detailed, tousled hair, illustration, dynamic angles, girly, fashion clothing, standing, mannequin, looking at viewer, interview, beach, beautiful detailed eyes, exquisitely beautiful face, floating, high saturation, beautiful and detailed light and shadow"@' && \ + sed -i "$BUILTIN/ui-config.json" -e 's@"txt2img/Negative prompt/value": ""@"txt2img/Negative prompt/value": "loli,nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly"@' && \ + sed -i "$VIRTUAL_NAS/ui-config.json" -e 's@"txt2img/Prompt/value": ""@"txt2img/Prompt/value": "masterpiece, best quality, very detailed, extremely detailed beautiful, super detailed, tousled hair, illustration, dynamic angles, girly, fashion clothing, standing, mannequin, looking at viewer, interview, beach, beautiful detailed eyes, exquisitely beautiful face, floating, high saturation, beautiful and detailed light and shadow"@' && \ + sed -i "$VIRTUAL_NAS/ui-config.json" -e 's@"txt2img/Negative prompt/value": ""@"txt2img/Negative prompt/value": "loli,nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly"@' + +# 写出镜像的版本 +ARG IMAGE_TAG="${IMAGE_TAG}" +ENV IMAGE_TAG=${IMAGE_TAG} + +RUN IMAGE_TAG="${IMAGE_TAG:-$(date +%y%m%d%H%M%S)}" && echo "${IMAGE_TAG}" > /IMAGE_TAG diff --git a/src/code/images/Dockerfile.tensorrt b/src/code/images/Dockerfile.tensorrt new file mode 100644 index 0000000..65ecbac --- /dev/null +++ b/src/code/images/Dockerfile.tensorrt @@ -0,0 +1,67 @@ +ARG BASE_IMAGE + +############################# +# 内置的模型 # +############################# +FROM python:3.10.9-slim AS models + +RUN apt update && apt install -y aria2 + +RUN aria2c -x 16 --dir "/models" --out "sd-v1-5-inpainting.ckpt" "https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt" + + +FROM alpine/git:2.36.2 AS extensions + +# Stable-Diffusion-WebUI-TensorRT +RUN git clone https://github.com/NVIDIA/Stable-Diffusion-WebUI-TensorRT.git /extensions/Stable-Diffusion-WebUI-TensorRT && \ + cd /extensions/Stable-Diffusion-WebUI-TensorRT && \ + git reset --hard b75f5604a7e4534899c720ef8db5e15042b2b9f9 + + +############################# +# 内置 sd1.5 模型 # +############################# +ARG BASE_IMAGE +FROM "$BASE_IMAGE" AS tensorrt + +# 将 venv 指回到容器内 +RUN grep -r "/venv" /venv/bin/* | awk -F: "{print \$1}" | xargs -I {} sed "s@${NAS_DIR}/venv@/venv@g" -i {} + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install importlib_metadata nvidia-cudnn-cu11==8.9.4.25 && \ + pip install --pre --extra-index-url https://pypi.nvidia.com tensorrt==9.0.1.post11.dev4 --no-cache-dir tensorrt && \ + pip uninstall -y nvidia-cudnn-cu11 && \ + pip install polygraphy --extra-index-url https://pypi.ngc.nvidia.com && \ + pip install onnx-graphsurgeon --extra-index-url https://pypi.ngc.nvidia.com && \ + pip install optimum + +# 内置模型放置到 builtin 目录 +RUN --mount=type=bind,from=models,source=/models,target=/models \ + mkdir -p ${BUILTIN}/models/Stable-diffusion && \ + cp -R /models/* ${BUILTIN}/models/Stable-diffusion/ + +# 挂载插件 +RUN --mount=type=bind,from=extensions,source=/extensions,target=/extensions \ + mkdir -p ${BUILTIN}/extensions/ && \ + cp -R /extensions/Stable-Diffusion-WebUI-TensorRT ${BUILTIN}/extensions/Stable-Diffusion-WebUI-TensorRT + +# 提前挂载模型、插件到虚拟 NAS 中 +RUN ln -s ${BUILTIN}/models/Stable-diffusion/sd-v1-5-inpainting.ckpt ${VIRTUAL_NAS}/models/Stable-diffusion/sd-v1-5-inpainting.ckpt && \ + ln -s ${BUILTIN}/extensions/Stable-Diffusion-WebUI-TensorRT ${VIRTUAL_NAS}/extensions/Stable-Diffusion-WebUI-TensorRT + +# 修改默认的提示词 +RUN sed -i "$BUILTIN/ui-config.json" -e 's@"txt2img/Prompt/value": ""@"txt2img/Prompt/value": "masterpiece, best quality, very detailed, extremely detailed beautiful, super detailed, tousled hair, illustration, dynamic angles, girly, fashion clothing, standing, mannequin, looking at viewer, interview, beach, beautiful detailed eyes, exquisitely beautiful face, floating, high saturation, beautiful and detailed light and shadow"@' && \ + sed -i "$BUILTIN/ui-config.json" -e 's@"txt2img/Negative prompt/value": ""@"txt2img/Negative prompt/value": "loli,nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly"@' && \ + sed -i "$VIRTUAL_NAS/ui-config.json" -e 's@"txt2img/Prompt/value": ""@"txt2img/Prompt/value": "masterpiece, best quality, very detailed, extremely detailed beautiful, super detailed, tousled hair, illustration, dynamic angles, girly, fashion clothing, standing, mannequin, looking at viewer, interview, beach, beautiful detailed eyes, exquisitely beautiful face, floating, high saturation, beautiful and detailed light and shadow"@' && \ + sed -i "$VIRTUAL_NAS/ui-config.json" -e 's@"txt2img/Negative prompt/value": ""@"txt2img/Negative prompt/value": "loli,nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly"@' && \ + sed -i "s/\"sd_vae\",/\"sd_vae\",\n\"sd_unet\"/g" "${BUILTIN}/config.json" && \ + sed -i "s/\"sd_vae\",/\"sd_vae\",\n\"sd_unet\"/g" "${VIRTUAL_NAS}/config.json" + +# 写出镜像的版本 +ARG IMAGE_TAG="${IMAGE_TAG}" +ENV IMAGE_TAG=${IMAGE_TAG} + +RUN --mount=type=bind,source=/sd-resource,target=/ctx \ + bash /ctx/init.bash + +RUN find -L ${VIRTUAL_NAS} -type l -delete diff --git a/src/code/images/Makefile b/src/code/images/Makefile new file mode 100644 index 0000000..8552513 --- /dev/null +++ b/src/code/images/Makefile @@ -0,0 +1,95 @@ +PWD=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +.PHONY: help +help: ## 帮助文件 + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-40s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +NAMESPACE=aliyun-fc +REPO=fc-stable-diffusion +REGIONS="ap-northeast-1" "cn-hangzhou" "cn-shanghai" "cn-beijing" "cn-shenzhen" "ap-southeast-1" "us-east-1" + +LITE_VERSION="lite-v12" +SD15_VERSION="sd1.5-v21" +TENSORRT_VERSION="tensorrt-v5" + +.PHONY: build-lite +build-lite: ## 构建 Lite 版本 + cd ${PWD} && \ + DOCKER_BUILDKIT=1 docker build -f Dockerfile --target lite --build-arg IMAGE_TAG=${LITE_VERSION} -t ${REPO}:${LITE_VERSION} . + +.PHONY: build-sd1.5 +build-sd1.5: ## 构建 sd 1.5 + cd ${PWD} && \ + DOCKER_BUILDKIT=1 docker build -f Dockerfile.sd1.5 --target sd1.5 --build-arg IMAGE_TAG=${SD15_VERSION} --build-arg BASE_IMAGE=${REPO}:${LITE_VERSION} -t ${REPO}:${SD15_VERSION} . + +.PHONY: build-tensorrt +build-tensorrt: ## 构建 TensorRT + cd ${PWD} && \ + DOCKER_BUILDKIT=1 docker build -f Dockerfile.tensorrt --target tensorrt --build-arg IMAGE_TAG=${TENSORRT_VERSION} --build-arg BASE_IMAGE=${REPO}:${LITE_VERSION} -t ${REPO}:${TENSORRT_VERSION} . + +.PHONY: build +build: build-lite build-sd1.5 # 构建所有 sd 镜像 + +.PHONY: push-lite +push-lite: build-lite ## push lite 镜像 + tag=${LITE_VERSION} && \ + for region in ${REGIONS}; do \ + image=registry.$$region.aliyuncs.com/${NAMESPACE}/${REPO}:$$tag; \ + docker tag ${REPO}:$$tag $$image; \ + docker push $$image; \ + done + +.PHONY: push-sd1.5 +push-sd1.5: ## push sd1.5 镜像 + tag=${SD15_VERSION} && \ + for region in ${REGIONS}; do \ + image=registry.$$region.aliyuncs.com/${NAMESPACE}/${REPO}:$$tag; \ + docker tag ${REPO}:$$tag $$image; \ + docker push $$image; \ + done + +.PHONY: push-tensorrt +push-tensorrt: ## push TensorRT 镜像 + tag=${TENSORRT_VERSION} && \ + for region in ${REGIONS}; do \ + image=registry.$$region.aliyuncs.com/${NAMESPACE}/${REPO}:$$tag; \ + docker tag ${REPO}:$$tag $$image; \ + docker push $$image; \ + done + +push: push-lite push-sd1.5 # 推送所有 sd 镜像 + + +dev: ## 使用动漫风格进行测试 + @eval $(shell for l in $(shell cat .env | grep -v '#'); do echo export $$l; done) && \ + if [ -z "$${FC_REGION}" ] || [ -z "$${FC_ACCOUNT_ID}" ] || [ -z "$${ALIBABA_CLOUD_ACCESS_KEY_ID}" ] || [ -z "$${ALIBABA_CLOUD_ACCESS_KEY_SECRET}" ]; then \ + echo "Please set FC_REGION, FC_ACCOUNT_ID, ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET in .env"; \ + fi && \ + docker run --rm -it --gpus=all --name=sd --net=host \ + -e EXTRA_ARGS="--api" \ + -e FC_REGION=$$FC_REGION \ + -e FC_ACCOUNT_ID=$$FC_ACCOUNT_ID \ + -e ALIBABA_CLOUD_ACCESS_KEY_ID=$$ALIBABA_CLOUD_ACCESS_KEY_ID \ + -e ALIBABA_CLOUD_ACCESS_KEY_SECRET=$$ALIBABA_CLOUD_ACCESS_KEY_SECRET \ + -e HF_HUB_OFFLINE=1 \ + -v ${shell pwd}/nas:/mnt/auto \ + ${REPO}:${SD15_VERSION} + +shell: ## 登入 sd shell 环境 + docker run --rm -it --name=sd --net=host --entrypoint="" -v ${shell pwd}/nas:/mnt/auto ${REPO}:${SD15_VERSION} /bin/bash + +exec: ## 登入容器实例 + docker exec -it sd /bin/bash + + +build-proxy: ## 构建 Serverless Stable Diffusion API Proxy 二进制文件 + cd ${PWD} && \ + mkdir -p ../serverless-stable-diffusion-api && \ + DOCKER_BUILDKIT=1 docker build -f Dockerfile --target serverless-stable-diffusion-api -t serverless-stable-diffusion-api:builder . && \ + docker create --name proxy-builder serverless-stable-diffusion-api:builder && \ + docker cp proxy-builder:/code/build/proxy/proxyServer ../serverless-stable-diffusion-api/proxy && \ + docker rm proxy-builder + + +registry: build-proxy ## 发布到 Serverless Devs Registry + s registry publish \ No newline at end of file diff --git a/src/code/images/clone.sh b/src/code/images/clone.sh deleted file mode 100755 index 7b9fa17..0000000 --- a/src/code/images/clone.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -Eeuox pipefail - -mkdir -p "$1" -cd "$1" -git init -git remote add origin "$2" -git fetch origin "$3" --depth=1 --tag -git reset --hard "$3" -rm -rf .git \ No newline at end of file diff --git a/src/code/images/config.json b/src/code/images/config.json deleted file mode 100644 index 9369c06..0000000 --- a/src/code/images/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "outdir_samples": "", - "outdir_txt2img_samples": "/mnt/auto/sd/outputs/txt2img", - "outdir_img2img_samples": "/mnt/auto/sd/outputs/img2img", - "outdir_extras_samples": "/mnt/auto/sd/outputs/extras", - "outdir_txt2img_grids": "/mnt/auto/sd/outputs/txt2img-grids", - "outdir_img2img_grids": "/mnt/auto/sd/outputs/img2img-grids", - "outdir_save": "/mnt/auto/sd/outputs/saved", - "font": "DejaVuSans.ttf" -} \ No newline at end of file diff --git a/src/code/images/entrypoint.sh b/src/code/images/entrypoint.sh deleted file mode 100755 index 87c348c..0000000 --- a/src/code/images/entrypoint.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -function set_start_time() { - START_TIME=$(date '+%s.%N') -} - -function show_cost_time() { - echo "$START_TIME $(date '+%s.%N')" | awk "{printf \"$1, cost %f seconds\n\", \$2 - \$1}" -} - -function mount_file() { - echo Mount $1 to $2 - - SRC="$1" - DST="$2" - - rm -rf "${DST}" - - if [ ! -f "${SRC}" ]; then - mkdir -pv "${SRC}" - fi - - mkdir -pv "$(dirname "${DST}")" - - ln -sT "${SRC}" "${DST}" -} - - -NAS_DIR="/mnt/auto/sd" - -# 内置模型准备 -# 如果挂载了 NAS,软链接到 NAS 中 -# 如果未挂载 NAS,则尝试直接将内置模型过载 -NAS_MOUNTED=0 -if [ -d "/mnt/auto" ]; then - NAS_MOUNTED=1 -fi - -if [ "$NAS_MOUNTED" == "0" ]; then - echo "without NAS, mount $SD_BUILTIN to ${NAS_DIR}" - mount_file "$SD_BUILTIN" "${NAS_DIR}" -else - mkdir -p "${NAS_DIR}" - - - IMAGE_TAG_I=$(cat /IMAGE_TAG) - IMAGE_TAG_N=$(cat /${NAS_DIR}/IMAGE_TAG 2>/dev/null || echo '') - - echo "IMAGE_TAG [[${IMAGE_TAG_I}]] [[${IMAGE_TAG_N}]]" - - if [ "${IMAGE_TAG_I}" != "${IMAGE_TAG_N}" ]; then - # 去除无用的软链接/空文件夹 - set_start_time - find -L ${NAS_DIR} -type l -delete - find ${NAS_DIR} -type d -empty -delete - show_cost_time "remove symbolic links" - - - - echo "with NAS, mount built-in files to ${NAS_DIR}" - - set_start_time - - find ${SD_BUILTIN} | while read -r file; do - SRC="${file}" - DST="${NAS_DIR}/${file#$SD_BUILTIN/}" - - if [ ! -e "$DST" ] && [ ! -d "$SRC" ] && [ "$DST" != "${NAS_DIR}/config.json" ] && [ "$DST" != "${NAS_DIR}/ui-config.json" ]; then - mount_file "$SRC" "$DST" - fi - done - - if [ ! -e "${NAS_DIR}/ui-config.json" ]; then - echo "no ui-config.json, copy it" - cp "${SD_BUILTIN}/ui-config.json" "${NAS_DIR}/ui-config.json" - fi - - show_cost_time "mount built-in files" - - - echo -n ${IMAGE_TAG_I} > /${NAS_DIR}/IMAGE_TAG - fi -fi - - -if [ ! -e "${NAS_DIR}/config.json" ]; then - echo "no config.json, copy it" - cp "${SD_BUILTIN}/config.json" "${NAS_DIR}/config.json" -fi - -if [ "$(wc -c ${NAS_DIR}/config.json | cut -f 1 -d ' ')" == "0" ]; then - echo "config.json is empty, copy it" - rm -f "${SD_BUILTIN}/config.json" - cp "${SD_BUILTIN}/config.json" "${NAS_DIR}/config.json" -fi - -if [ ! -e "${NAS_DIR}/styles.csv" ]; then - echo "no styles.csv, create it" - touch "${NAS_DIR}/styles.csv" -fi - - -declare -A MOUNTS - -MOUNTS["/root"]="${NAS_DIR}/root" -MOUNTS["${ROOT}/models"]="${NAS_DIR}/models" -MOUNTS["${ROOT}/localizations"]="${NAS_DIR}/localizations" -MOUNTS["${ROOT}/configs"]="${NAS_DIR}/configs" -MOUNTS["${ROOT}/extensions-builtin"]="${NAS_DIR}/extensions-builtin" -MOUNTS["${ROOT}/embeddings"]="${NAS_DIR}/embeddings" -MOUNTS["${ROOT}/config.json"]="${NAS_DIR}/config.json" -MOUNTS["${ROOT}/ui-config.json"]="${NAS_DIR}/ui-config.json" -MOUNTS["${ROOT}/extensions"]="${NAS_DIR}/extensions" -MOUNTS["${ROOT}/outputs"]="${NAS_DIR}/outputs" -MOUNTS["${ROOT}/styles.csv"]="${NAS_DIR}/styles.csv" -# MOUNTS["${ROOT}/cache.json"]="${NAS_DIR}/cache.json" -MOUNTS["${ROOT}/scripts"]="${NAS_DIR}/scripts" -MOUNTS["${ROOT}/textual_inversion_templates"]="${NAS_DIR}/textual_inversion_templates" -# MOUNTS["${ROOT}/javascript"]="${NAS_DIR}/javascript" -# MOUNTS["${ROOT}/html"]="${NAS_DIR}/html" -MOUNTS["${ROOT}/repositories/CodeFormer/weights/facelib"]="${NAS_DIR}/repositories/CodeFormer/weights/facelib" - - -for to_path in "${!MOUNTS[@]}"; do - mount_file "${MOUNTS[${to_path}]}" "${to_path}" -done - -if [ -f "/mnt/auto/sd/startup.sh" ]; then - pushd ${ROOT} - . /mnt/auto/sd/startup.sh - popd -fi - -CLI_ARGS="${CLI_ARGS:---xformers --enable-insecure-extension-access --skip-version-check --no-download-sd-model}" -EXTRA_ARGS="${EXTRA_ARGS:-}" -DISABLE_AGENT="${DISABLE_AGENT:-}" - -export ARGS="${CLI_ARGS} ${EXTRA_ARGS}" -export PYTHONPATH="${PYTHONPATH:-}:${NAS_DIR}/python" -export SD_WEBUI_CACHE_FILE="/mnt/auto/sd/cache.json" - -echo "args: $ARGS" - -if [ -z "$DISABLE_AGENT" ]; then - /docker/sd-agent python -u webui.py --listen --port 7861 ${ARGS} -else - python -u webui.py --listen --port 7860 ${ARGS} -fi diff --git a/src/code/images/fix.diff b/src/code/images/fix.diff deleted file mode 100644 index 9da60b7..0000000 --- a/src/code/images/fix.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/webui.py b/webui.py -index 6bf06854..e44b755e 100644 ---- a/webui.py -+++ b/webui.py -@@ -368,6 +368,7 @@ def api_only(): - setup_middleware(app) - api = create_api(app) - -+ modules.script_callbacks.before_ui_callback() - modules.script_callbacks.app_started_callback(None, app) - - print(f"Startup time: {startup_timer.summary()}.") diff --git a/src/code/images/info.py b/src/code/images/info.py deleted file mode 100644 index 6ee9bc8..0000000 --- a/src/code/images/info.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys -from pathlib import Path - -file = Path(sys.argv[1]) -file.write_text( - file.read_text()\ - .replace(' return demo', """ - with demo: - gr.Markdown( - 'Created by [AUTOMATIC1111 / stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker/)' - ) - return demo -""", 1) -) \ No newline at end of file diff --git a/src/code/images/init/models--google--t5-v1_1-xxl.tar.gz b/src/code/images/init/models--google--t5-v1_1-xxl.tar.gz new file mode 100644 index 0000000..4d037eb Binary files /dev/null and b/src/code/images/init/models--google--t5-v1_1-xxl.tar.gz differ diff --git a/src/code/images/plus.sh b/src/code/images/plus.sh deleted file mode 100644 index 5b8ccf5..0000000 --- a/src/code/images/plus.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -# TODO: move all mkdir -p ? -mkdir -p /mnt/auto/sd/scripts/ -# mount scripts individually -find "${ROOT}/scripts/" -maxdepth 1 -type l -delete -cp -vrfTs /mnt/auto/sd/scripts/ "${ROOT}/scripts/" - -cp -n /docker/config.json /mnt/auto/sd/config.json -jq '. * input' /mnt/auto/sd/config.json /docker/config.json | sponge /mnt/auto/sd/config.json - -if [ ! -f /mnt/auto/sd/ui-config.json ]; then - echo '{}' >/mnt/auto/sd/ui-config.json -fi - -declare -A MOUNTS - -MOUNTS["/root/.cache"]="/mnt/auto/sd/.cache" - - -MOUNTS["${ROOT}/models"]="/mnt/auto/sd/models" - -MOUNTS["${ROOT}/localizations"]="/mnt/auto/sd/localizations" - -MOUNTS["${ROOT}/configs"]="/mnt/auto/sd/configs" - -MOUNTS["${ROOT}/extensions-builtin"]="/mnt/auto/sd/extensions-builtin" - - -MOUNTS["${ROOT}/embeddings"]="/mnt/auto/sd/embeddings" -MOUNTS["${ROOT}/config.json"]="/mnt/auto/sd/config.json" -MOUNTS["${ROOT}/ui-config.json"]="/mnt/auto/sd/ui-config.json" -MOUNTS["${ROOT}/extensions"]="/mnt/auto/sd/extensions" -MOUNTS["${ROOT}/outputs"]="/mnt/auto/sd/outputs" -# MOUNTS["${ROOT}/javascript"]="/mnt/auto/sd/javascript" -# MOUNTS["${ROOT}/html"]="/mnt/auto/sd/html" - -# extra hacks -MOUNTS["${ROOT}/repositories/CodeFormer/weights/facelib"]="/mnt/auto/sd/.cache" - -for to_path in "${!MOUNTS[@]}"; do - set -Eeuo pipefail - from_path="${MOUNTS[${to_path}]}" - rm -rf "${to_path}" - if [ ! -f "$from_path" ]; then - mkdir -vp "$from_path" - fi - mkdir -vp "$(dirname "${to_path}")" - ln -sT "${from_path}" "${to_path}" - echo Mounted $(basename "${from_path}") -done - -if [ -f "/mnt/auto/sd/startup.sh" ]; then - pushd ${ROOT} - . /mnt/auto/sd/startup.sh - popd -fi - -exec "$@" \ No newline at end of file diff --git a/src/code/images/requirements_versions.txt b/src/code/images/requirements_versions.txt deleted file mode 100644 index cd2a41b..0000000 --- a/src/code/images/requirements_versions.txt +++ /dev/null @@ -1,30 +0,0 @@ -blendmodes==2022 -transformers==4.25.1 -accelerate==0.18.0 -basicsr==1.4.2 -gfpgan==1.3.8 -gradio==3.29.0 -numpy==1.23.5 -Pillow==9.4.0 -realesrgan==0.3.0 -torch -omegaconf==2.2.3 -pytorch_lightning==1.9.4 -scikit-image==0.19.2 -fonts -font-roboto -timm==0.6.7 -piexif==1.1.3 -einops==0.4.1 -jsonmerge==1.8.0 -clean-fid==0.1.29 -resize-right==0.0.2 -torchdiffeq==0.2.3 -kornia==0.6.7 -lark==1.1.2 -inflection==0.5.1 -GitPython==3.1.30 -torchsde==0.2.5 -safetensors==0.3.1 -httpcore<=0.15 -fastapi==0.90.1 \ No newline at end of file diff --git a/src/code/images/sd-agent b/src/code/images/sd-agent deleted file mode 100644 index 9a00494..0000000 Binary files a/src/code/images/sd-agent and /dev/null differ diff --git a/src/code/images/sd-resource/config.json b/src/code/images/sd-resource/config.json index 5c34f9d..32c849f 100644 --- a/src/code/images/sd-resource/config.json +++ b/src/code/images/sd-resource/config.json @@ -130,7 +130,7 @@ "hidden_tabs": [], "ui_reorder": "inpaint, sampler, checkboxes, hires_fix, dimensions, cfg, seed, batch, override_settings, scripts", "ui_extra_networks_tab_reorder": "", - "localization": "chinese-all-0722", + "localization": "chinese-only-0313", "show_progressbar": true, "live_previews_enable": true, "show_progress_grid": true, @@ -163,8 +163,221 @@ "stable-diffusion-webui-images-browser", "stable-diffusion-webui-rembg", "stable-diffusion-webui-wd14-tagger", - "stable-diffusion-webui-dataset-tag-editor" + "stable-diffusion-webui-dataset-tag-editor", + "sd-prompt-translator" ], "upscaling_max_images_in_cache": 5, - "disable_mmap_load_safetensors": true -} + "extra_options_txt2img": [ + "face_restoration" + ], + "face_restoration": false, + "sd_vae_overrides_per_model_preferences": false, + "ui_reorder_list": [ + "inpaint", + "sampler", + "checkboxes", + "hires_fix", + "dimensions", + "cfg", + "seed", + "batch", + "override_settings", + "scripts" + ], + "SCUNET_tile": 256, + "SCUNET_tile_overlap": 8, + "SWIN_torch_compile": false, + "hypertile_enable_unet": false, + "hypertile_enable_unet_secondpass": false, + "hypertile_max_depth_unet": 3, + "hypertile_max_tile_unet": 256, + "hypertile_swap_size_unet": 3, + "hypertile_enable_vae": false, + "hypertile_max_depth_vae": 3, + "hypertile_max_tile_vae": 128, + "hypertile_swap_size_vae": 3, + "outdir_init_images": "outputs/init-images", + "save_images_replace_action": "Replace", + "grid_zip_filename_pattern": "", + "grid_text_active_color": "#000000", + "grid_text_inactive_color": "#999999", + "grid_background_color": "#ffffff", + "save_mask": false, + "save_mask_composite": false, + "save_init_img": false, + "save_incomplete_images": false, + "notification_audio": true, + "notification_volume": 100, + "auto_backcompat": true, + "dont_fix_second_order_samplers_schedule": false, + "hires_fix_use_firstpass_conds": false, + "use_old_scheduling": false, + "use_downcasted_alpha_bar": false, + "refiner_switch_by_sample_steps": false, + "lora_functional": false, + "extra_networks_show_hidden_directories": true, + "extra_networks_dir_button_function": false, + "extra_networks_hidden_models": "When searched", + "extra_networks_card_width": 0.0, + "extra_networks_card_height": 0.0, + "extra_networks_card_text_scale": 1, + "extra_networks_card_show_desc": true, + "extra_networks_card_description_is_html": false, + "extra_networks_card_order_field": "Path", + "extra_networks_card_order": "Ascending", + "extra_networks_tree_view_style": "Dirs", + "extra_networks_tree_view_default_enabled": true, + "extra_networks_tree_view_default_width": 180.0, + "textual_inversion_print_at_load": false, + "textual_inversion_add_hashes_to_infotext": true, + "lora_preferred_name": "Alias from file", + "lora_add_hashes_to_infotext": true, + "lora_bundled_ti_to_infotext": true, + "lora_show_all": false, + "lora_hide_unknown_for_versions": [], + "lora_in_memory_limit": 0, + "lora_not_found_warning_console": false, + "lora_not_found_gradio_warning": false, + "cross_attention_optimization": "Automatic", + "s_min_uncond": 0, + "s_min_uncond_all": false, + "token_merging_ratio": 0, + "token_merging_ratio_img2img": 0, + "token_merging_ratio_hr": 0, + "pad_cond_uncond": false, + "pad_cond_uncond_v0": false, + "persistent_cond_cache": true, + "batch_cond_uncond": true, + "fp8_storage": "Disable", + "cache_fp16_weight": false, + "s_tmax": 0, + "sigma_min": 0.0, + "sigma_max": 0.0, + "rho": 0.0, + "sgm_noise_multiplier": false, + "sd_noise_schedule": "Default", + "skip_early_cond": 0, + "sd_checkpoints_limit": 1, + "sd_checkpoints_keep_in_cpu": true, + "sd_unet": "Automatic", + "emphasis": "Original", + "sdxl_clip_l_skip": false, + "randn_source": "GPU", + "tiling": false, + "hires_fix_refiner_pass": "second pass", + "enable_prompt_comments": true, + "sdxl_crop_top": 0.0, + "sdxl_crop_left": 0.0, + "sdxl_refiner_low_aesthetic_score": 2.5, + "sdxl_refiner_high_aesthetic_score": 6.0, + "auto_vae_precision_bfloat16": false, + "auto_vae_precision": true, + "sd_vae_encode_method": "Full", + "sd_vae_decode_method": "Full", + "img2img_extra_noise": 0, + "img2img_editor_height": 720, + "img2img_sketch_default_brush_color": "#ffffff", + "img2img_inpaint_mask_brush_color": "#ffffff", + "img2img_inpaint_sketch_default_brush_color": "#ffffff", + "return_mask": false, + "return_mask_composite": false, + "img2img_batch_show_results_limit": 32, + "overlay_inpaint": true, + "js_modal_lightbox_gamepad": false, + "js_modal_lightbox_gamepad_repeat": 250.0, + "sd_webui_modal_lightbox_icon_opacity": 1, + "sd_webui_modal_lightbox_toolbar_opacity": 0.9, + "gallery_height": "", + "open_dir_button_choice": "Subdirectory", + "add_vae_name_to_info": true, + "add_vae_hash_to_info": true, + "add_user_name_to_info": false, + "add_version_to_infotext": true, + "infotext_skip_pasting": [], + "infotext_styles": "Apply if any", + "live_previews_image_format": "png", + "live_preview_allow_lowvram_full": false, + "live_preview_fast_interrupt": false, + "js_live_preview_in_modal_lightbox": false, + "prevent_screen_sleep_during_generation": true, + "keyedit_delimiters": ".,\\/!?%^*;:{}=`~() ", + "keyedit_delimiters_whitespace": [ + "Tab", + "Carriage Return", + "Line Feed" + ], + "keyedit_move": true, + "disable_token_counters": false, + "include_styles_into_token_counters": true, + "extra_options_img2img": [], + "extra_options_cols": 1, + "extra_options_accordion": false, + "compact_prompt_box": false, + "sd_checkpoint_dropdown_use_short": false, + "hires_fix_show_sampler": false, + "hires_fix_show_prompts": false, + "txt2img_settings_accordion": false, + "img2img_settings_accordion": false, + "interrupt_after_current": true, + "ui_tab_order": [], + "gradio_theme": "Default", + "gradio_themes_cache": true, + "enable_reloading_ui_scripts": false, + "api_enable_requests": true, + "api_forbid_local_requests": true, + "api_useragent": "", + "prioritized_callbacks_app_started": [], + "prioritized_callbacks_model_loaded": [], + "prioritized_callbacks_ui_settings": [], + "prioritized_callbacks_infotext_pasted": [], + "prioritized_callbacks_script_unloaded": [], + "prioritized_callbacks_before_ui": [], + "prioritized_callbacks_list_optimizers": [], + "prioritized_callbacks_before_token_counter": [], + "prioritized_callbacks_script_before_process": [], + "prioritized_callbacks_script_process": [], + "prioritized_callbacks_script_postprocess": [], + "prioritized_callbacks_script_post_sample": [], + "prioritized_callbacks_script_on_mask_blend": [], + "prioritized_callbacks_script_postprocess_maskoverlay": [], + "profiling_enable": false, + "profiling_activities": [ + "CPU" + ], + "profiling_record_shapes": true, + "profiling_profile_memory": true, + "profiling_with_stack": true, + "profiling_filename": "trace.json", + "auto_launch_browser": "Local", + "enable_console_prompts": false, + "show_gradio_deprecation_warnings": true, + "enable_upscale_progressbar": true, + "list_hidden_files": true, + "disable_mmap_load_safetensors": false, + "hide_ldm_prints": true, + "dump_stacks_on_signal": false, + "postprocessing_disable_in_extras": [], + "postprocessing_existing_caption_action": "Ignore", + "dat_enabled_models": [ + "DAT x2", + "DAT x3", + "DAT x4" + ], + "DAT_tile": 192, + "DAT_tile_overlap": 8, + "set_scale_by_when_changing_upscaler": false, + "canvas_hotkey_zoom": "Alt", + "canvas_hotkey_adjust": "Ctrl", + "canvas_hotkey_shrink_brush": "Q", + "canvas_hotkey_grow_brush": "W", + "canvas_hotkey_move": "F", + "canvas_hotkey_fullscreen": "S", + "canvas_hotkey_reset": "R", + "canvas_hotkey_overlap": "O", + "canvas_show_tooltip": true, + "canvas_auto_expand": true, + "canvas_blur_prompt": false, + "canvas_disabled_functions": [ + "Overlap" + ] +} \ No newline at end of file diff --git a/src/code/images/sd-resource/entrypoint.bash b/src/code/images/sd-resource/entrypoint.bash new file mode 100644 index 0000000..0708da2 --- /dev/null +++ b/src/code/images/sd-resource/entrypoint.bash @@ -0,0 +1,114 @@ +#!/bin/bash + +set -Eeuo pipefail + +source /etc/profile + +function set_start_time() { + START_TIME=$(date '+%s.%N') +} + +function show_cost_time() { + echo "$START_TIME $(date '+%s.%N')" | awk "{printf \"$1, cost %f seconds\n\", \$2 - \$1}" +} + +function mount_file_if_not_exist() { + SRC="$1" + DST="$2" + + mkdir -p "$(dirname "${DST}")" + + # 如果文件已经存在,则跳过 + if [ ! -e ${DST} ]; then + ln -sT "${SRC}" "${DST}" + fi +} + +function mount_builtin_files() { + set_start_time + + rsync -a --ignore-existing ${VIRTUAL_NAS}/* ${NAS_DIR} + + if [ "$(wc -c ${NAS_DIR}/config.json | cut -f 1 -d ' ')" == "0" ]; then + echo "config.json is empty, copy it" + rm -f "${BUILTIN}/config.json" + cp "${BUILTIN}/config.json" "${NAS_DIR}/config.json" + fi + + local dirs=("extensions" "models" "localizations" "configs" "extensions-builtin" \ + "embeddings" "config.json" "ui-config.json" "outputs" "styles.csv" \ + "scripts" "textual_inversion_templates" "repositories/CodeFormer/weights/facelib") + for dir in ${dirs[@]}; do + local src="${NAS_DIR}/${dir}" + local dst="${SD_DIR}/${dir}" + rm -rf $dst + mount_file_if_not_exist $src $dst + done + + + mkdir -p "${NAS_DIR}/root" "${NAS_DIR}/temp" + rm -rf /root /tmp + mount_file_if_not_exist "${NAS_DIR}/root" "/root" + mount_file_if_not_exist "${NAS_DIR}/temp" "/tmp" + + show_cost_time "mount built-in files" +} + + +# 内置模型准备 +# 如果挂载了 NAS,软链接到 NAS 中 +# 如果未挂载 NAS,则尝试直接将内置模型过载 +NAS_MOUNTED=0 +if [ -d "/mnt/auto" ]; then + NAS_MOUNTED=1 +fi + +mkdir -p ${NAS_DIR} + +if [ "$NAS_MOUNTED" == "0" ]; then + echo "without NAS" +else + echo "with NAS" + + IMAGE_TAG_I=$(cat /IMAGE_TAG) + IMAGE_TAG_N=$(cat ${NAS_DIR}/IMAGE_TAG 2>/dev/null || echo '') + + echo "IMAGE_TAG [[${IMAGE_TAG_I}]] [[${IMAGE_TAG_N}]]" + + if [ "${IMAGE_TAG_I}" != "${IMAGE_TAG_N}" ]; then + # 去除无用的软链接/空文件夹 + echo "remove unused links" + + set_start_time + find -L ${NAS_DIR} -type l -delete + find ${NAS_DIR} ! -wholename ${NAS_DIR} -type d -empty -delete + show_cost_time "remove symbolic links" + + echo -n ${IMAGE_TAG_I} > ${NAS_DIR}/IMAGE_TAG + fi +fi + +mount_builtin_files + +if [ -f "${NAS_DIR}/startup.sh" ]; then + pushd ${NAS_DIR} + . ${NAS_DIR}/startup.sh + popd +fi + +CLI_ARGS="${CLI_ARGS:---xformers --enable-insecure-extension-access --skip-version-check --no-download-sd-model --gradio-allowed-path=/}" +EXTRA_ARGS="${EXTRA_ARGS:-}" +DISABLE_AGENT="${DISABLE_AGENT:-}" + +export ARGS="${CLI_ARGS} ${EXTRA_ARGS}" +export PYTHONPATH="${PYTHONPATH:-}:${NAS_DIR}/python" +export SD_WEBUI_CACHE_FILE="/mnt/auto/sd/cache.json" + +echo "args: $ARGS" + +if [ -z "$DISABLE_AGENT" ]; then + /docker/sd-agent -port=7860 -dbType=tableStore -sd="python -u webui.py --listen --port 7861 ${ARGS}" +else + python -u webui.py --listen --port 7860 ${ARGS} +fi + diff --git a/src/code/images/sd-resource/extensions-builtin/tablestore-sd-manager-extension/scripts/tablestore-sd-manager.py b/src/code/images/sd-resource/extensions-builtin/tablestore-sd-manager-extension/scripts/tablestore-sd-manager.py index 123ccfc..c4721bc 100644 --- a/src/code/images/sd-resource/extensions-builtin/tablestore-sd-manager-extension/scripts/tablestore-sd-manager.py +++ b/src/code/images/sd-resource/extensions-builtin/tablestore-sd-manager-extension/scripts/tablestore-sd-manager.py @@ -1,6 +1,7 @@ import json import os import re +import traceback import urllib.request from datetime import datetime, timezone, timedelta @@ -39,28 +40,39 @@ def ui(self, is_img2img): return [] def postprocess(self, p: processing.StableDiffusionProcessing, processed: processing.Processed): - if not self.is_enabled(): - return - - for index, image in enumerate(processed.images): - data = dict() - data["interrupted"] = shared.state.interrupted - data["skipped"] = shared.state.skipped - data["isTxt2Img"] = self.is_txt2img - data["isImg2Img"] = self.is_img2img - data['comments'] = getattr(processed, 'comments', None) - job_timestamp = datetime.strptime(processed.job_timestamp, '%Y%m%d%H%M%S') - data['usedTimeInSeconds'] = round(datetime.now().timestamp() - job_timestamp.timestamp()) - data['jobStartTime'] = job_timestamp.astimezone(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S") - already_saved_as = getattr(image, 'already_saved_as', None) - if already_saved_as.startswith("/"): - data['imagePath'] = already_saved_as - else: - data['imagePath'] = "%s/%s" % (scripts.shared.data_path, already_saved_as) if already_saved_as is not None else None - data['parameters'] = image.info['parameters'] - all_parameters = self.__parse_parameters(data['parameters']) - data.update(all_parameters) - self.__send_data(data) + try: + if not self.is_enabled(): + return + + for index, image in enumerate(processed.images): + try: + data = dict() + data["interrupted"] = shared.state.interrupted + data["skipped"] = shared.state.skipped + data["isTxt2Img"] = self.is_txt2img + data["isImg2Img"] = self.is_img2img + data['comments'] = getattr(processed, 'comments', None) + job_timestamp = datetime.strptime(processed.job_timestamp, '%Y%m%d%H%M%S') + data['usedTimeInSeconds'] = round(datetime.now().timestamp() - job_timestamp.timestamp()) + data['jobStartTime'] = job_timestamp.astimezone(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S") + already_saved_as = getattr(image, 'already_saved_as', None) + if type(already_saved_as) != str: + print("already_saved_as isn't string, data:", data) + continue + if already_saved_as.startswith("/"): + data['imagePath'] = already_saved_as + else: + data['imagePath'] = "%s/%s" % (scripts.shared.data_path, already_saved_as) if already_saved_as is not None else None + data['parameters'] = image.info['parameters'] + all_parameters = self.__parse_parameters(data['parameters']) + data.update(all_parameters) + self.__send_data(data) + except Exception as e: + print("table store sd extension parse image info error", e) + traceback.print_exc() + except Exception as e: + print("table store sd extension error", e) + traceback.print_exc() return def __send_data(self, data: dict): diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/.gitignore b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/.gitignore deleted file mode 100644 index 6e3fbe8..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/LICENSE b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/LICENSE deleted file mode 100644 index fadc367..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Adi Eyal - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/README.md b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/README.md deleted file mode 100644 index 6879dce..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Easy Prompt Selector - -[使い方(暫定)](https://blue-pen5805.fanbox.cc/posts/5306601) diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/easy_prompt_selector.js b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/easy_prompt_selector.js deleted file mode 100644 index 60d49cc..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/easy_prompt_selector.js +++ /dev/null @@ -1,342 +0,0 @@ -class EPSElementBuilder { - // Templates - static baseButton(text, { size = 'sm', color = 'primary' }) { - const button = gradioApp().getElementById('txt2img_generate').cloneNode() - button.id = '' - button.classList.remove('gr-button-lg', 'gr-button-primary', 'lg', 'primary') - button.classList.add( - // gradio 3.16 - `gr-button-${size}`, - `gr-button-${color}`, - // gradio 3.22 - size, - color - ) - button.textContent = text - - return button - } - - static tagFields() { - const fields = document.createElement('div') - fields.style.display = 'flex' - fields.style.flexDirection = 'row' - fields.style.flexWrap = 'wrap' - fields.style.minWidth = 'min(320px, 100%)' - fields.style.maxWidth = '100%' - fields.style.flex = '1 calc(50% - 20px)' - fields.style.borderWidth = '1px' - fields.style.borderColor = 'var(--block-border-color,#374151)' - fields.style.borderRadius = 'var(--block-radius,8px)' - fields.style.padding = '8px' - fields.style.height = 'fit-content' - - return fields - } - - // Elements - static openButton({ onClick }) { - const button = EPSElementBuilder.baseButton('🔯提示词', { size: 'sm', color: 'secondary' }) - button.classList.add('easy_prompt_selector_button') - button.addEventListener('click', onClick) - - return button - } - - static areaContainer(id = undefined) { - const container = gradioApp().getElementById('txt2img_results').cloneNode() - container.id = id - container.style.gap = 0 - container.style.display = 'none' - - return container - } - - static tagButton({ title, onClick, onRightClick, color = 'primary' }) { - const button = EPSElementBuilder.baseButton(title, { color }) - button.style.height = '2rem' - button.style.flexGrow = '0' - button.style.margin = '2px' - - button.addEventListener('click', onClick) - button.addEventListener('contextmenu', onRightClick) - - return button - } - - static dropDown(id, options, { onChange }) { - const select = document.createElement('select') - select.id = id - - // gradio 3.16 - select.classList.add('gr-box', 'gr-input') - - // gradio 3.22 - select.style.color = 'var(--body-text-color)' - select.style.backgroundColor = 'var(--input-background-fill)' - select.style.borderColor = 'var(--block-border-color)' - select.style.borderRadius = 'var(--block-radius)' - select.style.margin = '2px' - select.addEventListener('change', (event) => { onChange(event.target.value) }) - - const none = ['空'] - none.concat(options).forEach((key) => { - const option = document.createElement('option') - option.value = key - option.textContent = key - select.appendChild(option) - }) - - return select - } - - static checkbox(text, { onChange }) { - const label = document.createElement('label') - label.style.display = 'flex' - label.style.alignItems = 'center' - - const checkbox = gradioApp().querySelector('input[type=checkbox]').cloneNode() - checkbox.checked = false - checkbox.addEventListener('change', (event) => { - onChange(event.target.checked) - }) - - const span = document.createElement('span') - span.style.marginLeft = 'var(--size-2, 8px)' - span.textContent = text - - label.appendChild(checkbox) - label.appendChild(span) - - return label - } -} - -class EasyPromptSelector { - PATH_FILE = 'tmp/easyPromptSelector.txt' - AREA_ID = 'easy-prompt-selector' - SELECT_ID = 'easy-prompt-selector-select' - CONTENT_ID = 'easy-prompt-selector-content' - TO_NEGATIVE_PROMPT_ID = 'easy-prompt-selector-to-negative-prompt' - - constructor(yaml, gradioApp) { - this.yaml = yaml - this.gradioApp = gradioApp - this.visible = false - this.toNegative = false - this.tags = undefined - } - - async init() { - this.tags = await this.parseFiles() - - const tagArea = gradioApp().querySelector(`#${this.AREA_ID}`) - if (tagArea != null) { - this.visible = false - this.changeVisibility(tagArea, this.visible) - tagArea.remove() - } - - gradioApp() - .getElementById('txt2img_toprow') - .after(this.render()) - } - - async readFile(filepath) { - const response = await fetch(`file=${filepath}?${new Date().getTime()}`); - - return await response.text(); - } - - async parseFiles() { - const text = await this.readFile(this.PATH_FILE); - if (text === '') { return {} } - - const paths = text.split(/\r\n|\n/) - - const tags = {} - for (const path of paths) { - const filename = path.split('/').pop().split('.').shift() - const data = await this.readFile(path) - yaml.loadAll(data, function (doc) { - tags[filename] = doc - }) - } - - return tags - } - - // Render - render() { - const row = document.createElement('div') - row.style.display = 'flex' - row.style.alignItems = 'center' - row.style.gap = '10px' - - const dropDown = this.renderDropdown() - dropDown.style.flex = '1' - dropDown.style.minWidth = '1' - row.appendChild(dropDown) - - const settings = document.createElement('div') - const checkbox = EPSElementBuilder.checkbox('负面提示词', { - onChange: (checked) => { this.toNegative = checked } - }) - settings.style.flex = '1' - settings.appendChild(checkbox) - - row.appendChild(settings) - - const container = EPSElementBuilder.areaContainer(this.AREA_ID) - - container.appendChild(row) - container.appendChild(this.renderContent()) - - return container - } - - renderDropdown() { - const dropDown = EPSElementBuilder.dropDown( - this.SELECT_ID, - Object.keys(this.tags), { - onChange: (selected) => { - const content = gradioApp().getElementById(this.CONTENT_ID) - Array.from(content.childNodes).forEach((node) => { - const visible = node.id === `easy-prompt-selector-container-${selected}` - this.changeVisibility(node, visible) - }) - } - } - ) - - return dropDown - } - - renderContent() { - const content = document.createElement('div') - content.id = this.CONTENT_ID - - Object.keys(this.tags).forEach((key) => { - const values = this.tags[key] - - const fields = EPSElementBuilder.tagFields() - fields.id = `easy-prompt-selector-container-${key}` - fields.style.display = 'none' - fields.style.flexDirection = 'row' - fields.style.marginTop = '10px' - - this.renderTagButtons(values, key).forEach((group) => { - fields.appendChild(group) - }) - - content.appendChild(fields) - }) - - return content - } - - renderTagButtons(tags, prefix = '') { - if (Array.isArray(tags)) { - return tags.map((tag) => this.renderTagButton(tag, tag, 'secondary')) - } else { - return Object.keys(tags).map((key) => { - const values = tags[key] - const randomKey = `${prefix}:${key}` - - if (typeof values === 'string') { return this.renderTagButton(key, values, 'secondary') } - - const fields = EPSElementBuilder.tagFields() - fields.style.flexDirection = 'column' - - fields.append(this.renderTagButton(key, `@${randomKey}@`)) - - const buttons = EPSElementBuilder.tagFields() - buttons.id = 'buttons' - fields.append(buttons) - this.renderTagButtons(values, randomKey).forEach((button) => { - buttons.appendChild(button) - }) - - return fields - }) - } - } - - renderTagButton(title, value, color = 'primary') { - return EPSElementBuilder.tagButton({ - title, - onClick: (e) => { - e.preventDefault(); - - this.addTag(value, this.toNegative || e.metaKey || e.ctrlKey) - }, - onRightClick: (e) => { - e.preventDefault(); - - this.removeTag(value, this.toNegative || e.metaKey || e.ctrlKey) - }, - color - }) - } - - // Util - changeVisibility(node, visible) { - node.style.display = visible ? 'flex' : 'none' - } - - addTag(tag, toNegative = false) { - const id = toNegative ? 'txt2img_neg_prompt' : 'txt2img_prompt' - const textarea = gradioApp().getElementById(id).querySelector('textarea') - - if (textarea.value.trim() === '') { - textarea.value = tag - } else if (textarea.value.trim().endsWith(',')) { - textarea.value += ' ' + tag - } else { - textarea.value += ', ' + tag - } - - updateInput(textarea) - } - - removeTag(tag, toNegative = false) { - const id = toNegative ? 'txt2img_neg_prompt' : 'txt2img_prompt' - const textarea = gradioApp().getElementById(id).querySelector('textarea') - - if (textarea.value.trimStart().startsWith(tag)) { - const matched = textarea.value.match(new RegExp(`${tag.replace(/[-\/\\^$*+?.()|\[\]{}]/g, '\\$&') },*`)) - textarea.value = textarea.value.replace(matched[0], '').trimStart() - } else { - textarea.value = textarea.value.replace(`, ${tag}`, '') - } - - updateInput(textarea) - } -} - -onUiLoaded(async () => { - yaml = window.jsyaml - const easyPromptSelector = new EasyPromptSelector(yaml, gradioApp()) - - const button = EPSElementBuilder.openButton({ - onClick: () => { - const tagArea = gradioApp().querySelector(`#${easyPromptSelector.AREA_ID}`) - easyPromptSelector.changeVisibility(tagArea, easyPromptSelector.visible = !easyPromptSelector.visible) - } - }) - - const reloadButton = gradioApp().getElementById('easy_prompt_selector_reload_button') - reloadButton.addEventListener('click', async () => { - await easyPromptSelector.init() - }) - - const txt2imgActionColumn = gradioApp().getElementById('txt2img_actions_column') - const container = document.createElement('div') - container.classList.add('easy_prompt_selector_container') - container.appendChild(button) - container.appendChild(reloadButton) - - txt2imgActionColumn.appendChild(container) - - await easyPromptSelector.init() -}) diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/js-yaml.min.js b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/js-yaml.min.js deleted file mode 100644 index a33ae02..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/javascript/js-yaml.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ -!function (e, t) { "object" == typeof exports && "undefined" != typeof module ? t(exports) : "function" == typeof define && define.amd ? define(["exports"], t) : t((e = "undefined" != typeof globalThis ? globalThis : e || self).jsyaml = {}) }(this, (function (e) { "use strict"; function t(e) { return null == e } var n = { isNothing: t, isObject: function (e) { return "object" == typeof e && null !== e }, toArray: function (e) { return Array.isArray(e) ? e : t(e) ? [] : [e] }, repeat: function (e, t) { var n, i = ""; for (n = 0; n < t; n += 1)i += e; return i }, isNegativeZero: function (e) { return 0 === e && Number.NEGATIVE_INFINITY === 1 / e }, extend: function (e, t) { var n, i, r, o; if (t) for (n = 0, i = (o = Object.keys(t)).length; n < i; n += 1)e[r = o[n]] = t[r]; return e } }; function i(e, t) { var n = "", i = e.reason || "(unknown reason)"; return e.mark ? (e.mark.name && (n += 'in "' + e.mark.name + '" '), n += "(" + (e.mark.line + 1) + ":" + (e.mark.column + 1) + ")", !t && e.mark.snippet && (n += "\n\n" + e.mark.snippet), i + " " + n) : i } function r(e, t) { Error.call(this), this.name = "YAMLException", this.reason = e, this.mark = t, this.message = i(this, !1), Error.captureStackTrace ? Error.captureStackTrace(this, this.constructor) : this.stack = (new Error).stack || "" } r.prototype = Object.create(Error.prototype), r.prototype.constructor = r, r.prototype.toString = function (e) { return this.name + ": " + i(this, e) }; var o = r; function a(e, t, n, i, r) { var o = "", a = "", l = Math.floor(r / 2) - 1; return i - t > l && (t = i - l + (o = " ... ").length), n - i > l && (n = i + l - (a = " ...").length), { str: o + e.slice(t, n).replace(/\t/g, "→") + a, pos: i - t + o.length } } function l(e, t) { return n.repeat(" ", t - e.length) + e } var c = function (e, t) { if (t = Object.create(t || null), !e.buffer) return null; t.maxLength || (t.maxLength = 79), "number" != typeof t.indent && (t.indent = 1), "number" != typeof t.linesBefore && (t.linesBefore = 3), "number" != typeof t.linesAfter && (t.linesAfter = 2); for (var i, r = /\r?\n|\r|\0/g, o = [0], c = [], s = -1; i = r.exec(e.buffer);)c.push(i.index), o.push(i.index + i[0].length), e.position <= i.index && s < 0 && (s = o.length - 2); s < 0 && (s = o.length - 1); var u, p, f = "", d = Math.min(e.line + t.linesAfter, c.length).toString().length, h = t.maxLength - (t.indent + d + 3); for (u = 1; u <= t.linesBefore && !(s - u < 0); u++)p = a(e.buffer, o[s - u], c[s - u], e.position - (o[s] - o[s - u]), h), f = n.repeat(" ", t.indent) + l((e.line - u + 1).toString(), d) + " | " + p.str + "\n" + f; for (p = a(e.buffer, o[s], c[s], e.position, h), f += n.repeat(" ", t.indent) + l((e.line + 1).toString(), d) + " | " + p.str + "\n", f += n.repeat("-", t.indent + d + 3 + p.pos) + "^\n", u = 1; u <= t.linesAfter && !(s + u >= c.length); u++)p = a(e.buffer, o[s + u], c[s + u], e.position - (o[s] - o[s + u]), h), f += n.repeat(" ", t.indent) + l((e.line + u + 1).toString(), d) + " | " + p.str + "\n"; return f.replace(/\n$/, "") }, s = ["kind", "multi", "resolve", "construct", "instanceOf", "predicate", "represent", "representName", "defaultStyle", "styleAliases"], u = ["scalar", "sequence", "mapping"]; var p = function (e, t) { if (t = t || {}, Object.keys(t).forEach((function (t) { if (-1 === s.indexOf(t)) throw new o('Unknown option "' + t + '" is met in definition of "' + e + '" YAML type.') })), this.options = t, this.tag = e, this.kind = t.kind || null, this.resolve = t.resolve || function () { return !0 }, this.construct = t.construct || function (e) { return e }, this.instanceOf = t.instanceOf || null, this.predicate = t.predicate || null, this.represent = t.represent || null, this.representName = t.representName || null, this.defaultStyle = t.defaultStyle || null, this.multi = t.multi || !1, this.styleAliases = function (e) { var t = {}; return null !== e && Object.keys(e).forEach((function (n) { e[n].forEach((function (e) { t[String(e)] = n })) })), t }(t.styleAliases || null), -1 === u.indexOf(this.kind)) throw new o('Unknown kind "' + this.kind + '" is specified for "' + e + '" YAML type.') }; function f(e, t) { var n = []; return e[t].forEach((function (e) { var t = n.length; n.forEach((function (n, i) { n.tag === e.tag && n.kind === e.kind && n.multi === e.multi && (t = i) })), n[t] = e })), n } function d(e) { return this.extend(e) } d.prototype.extend = function (e) { var t = [], n = []; if (e instanceof p) n.push(e); else if (Array.isArray(e)) n = n.concat(e); else { if (!e || !Array.isArray(e.implicit) && !Array.isArray(e.explicit)) throw new o("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })"); e.implicit && (t = t.concat(e.implicit)), e.explicit && (n = n.concat(e.explicit)) } t.forEach((function (e) { if (!(e instanceof p)) throw new o("Specified list of YAML types (or a single Type object) contains a non-Type object."); if (e.loadKind && "scalar" !== e.loadKind) throw new o("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported."); if (e.multi) throw new o("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.") })), n.forEach((function (e) { if (!(e instanceof p)) throw new o("Specified list of YAML types (or a single Type object) contains a non-Type object.") })); var i = Object.create(d.prototype); return i.implicit = (this.implicit || []).concat(t), i.explicit = (this.explicit || []).concat(n), i.compiledImplicit = f(i, "implicit"), i.compiledExplicit = f(i, "explicit"), i.compiledTypeMap = function () { var e, t, n = { scalar: {}, sequence: {}, mapping: {}, fallback: {}, multi: { scalar: [], sequence: [], mapping: [], fallback: [] } }; function i(e) { e.multi ? (n.multi[e.kind].push(e), n.multi.fallback.push(e)) : n[e.kind][e.tag] = n.fallback[e.tag] = e } for (e = 0, t = arguments.length; e < t; e += 1)arguments[e].forEach(i); return n }(i.compiledImplicit, i.compiledExplicit), i }; var h = d, g = new p("tag:yaml.org,2002:str", { kind: "scalar", construct: function (e) { return null !== e ? e : "" } }), m = new p("tag:yaml.org,2002:seq", { kind: "sequence", construct: function (e) { return null !== e ? e : [] } }), y = new p("tag:yaml.org,2002:map", { kind: "mapping", construct: function (e) { return null !== e ? e : {} } }), b = new h({ explicit: [g, m, y] }); var A = new p("tag:yaml.org,2002:null", { kind: "scalar", resolve: function (e) { if (null === e) return !0; var t = e.length; return 1 === t && "~" === e || 4 === t && ("null" === e || "Null" === e || "NULL" === e) }, construct: function () { return null }, predicate: function (e) { return null === e }, represent: { canonical: function () { return "~" }, lowercase: function () { return "null" }, uppercase: function () { return "NULL" }, camelcase: function () { return "Null" }, empty: function () { return "" } }, defaultStyle: "lowercase" }); var v = new p("tag:yaml.org,2002:bool", { kind: "scalar", resolve: function (e) { if (null === e) return !1; var t = e.length; return 4 === t && ("true" === e || "True" === e || "TRUE" === e) || 5 === t && ("false" === e || "False" === e || "FALSE" === e) }, construct: function (e) { return "true" === e || "True" === e || "TRUE" === e }, predicate: function (e) { return "[object Boolean]" === Object.prototype.toString.call(e) }, represent: { lowercase: function (e) { return e ? "true" : "false" }, uppercase: function (e) { return e ? "TRUE" : "FALSE" }, camelcase: function (e) { return e ? "True" : "False" } }, defaultStyle: "lowercase" }); function w(e) { return 48 <= e && e <= 55 } function k(e) { return 48 <= e && e <= 57 } var C = new p("tag:yaml.org,2002:int", { kind: "scalar", resolve: function (e) { if (null === e) return !1; var t, n, i = e.length, r = 0, o = !1; if (!i) return !1; if ("-" !== (t = e[r]) && "+" !== t || (t = e[++r]), "0" === t) { if (r + 1 === i) return !0; if ("b" === (t = e[++r])) { for (r++; r < i; r++)if ("_" !== (t = e[r])) { if ("0" !== t && "1" !== t) return !1; o = !0 } return o && "_" !== t } if ("x" === t) { for (r++; r < i; r++)if ("_" !== (t = e[r])) { if (!(48 <= (n = e.charCodeAt(r)) && n <= 57 || 65 <= n && n <= 70 || 97 <= n && n <= 102)) return !1; o = !0 } return o && "_" !== t } if ("o" === t) { for (r++; r < i; r++)if ("_" !== (t = e[r])) { if (!w(e.charCodeAt(r))) return !1; o = !0 } return o && "_" !== t } } if ("_" === t) return !1; for (; r < i; r++)if ("_" !== (t = e[r])) { if (!k(e.charCodeAt(r))) return !1; o = !0 } return !(!o || "_" === t) }, construct: function (e) { var t, n = e, i = 1; if (-1 !== n.indexOf("_") && (n = n.replace(/_/g, "")), "-" !== (t = n[0]) && "+" !== t || ("-" === t && (i = -1), t = (n = n.slice(1))[0]), "0" === n) return 0; if ("0" === t) { if ("b" === n[1]) return i * parseInt(n.slice(2), 2); if ("x" === n[1]) return i * parseInt(n.slice(2), 16); if ("o" === n[1]) return i * parseInt(n.slice(2), 8) } return i * parseInt(n, 10) }, predicate: function (e) { return "[object Number]" === Object.prototype.toString.call(e) && e % 1 == 0 && !n.isNegativeZero(e) }, represent: { binary: function (e) { return e >= 0 ? "0b" + e.toString(2) : "-0b" + e.toString(2).slice(1) }, octal: function (e) { return e >= 0 ? "0o" + e.toString(8) : "-0o" + e.toString(8).slice(1) }, decimal: function (e) { return e.toString(10) }, hexadecimal: function (e) { return e >= 0 ? "0x" + e.toString(16).toUpperCase() : "-0x" + e.toString(16).toUpperCase().slice(1) } }, defaultStyle: "decimal", styleAliases: { binary: [2, "bin"], octal: [8, "oct"], decimal: [10, "dec"], hexadecimal: [16, "hex"] } }), x = new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); var I = /^[-+]?[0-9]+e/; var S = new p("tag:yaml.org,2002:float", { kind: "scalar", resolve: function (e) { return null !== e && !(!x.test(e) || "_" === e[e.length - 1]) }, construct: function (e) { var t, n; return n = "-" === (t = e.replace(/_/g, "").toLowerCase())[0] ? -1 : 1, "+-".indexOf(t[0]) >= 0 && (t = t.slice(1)), ".inf" === t ? 1 === n ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY : ".nan" === t ? NaN : n * parseFloat(t, 10) }, predicate: function (e) { return "[object Number]" === Object.prototype.toString.call(e) && (e % 1 != 0 || n.isNegativeZero(e)) }, represent: function (e, t) { var i; if (isNaN(e)) switch (t) { case "lowercase": return ".nan"; case "uppercase": return ".NAN"; case "camelcase": return ".NaN" } else if (Number.POSITIVE_INFINITY === e) switch (t) { case "lowercase": return ".inf"; case "uppercase": return ".INF"; case "camelcase": return ".Inf" } else if (Number.NEGATIVE_INFINITY === e) switch (t) { case "lowercase": return "-.inf"; case "uppercase": return "-.INF"; case "camelcase": return "-.Inf" } else if (n.isNegativeZero(e)) return "-0.0"; return i = e.toString(10), I.test(i) ? i.replace("e", ".e") : i }, defaultStyle: "lowercase" }), O = b.extend({ implicit: [A, v, C, S] }), j = O, T = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"), N = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"); var F = new p("tag:yaml.org,2002:timestamp", { kind: "scalar", resolve: function (e) { return null !== e && (null !== T.exec(e) || null !== N.exec(e)) }, construct: function (e) { var t, n, i, r, o, a, l, c, s = 0, u = null; if (null === (t = T.exec(e)) && (t = N.exec(e)), null === t) throw new Error("Date resolve error"); if (n = +t[1], i = +t[2] - 1, r = +t[3], !t[4]) return new Date(Date.UTC(n, i, r)); if (o = +t[4], a = +t[5], l = +t[6], t[7]) { for (s = t[7].slice(0, 3); s.length < 3;)s += "0"; s = +s } return t[9] && (u = 6e4 * (60 * +t[10] + +(t[11] || 0)), "-" === t[9] && (u = -u)), c = new Date(Date.UTC(n, i, r, o, a, l, s)), u && c.setTime(c.getTime() - u), c }, instanceOf: Date, represent: function (e) { return e.toISOString() } }); var E = new p("tag:yaml.org,2002:merge", { kind: "scalar", resolve: function (e) { return "<<" === e || null === e } }), M = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r"; var L = new p("tag:yaml.org,2002:binary", { kind: "scalar", resolve: function (e) { if (null === e) return !1; var t, n, i = 0, r = e.length, o = M; for (n = 0; n < r; n++)if (!((t = o.indexOf(e.charAt(n))) > 64)) { if (t < 0) return !1; i += 6 } return i % 8 == 0 }, construct: function (e) { var t, n, i = e.replace(/[\r\n=]/g, ""), r = i.length, o = M, a = 0, l = []; for (t = 0; t < r; t++)t % 4 == 0 && t && (l.push(a >> 16 & 255), l.push(a >> 8 & 255), l.push(255 & a)), a = a << 6 | o.indexOf(i.charAt(t)); return 0 === (n = r % 4 * 6) ? (l.push(a >> 16 & 255), l.push(a >> 8 & 255), l.push(255 & a)) : 18 === n ? (l.push(a >> 10 & 255), l.push(a >> 2 & 255)) : 12 === n && l.push(a >> 4 & 255), new Uint8Array(l) }, predicate: function (e) { return "[object Uint8Array]" === Object.prototype.toString.call(e) }, represent: function (e) { var t, n, i = "", r = 0, o = e.length, a = M; for (t = 0; t < o; t++)t % 3 == 0 && t && (i += a[r >> 18 & 63], i += a[r >> 12 & 63], i += a[r >> 6 & 63], i += a[63 & r]), r = (r << 8) + e[t]; return 0 === (n = o % 3) ? (i += a[r >> 18 & 63], i += a[r >> 12 & 63], i += a[r >> 6 & 63], i += a[63 & r]) : 2 === n ? (i += a[r >> 10 & 63], i += a[r >> 4 & 63], i += a[r << 2 & 63], i += a[64]) : 1 === n && (i += a[r >> 2 & 63], i += a[r << 4 & 63], i += a[64], i += a[64]), i } }), _ = Object.prototype.hasOwnProperty, D = Object.prototype.toString; var U = new p("tag:yaml.org,2002:omap", { kind: "sequence", resolve: function (e) { if (null === e) return !0; var t, n, i, r, o, a = [], l = e; for (t = 0, n = l.length; t < n; t += 1) { if (i = l[t], o = !1, "[object Object]" !== D.call(i)) return !1; for (r in i) if (_.call(i, r)) { if (o) return !1; o = !0 } if (!o) return !1; if (-1 !== a.indexOf(r)) return !1; a.push(r) } return !0 }, construct: function (e) { return null !== e ? e : [] } }), q = Object.prototype.toString; var Y = new p("tag:yaml.org,2002:pairs", { kind: "sequence", resolve: function (e) { if (null === e) return !0; var t, n, i, r, o, a = e; for (o = new Array(a.length), t = 0, n = a.length; t < n; t += 1) { if (i = a[t], "[object Object]" !== q.call(i)) return !1; if (1 !== (r = Object.keys(i)).length) return !1; o[t] = [r[0], i[r[0]]] } return !0 }, construct: function (e) { if (null === e) return []; var t, n, i, r, o, a = e; for (o = new Array(a.length), t = 0, n = a.length; t < n; t += 1)i = a[t], r = Object.keys(i), o[t] = [r[0], i[r[0]]]; return o } }), R = Object.prototype.hasOwnProperty; var B = new p("tag:yaml.org,2002:set", { kind: "mapping", resolve: function (e) { if (null === e) return !0; var t, n = e; for (t in n) if (R.call(n, t) && null !== n[t]) return !1; return !0 }, construct: function (e) { return null !== e ? e : {} } }), K = j.extend({ implicit: [F, E], explicit: [L, U, Y, B] }), P = Object.prototype.hasOwnProperty, W = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/, H = /[\x85\u2028\u2029]/, $ = /[,\[\]\{\}]/, G = /^(?:!|!!|![a-z\-]+!)$/i, V = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; function Z(e) { return Object.prototype.toString.call(e) } function J(e) { return 10 === e || 13 === e } function Q(e) { return 9 === e || 32 === e } function z(e) { return 9 === e || 32 === e || 10 === e || 13 === e } function X(e) { return 44 === e || 91 === e || 93 === e || 123 === e || 125 === e } function ee(e) { var t; return 48 <= e && e <= 57 ? e - 48 : 97 <= (t = 32 | e) && t <= 102 ? t - 97 + 10 : -1 } function te(e) { return 48 === e ? "\0" : 97 === e ? "" : 98 === e ? "\b" : 116 === e || 9 === e ? "\t" : 110 === e ? "\n" : 118 === e ? "\v" : 102 === e ? "\f" : 114 === e ? "\r" : 101 === e ? "" : 32 === e ? " " : 34 === e ? '"' : 47 === e ? "/" : 92 === e ? "\\" : 78 === e ? "Â…" : 95 === e ? " " : 76 === e ? "\u2028" : 80 === e ? "\u2029" : "" } function ne(e) { return e <= 65535 ? String.fromCharCode(e) : String.fromCharCode(55296 + (e - 65536 >> 10), 56320 + (e - 65536 & 1023)) } for (var ie = new Array(256), re = new Array(256), oe = 0; oe < 256; oe++)ie[oe] = te(oe) ? 1 : 0, re[oe] = te(oe); function ae(e, t) { this.input = e, this.filename = t.filename || null, this.schema = t.schema || K, this.onWarning = t.onWarning || null, this.legacy = t.legacy || !1, this.json = t.json || !1, this.listener = t.listener || null, this.implicitTypes = this.schema.compiledImplicit, this.typeMap = this.schema.compiledTypeMap, this.length = e.length, this.position = 0, this.line = 0, this.lineStart = 0, this.lineIndent = 0, this.firstTabInLine = -1, this.documents = [] } function le(e, t) { var n = { name: e.filename, buffer: e.input.slice(0, -1), position: e.position, line: e.line, column: e.position - e.lineStart }; return n.snippet = c(n), new o(t, n) } function ce(e, t) { throw le(e, t) } function se(e, t) { e.onWarning && e.onWarning.call(null, le(e, t)) } var ue = { YAML: function (e, t, n) { var i, r, o; null !== e.version && ce(e, "duplication of %YAML directive"), 1 !== n.length && ce(e, "YAML directive accepts exactly one argument"), null === (i = /^([0-9]+)\.([0-9]+)$/.exec(n[0])) && ce(e, "ill-formed argument of the YAML directive"), r = parseInt(i[1], 10), o = parseInt(i[2], 10), 1 !== r && ce(e, "unacceptable YAML version of the document"), e.version = n[0], e.checkLineBreaks = o < 2, 1 !== o && 2 !== o && se(e, "unsupported YAML version of the document") }, TAG: function (e, t, n) { var i, r; 2 !== n.length && ce(e, "TAG directive accepts exactly two arguments"), i = n[0], r = n[1], G.test(i) || ce(e, "ill-formed tag handle (first argument) of the TAG directive"), P.call(e.tagMap, i) && ce(e, 'there is a previously declared suffix for "' + i + '" tag handle'), V.test(r) || ce(e, "ill-formed tag prefix (second argument) of the TAG directive"); try { r = decodeURIComponent(r) } catch (t) { ce(e, "tag prefix is malformed: " + r) } e.tagMap[i] = r } }; function pe(e, t, n, i) { var r, o, a, l; if (t < n) { if (l = e.input.slice(t, n), i) for (r = 0, o = l.length; r < o; r += 1)9 === (a = l.charCodeAt(r)) || 32 <= a && a <= 1114111 || ce(e, "expected valid JSON character"); else W.test(l) && ce(e, "the stream contains non-printable characters"); e.result += l } } function fe(e, t, i, r) { var o, a, l, c; for (n.isObject(i) || ce(e, "cannot merge mappings; the provided source object is unacceptable"), l = 0, c = (o = Object.keys(i)).length; l < c; l += 1)a = o[l], P.call(t, a) || (t[a] = i[a], r[a] = !0) } function de(e, t, n, i, r, o, a, l, c) { var s, u; if (Array.isArray(r)) for (s = 0, u = (r = Array.prototype.slice.call(r)).length; s < u; s += 1)Array.isArray(r[s]) && ce(e, "nested arrays are not supported inside keys"), "object" == typeof r && "[object Object]" === Z(r[s]) && (r[s] = "[object Object]"); if ("object" == typeof r && "[object Object]" === Z(r) && (r = "[object Object]"), r = String(r), null === t && (t = {}), "tag:yaml.org,2002:merge" === i) if (Array.isArray(o)) for (s = 0, u = o.length; s < u; s += 1)fe(e, t, o[s], n); else fe(e, t, o, n); else e.json || P.call(n, r) || !P.call(t, r) || (e.line = a || e.line, e.lineStart = l || e.lineStart, e.position = c || e.position, ce(e, "duplicated mapping key")), "__proto__" === r ? Object.defineProperty(t, r, { configurable: !0, enumerable: !0, writable: !0, value: o }) : t[r] = o, delete n[r]; return t } function he(e) { var t; 10 === (t = e.input.charCodeAt(e.position)) ? e.position++ : 13 === t ? (e.position++, 10 === e.input.charCodeAt(e.position) && e.position++) : ce(e, "a line break is expected"), e.line += 1, e.lineStart = e.position, e.firstTabInLine = -1 } function ge(e, t, n) { for (var i = 0, r = e.input.charCodeAt(e.position); 0 !== r;) { for (; Q(r);)9 === r && -1 === e.firstTabInLine && (e.firstTabInLine = e.position), r = e.input.charCodeAt(++e.position); if (t && 35 === r) do { r = e.input.charCodeAt(++e.position) } while (10 !== r && 13 !== r && 0 !== r); if (!J(r)) break; for (he(e), r = e.input.charCodeAt(e.position), i++, e.lineIndent = 0; 32 === r;)e.lineIndent++, r = e.input.charCodeAt(++e.position) } return -1 !== n && 0 !== i && e.lineIndent < n && se(e, "deficient indentation"), i } function me(e) { var t, n = e.position; return !(45 !== (t = e.input.charCodeAt(n)) && 46 !== t || t !== e.input.charCodeAt(n + 1) || t !== e.input.charCodeAt(n + 2) || (n += 3, 0 !== (t = e.input.charCodeAt(n)) && !z(t))) } function ye(e, t) { 1 === t ? e.result += " " : t > 1 && (e.result += n.repeat("\n", t - 1)) } function be(e, t) { var n, i, r = e.tag, o = e.anchor, a = [], l = !1; if (-1 !== e.firstTabInLine) return !1; for (null !== e.anchor && (e.anchorMap[e.anchor] = a), i = e.input.charCodeAt(e.position); 0 !== i && (-1 !== e.firstTabInLine && (e.position = e.firstTabInLine, ce(e, "tab characters must not be used in indentation")), 45 === i) && z(e.input.charCodeAt(e.position + 1));)if (l = !0, e.position++, ge(e, !0, -1) && e.lineIndent <= t) a.push(null), i = e.input.charCodeAt(e.position); else if (n = e.line, we(e, t, 3, !1, !0), a.push(e.result), ge(e, !0, -1), i = e.input.charCodeAt(e.position), (e.line === n || e.lineIndent > t) && 0 !== i) ce(e, "bad indentation of a sequence entry"); else if (e.lineIndent < t) break; return !!l && (e.tag = r, e.anchor = o, e.kind = "sequence", e.result = a, !0) } function Ae(e) { var t, n, i, r, o = !1, a = !1; if (33 !== (r = e.input.charCodeAt(e.position))) return !1; if (null !== e.tag && ce(e, "duplication of a tag property"), 60 === (r = e.input.charCodeAt(++e.position)) ? (o = !0, r = e.input.charCodeAt(++e.position)) : 33 === r ? (a = !0, n = "!!", r = e.input.charCodeAt(++e.position)) : n = "!", t = e.position, o) { do { r = e.input.charCodeAt(++e.position) } while (0 !== r && 62 !== r); e.position < e.length ? (i = e.input.slice(t, e.position), r = e.input.charCodeAt(++e.position)) : ce(e, "unexpected end of the stream within a verbatim tag") } else { for (; 0 !== r && !z(r);)33 === r && (a ? ce(e, "tag suffix cannot contain exclamation marks") : (n = e.input.slice(t - 1, e.position + 1), G.test(n) || ce(e, "named tag handle cannot contain such characters"), a = !0, t = e.position + 1)), r = e.input.charCodeAt(++e.position); i = e.input.slice(t, e.position), $.test(i) && ce(e, "tag suffix cannot contain flow indicator characters") } i && !V.test(i) && ce(e, "tag name cannot contain such characters: " + i); try { i = decodeURIComponent(i) } catch (t) { ce(e, "tag name is malformed: " + i) } return o ? e.tag = i : P.call(e.tagMap, n) ? e.tag = e.tagMap[n] + i : "!" === n ? e.tag = "!" + i : "!!" === n ? e.tag = "tag:yaml.org,2002:" + i : ce(e, 'undeclared tag handle "' + n + '"'), !0 } function ve(e) { var t, n; if (38 !== (n = e.input.charCodeAt(e.position))) return !1; for (null !== e.anchor && ce(e, "duplication of an anchor property"), n = e.input.charCodeAt(++e.position), t = e.position; 0 !== n && !z(n) && !X(n);)n = e.input.charCodeAt(++e.position); return e.position === t && ce(e, "name of an anchor node must contain at least one character"), e.anchor = e.input.slice(t, e.position), !0 } function we(e, t, i, r, o) { var a, l, c, s, u, p, f, d, h, g = 1, m = !1, y = !1; if (null !== e.listener && e.listener("open", e), e.tag = null, e.anchor = null, e.kind = null, e.result = null, a = l = c = 4 === i || 3 === i, r && ge(e, !0, -1) && (m = !0, e.lineIndent > t ? g = 1 : e.lineIndent === t ? g = 0 : e.lineIndent < t && (g = -1)), 1 === g) for (; Ae(e) || ve(e);)ge(e, !0, -1) ? (m = !0, c = a, e.lineIndent > t ? g = 1 : e.lineIndent === t ? g = 0 : e.lineIndent < t && (g = -1)) : c = !1; if (c && (c = m || o), 1 !== g && 4 !== i || (d = 1 === i || 2 === i ? t : t + 1, h = e.position - e.lineStart, 1 === g ? c && (be(e, h) || function (e, t, n) { var i, r, o, a, l, c, s, u = e.tag, p = e.anchor, f = {}, d = Object.create(null), h = null, g = null, m = null, y = !1, b = !1; if (-1 !== e.firstTabInLine) return !1; for (null !== e.anchor && (e.anchorMap[e.anchor] = f), s = e.input.charCodeAt(e.position); 0 !== s;) { if (y || -1 === e.firstTabInLine || (e.position = e.firstTabInLine, ce(e, "tab characters must not be used in indentation")), i = e.input.charCodeAt(e.position + 1), o = e.line, 63 !== s && 58 !== s || !z(i)) { if (a = e.line, l = e.lineStart, c = e.position, !we(e, n, 2, !1, !0)) break; if (e.line === o) { for (s = e.input.charCodeAt(e.position); Q(s);)s = e.input.charCodeAt(++e.position); if (58 === s) z(s = e.input.charCodeAt(++e.position)) || ce(e, "a whitespace character is expected after the key-value separator within a block mapping"), y && (de(e, f, d, h, g, null, a, l, c), h = g = m = null), b = !0, y = !1, r = !1, h = e.tag, g = e.result; else { if (!b) return e.tag = u, e.anchor = p, !0; ce(e, "can not read an implicit mapping pair; a colon is missed") } } else { if (!b) return e.tag = u, e.anchor = p, !0; ce(e, "can not read a block mapping entry; a multiline key may not be an implicit key") } } else 63 === s ? (y && (de(e, f, d, h, g, null, a, l, c), h = g = m = null), b = !0, y = !0, r = !0) : y ? (y = !1, r = !0) : ce(e, "incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"), e.position += 1, s = i; if ((e.line === o || e.lineIndent > t) && (y && (a = e.line, l = e.lineStart, c = e.position), we(e, t, 4, !0, r) && (y ? g = e.result : m = e.result), y || (de(e, f, d, h, g, m, a, l, c), h = g = m = null), ge(e, !0, -1), s = e.input.charCodeAt(e.position)), (e.line === o || e.lineIndent > t) && 0 !== s) ce(e, "bad indentation of a mapping entry"); else if (e.lineIndent < t) break } return y && de(e, f, d, h, g, null, a, l, c), b && (e.tag = u, e.anchor = p, e.kind = "mapping", e.result = f), b }(e, h, d)) || function (e, t) { var n, i, r, o, a, l, c, s, u, p, f, d, h = !0, g = e.tag, m = e.anchor, y = Object.create(null); if (91 === (d = e.input.charCodeAt(e.position))) a = 93, s = !1, o = []; else { if (123 !== d) return !1; a = 125, s = !0, o = {} } for (null !== e.anchor && (e.anchorMap[e.anchor] = o), d = e.input.charCodeAt(++e.position); 0 !== d;) { if (ge(e, !0, t), (d = e.input.charCodeAt(e.position)) === a) return e.position++, e.tag = g, e.anchor = m, e.kind = s ? "mapping" : "sequence", e.result = o, !0; h ? 44 === d && ce(e, "expected the node content, but found ','") : ce(e, "missed comma between flow collection entries"), f = null, l = c = !1, 63 === d && z(e.input.charCodeAt(e.position + 1)) && (l = c = !0, e.position++, ge(e, !0, t)), n = e.line, i = e.lineStart, r = e.position, we(e, t, 1, !1, !0), p = e.tag, u = e.result, ge(e, !0, t), d = e.input.charCodeAt(e.position), !c && e.line !== n || 58 !== d || (l = !0, d = e.input.charCodeAt(++e.position), ge(e, !0, t), we(e, t, 1, !1, !0), f = e.result), s ? de(e, o, y, p, u, f, n, i, r) : l ? o.push(de(e, null, y, p, u, f, n, i, r)) : o.push(u), ge(e, !0, t), 44 === (d = e.input.charCodeAt(e.position)) ? (h = !0, d = e.input.charCodeAt(++e.position)) : h = !1 } ce(e, "unexpected end of the stream within a flow collection") }(e, d) ? y = !0 : (l && function (e, t) { var i, r, o, a, l, c = 1, s = !1, u = !1, p = t, f = 0, d = !1; if (124 === (a = e.input.charCodeAt(e.position))) r = !1; else { if (62 !== a) return !1; r = !0 } for (e.kind = "scalar", e.result = ""; 0 !== a;)if (43 === (a = e.input.charCodeAt(++e.position)) || 45 === a) 1 === c ? c = 43 === a ? 3 : 2 : ce(e, "repeat of a chomping mode identifier"); else { if (!((o = 48 <= (l = a) && l <= 57 ? l - 48 : -1) >= 0)) break; 0 === o ? ce(e, "bad explicit indentation width of a block scalar; it cannot be less than one") : u ? ce(e, "repeat of an indentation width identifier") : (p = t + o - 1, u = !0) } if (Q(a)) { do { a = e.input.charCodeAt(++e.position) } while (Q(a)); if (35 === a) do { a = e.input.charCodeAt(++e.position) } while (!J(a) && 0 !== a) } for (; 0 !== a;) { for (he(e), e.lineIndent = 0, a = e.input.charCodeAt(e.position); (!u || e.lineIndent < p) && 32 === a;)e.lineIndent++, a = e.input.charCodeAt(++e.position); if (!u && e.lineIndent > p && (p = e.lineIndent), J(a)) f++; else { if (e.lineIndent < p) { 3 === c ? e.result += n.repeat("\n", s ? 1 + f : f) : 1 === c && s && (e.result += "\n"); break } for (r ? Q(a) ? (d = !0, e.result += n.repeat("\n", s ? 1 + f : f)) : d ? (d = !1, e.result += n.repeat("\n", f + 1)) : 0 === f ? s && (e.result += " ") : e.result += n.repeat("\n", f) : e.result += n.repeat("\n", s ? 1 + f : f), s = !0, u = !0, f = 0, i = e.position; !J(a) && 0 !== a;)a = e.input.charCodeAt(++e.position); pe(e, i, e.position, !1) } } return !0 }(e, d) || function (e, t) { var n, i, r; if (39 !== (n = e.input.charCodeAt(e.position))) return !1; for (e.kind = "scalar", e.result = "", e.position++, i = r = e.position; 0 !== (n = e.input.charCodeAt(e.position));)if (39 === n) { if (pe(e, i, e.position, !0), 39 !== (n = e.input.charCodeAt(++e.position))) return !0; i = e.position, e.position++, r = e.position } else J(n) ? (pe(e, i, r, !0), ye(e, ge(e, !1, t)), i = r = e.position) : e.position === e.lineStart && me(e) ? ce(e, "unexpected end of the document within a single quoted scalar") : (e.position++, r = e.position); ce(e, "unexpected end of the stream within a single quoted scalar") }(e, d) || function (e, t) { var n, i, r, o, a, l, c; if (34 !== (l = e.input.charCodeAt(e.position))) return !1; for (e.kind = "scalar", e.result = "", e.position++, n = i = e.position; 0 !== (l = e.input.charCodeAt(e.position));) { if (34 === l) return pe(e, n, e.position, !0), e.position++, !0; if (92 === l) { if (pe(e, n, e.position, !0), J(l = e.input.charCodeAt(++e.position))) ge(e, !1, t); else if (l < 256 && ie[l]) e.result += re[l], e.position++; else if ((a = 120 === (c = l) ? 2 : 117 === c ? 4 : 85 === c ? 8 : 0) > 0) { for (r = a, o = 0; r > 0; r--)(a = ee(l = e.input.charCodeAt(++e.position))) >= 0 ? o = (o << 4) + a : ce(e, "expected hexadecimal character"); e.result += ne(o), e.position++ } else ce(e, "unknown escape sequence"); n = i = e.position } else J(l) ? (pe(e, n, i, !0), ye(e, ge(e, !1, t)), n = i = e.position) : e.position === e.lineStart && me(e) ? ce(e, "unexpected end of the document within a double quoted scalar") : (e.position++, i = e.position) } ce(e, "unexpected end of the stream within a double quoted scalar") }(e, d) ? y = !0 : !function (e) { var t, n, i; if (42 !== (i = e.input.charCodeAt(e.position))) return !1; for (i = e.input.charCodeAt(++e.position), t = e.position; 0 !== i && !z(i) && !X(i);)i = e.input.charCodeAt(++e.position); return e.position === t && ce(e, "name of an alias node must contain at least one character"), n = e.input.slice(t, e.position), P.call(e.anchorMap, n) || ce(e, 'unidentified alias "' + n + '"'), e.result = e.anchorMap[n], ge(e, !0, -1), !0 }(e) ? function (e, t, n) { var i, r, o, a, l, c, s, u, p = e.kind, f = e.result; if (z(u = e.input.charCodeAt(e.position)) || X(u) || 35 === u || 38 === u || 42 === u || 33 === u || 124 === u || 62 === u || 39 === u || 34 === u || 37 === u || 64 === u || 96 === u) return !1; if ((63 === u || 45 === u) && (z(i = e.input.charCodeAt(e.position + 1)) || n && X(i))) return !1; for (e.kind = "scalar", e.result = "", r = o = e.position, a = !1; 0 !== u;) { if (58 === u) { if (z(i = e.input.charCodeAt(e.position + 1)) || n && X(i)) break } else if (35 === u) { if (z(e.input.charCodeAt(e.position - 1))) break } else { if (e.position === e.lineStart && me(e) || n && X(u)) break; if (J(u)) { if (l = e.line, c = e.lineStart, s = e.lineIndent, ge(e, !1, -1), e.lineIndent >= t) { a = !0, u = e.input.charCodeAt(e.position); continue } e.position = o, e.line = l, e.lineStart = c, e.lineIndent = s; break } } a && (pe(e, r, o, !1), ye(e, e.line - l), r = o = e.position, a = !1), Q(u) || (o = e.position + 1), u = e.input.charCodeAt(++e.position) } return pe(e, r, o, !1), !!e.result || (e.kind = p, e.result = f, !1) }(e, d, 1 === i) && (y = !0, null === e.tag && (e.tag = "?")) : (y = !0, null === e.tag && null === e.anchor || ce(e, "alias node should not have any properties")), null !== e.anchor && (e.anchorMap[e.anchor] = e.result)) : 0 === g && (y = c && be(e, h))), null === e.tag) null !== e.anchor && (e.anchorMap[e.anchor] = e.result); else if ("?" === e.tag) { for (null !== e.result && "scalar" !== e.kind && ce(e, 'unacceptable node kind for ! tag; it should be "scalar", not "' + e.kind + '"'), s = 0, u = e.implicitTypes.length; s < u; s += 1)if ((f = e.implicitTypes[s]).resolve(e.result)) { e.result = f.construct(e.result), e.tag = f.tag, null !== e.anchor && (e.anchorMap[e.anchor] = e.result); break } } else if ("!" !== e.tag) { if (P.call(e.typeMap[e.kind || "fallback"], e.tag)) f = e.typeMap[e.kind || "fallback"][e.tag]; else for (f = null, s = 0, u = (p = e.typeMap.multi[e.kind || "fallback"]).length; s < u; s += 1)if (e.tag.slice(0, p[s].tag.length) === p[s].tag) { f = p[s]; break } f || ce(e, "unknown tag !<" + e.tag + ">"), null !== e.result && f.kind !== e.kind && ce(e, "unacceptable node kind for !<" + e.tag + '> tag; it should be "' + f.kind + '", not "' + e.kind + '"'), f.resolve(e.result, e.tag) ? (e.result = f.construct(e.result, e.tag), null !== e.anchor && (e.anchorMap[e.anchor] = e.result)) : ce(e, "cannot resolve a node with !<" + e.tag + "> explicit tag") } return null !== e.listener && e.listener("close", e), null !== e.tag || null !== e.anchor || y } function ke(e) { var t, n, i, r, o = e.position, a = !1; for (e.version = null, e.checkLineBreaks = e.legacy, e.tagMap = Object.create(null), e.anchorMap = Object.create(null); 0 !== (r = e.input.charCodeAt(e.position)) && (ge(e, !0, -1), r = e.input.charCodeAt(e.position), !(e.lineIndent > 0 || 37 !== r));) { for (a = !0, r = e.input.charCodeAt(++e.position), t = e.position; 0 !== r && !z(r);)r = e.input.charCodeAt(++e.position); for (i = [], (n = e.input.slice(t, e.position)).length < 1 && ce(e, "directive name must not be less than one character in length"); 0 !== r;) { for (; Q(r);)r = e.input.charCodeAt(++e.position); if (35 === r) { do { r = e.input.charCodeAt(++e.position) } while (0 !== r && !J(r)); break } if (J(r)) break; for (t = e.position; 0 !== r && !z(r);)r = e.input.charCodeAt(++e.position); i.push(e.input.slice(t, e.position)) } 0 !== r && he(e), P.call(ue, n) ? ue[n](e, n, i) : se(e, 'unknown document directive "' + n + '"') } ge(e, !0, -1), 0 === e.lineIndent && 45 === e.input.charCodeAt(e.position) && 45 === e.input.charCodeAt(e.position + 1) && 45 === e.input.charCodeAt(e.position + 2) ? (e.position += 3, ge(e, !0, -1)) : a && ce(e, "directives end mark is expected"), we(e, e.lineIndent - 1, 4, !1, !0), ge(e, !0, -1), e.checkLineBreaks && H.test(e.input.slice(o, e.position)) && se(e, "non-ASCII line breaks are interpreted as content"), e.documents.push(e.result), e.position === e.lineStart && me(e) ? 46 === e.input.charCodeAt(e.position) && (e.position += 3, ge(e, !0, -1)) : e.position < e.length - 1 && ce(e, "end of the stream or a document separator is expected") } function Ce(e, t) { t = t || {}, 0 !== (e = String(e)).length && (10 !== e.charCodeAt(e.length - 1) && 13 !== e.charCodeAt(e.length - 1) && (e += "\n"), 65279 === e.charCodeAt(0) && (e = e.slice(1))); var n = new ae(e, t), i = e.indexOf("\0"); for (-1 !== i && (n.position = i, ce(n, "null byte is not allowed in input")), n.input += "\0"; 32 === n.input.charCodeAt(n.position);)n.lineIndent += 1, n.position += 1; for (; n.position < n.length - 1;)ke(n); return n.documents } var xe = { loadAll: function (e, t, n) { null !== t && "object" == typeof t && void 0 === n && (n = t, t = null); var i = Ce(e, n); if ("function" != typeof t) return i; for (var r = 0, o = i.length; r < o; r += 1)t(i[r]) }, load: function (e, t) { var n = Ce(e, t); if (0 !== n.length) { if (1 === n.length) return n[0]; throw new o("expected a single document in the stream, but found more") } } }, Ie = Object.prototype.toString, Se = Object.prototype.hasOwnProperty, Oe = 65279, je = { 0: "\\0", 7: "\\a", 8: "\\b", 9: "\\t", 10: "\\n", 11: "\\v", 12: "\\f", 13: "\\r", 27: "\\e", 34: '\\"', 92: "\\\\", 133: "\\N", 160: "\\_", 8232: "\\L", 8233: "\\P" }, Te = ["y", "Y", "yes", "Yes", "YES", "on", "On", "ON", "n", "N", "no", "No", "NO", "off", "Off", "OFF"], Ne = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; function Fe(e) { var t, i, r; if (t = e.toString(16).toUpperCase(), e <= 255) i = "x", r = 2; else if (e <= 65535) i = "u", r = 4; else { if (!(e <= 4294967295)) throw new o("code point within a string may not be greater than 0xFFFFFFFF"); i = "U", r = 8 } return "\\" + i + n.repeat("0", r - t.length) + t } function Ee(e) { this.schema = e.schema || K, this.indent = Math.max(1, e.indent || 2), this.noArrayIndent = e.noArrayIndent || !1, this.skipInvalid = e.skipInvalid || !1, this.flowLevel = n.isNothing(e.flowLevel) ? -1 : e.flowLevel, this.styleMap = function (e, t) { var n, i, r, o, a, l, c; if (null === t) return {}; for (n = {}, r = 0, o = (i = Object.keys(t)).length; r < o; r += 1)a = i[r], l = String(t[a]), "!!" === a.slice(0, 2) && (a = "tag:yaml.org,2002:" + a.slice(2)), (c = e.compiledTypeMap.fallback[a]) && Se.call(c.styleAliases, l) && (l = c.styleAliases[l]), n[a] = l; return n }(this.schema, e.styles || null), this.sortKeys = e.sortKeys || !1, this.lineWidth = e.lineWidth || 80, this.noRefs = e.noRefs || !1, this.noCompatMode = e.noCompatMode || !1, this.condenseFlow = e.condenseFlow || !1, this.quotingType = '"' === e.quotingType ? 2 : 1, this.forceQuotes = e.forceQuotes || !1, this.replacer = "function" == typeof e.replacer ? e.replacer : null, this.implicitTypes = this.schema.compiledImplicit, this.explicitTypes = this.schema.compiledExplicit, this.tag = null, this.result = "", this.duplicates = [], this.usedDuplicates = null } function Me(e, t) { for (var i, r = n.repeat(" ", t), o = 0, a = -1, l = "", c = e.length; o < c;)-1 === (a = e.indexOf("\n", o)) ? (i = e.slice(o), o = c) : (i = e.slice(o, a + 1), o = a + 1), i.length && "\n" !== i && (l += r), l += i; return l } function Le(e, t) { return "\n" + n.repeat(" ", e.indent * t) } function _e(e) { return 32 === e || 9 === e } function De(e) { return 32 <= e && e <= 126 || 161 <= e && e <= 55295 && 8232 !== e && 8233 !== e || 57344 <= e && e <= 65533 && e !== Oe || 65536 <= e && e <= 1114111 } function Ue(e) { return De(e) && e !== Oe && 13 !== e && 10 !== e } function qe(e, t, n) { var i = Ue(e), r = i && !_e(e); return (n ? i : i && 44 !== e && 91 !== e && 93 !== e && 123 !== e && 125 !== e) && 35 !== e && !(58 === t && !r) || Ue(t) && !_e(t) && 35 === e || 58 === t && r } function Ye(e, t) { var n, i = e.charCodeAt(t); return i >= 55296 && i <= 56319 && t + 1 < e.length && (n = e.charCodeAt(t + 1)) >= 56320 && n <= 57343 ? 1024 * (i - 55296) + n - 56320 + 65536 : i } function Re(e) { return /^\n* /.test(e) } function Be(e, t, n, i, r, o, a, l) { var c, s, u = 0, p = null, f = !1, d = !1, h = -1 !== i, g = -1, m = De(s = Ye(e, 0)) && s !== Oe && !_e(s) && 45 !== s && 63 !== s && 58 !== s && 44 !== s && 91 !== s && 93 !== s && 123 !== s && 125 !== s && 35 !== s && 38 !== s && 42 !== s && 33 !== s && 124 !== s && 61 !== s && 62 !== s && 39 !== s && 34 !== s && 37 !== s && 64 !== s && 96 !== s && function (e) { return !_e(e) && 58 !== e }(Ye(e, e.length - 1)); if (t || a) for (c = 0; c < e.length; u >= 65536 ? c += 2 : c++) { if (!De(u = Ye(e, c))) return 5; m = m && qe(u, p, l), p = u } else { for (c = 0; c < e.length; u >= 65536 ? c += 2 : c++) { if (10 === (u = Ye(e, c))) f = !0, h && (d = d || c - g - 1 > i && " " !== e[g + 1], g = c); else if (!De(u)) return 5; m = m && qe(u, p, l), p = u } d = d || h && c - g - 1 > i && " " !== e[g + 1] } return f || d ? n > 9 && Re(e) ? 5 : a ? 2 === o ? 5 : 2 : d ? 4 : 3 : !m || a || r(e) ? 2 === o ? 5 : 2 : 1 } function Ke(e, t, n, i, r) { e.dump = function () { if (0 === t.length) return 2 === e.quotingType ? '""' : "''"; if (!e.noCompatMode && (-1 !== Te.indexOf(t) || Ne.test(t))) return 2 === e.quotingType ? '"' + t + '"' : "'" + t + "'"; var a = e.indent * Math.max(1, n), l = -1 === e.lineWidth ? -1 : Math.max(Math.min(e.lineWidth, 40), e.lineWidth - a), c = i || e.flowLevel > -1 && n >= e.flowLevel; switch (Be(t, c, e.indent, l, (function (t) { return function (e, t) { var n, i; for (n = 0, i = e.implicitTypes.length; n < i; n += 1)if (e.implicitTypes[n].resolve(t)) return !0; return !1 }(e, t) }), e.quotingType, e.forceQuotes && !i, r)) { case 1: return t; case 2: return "'" + t.replace(/'/g, "''") + "'"; case 3: return "|" + Pe(t, e.indent) + We(Me(t, a)); case 4: return ">" + Pe(t, e.indent) + We(Me(function (e, t) { var n, i, r = /(\n+)([^\n]*)/g, o = (l = e.indexOf("\n"), l = -1 !== l ? l : e.length, r.lastIndex = l, He(e.slice(0, l), t)), a = "\n" === e[0] || " " === e[0]; var l; for (; i = r.exec(e);) { var c = i[1], s = i[2]; n = " " === s[0], o += c + (a || n || "" === s ? "" : "\n") + He(s, t), a = n } return o }(t, l), a)); case 5: return '"' + function (e) { for (var t, n = "", i = 0, r = 0; r < e.length; i >= 65536 ? r += 2 : r++)i = Ye(e, r), !(t = je[i]) && De(i) ? (n += e[r], i >= 65536 && (n += e[r + 1])) : n += t || Fe(i); return n }(t) + '"'; default: throw new o("impossible error: invalid scalar style") } }() } function Pe(e, t) { var n = Re(e) ? String(t) : "", i = "\n" === e[e.length - 1]; return n + (i && ("\n" === e[e.length - 2] || "\n" === e) ? "+" : i ? "" : "-") + "\n" } function We(e) { return "\n" === e[e.length - 1] ? e.slice(0, -1) : e } function He(e, t) { if ("" === e || " " === e[0]) return e; for (var n, i, r = / [^ ]/g, o = 0, a = 0, l = 0, c = ""; n = r.exec(e);)(l = n.index) - o > t && (i = a > o ? a : l, c += "\n" + e.slice(o, i), o = i + 1), a = l; return c += "\n", e.length - o > t && a > o ? c += e.slice(o, a) + "\n" + e.slice(a + 1) : c += e.slice(o), c.slice(1) } function $e(e, t, n, i) { var r, o, a, l = "", c = e.tag; for (r = 0, o = n.length; r < o; r += 1)a = n[r], e.replacer && (a = e.replacer.call(n, String(r), a)), (Ve(e, t + 1, a, !0, !0, !1, !0) || void 0 === a && Ve(e, t + 1, null, !0, !0, !1, !0)) && (i && "" === l || (l += Le(e, t)), e.dump && 10 === e.dump.charCodeAt(0) ? l += "-" : l += "- ", l += e.dump); e.tag = c, e.dump = l || "[]" } function Ge(e, t, n) { var i, r, a, l, c, s; for (a = 0, l = (r = n ? e.explicitTypes : e.implicitTypes).length; a < l; a += 1)if (((c = r[a]).instanceOf || c.predicate) && (!c.instanceOf || "object" == typeof t && t instanceof c.instanceOf) && (!c.predicate || c.predicate(t))) { if (n ? c.multi && c.representName ? e.tag = c.representName(t) : e.tag = c.tag : e.tag = "?", c.represent) { if (s = e.styleMap[c.tag] || c.defaultStyle, "[object Function]" === Ie.call(c.represent)) i = c.represent(t, s); else { if (!Se.call(c.represent, s)) throw new o("!<" + c.tag + '> tag resolver accepts not "' + s + '" style'); i = c.represent[s](t, s) } e.dump = i } return !0 } return !1 } function Ve(e, t, n, i, r, a, l) { e.tag = null, e.dump = n, Ge(e, n, !1) || Ge(e, n, !0); var c, s = Ie.call(e.dump), u = i; i && (i = e.flowLevel < 0 || e.flowLevel > t); var p, f, d = "[object Object]" === s || "[object Array]" === s; if (d && (f = -1 !== (p = e.duplicates.indexOf(n))), (null !== e.tag && "?" !== e.tag || f || 2 !== e.indent && t > 0) && (r = !1), f && e.usedDuplicates[p]) e.dump = "*ref_" + p; else { if (d && f && !e.usedDuplicates[p] && (e.usedDuplicates[p] = !0), "[object Object]" === s) i && 0 !== Object.keys(e.dump).length ? (!function (e, t, n, i) { var r, a, l, c, s, u, p = "", f = e.tag, d = Object.keys(n); if (!0 === e.sortKeys) d.sort(); else if ("function" == typeof e.sortKeys) d.sort(e.sortKeys); else if (e.sortKeys) throw new o("sortKeys must be a boolean or a function"); for (r = 0, a = d.length; r < a; r += 1)u = "", i && "" === p || (u += Le(e, t)), c = n[l = d[r]], e.replacer && (c = e.replacer.call(n, l, c)), Ve(e, t + 1, l, !0, !0, !0) && ((s = null !== e.tag && "?" !== e.tag || e.dump && e.dump.length > 1024) && (e.dump && 10 === e.dump.charCodeAt(0) ? u += "?" : u += "? "), u += e.dump, s && (u += Le(e, t)), Ve(e, t + 1, c, !0, s) && (e.dump && 10 === e.dump.charCodeAt(0) ? u += ":" : u += ": ", p += u += e.dump)); e.tag = f, e.dump = p || "{}" }(e, t, e.dump, r), f && (e.dump = "&ref_" + p + e.dump)) : (!function (e, t, n) { var i, r, o, a, l, c = "", s = e.tag, u = Object.keys(n); for (i = 0, r = u.length; i < r; i += 1)l = "", "" !== c && (l += ", "), e.condenseFlow && (l += '"'), a = n[o = u[i]], e.replacer && (a = e.replacer.call(n, o, a)), Ve(e, t, o, !1, !1) && (e.dump.length > 1024 && (l += "? "), l += e.dump + (e.condenseFlow ? '"' : "") + ":" + (e.condenseFlow ? "" : " "), Ve(e, t, a, !1, !1) && (c += l += e.dump)); e.tag = s, e.dump = "{" + c + "}" }(e, t, e.dump), f && (e.dump = "&ref_" + p + " " + e.dump)); else if ("[object Array]" === s) i && 0 !== e.dump.length ? (e.noArrayIndent && !l && t > 0 ? $e(e, t - 1, e.dump, r) : $e(e, t, e.dump, r), f && (e.dump = "&ref_" + p + e.dump)) : (!function (e, t, n) { var i, r, o, a = "", l = e.tag; for (i = 0, r = n.length; i < r; i += 1)o = n[i], e.replacer && (o = e.replacer.call(n, String(i), o)), (Ve(e, t, o, !1, !1) || void 0 === o && Ve(e, t, null, !1, !1)) && ("" !== a && (a += "," + (e.condenseFlow ? "" : " ")), a += e.dump); e.tag = l, e.dump = "[" + a + "]" }(e, t, e.dump), f && (e.dump = "&ref_" + p + " " + e.dump)); else { if ("[object String]" !== s) { if ("[object Undefined]" === s) return !1; if (e.skipInvalid) return !1; throw new o("unacceptable kind of an object to dump " + s) } "?" !== e.tag && Ke(e, e.dump, t, a, u) } null !== e.tag && "?" !== e.tag && (c = encodeURI("!" === e.tag[0] ? e.tag.slice(1) : e.tag).replace(/!/g, "%21"), c = "!" === e.tag[0] ? "!" + c : "tag:yaml.org,2002:" === c.slice(0, 18) ? "!!" + c.slice(18) : "!<" + c + ">", e.dump = c + " " + e.dump) } return !0 } function Ze(e, t) { var n, i, r = [], o = []; for (Je(e, r, o), n = 0, i = o.length; n < i; n += 1)t.duplicates.push(r[o[n]]); t.usedDuplicates = new Array(i) } function Je(e, t, n) { var i, r, o; if (null !== e && "object" == typeof e) if (-1 !== (r = t.indexOf(e))) -1 === n.indexOf(r) && n.push(r); else if (t.push(e), Array.isArray(e)) for (r = 0, o = e.length; r < o; r += 1)Je(e[r], t, n); else for (r = 0, o = (i = Object.keys(e)).length; r < o; r += 1)Je(e[i[r]], t, n) } function Qe(e, t) { return function () { throw new Error("Function yaml." + e + " is removed in js-yaml 4. Use yaml." + t + " instead, which is now safe by default.") } } var ze = p, Xe = h, et = b, tt = O, nt = j, it = K, rt = xe.load, ot = xe.loadAll, at = { dump: function (e, t) { var n = new Ee(t = t || {}); n.noRefs || Ze(e, n); var i = e; return n.replacer && (i = n.replacer.call({ "": i }, "", i)), Ve(n, 0, i, !0, !0) ? n.dump + "\n" : "" } }.dump, lt = o, ct = { binary: L, float: S, map: y, null: A, pairs: Y, set: B, timestamp: F, bool: v, int: C, merge: E, omap: U, seq: m, str: g }, st = Qe("safeLoad", "load"), ut = Qe("safeLoadAll", "loadAll"), pt = Qe("safeDump", "dump"), ft = { Type: ze, Schema: Xe, FAILSAFE_SCHEMA: et, JSON_SCHEMA: tt, CORE_SCHEMA: nt, DEFAULT_SCHEMA: it, load: rt, loadAll: ot, dump: at, YAMLException: lt, types: ct, safeLoad: st, safeLoadAll: ut, safeDump: pt }; e.CORE_SCHEMA = nt, e.DEFAULT_SCHEMA = it, e.FAILSAFE_SCHEMA = et, e.JSON_SCHEMA = tt, e.Schema = Xe, e.Type = ze, e.YAMLException = lt, e.default = ft, e.dump = at, e.load = rt, e.loadAll = ot, e.safeDump = pt, e.safeLoad = st, e.safeLoadAll = ut, e.types = ct, Object.defineProperty(e, "__esModule", { value: !0 }) })); diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/easy_prompt_selector.py b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/easy_prompt_selector.py deleted file mode 100644 index d98f9c2..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/easy_prompt_selector.py +++ /dev/null @@ -1,148 +0,0 @@ -from pathlib import Path -import random -import re -import yaml -import gradio as gr - -import modules.scripts as scripts -from modules.scripts import AlwaysVisible, basedir -from modules import shared -from scripts.setup import write_filename_list - -FILE_DIR = Path().absolute() -BASE_DIR = Path(basedir()) -TAGS_DIR = BASE_DIR.joinpath('tags') - -def tag_files(): - return TAGS_DIR.rglob("*.yml") - -def load_tags(): - tags = {} - for filepath in tag_files(): - with open(filepath, "r", encoding="utf-8") as file: - yml = yaml.safe_load(file) - tags[filepath.stem] = yml - - return tags - -def find_tag(tags, location): - if type(location) == str: - return tags[location] - - value = '' - if len(location) > 0: - value = tags - for tag in location: - value = value[tag] - - if type(value) == dict: - key = random.choice(list(value.keys())) - tag = value[key] - if type(tag) == dict: - value = find_tag(tag, [random.choice(list(tag.keys()))]) - else: - value = find_tag(value, key) - - if (type(value) == list): - value = random.choice(value) - - return value - -def replace_template(tags, prompt): - count = 0 - while count < 100: - if not '@' in prompt: - break - - for match in re.finditer(r'(@((?P\d+(-\d+)?)\$\$)?(?P[^>]+?)@)', prompt): - template = match.group() - try: - try: - result = list(map(lambda x: int(x), match.group('num').split('-'))) - min_count = min(result) - max_count = max(result) - except Exception as e: - min_count, max_count = 1, 1 - count = random.randint(min_count, max_count) - - values = list(map(lambda x: find_tag(tags, match.group('ref').split(':')), list(range(count)))) - prompt = prompt.replace(template, ', '.join(values), 1) - except Exception as e: - prompt = prompt.replace(template, '', 1) - count += 1 - - return prompt - -class Script(scripts.Script): - tags = {} - - def __init__(self): - super().__init__() - self.tags = load_tags() - - def title(self): - return "EasyPromptSelector" - - def show(self, is_img2img): - if (is_img2img): - return None - - return AlwaysVisible - - def ui(self, is_img2img): - reload_button = gr.Button('🔄', variant='secondary', elem_id='easy_prompt_selector_reload_button') - reload_button.style(size='sm') - - def reload(): - self.tags = load_tags() - write_filename_list() - - reload_button.click(fn=reload) - - return [reload_button] - - def replace_template_tags(self, p): - if shared.opts.eps_use_old_template_feature == False: - if ('@' in p.prompt): - for i in range(len(p.all_prompts)): - self.save_prompt_to_pnginfo(p) - - prompt = "".join(replace_template(self.tags, p.all_prompts[i])) - p.all_prompts[i] = prompt - - if ('@' in p.negative_prompt): - for i in range(len(p.all_negative_prompts)): - self.save_prompt_to_pnginfo(p, True) - - negative_prompt = "".join(replace_template(self.tags, p.all_negative_prompts[i])) - p.all_negative_prompts[i] = negative_prompt - else: - if ('@' in p.prompt): - self.save_prompt_to_pnginfo(p) - - p.prompt = replace_template(self.tags, p.prompt) - for i in range(len(p.all_prompts)): - p.all_prompts[i] = p.prompt - - if ('@' in p.negative_prompt): - self.save_prompt_to_pnginfo(p, True) - - p.negative_prompt = replace_template(self.tags, p.negative_prompt) - for i in range(len(p.all_negative_prompts)): - p.all_negative_prompts[i] = p.negative_prompt - - def save_prompt_to_pnginfo(self, p, is_negative = False): - if shared.opts.eps_enable_save_raw_prompt_to_pnginfo == False: - return - - if is_negative == False: - prompt = p.prompt.replace('\n', ' ') - param_name = "Input Prompt" - else: - prompt = p.negative_prompt.replace('\n', ' ') - param_name = "Input NegativePrompt" - - p.extra_generation_params.update({param_name: prompt}) - - def process(self, p, *args): - self.replace_template_tags(p) diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/settings.py b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/settings.py deleted file mode 100644 index 309ee3a..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/settings.py +++ /dev/null @@ -1,7 +0,0 @@ -from modules import script_callbacks, shared - -def on_ui_settings(): - shared.opts.add_option("eps_enable_save_raw_prompt_to_pnginfo", shared.OptionInfo(False, "元プロンプトを pngninfo に保存する", section=("easy_prompt_selector", "EasyPromptSelector"))) - shared.opts.add_option("eps_use_old_template_feature", shared.OptionInfo(False, "古いランダム機能の実装を使用する(sdweb-eagle-pnginfo との互換性のため)", section=("easy_prompt_selector", "EasyPromptSelector"))) - -script_callbacks.on_ui_settings(on_ui_settings) diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/setup.py b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/setup.py deleted file mode 100644 index 20f9668..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/scripts/setup.py +++ /dev/null @@ -1,38 +0,0 @@ -from pathlib import Path -import shutil -import os - -from modules import scripts - -FILE_DIR = Path().absolute() -BASE_DIR = Path(scripts.basedir()) -TEMP_DIR = FILE_DIR.joinpath('tmp') - -TAGS_DIR = BASE_DIR.joinpath('tags') -EXAMPLES_DIR = BASE_DIR.joinpath('tags_examples') - -FILENAME_LIST = 'easyPromptSelector.txt' - -os.makedirs(TEMP_DIR, exist_ok=True) - -def examples(): - return EXAMPLES_DIR.rglob("*.yml") - -def copy_examples(): - for file in examples(): - file_path = str(file).replace('tags_examples', 'tags') - shutil.copy2(file, file_path) - -def tags(): - return TAGS_DIR.rglob("*.yml") - -def write_filename_list(): - filepaths = map(lambda path: path.relative_to(FILE_DIR).as_posix(), list(tags())) - - with open(TEMP_DIR.joinpath(FILENAME_LIST), 'w', encoding="utf-8") as f: - f.write('\n'.join(sorted(filepaths))) - -if len(list(TAGS_DIR.rglob("*.yml"))) == 0: - copy_examples() - -write_filename_list() diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/style.css b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/style.css deleted file mode 100644 index 29fb66b..0000000 --- a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/style.css +++ /dev/null @@ -1,10 +0,0 @@ -.easy_prompt_selector_container { - display: flex; - flex-direction: row; - gap: 0.5em; - margin-top: 0.5em; -} - -.easy_prompt_selector_button { - flex: 1; -} diff --git a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/.keep b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/.keep deleted file mode 100644 index e69de29..0000000 diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\344\272\272\347\211\251.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\344\272\272\347\211\251.yml" deleted file mode 100644 index bdca00a..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\344\272\272\347\211\251.yml" +++ /dev/null @@ -1,42 +0,0 @@ -对像: - - 1girl - - 1boy - - 1other - - multiple girls - -年龄: - 十几岁: teen - 少年: early teen - 大人: adult - 老人: elder - 儿童: child - -肤色: - 白: white skin - 色白: pale skin - 褐色: dark skin - 明亮: shiny skin - 有色: colored skin - -皮肤性质: - 日晒: tan - 晒痕: tanlines - 纹身: tattoo - 油性: oil - -体形: - 运动员: athlete - 模特: model - 苗条: slender - 诱惑: glamor - 丰满: plump - 胖: fat - 高: tall - 纤弱: petite - 矮: chibi - 肌肉: muscular - 细腰: narrow waist - - - - diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\244\264\345\217\221.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\244\264\345\217\221.yml" deleted file mode 100644 index 2a6626f..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\244\264\345\217\221.yml" +++ /dev/null @@ -1,81 +0,0 @@ -发色: - 単色: - 黑发: black hair - 金发: blonde hair - 茶发: brown hair - 赤发: red hair - 粉发: pink hair - 蓝发: blue hair - 水色发: aqua hair - 緑发: green hair - 紫发: purple hair - 橙发: orange hair - 银发: silver hair - 灰发: gray hair - 白发: white hair - 多色: - 多色: multicolored hair - 条纹色: streaked hair - 渐变色: gradient hair - 内侧彩色: colored inner hair - 分叉色: split-color hair - -发型: - 长度: - 极短发: very short hair - 短发: short hair - 中等长度: medium hair - 长发: long hair - 超长发: very long hair - 超超长发: absurdly long hair - 种类: - 乱发: messy hair - 直发: straight hair - 波浪发: wavy hair - 翻卷发: flipped hair - 非対称: asymmetrical hair - 马尾: - 马尾: ponytail - 高马尾: high ponytail - 低马尾: low ponytail - 前马尾: front ponytail - 侧马尾: side ponytail - 分叉马尾: split ponytail - 折叠马尾: folded ponytail - 短马尾: short ponytail - 双马尾: - 双马尾: twintails - 低双马尾: low twintails - 短双马尾: short twintails - 三马尾: tri tails - 四马尾: quad tails - 辫子: braid - 半向上: half updo - 一边向上: one side up - 两边向上: two side up - 多股头发: multi-tied hair - 头顶结: topknot - 卷发: curly hair - 钻头毛: drill hair - 双钻头毛: twin drills - 垂长卷: ringlets - 弓型发: bow-shaped hair - 发髻: hair bun - 发圈: hair rings - 长发绺: dreadlocks - -前发: - 钝刘海: blunt bangs - 非対称刘海: asymmetrical bangs - 眼睛上方刘海: hair over eyes - 一直眼睛上方刘海: hair over one eye - 分刘海: parted bangs - 齐刘海: swept bangs - 眼睛间头发: hair between eyes - 发量: hair intakes - 触角: sidelocks - -其他: - 横发: hair flaps - 傻毛: ahoge - 天线毛: antenna hair diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\247\277\346\200\201.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\247\277\346\200\201.yml" deleted file mode 100644 index af9486a..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\345\247\277\346\200\201.yml" +++ /dev/null @@ -1,125 +0,0 @@ -姿态: - 侧身坐: yokozuwari - 鸭子坐: ahirusuwari - 盘腿: indian style - 跪着: kneeling - 躬躯: arched back - 膝枕: lap pillow - 学猫叫: paw pose - 单膝跪地: one knee - 蜷起身子侧躺: fetal position - 仰卧: on back - 俯卧: on stomach - 坐着: sitting - 屈膝抱腿坐: hugging own legs - 立式跨骑: upright straddle - 站着: standing - 蹲着: squatting - 绑在十字架上: crucifixion - 双腿缠绕: leg lock - 四肢着地: all fours - 戴耳机: hand on headphones - 鬼姿势: ghost pose - 回头: turning around - 歪头: head tilt - 前倾: leaning forward -手势: - 嘘手势: shushing - 翘大拇指: thumbs up - 手放脑后: arms behind head - 手放身后: arms behind back - 手插口袋: hand in pocket - 双手插口袋: hands in pocket - 十指相扣: interlocked fingers - V字手势: victory pose - 手在地板上: hand on floor - 手在额头上: hand on forehead - 手在肚子上: hand on own stomach - 手在肩膀上: arm over shoulder - 手搭别人的腿: hand on another's leg - 手搭别人的腰: hand on another's waist - 双手合十: own hands clasped - 翼展双臂: wide open arms - 手放嘴边: hand to mouth - 手枪手势: finger gun - 猫爪手势: cat pose -视线: - 远眺: looking afar - 照镜子: looking at mirror - 看手机: looking at phone - 看向别处: looking away - 透过刘海看: visible through hair - 透过眼镜看: looking over glasses - 面向观者: look at viewer - 靠近观者: close to viewer - 动态角度: dynamic angle - 舞台角度: dramatic angle - 凝视: stare - 向上看: looking up - 向下看: looking down - 看向旁边: looking to the side - 移开目光: looking away -整体: - 嗅闻: smelling - 公主抱: princess carry - 拥抱: hug - 背对背: back-to-back - 耶: peace symbol - 调整过膝袜: adjusting_thighhigh - 抓住: grabbing - 战斗姿态: fighting_stance - 走: walking - 跑: running - 跨坐: straddling - 跳: jump - 飞: fly - 靠墙: against wall - 躺: lie - 从背后抱: hug from behind - 遛狗: walk a dog - 提裙: skirt lift - 泡温泉: half body under water - 骑马: horse riding - 自拍: selfie - 一字马: standing split - 敬礼: salute - 祈祷: pray - 冥想: doing a meditation -上半身: - 伸懒腰: stretch - 托腮: gill support - 牵手: holding hands - 单手叉腰: hand_on_hip - 双手叉腰: hands_on_hips - 招手: waving - 撮头发: hair scrunchie - 拉头发: hair_pull - 抓别人的头发: grabbing another's hair - 竖中指: middle_finger - 弯腰: bent over - 亲吻脸颊: kissing cheek - 亲吻额头: kissing forehead - 踮起脚尖吻: tiptoe kiss - 头顶水果: fruit on head - 咬手套: glove biting - 脸贴脸: cheek-to-cheek - 手牵手: hand on another's hand - 双手交叉: crossed arms - 双手张开伸直: spread arms - 挥动手臂: waving arms - 伸出手臂: outstretched arm - 用手臂支撑: carrying - 搂着手臂: arm hug - 拿着: holding - 拿着餐刀: holding knife - 拿着枪: holding gun - 拿着杯子: holding cup - 拿着食物: holding food - 拿着书: holding book - 拿着魔杖: holding wand - 打着伞: holding umbrella - 捧着花: holding flower - 拿着麦克风: holding microphone - 抱着物品: object hug - 抱着心: holding heart - diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\216\257\345\242\203.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\216\257\345\242\203.yml" deleted file mode 100644 index 12aaaae..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\216\257\345\242\203.yml" +++ /dev/null @@ -1,124 +0,0 @@ -四季朝暮: - 春天: in spring - 夏天: in summer - 秋天: in autumn - 冬天: in winter - 黄昏: dusk - 夜晚: night - 秋景: (autumn maple forest:1.3),(very few fallen leaves),(path) -日月星辰: - 太阳: sun - 落日: sunset - 月亮: moon - 满月: full_moon - 星星: stars - 天空: sky - 多云: cloudy - 雨天: rain - 冰雪: snow,ice - 雪花: snowflakes - 闪电: lighting - 彩虹: rainbow - 流星雨: meteor shower - 宇宙: universe -天涯海角: - 大海: sea - 山丘: hills - 草地: in a meadow - 海滩: on the beach - 水中: underwater - 海边: over the sea - 树林: grove - 沙漠: on a desert - 高原: plateau - 悬崖: cliff - 峡谷: canyon - 绿洲: oasis - 竹林: bamboo forest - 冰川: glacier - 浮岛: floating island - 火山: volcano - 大草原: savanna - 瀑布: waterfall - 溪流: stream - 荒地: wasteland - 稻田: rice paddy - 麦田: wheat field - 花田: flower field - 花海: flower sea -室内场景: - 室内: indoor - 窗帘: curtain - 床: bed - 浴室: bathroom - 厕所隔间: toilet stall - 宅男房间: otaku room - 自助餐厅: cafeteria - 教室: classroom - 俱乐部: clubroom - 沙龙: salon - 酒吧: bar - 居酒屋: izakaya - 咖啡馆: cafe - 面包店: bakery - 便利店: convenience store - 超市: supermarket - 书店: bookstore - 药店: pharmacy - 剧院: theater - 电影院: movie theater - 温室: greenhouse - 地库: dungeon - 健身房: gym - 医务室: infirmary - 实验室: laboratory - 图书馆: library - 工作坊: workshop - 舞台: stage - 法庭: courtroom -城市建筑: - 城堡: castle - 城市: city - 水上乐园: waterpark - 旋转木马: carousel - 摩天轮: ferris wheel - 水族馆: aquarium - 动物园: zoo - 保龄球馆: bowling alley - 美术馆: art gallery - 博物馆: museum - 天文馆: planetarium - 游泳池: swimming pool - 体育场: stadium - 寺庙: temple - 巴士车站: bus stop - 火车站: train station - 喷泉: fountain - 游乐场: playground - 市场摊位: market stall - 电话亭: phone booth - 铁轨: railroad tracks - 机场: airport - 隧道: tunnel -背景氛围: - 新年: new year - 兔年: year of the rabbit - 情人节: valentine - 元宵节: lantern festival - 夏日祭: summer festival - 七夕节: tanabata - 中秋节: mid-autumn festival - 万圣节: halloween - 圣诞节: christmas - 爆炸: explosion - 蒸汽: water vapor - 焰火: fireworks - 落地窗: ceiling window - 彩色玻璃: colourful glass - 染色玻璃: stain glass - 涂鸦墙: Graffiti wall - 马赛克背景: mosaic background - 液体背景: liquid background, Sputtered water - 魔法环: magic circles - 荧光蘑菇森林: fluorescent mushroom forests background - 彩色泡泡: (((colorful bubble))) diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\224\273\350\264\250.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\224\273\350\264\250.yml" deleted file mode 100644 index 26e3ec3..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\224\273\350\264\250.yml" +++ /dev/null @@ -1,58 +0,0 @@ -画质: - 提高质量: HDR,UHD,8K - 最佳质量: best quality - 杰作: masterpiece - 更多细节: Highly detailed - 演播室灯光: Studio lighting - 超精细绘画: ultra-fine painting - 聚焦清晰: sharp focus - 物理渲染: physically-based rendering - 极详细刻画: extreme detail description - 改善细节: Professional - 添加鲜艳色彩: Vivid Colors - 虚化模糊景: Bokeh - 相机设置: (EOS R8,50mm,F1.2,8K,RAW photo:1.2) - 老照片: High resolution scan - 素描: Sketch - 绘画: Painting -视角: - 动态角度: dynamic angle - 从左侧视角: from the left - 从右侧视角: from the right - 从上方: from above - 从下面: from below - 从下往上看: looking up - 从上往下看: looking down - 从正上方往下看: top down - 从侧面往上看: side view up - 从侧面往下看: side view down - 从人物的角度往上看: subject look up - 从人物的角度往下看: subject look down - 在地面往上看: ground view up - 在地面往下看: ground view down - 全景: panoramic view - 广角宽景: wide shot - 广角: wide-angle view - 空中俯瞰视图: aerial view - 在高处往下看: bird view - 鸟瞰视角: bird’s-eye view - 蚯蚓视角: worm’s eye view - 带有角度的视角: angled - 低角度视角: low-angle view - 俯视视角: top-down - 放大镜效果: zoomed in - 缩小镜效果: zoomed out - 俯视: top-down view - 高角度视角: high-angle view - 平视: eye level view/level gaze/straight gaze - 特写: close-up view - 极端特写: extreme close-up view -视线: - 面对画面或观众: looking at viewer - 两个角色对视: looking at another - 看着别的方: looking away - 回头看: looking back - 向上看: looking up - - - diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\234\211\347\234\274.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\234\211\347\234\274.yml" deleted file mode 100644 index 320eae8..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\234\211\347\234\274.yml" +++ /dev/null @@ -1,75 +0,0 @@ -眉毛: - 浓眉: thick eyebrows - 眉毛翘起: cocked eyebrow - 短眉毛: short eyebrows - V字眉: v-shaped eyebrows -眼睛: - 黒: black eyes - 白: white eyes - 红: red eyes - 蓝: blue eyes - 绿: green eyes - 紫: purple eyes - 银色: silver eyes - 金色: golden eyes - 灰色: gray eyes - 水色: aqua eyes - 茶色: brown eyes - 粉色: pink eyes - 橙色: orange eyes - 异色: heterochromia - 空洞眼睛: empty eyes - 睁大眼睛: wide eyes - 闭上一只眼: one eye closed - 半闭眼睛: half-closed eyes - 渐变眼: gradient_eyes - 水汪汪大眼: aqua eyes - 翻白眼: rolling eyes - 斗鸡眼: cross-eyed - 猫眼: slit pupils - 布满血丝的眼睛: bloodshot eyes - 发光眼睛: glowing eyes - 吊眼角: tsurime - 垂眼角: tareme - 恶魔眼: devil eyes - 收缩的瞳孔: constricted pupils - 魔瞳: devil pupils - 蛇瞳: snake pupils - 闪闪发光瞳: pupils sparkling - 花形瞳: flower-shaped pupils - 爱心瞳: heart-shaped pupils - 异色瞳: heterochromia - 美瞳: color contact lenses - 长睫毛: longeyelashes - 彩色睫毛: colored eyelashes - 眼下痣: mole under eye -嘴巴: - 栗子嘴: chestnut mouth - 厚嘴唇: thick lips - 嘴唇浮肿: puffy lips - 口红: lipstick - 心形嘴: heart-shaped mouth - 嘟嘴: pout - 张嘴: open mouth - 闭嘴: closed mouth - 猫咪嘴: :3 - 鲨鱼嘴: shark mouth - 吐舌头: :p - 分开嘴唇: parted lips - 嘴下痣: mole under mouth -耳朵: - 精灵耳: elf ears - 动物耳朵: fake animal ears - 猫耳朵: cat ears - 狗耳朵: dog ears - 狐狸耳朵: fox ears - 兔子耳朵: bunny ears - 熊耳朵: bear ears -胡子&牙: - 胡须: beard - 小胡子: mustache - 山羊胡: goatee - 长鬓角: long sideburns - 尖牙: fangs - 虎牙: canine teeth - 咬紧牙关: clenched teeth diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\277\205\350\206\200.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\277\205\350\206\200.yml" deleted file mode 100644 index ffee2ee..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\347\277\205\350\206\200.yml" +++ /dev/null @@ -1,44 +0,0 @@ -尾巴: - 宝可梦尾巴: pokemon tail - 皮卡丘尾巴: pikachu tail - 水獭尾巴: otter tail - 蝎尾: scorpion tail - 鹿尾: deer tail - 黄鼠狼尾巴: weasel tail - 羊驼尾巴: alpaca tail - 恐龙尾巴: dinosaur tail - 企鹅尾巴: penguin tail - 羊尾巴: sheep tail - 山羊尾巴: goat tail - 海狸尾巴: beaver tail - 小熊猫尾巴: red panda tail - 豺尾巴: jackal tail - 食蚁兽尾巴: anteater tail - 土狼尾巴: aardwolf tail - 猎豹尾巴: panther tail - 熊猫尾巴: panda tail -翅膀: - 天使尾巴: Angel wings - 蝴蝶翅膀: Butterfly wings - 昆虫翅膀: insect wings - 蝙蝠翅膀: Bat wings - 鸟翼: bird wings - 羽翼: feathered wings - 妖精翅膀: Fairy wings - 龙之翼: Dragon wings - 恶魔之翼: Demon wings - 火焰翅膀: Fiery wings - 机械翅膀: Mechanical wings - 冰翅: ice crystal texture - 冰火之翼: ((burning feathers)),(feathers_made_of_ice),(frozen feathers),(((ice and fire together))) -角: - 羚羊角: antelope horns - 山羊角: goat horns - 羊角: sheep horns - 奶牛角: cow horns - 公牛角: ox horns - 鬼角: oni horns - 断角: broken horn - 机械角: mechanical horns - 恶魔之角: demon horns - 龙之角: dragon horns diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\201\214\344\270\232.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\201\214\344\270\232.yml" deleted file mode 100644 index db28cf2..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\201\214\344\270\232.yml" +++ /dev/null @@ -1,77 +0,0 @@ -职业: - 救生员: lifeguard - 拳击手: boxer - 科学家: scientist - 运动员: athletes - 职场女性: office lady - 和尚: monk - 杂技演员: crobat - 修女: nun - 护士: nurse - 空姐: stewardess - 学生: student - 女服务员: waitress - 老师: teacher - 赛车手: racer - 警察: police - 士兵: soldier - 啦啦队: cheerleader - 男演员: actor - 女演员: actress - 间谍: spy - 特工: agent - 刺客: assassin - 诗人: poet - 日本武士: samurai - 舞女: dancing girl - 摩托车手: motorcyclist - 黑客: hacker - 魔术师: magician - 侦探: detective - 人偶: doll - 女仆: maid - 飞行员: pilot - 潜水员: diver - 酒吧审查员: bar censor - 传教士: missionary - 消防员: firefighter - 守门员: goalkeeper - 厨师: chef - 宇航员: astronaut - 收银员: cashier - 邮递员: mailman - 咖啡师: barista - 隐士: the hermit - 牧羊人: makihitsuji -动漫: - 宝可梦: pokemon - 泰迪熊: teddy bear - 马里奥: mario - 皮卡丘: pikachu - 新世纪福音战士: neon genesis evangelion - 初音未来: hatsune miku - 哈利波特: harry potter - 哆啦A梦: doraemon - 圣斗士星矢: saint seiya - 五条悟: gojou satoru - 复仇者联盟: avengers - 神奇女侠: mazinger - 美国队长: captain america - 蜡笔小新: crayon shin-chan - 灌篮高手: slam dunk - 孙悟空: sun wukong - 女巫: witch - 忍者: ninja - 吸血鬼: vampire - 骑士: knight - 魔法少女: magical_girl - 半兽人: orc - 德鲁伊: druid - 妖精: elf - 小精灵: fairy - 兽人: furry - 美人鱼: mermaid - 假面骑士: kamen rider - 魔导师: magister - 蜘蛛侠: spider-man - 圣诞老人: santa alter diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\243\346\234\215.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\243\346\234\215.yml" deleted file mode 100644 index 2b6fca0..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\243\346\234\215.yml" +++ /dev/null @@ -1,81 +0,0 @@ -上装: - 过手袖: sleeves_past_fingers - 背心: tank top - 白衬衫: white shirt - 水手衬衫: sailor shirt - T恤: T-shirt - 毛衣: sweater - 夏日长裙: summer dress - 连帽衫: hoodie - 毛领: fur trimmed colla - 兜帽斗篷: hooded cloak - 夹克: jacket - 皮夹克: leather jacket - 探险家夹克: safari jacket - 兜帽: hood - 牛仔夹克: denim jacket - 高领夹克: turtleneck jacket - 消防员夹克: firefighter jacket - 透明夹克: see-through jacket - 战壕大衣: trench coat - 实验室外套: lab coat - 羽绒服: Down Jackets - 防弹盔甲: body armor - 防弹衣: flak jacket - 大衣: overcoat - 粗呢大衣: duffel coat -服装: - 燕尾服: tailcoat - 女仆装: Victoria black maid dress - 水手服: sailor suit - 学生服: school uniform - 职场制服: bussiness suit - 西装: suit - 军装: military uniform - 礼服: lucency full dress - 汉服: hanfu - 旗袍: cheongsam - 和服: japanses clothes - 运动服: sportswear - 工装服: dungarees - 婚纱: wedding dress - 银色连衣裙: silvercleavage dress - 长袍: robe - 围裙: apron - 快餐制服: fast food uniform - JK制服: JK - 健身服: gym_uniform - 巫女服: miko attire - 海军陆战队服: SWAT uniform - 无袖连衣裙: sleeveless dress - 雨衣: raincoat - 机甲衣: mech suit - 巫师法袍: wizard robe - 刺客装束: assassin-style -下装: - 牛仔短裤: denim shorts - 百褶裙: pleated skirt - 热裤: short shorts - 铅笔裙: pencil skirt - 皮裙: leather skirt - 黑色紧身裤: black leggings - 和服下的裙子: skirt under kimono -其他服装: - 褶边: frills - 花边: lace - 哥特风格: gothic - 洛丽塔风格: lolita fashion - 西部风格: western - 湿身: wet clothes - 露单肩: off_shoulder - 露双肩: bare_shoulders - 格子花纹: tartan - 横条花纹: striped - 披甲: armored skirt - 盔甲: armor - 金属盔甲: metal armor - 狂战士铠甲: berserker armor - 腰带: belt - 围巾: scarf - 披肩: cape - 皮草披肩: fur shawl diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\250\346\203\205.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\250\346\203\205.yml" deleted file mode 100644 index 28efe36..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\241\250\346\203\205.yml" +++ /dev/null @@ -1,38 +0,0 @@ -表情: - 笑: smile - 微笑: light smile - 惨笑: sad smile - 邪恶笑: evil smile - 天使笑: angelic smile - 强笑: forced smile - 诱人笑: seductive smile - 咧嘴笑: grin - 邪恶咧嘴笑: evil grin - 傻笑: smirk - 怒: angry - 悲伤: sad - 哭: crying - 泪: tears - 恐怖: scared - 不好的: serious - 恼怒: annoyed - 黑暗人格: dark persona - 多亚脸: doyagao - 脸红: blush - 脸通红: full-face blush - 无聊: bored - 罪恶感: guilt - 无感情: expressionless - 决心: determined - 接吻: incoming kiss - 失望: disappointed - 轻蔑: disdain - 嫉妒: envy - 厌恶: disgust - 困惑: confused - 烦恼挑眉: troubled eyebrows - V型眉: v-shaped eyebrows - 羞耻: embarrassed - 顽皮: naughty - 困乏: sleepy - diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\243\205\351\245\260.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\243\205\351\245\260.yml" deleted file mode 100644 index 7c0b020..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\243\205\351\245\260.yml" +++ /dev/null @@ -1,71 +0,0 @@ -发饰: - 发带: hair ribbon - 头巾: head scarf - 动物头巾: animal hood - 蝴蝶结发饰: hair bow - 新月发饰: crescent hair ornament - 洛丽塔发饰: lolita hairband - 羽毛发饰: feather hair ornament - 头花: hair flower - 发髻: hair bun - 发夹: hairclip - 发箍: hair scrunchie - 发圈: hair rings - 发饰: hair ornament - 发棒: hair stick - 心形发饰: heart hair ornament -首饰: - 手链: bracelet - 项圈: choker - 金属项圈: metal collar - 戒指: ring - 腕带: wristband - 吊坠: pendant - 胸针: brooch - 圈形耳环: hoop earrings - 手镯: bangle - 耳钉: stud earrings - 旭日形首饰: sunburst - 珍珠手链: pearl bracelet - 耳坠: drop earrings - 木偶戒指: puppet rings - 胸花: corsage - 蓝宝石胸针: sapphire brooch - 珠宝首饰: jewelry - 项链: necklace -装饰: - 丝带: ribbon - 丝带饰边: ribbon trim - 蕾丝饰边: lace trim - 裙撑: skirt lift - 护手: gauntlets - 领巾: neckerchief - 红领巾: red neckerchief - 肩章: pauldrons - 臂带: arm strap - 臂镯: armlet - 细肩带: spaghetti strap - 般若面具: Prajna in mask - 面纱: veil - 新娘面纱: bridal veil - 皇冠: tiara - 迷你皇冠: mini crown - 耳罩: ear covers - 飞行员太阳镜: aviator sunglasses - 无边框眼镜: semi-rimless eyewear - 半无框眼镜: semi-rimless eyewear - 太阳镜: sunglasses - 风镜: goggles - 独眼眼罩: eyepatch - 黑色眼罩: black blindfold - 铁棘: metal thorns - 光环: halo - 口罩: mouth mask - 创口贴: bandaid hair ornament - 指甲油: nail polish - 玩偶关节: doll joints - 机械义肢: cybernetic prosthesis - 机械腿: mechanical legs - 沙滩巾: beach towel - 雨披: poncho - 浓妆: make up diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\264\237\351\235\242\346\217\220\347\244\272\350\257\215.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\264\237\351\235\242\346\217\220\347\244\272\350\257\215.yml" deleted file mode 100644 index fc3a771..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\350\264\237\351\235\242\346\217\220\347\244\272\350\257\215.yml" +++ /dev/null @@ -1,23 +0,0 @@ -负面提示: - NSFW: nsfw,logo,text - embeddings: badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,bad-picture-chill-75v - 变异手指: mutated hands and fingers - 畸形的: deformed - 解剖不良: bad anatomy - 毁容: disfigured - 脸不好: poorly drawn face - 变异的: mutated - 多余肢体: extra limb - 丑陋: ugly - 手画得差: poorly drawn hands - 缺少的肢体: missing limb - 漂浮的四肢: floating limbs - 肢体不连贯: disconnected limbs - 畸形的手: malformed hands - 脱离焦点: out of focus - 长颈: long neck - 身体长: long body - 全选: nsfw,logo,text,badhandv4,EasyNegative,ng_deepnegative_v1_75t,rev2-badprompt,verybadimagenegative_v1.3,negative_hand-neg,mutated hands and fingers,poorly drawn face,extra limb,missing limb,disconnected limbs,malformed hands,ugly - - - diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\236\213\345\270\275.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\236\213\345\270\275.yml" deleted file mode 100644 index e245ffc..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\236\213\345\270\275.yml" +++ /dev/null @@ -1,82 +0,0 @@ -帽饰: - 棒球帽: Baseball cap - 针织帽: Beanie - 拿破仑帽: Bicorne - 太阳帽: Boater hat - 遮阳帽: Visor cap - 圆顶礼帽: Bowler hat - 报童帽: Cabbie hat - 渔夫帽: Bucket hat - 侦探帽: Fedora - 牛仔帽: Cowboy hat - 厨师帽: Chef hat - 军官帽: Military hat - 圣诞帽: Santa hat - 派对帽: Party hat - 小丑帽: Jester cap - 安全帽: Hardhat - 棒球头盔: Baseball helmet - 橄榄球头盔: Football helmet - 动物头盔: animal helmet - 女巫帽: witch hat - 贝雷帽: beret - 鸭舌帽: peaked cap - 草帽: Straw hat -鞋类: - 裸足: bare_legs - 靴子: boots - 马丁靴: knee boots - 脚踝靴: ankle boots - 系带靴: cross-laced_footwear - 战斗靴: combat boots - 装甲靴: armored boots - 过膝靴: knee boots - 防水橡胶靴: rubber boots - 皮靴: leather boots - 雪地靴: snow boots - 圣诞靴: santa boots - 鞋子: shoes - 厚底鞋: platform footwear - 尖头鞋: pointy footwear - 芭蕾舞鞋: ballet slippers - 运动鞋: sneakers - 旱冰鞋: roller skates - 溜冰鞋: ice skates - 钉鞋: spiked shoes - 高跟鞋: high heels - 玛丽珍鞋: mary janes - 乐福鞋: loafers - 女式学生鞋: uwabaki - 凉鞋: sandals - 木屐: geta - 拖鞋: slippers - 人字拖: flip-flops -袜类: - 不穿袜子: no socks - 短袜: socks - 日式厚底短袜: tabi - 丝袜: stockings - 圣诞袜: christmas stocking - 暖腿袜: leg warmers - 荷叶边袜子: frilled socks - 丝带边袜子: ribbon-trimmed legwear - 闪亮袜子: shiny legwear - 褶边长筒袜: frilled thighhighs - 过膝袜: thighhighs - 渔网袜: fishnet stockings - 堆堆袜: loose socks - 裤袜: leggings - 蕾丝裤袜: lace legwear - 罗纹裤袜: ribbed legwear - 湿连裤袜: wet pantyhose - 格子裤袜: plaid legwear - 透视裤袜: see-through legwear - 连裤袜: pantyhose - 撕裂的连裤袜: torn pantyhose - 单腿连裤袜: single leg pantyhose - 荷叶边连裤袜: frilled pantyhose - 柳丁吊袜带: studded garter belt - 吊袜带: sock dangle - 大腿系带: thigh strap - 腿部花边环: leg_garter - 包扎腿: bandaged leg diff --git "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\243\216\346\240\274.yml" "b/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\243\216\346\240\274.yml" deleted file mode 100644 index 7349255..0000000 --- "a/src/code/images/sd-resource/extensions/sdweb-easy-prompt-selector/tags/\351\243\216\346\240\274.yml" +++ /dev/null @@ -1,66 +0,0 @@ -艺术风格: - 8bit游戏: 8 Bit Game - 80动画: 1980s anime - 迪士尼电影: disney movie - 哥特摇滚: goth - 80电影: 80s movie - 泡泡龙: bubble bobble - 皮克斯动画: style of Pixar - 宝丽来艺术: Polaroid art - 万花筒摄影: Kaleidoscope Photography - 欧泊渲染: opal render - 色谱图: chemigram - 吉卜力风格: Studio Ghibli - 梦幻: dreamlike - 签绘风格: (faux traditional media) - 舰队收藏: kantai collection - 边缘行者: rebecca (cyberpunk) - 电锯人: chainsaw man - 魔法旋涡: Magic Vortex - 柴油朋克: ((dieselpunk)) - 四格: 4koma - 杂志扫描: magazine scan - 专辑封面: album cover - 线条变粗: (lineart) - 蒸汽波: synthwave - 洛可可: (illustration),(paper figure),(lococo),((impasto)),(shiny skin) -艺术类型: - 单色图片: monochrome - 拼贴艺术: Collage - 彩色玻璃: Dalle de verre - 像素画: pixel art - 瓷画: Encaustic painting - 水墨画: Ink wash painting - 铜版雕刻: Mezzotint - 剪影: silhouette - 插画: illustration - 水彩画: (((ink))), ((watercolor)) - 浮世绘: illustration,(((ukiyoe))),((sketch)),((japanese_art)) - 中国风: ((wash painting)),((ink s... - 油画: ((dyeing)),((oil painting)),((impasto)) - 黑白草图: (posing sketch), (monochrome) - 手画草稿: sketch - 铅笔速写: (monochrome), (gray scale), (pencil sketch lines - 彩铅画: (watercolor pencil) -艺术派系: - 新艺术主义: ((art nouveau)) - 古典主义: ((classicism)) - 未来主义: ((futurism)) - 达达主义: ((Dadaism)) - 抽象艺术: ((abstract art)) - ASCII艺术: ((ASCII art)) -艺术家风格: - 穆夏风格: ((alphonse mucha)) - 莫奈风格: ((Monet style)) -光照: - 轮廓光: rim light - 体积光: Volumetric Lighting - 霓虹灯: glowing neon lights - 电影级光照: Cinematic Lighting - 透镜光晕: lens flare - 金属光泽: metallic luster - 氛围光照: moody lighting - 丁达尔效应: Tyndall effect - 漏光光效: light leaks - 背景光: background light - 自然光: available light diff --git a/src/code/images/sd-resource/init.bash b/src/code/images/sd-resource/init.bash new file mode 100644 index 0000000..f4d8561 --- /dev/null +++ b/src/code/images/sd-resource/init.bash @@ -0,0 +1,154 @@ +#!/bin/bash +set -Eeuov pipefail + +# 处理一下镜像内置的文件 +# +# 特定目录 +# - BUILTIN: 内置文件目录,实际文件的存放位置 +# - SD_DIR: sd 的根目录 +# - VIRTUAL_NAS: 虚拟 NAS 目录,运行时会完整 copy 至 nas 挂载点,除去允许用户修改的配置文件外,均为软链接 +# +# 程序期望访问的目录 实际访问的目录 文件真正的存放位置 备注 +# /root ${NAS_DIR}/root 用户目录 +# /root/.huggingface/a ${NAS_DIR}/root/.huggingface/a ${BUILTIN}/root/.huggingface/a 内置的 root 文件 +# /root/.huggingface/b ${NAS_DIR}/root/.huggingface/b 用户自己安装的 root 文件 +# ${SD_DIR}/models ${NAS_DIR}/models 模型目录 +# ${SD_DIR}/models/aaa.safetensors ${NAS_DIR}/models/aaa.safetensors ${BUILTIN}/models/aaa.safetensors 内置的模型 +# ${SD_DIR}/models/bbb.safetensors ${NAS_DIR}/models/bbb.safetensors 用户自己安装的模型 +# ${NAS_DIR}/venv ${NAS_DIR}/venv python 虚拟环境 +# ${NAS_DIR}/venv/.../torch /venv/.../torch /venv/.../torch 内置依赖 +# ${NAS_DIR}/venv/.../xxx ${NAS_DIR}/venv/.../xxx 用户自己安装的依赖 + + +function mount_file_if_not_exist() { + # 挂载单个文件到指定目录,如果已存在文件则不做处理 + SRC="$1" + DST="$2" + + # 如果文件已经存在,则跳过 + if [ ! -e "${DST}" ]; then + mkdir -p "$(dirname "${DST}")" + ln -sT "${SRC}" "${DST}" + fi +} + +function mount_folder_files() { + # 挂载目录下直属的文件/文件夹到指定目录 + local SRC=$1 + local DST=$2 + ls ${SRC} | xargs -I {} bash -c "mount_file_if_not_exist ${SRC}/{} ${DST}/{}" +} + +function mount_all_files() { + # 挂载目录所有文件逐个到指定目录 + local SRC=$1 + local DST=$2 + find $SRC ! -type d -printf "%P\n" | xargs -I {} bash -c "mount_file_if_not_exist '${SRC}/{}' '${DST}/{}'" +} + +export -f \ + mount_file_if_not_exist \ + mount_folder_files \ + mount_all_files + + +# 将所有必要的文件放到 BUILTIN 目录 +# 该部分是处理的实际文件,因此只考虑复制和移动,不用考虑挂载 + +mkdir -p "$BUILTIN" + +# 要移动的文件,主要涉及 sd 代码自带的内容,需要保留下来,避免被后续挂载覆盖 +declare -A move_files +for dir in "models" "extensions" "extensions-builtin" "scripts" "localizations" \ + "configs" "embeddings" "textual_inversion_templates"; do + move_files["${SD_DIR}/${dir}/"]="${BUILTIN}/${dir}" +done +for src in "${!move_files[@]}"; do + dst="${move_files[${src}]}" + mkdir -p $(dirname $dst) + rsync -a --ignore-existing --remove-source-files "$src" "$dst" +done + +# 要复制的文件,主要涉及 Docker 构建上下文附加的文件 +declare -A copy_folder +for dir in "configs" "embeddings" "extensions-builtin" \ + "localizations" "models"; do + copy_folder["/ctx/${dir}/"]="${BUILTIN}/${dir}" +done +copy_folder["/ctx/config.json"]="$BUILTIN/config.json" +copy_folder["/ctx/ui-config.json"]="$BUILTIN/ui-config.json" +for src in "${!copy_folder[@]}"; do + dst="${copy_folder[${src}]}" + mkdir -p $(dirname $dst) + rsync -a --ignore-existing $src $dst +done + +mkdir -p $VIRTUAL_NAS +rsync -a --ignore-existing /ctx/config.json $VIRTUAL_NAS +rsync -a --ignore-existing /ctx/ui-config.json $VIRTUAL_NAS + + +touch "${VIRTUAL_NAS}/styles.csv" + +# 构建 VIRTUAL_NAS 目录,提升启动速度 +# 挂载分为如下类型 +# - 挂载文件夹,不挂载子文件:用户无法修改文件夹内部的内容(因为没有持久化到 NAS,主要应用于不存在改动的场景,如依赖) +# - 挂载文件夹及所有子文件: 用户有修改文件夹内容的需要,如模型目录 +# - 挂载文件:主要应用于挂载文件夹及所有文件 + +# 挂载文件夹及所有子文件 +declare -A all_files +for dir in "configs" "embeddings" "extensions" "extensions-builtin" \ + "localizations" "models" "scripts"; do + all_files["${BUILTIN}/${dir}"]="${VIRTUAL_NAS}/${dir}" +done +all_files["${BUILTIN}/root"]="${VIRTUAL_NAS}/root" +for src in "${!all_files[@]}"; do + dst="${all_files[${src}]}" + mount_all_files "$src" "$dst" +done + +# 挂载单个文件 / 仅挂载文件夹,不挂载子文件 +declare -A single_files +# single_files[""]="" +for src in "${!single_files[@]}"; do + dst="${single_files[${src}]}" + mount_file_if_not_exist "$src" "$dst" +done + + + +# 处理 venv 虚拟环境 /venv => ${VIRTUAL_NAS}/venv => ${NAS_DIR}/venv + +# 先尝试将 venv 切回到默认位置 +grep -r "/venv" /venv/bin/* | awk -F: "{print \$1}" | xargs -I {} sed "s@${NAS_DIR}/venv@/venv@g" -i {} + +# 处理文件挂载 +mount_file_if_not_exist /venv/bin ${VIRTUAL_NAS}/venv/bin +mount_file_if_not_exist /venv/include ${VIRTUAL_NAS}/venv/include +mount_file_if_not_exist /venv/pyvenv.cfg ${VIRTUAL_NAS}/venv/pyvenv.cfg +mount_file_if_not_exist /venv/include ${VIRTUAL_NAS}/venv/include +mount_folder_files /venv/lib/python3.10/site-packages ${VIRTUAL_NAS}/venv/lib/python3.10/site-packages +mount_folder_files /venv/lib64/python3.10/site-packages ${VIRTUAL_NAS}/venv/lib64/python3.10/site-packages + +# 重写虚拟环境配置 +export VIRTUAL_ENV="${NAS_DIR}/venv" +export PATH="${VIRTUAL_ENV}/bin:$PATH" +grep -r "/venv" /venv/bin/* | awk -F: '{print $1}' | xargs -I {} sed "s@/venv@${VIRTUAL_ENV}@" -i {} +echo "export VIRTUAL_ENV=${VIRTUAL_ENV}" >> /etc/profile +echo "export PATH=${PATH}" >> /etc/profile + + + +# 复制启动文件 +mkdir -p /docker +cp /ctx/entrypoint.bash /docker/entrypoint.bash + +if [ ! -e "/docker/sd-agent" ] && [ -e /serverless-api ]; then + cp /serverless-api/build/agent/agentServer /docker/sd-agent +fi + +chmod a+x /docker/entrypoint.bash /docker/sd-agent + +# 写入镜像版本 +IMAGE_TAG="${IMAGE_TAG:-$(date +%y%m%d%H%M%S)}" && echo "${IMAGE_TAG}" > /IMAGE_TAG \ No newline at end of file diff --git a/src/code/images/sd-resource/localizations/Chinese-English-0220.json b/src/code/images/sd-resource/localizations/Chinese-English-0220.json deleted file mode 100644 index c383629..0000000 --- a/src/code/images/sd-resource/localizations/Chinese-English-0220.json +++ /dev/null @@ -1,726 +0,0 @@ -{ - "⤡": "⤡", - "⊞": "⊞", - "×": "×", - "❮": "❮", - "❯": "❯", - "Loading...": "载入中.../Loading...", - "Use via API": "Use via API", - "·": "·", - "Built with Gradio": "基于gradio构建/Built with Gradio", - "Stable Diffusion checkpoint": "Stable Diffusion 模型(ckpt)", - "txt2img": "文生图/txt2img", - "img2img": "图生图/img2img", - "Extras": "附加功能/Extras", - "PNG Info": "图像信息/PNG Info", - "Checkpoint Merger": "模型合并/Checkpoint Merger", - "Train": "训练/Train", - "Settings": "设置/Settings", - "Extensions": "扩展插件/Extensions", - "Prompt": "提示词/Prompt", - "Negative prompt": "反向提示词/Negative prompt", - "Interrupt": "中止/Interrupt", - "Skip": "跳过/Skip", - "Generate": "生成/Generate", - "Run": "运行/Run", - "Styles": "模板预设/Styles", - "Label": "标签/Label", - "File": "文件/File", - "Drop File Here": "拖拽文件至此/Drop File Here", - "-": "-", - "or": "或/or", - "Click to Upload": "点击上传/Click to Upload", - "Textual Inversion": "嵌入式(Embedding)/Textual Inversion", - "Hypernetworks": "超网络(Hypernetworks)/Hypernetworks", - "Checkpoints": "Checkpoints", - "Lora": "低秩微调模型(LoRA)/Lora", - "Refresh": "刷新/Refresh", - "Close": "关闭/Close", - "replace preview": "用当前生成图片替换预览/replace preview", - "Nothing here. Add some content to the following directories:": "无内容,请将模型添加到以下目录:/Nothing here. Add some content to the following directories:", - "Textbox": "文本框/Textbox", - "Save preview": "保存预览/Save preview", - "Sampling method": "采样器/Sampling method", - "Euler a": "Euler a", - "Euler": "Euler", - "LMS": "LMS", - "Heun": "Heun", - "DPM2": "DPM2", - "DPM2 a": "DPM2 a", - "DPM++ 2S a": "DPM++ 2S a", - "DPM++ 2M": "DPM++ 2M", - "DPM++ SDE": "DPM++ SDE", - "DPM fast": "DPM fast", - "DPM adaptive": "DPM adaptive", - "LMS Karras": "LMS Karras", - "DPM2 Karras": "DPM2 Karras", - "DPM2 a Karras": "DPM2 a Karras", - "DPM++ 2S a Karras": "DPM++ 2S a Karras", - "DPM++ 2M Karras": "DPM++ 2M Karras", - "DPM++ SDE Karras": "DPM++ SDE Karras", - "DDIM": "DDIM", - "PLMS": "PLMS", - "Sampling steps": "采样步数/Sampling steps", - "Restore faces": "面部修复/Restore faces", - "Tiling": "无缝贴图/Tiling", - "Hires. fix": "高分辨率修复/Hires. fix", - "Upscaler": "高清化算法/Upscaler", - "Latent": "Latent", - "Latent (antialiased)": "Latent (抗锯齿)/Latent (antialiased)", - "Latent (bicubic)": "Latent (双三次插值)/Latent (bicubic)", - "Latent (bicubic antialiased)": "Latent (双三次插值/抗锯齿)/Latent (bicubic antialiased)", - "Latent (nearest)": "Latent (最近邻插值)/Latent (nearest)", - "Latent (nearest-exact)": "Latent (最近邻插值-精确)/Latent (nearest-exact)", - "None": "无/None", - "Lanczos": "Lanczos", - "Nearest": "Nearest", - "ESRGAN_4x": "ESRGAN_4x", - "R-ESRGAN 4x+": "R-ESRGAN 4x+", - "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B", - "LDSR": "LDSR", - "ScuNET GAN": "ScuNET GAN", - "ScuNET PSNR": "ScuNET PSNR", - "SwinIR 4x": "SwinIR 4x", - "Hires steps": "高分辨率采样步数/Hires steps", - "Denoising strength": "重绘强度/Denoising strength", - "Upscale by": "放大倍率/Upscale by", - "Resize width to": "将宽度调整到/Resize width to", - "Resize height to": "将高度调整到/Resize height to", - "Width": "宽度/Width", - "Height": "高度/Height", - "⇅": "⇅", - "Batch count": "生成批次/Batch count", - "Batch size": "每批数量/Batch size", - "CFG Scale": "提示词引导系数/CFG Scale", - "Seed": "图像生成种子/Seed", - "Extra": "▼", - "Variation seed": "随机数差异种子/Variation seed", - "Variation strength": "差异强度/Variation strength", - "Resize seed from width": "随机数宽度/Resize seed from width", - "Resize seed from height": "随机数高度/Resize seed from height", - "Override settings": "覆盖设置/Override settings", - "ControlNet": "ControlNet", - "Image": "图像/Image", - "Drop Image Here": "拖拽图像至此/Drop Image Here", - "Enable scribble mode if your image has white background.": "如果图片有白色背景,请启用涂鸦模式/Enable scribble mode if your image has white background.", - "Change your brush width to make it thinner if you want to draw something.": "如要要进行绘制,请将画笔宽度调小/Change your brush width to make it thinner if you want to draw something.", - "Enable": "启用/Enable", - "Scribble Mode (Invert colors)": "涂鸦模式(色彩反转)/Scribble Mode (Invert colors)", - "RGB to BGR": "RGB转BGR/RGB to BGR", - "Low VRAM": "低显存模式/Low VRAM", - "Preprocessor": "预处理/Preprocessor", - "none": "无/none", - "canny": "线稿检测(canny)", - "depth": "深度检测(depth)", - "depth_leres": "深度检测(depth_leres)", - "hed": "模糊检测(hed)", - "mlsd": "直线检测(mlsd)", - "normal_map": "法线贴图(normal_map)", - "openpose": "人体姿势检测(openpose)", - "openpose_hand": "人体手部姿势检测(openpose_hand)", - "pidinet": "像素差分边缘检测(pidinet)", - "scribble": "涂鸦(scribble)", - "fake_scribble": "伪涂鸦(fake_scribble)", - "segmentation": "分块检测(segmentation)", - "Model": "模型", - "Weight": "权重/Weight", - "Guidance strength (T)": "控制网引导系数", - "Annotator resolution": "标注分辨率/Annotator resolution", - "Threshold A": "A阈值/Threshold A", - "Threshold B": "B阈值/Threshold B", - "Resize Mode": "缩放模式/Resize Mode", - "Envelope (Outer Fit)": "拓展画布适配(向内)/Envelope (Outer Fit)", - "Scale to Fit (Inner Fit)": "裁剪画布适配(向外)/Scale to Fit (Inner Fit)", - "Just Resize": "拉伸/Just Resize", - "Canvas Width": "画布宽度/Canvas Width", - "Canvas Height": "画布高度/Canvas Height", - "Create blank canvas": "创建空白画布/Create blank canvas", - "Script": "脚本/Script", - "Prompt matrix": "提示词矩阵/Prompt matrix", - "Prompts from file or textbox": "从文本框或文件载入提示词/Prompts from file or textbox", - "X/Y/Z plot": "X/Y/Z图表/X/Y/Z plot", - "Put variable parts at start of prompt": "把变量部分放在提示词文本的开头处/Put variable parts at start of prompt", - "Use different seed for each picture": "为每张图片使用不同的随机数种子/Use different seed for each picture", - "Select prompt": "选择提示类型/Select prompt", - "positive": "正面提示词/positive", - "negative": "反向提示词/negative", - "Select joining char": "选择连接符号/Select joining char", - "comma": "逗号/comma", - "space": "空格/space", - "Grid margins (px)": "宫格边距(像素)/Grid margins (px)", - "Iterate seed every line": "每行输入都换一个随机数种子/Iterate seed every line", - "Use same random seed for all lines": "每行输入都使用同一个随机数种子/Use same random seed for all lines", - "List of prompt inputs": "提示词输入列表/List of prompt inputs", - "Upload prompt inputs": "上传提示词输入文件/Upload prompt inputs", - "X type": "X轴类型/X type", - "Nothing": "无/Nothing", - "Var. seed": "随机数差异种子/Var. seed", - "Var. strength": "差异强度/Var. strength", - "Steps": "迭代步数/Steps", - "Prompt S/R": "提示词搜索/替换/Prompt S/R", - "Prompt order": "提示词顺序/Prompt order", - "Sampler": "采样器/Sampler", - "Checkpoint name": "模型名称/Checkpoint name", - "Sigma Churn": "Sigma混乱强度/Sigma Churn", - "Sigma min": "Sigma最小值/Sigma min", - "Sigma max": "Sigma最大值/Sigma max", - "Sigma noise": "Sigma噪声强度/Sigma noise", - "Eta": "Eta", - "Clip skip": "Clip 跳过层/Clip skip", - "Denoising": "重绘强度/Denoising", - "Hires upscaler": "高清化算法/Hires upscaler", - "VAE": "VAE", - "[ControlNet] Model": "[控制网]模型/Model", - "[ControlNet] Weight": "[控制网]权重/Weight", - "[ControlNet] Guidance Strength": "[控制网]引导系数/Guidance Strength", - "[ControlNet] Resize Mode": "[控制网]缩放模式/Resize Mode", - "[ControlNet] Preprocessor": "[控制网]预处理/Preprocessor", - "[ControlNet] Pre Resolution": "[控制网]原始分辨率/Pre Resolution", - "[ControlNet] Pre Threshold A": "[控制网]原始阈值A/Threshold A", - "[ControlNet] Pre Threshold B": "[控制网]原始阈值B/Pre Threshold B", - "X values": "X轴值/X values", - "Y type": "Y轴类型/Y type", - "Y values": "Y轴值/Y values", - "Z type": "Z轴类型/Z type", - "Z values": "Z轴值/Z values", - "Draw legend": "在图表中包括轴类型和值/Draw legend", - "Keep -1 for seeds": "保持随机数种子为-1/Keep -1 for seeds", - "Include Sub Images": "包含子图像/Include Sub Images", - "Include Sub Grids": "包含子宫格/Include Sub Grids", - "Swap X/Y axes": "交换X/Y轴/Swap X/Y axes", - "Swap Y/Z axes": "交换Y/Z轴/Swap Y/Z axes", - "Swap X/Z axes": "交换X/Z轴/Swap X/Z axes", - "Save": "保存/Save", - "Zip": "Zip", - "Send to img2img": ">> 图生图/Send to img2img", - "Send to inpaint": ">> 局部绘制/Send to inpaint", - "Send to extras": ">> 附加功能/Send to extras", - "Interrogate\nCLIP": "CLIP\n反向推导提示词\n(需要几分钟时间加载模型,请耐心等待)/Interrogate\nCLIP", - "Interrogate\nDeepBooru": "DeepBooru\n反向推导提示词/Interrogate\nDeepBooru", - "Sketch": "涂鸦绘制/Sketch", - "Inpaint": "局部绘制/Inpaint", - "Inpaint sketch": "局部绘制(涂鸦蒙版)/Inpaint sketch", - "Inpaint upload": "局部绘制(上传蒙版)/Inpaint upload", - "Batch": "批量处理/Batch", - "Image for img2img": "图生图的图像/Image for img2img", - "Copy image to:": "复制图像到:/Copy image to:", - "sketch": "涂鸦绘制/sketch", - "inpaint": "局部绘制/inpaint", - "inpaint sketch": "局部绘制(涂鸦蒙版)/inpaint sketch", - "Image for inpainting with mask": "使用蒙版绘制的图像/Image for inpainting with mask", - "Color sketch inpainting": "彩色涂鸦绘制/Color sketch inpainting", - "Mask": "蒙版/Mask", - "Process images in a directory on the same machine where the server is running.": "处理服务器主机上某一目录里的图像/Process images in a directory on the same machine where the server is running.", - "Use an empty output directory to save pictures normally instead of writing to the output directory.": "输出图像到一个空目录,而非设置里指定的输出目录/Use an empty output directory to save pictures normally instead of writing to the output directory.", - "Add inpaint batch mask directory to enable inpaint batch processing.": "添加批量绘制遮罩文件夹以启用批量绘制处理/Add inpaint batch mask directory to enable inpaint batch processing.", - "Input directory": "输入目录/Input directory", - "Output directory": "输出目录/Output directory", - "Inpaint batch mask directory (required for inpaint batch processing only)": "批量绘制遮罩图片目录(仅对批量处理中的绘制功能需要)/Inpaint batch mask directory (required for inpaint batch processing only)", - "Resize mode": "缩放模式/Resize mode", - "Just resize": "拉伸/Just resize", - "Crop and resize": "裁剪/Crop and resize", - "Resize and fill": "填充/Resize and fill", - "Just resize (latent upscale)": "仅调整大小(潜空间放大)/Just resize (latent upscale)", - "Mask blur": "蒙版模糊度/Mask blur", - "Mask transparency": "蒙版透明度/Mask transparency", - "Mask mode": "蒙版模式/Mask mode", - "Inpaint masked": "绘制蒙版内容/Inpaint masked", - "Inpaint not masked": "绘制非蒙版内容/Inpaint not masked", - "Masked content": "蒙版蒙住的内容/Masked content", - "fill": "填充/fill", - "original": "原图/original", - "latent noise": "潜在噪声/latent noise", - "latent nothing": "无潜在空间/latent nothing", - "Inpaint area": "绘制区域/Inpaint area", - "Whole picture": "全图/Whole picture", - "Only masked": "仅蒙版/Only masked", - "Only masked padding, pixels": "仅蒙版绘制参考半径(像素)/Only masked padding, pixels", - "Image CFG Scale": "图像引导系数/Image CFG Scale", - "img2img alternative test": "图生图替代测试/img2img alternative test", - "Loopback": "图像迭代/Loopback", - "Outpainting mk2": "向外绘制第二版/Outpainting mk2", - "Poor man's outpainting": "低质量画布补全/Poor man's outpainting", - "SD upscale": "SD模式放大/SD upscale", - "should be 2 or lower.": "应小于等于2/should be 2 or lower.", - "Override `Sampling method` to Euler?(this method is built for it)": "重写'采样器'为 Euler?(这个方法就是为此设计的)/Override `Sampling method` to Euler?(this method is built for it)", - "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "重写'提示词'为'初始提示词'?(`反向提示词` 同理)/Override `prompt` to the same value as `original prompt`?(and `negative prompt`)", - "Original prompt": "初始提示词/Original prompt", - "Original negative prompt": "初始反向提示词/Original negative prompt", - "Override `Sampling Steps` to the same value as `Decode steps`?": "覆写'采样步数'为'解码步数'?/Override `Sampling Steps` to the same value as `Decode steps`?", - "Decode steps": "解码步数/Decode steps", - "Override `Denoising strength` to 1?": "重写'重绘强度'为1?/Override `Denoising strength` to 1?", - "Decode CFG scale": "解码重绘强度/Decode CFG scale", - "Randomness": "随机度/Randomness", - "Sigma adjustment for finding noise for image": "Sigma调整图像噪声部分/Sigma adjustment for finding noise for image", - "Loops": "图像迭代次数/Loops", - "Denoising strength change factor": "重绘强度的变化系数/Denoising strength change factor", - "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "推荐设置:采样步数:80-100,采样器:Euler a,重绘强度:0.8/Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8", - "Pixels to expand": "向外拓展的像素数量/Pixels to expand", - "Outpainting direction": "补全画布的方向/Outpainting direction", - "left": "左/left", - "right": "右/right", - "up": "上/up", - "down": "下/down", - "Fall-off exponent (lower=higher detail)": "衰减指数(越小细节越多)/Fall-off exponent (lower=higher detail)", - "Color variation": "色彩变化/Color variation", - "Will upscale the image by the selected scale factor; use width and height sliders to set tile size": "将图像放大至所选比例;使用宽度和高度滑块设置图块大小/Will upscale the image by the selected scale factor; use width and height sliders to set tile size", - "Tile overlap": "图块重叠范围/Tile overlap", - "Scale Factor": "缩放比例/Scale Factor", - "Cond. Image Mask Weight": "条件图像蒙版权重/Cond. Image Mask Weight", - "Single Image": "单张图像/Single Image", - "Batch Process": "批量处理/Batch Process", - "Batch from Directory": "批量处理目录下图像/Batch from Directory", - "Source": "图像资源/Source", - "Show result images": "显示输出图像/Show result images", - "Scale by": "等比缩放/Scale by", - "Scale to": "指定分辨率缩放/Scale to", - "Resize": "缩放比例/Resize", - "Crop to fit": "裁剪以适应宽高比/Crop to fit", - "Upscaler 2 visibility": "Upscaler 2可见度/Upscaler 2 visibility", - "GFPGAN visibility": "GFPGAN面部修复程度/GFPGAN visibility", - "CodeFormer visibility": "CodeFormer面部重建程度/CodeFormer visibility", - "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer面部重建权重(为0时效果最大,为1时效果最小)/CodeFormer weight (0 = maximum effect, 1 = minimum effect)", - "Send to txt2img": ">> 文生图/Send to txt2img", - "A weighted sum will be used for interpolation. Requires two models; A and B. The result is calculated as A * (1 - M) + B * M": "将两个模型权重的加权和作为新模型的权重,仅需要填入模型A和B,公式:A*(1-m)+B*M,倍率M为模型B所占比例/A weighted sum will be used for interpolation. Requires two models; A and B. The result is calculated as A * (1 - M) + B * M", - "Primary model (A)": "主要模型(A)/Primary model (A)", - "Secondary model (B)": "次要模型(B)/Secondary model (B)", - "Tertiary model (C)": "第三模型(C)/Tertiary model (C)", - "Custom Name (Optional)": "自定义名称(可选)/Custom Name (Optional)", - "Multiplier (M) - set to 0 to get model A": "乘数(M)-设为0得到A模型/Multiplier (M) - set to 0 to get model A", - "Interpolation Method": "插值方法/Interpolation Method", - "No interpolation": "无插值/No interpolation", - "Weighted sum": "加权和/Weighted sum", - "Add difference": "加上差值/Add difference", - "Checkpoint format": "模型格式/Checkpoint format", - "ckpt": "ckpt", - "safetensors": "safetensors", - "Save as float16": "以float16半精度保存/Save as float16", - "Copy config from": "复制...模型配置/Copy config from", - "A, B or C": "A, B or C", - "B": "B", - "C": "C", - "Don't": "Don't", - "Bake in VAE": "使用以下VAE校正:/Bake in VAE", - "Discard weights with matching name": "放弃与下列名称匹配的权重/Discard weights with matching name", - "Merge": "开始合并/Merge", - "See": "查看/See", - "wiki": "wiki文档/wiki", - "for detailed explanation.": "以了解详细说明/for detailed explanation.", - "Create embedding": "创建Embedding/Create embedding", - "Create hypernetwork": "创建超网络(Hypernetwork)/Create hypernetwork", - "Preprocess images": "预处理图像/Preprocess images", - "Name": "名称/Name", - "Initialization text": "初始化文本/Initialization text", - "Number of vectors per token": "每个词元(token)的向量数/Number of vectors per token", - "Overwrite Old Embedding": "覆写旧的 Embedding/Overwrite Old Embedding", - "Modules": "模块/Modules", - "Enter hypernetwork layer structure": "输入超网络层结构/Enter hypernetwork layer structure", - "Select activation function of hypernetwork. Recommended : Swish / Linear(none)": "选择超网络的激活函数。建议:Swish/Linear(无激活函数)/Select activation function of hypernetwork. Recommended : Swish / Linear(none)", - "linear": "linear", - "relu": "relu", - "leakyrelu": "leakyrelu", - "elu": "elu", - "swish": "swish", - "tanh": "tanh", - "sigmoid": "sigmoid", - "celu": "celu", - "gelu": "gelu", - "glu": "glu", - "hardshrink": "hardshrink", - "hardsigmoid": "hardsigmoid", - "hardtanh": "hardtanh", - "logsigmoid": "logsigmoid", - "logsoftmax": "logsoftmax", - "mish": "mish", - "prelu": "prelu", - "rrelu": "rrelu", - "relu6": "relu6", - "selu": "selu", - "silu": "silu", - "softmax": "softmax", - "softmax2d": "softmax2d", - "softmin": "softmin", - "softplus": "softplus", - "softshrink": "softshrink", - "softsign": "softsign", - "tanhshrink": "tanhshrink", - "threshold": "threshold", - "Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise": "Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise", - "Normal": "Normal", - "KaimingUniform": "KaimingUniform", - "KaimingNormal": "KaimingNormal", - "XavierUniform": "XavierUniform", - "XavierNormal": "XavierNormal", - "Add layer normalization": "Add layer normalization", - "Use dropout": "Use dropout", - "Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15": "Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15", - "Overwrite Old Hypernetwork": "Overwrite Old Hypernetwork", - "Source directory": "资源目录/Source directory", - "Destination directory": "目标目录/Destination directory", - "Existing Caption txt Action": "对已有的标题文本进行操作/Existing Caption txt Action", - "ignore": "无视/ignore", - "copy": "复制/copy", - "prepend": "置前/prepend", - "append": "置后/append", - "Create flipped copies": "创建镜像副本/Create flipped copies", - "Split oversized images": "分割过大图像/Split oversized images", - "Auto focal point crop": "自动焦点裁剪/Auto focal point crop", - "Auto-sized crop": "自动尺寸裁剪/Auto-sized crop", - "Use BLIP for caption": "使用BLIP添加说明/Use BLIP for caption", - "Use deepbooru for caption": "使用Deepbooru添加说明/Use deepbooru for caption", - "Split image threshold": "图像分割阈值/Split image threshold", - "Split image overlap ratio": "分割图像重叠比例/Split image overlap ratio", - "Focal point face weight": "焦点面部权重/Focal point face weight", - "Focal point entropy weight": "焦点熵权重/Focal point entropy weight", - "Focal point edges weight": "焦点线条权重/Focal point edges weight", - "Create debug image": "创建调试图像/Create debug image", - "Each image is center-cropped with an automatically chosen width and height.": "每个图像都会被自动选择的宽度和高度进行中心裁剪/Each image is center-cropped with an automatically chosen width and height.", - "Dimension lower bound": "尺寸下限/Dimension lower bound", - "Dimension upper bound": "尺寸上限/Dimension upper bound", - "Area lower bound": "面积下限/Area lower bound", - "Area upper bound": "面积上限/Area upper bound", - "Resizing objective": "调整大小目标/Resizing objective", - "Maximize area": "最大化面积/Maximize area", - "Minimize error": "最小化误差/Minimize error", - "Error threshold": "误差阈值/Error threshold", - "Preprocess": "预处理图像/Preprocess", - "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "训练Embedding或者超网络;必须指定一个具有一组1:1比例图像的目录/Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images", - "[wiki]": "[wiki文档]/[wiki]", - "Embedding": "Embedding", - "Hypernetwork": "超网络(Hypernetwork)/Hypernetwork", - "Embedding Learning rate": "Embedding学习率/Embedding Learning rate", - "Hypernetwork Learning rate": "超网络学习率/Hypernetwork Learning rate", - "Gradient Clipping": "梯度剪裁/Gradient Clipping", - "disabled": "已禁用/disabled", - "value": "value", - "norm": "norm", - "Gradient accumulation steps": "梯度累积步数/Gradient accumulation steps", - "Dataset directory": "数据集目录/Dataset directory", - "Log directory": "日志目录/Log directory", - "Prompt template": "提示词模板/Prompt template", - "Do not resize images": "不调整图像大小/Do not resize images", - "Max steps": "最大迭代步数/Max steps", - "Save an image to log directory every N steps, 0 to disable": "每N步保存一个图像到日志目录,0为禁用/Save an image to log directory every N steps, 0 to disable", - "Save a copy of embedding to log directory every N steps, 0 to disable": "每N步保存Embedding的副本到日志目录,0表示禁用/Save a copy of embedding to log directory every N steps, 0 to disable", - "Save images with embedding in PNG chunks": "保存Embedding在PNG图像信息内/Save images with embedding in PNG chunks", - "Read parameters (prompt, etc...) from txt2img tab when making previews": "在进行预览时,从文生图选项卡中读取参数(提示词等)/Read parameters (prompt, etc...) from txt2img tab when making previews", - "Shuffle tags by ',' when creating prompts.": "在创建提示词时按','随机打乱tags/Shuffle tags by ',' when creating prompts.", - "Drop out tags when creating prompts.": "在创建提示词时删除tags/Drop out tags when creating prompts.", - "Choose latent sampling method": "选择潜在空间采样器/Choose latent sampling method", - "once": "once", - "deterministic": "deterministic", - "random": "随机/random", - "Train Embedding": "训练Embedding/Train Embedding", - "Train Hypernetwork": "训练超网络/Train Hypernetwork", - "Apply settings": "应用设置/Apply settings", - "Reload UI": "重新加载WebUI/Reload UI", - "Saving images/grids": "保存图像/宫格图/Saving images/grids", - "Paths for saving": "保存路径/Paths for saving", - "Saving to a directory": "保存到目录/Saving to a directory", - "Upscaling": "高清化设置/Upscaling", - "Face restoration": "面部修复/Face restoration", - "System": "系统/System", - "Training": "训练/Training", - "Stable Diffusion": "Stable Diffusion", - "Compatibility": "兼容性设置/Compatibility", - "Interrogate Options": "反推提示词选项/Interrogate Options", - "Extra Networks": "附加网络/Extra Networks", - "User interface": "用户界面/User interface", - "Live previews": "实时预览/Live previews", - "Sampler parameters": "采样器参数/Sampler parameters", - "Postprocessing": "后处理/Postprocessing", - "Actions": "其他操作/Actions", - "Licenses": "证书/Licenses", - "Always save all generated images": "始终保存所有生成的图像/Always save all generated images", - "File format for images": "图像的文件格式/File format for images", - "Images filename pattern": "图像文件名格式/Images filename pattern", - "Add number to filename when saving": "储存的时候在文件名里添加数字/Add number to filename when saving", - "Always save all generated image grids": "始终保存所有生成的宫格图/Always save all generated image grids", - "File format for grids": "宫格图的文件格式/File format for grids", - "Add extended info (seed, prompt) to filename when saving grid": "保存宫格图时,将扩展信息(图像生成种子、提示词)添加到文件名/Add extended info (seed, prompt) to filename when saving grid", - "Do not save grids consisting of one picture": "只有一张图像时不要保存宫格图/Do not save grids consisting of one picture", - "Prevent empty spots in grid (when set to autodetect)": "防止宫格图中出现空位(启用自动检测时)/Prevent empty spots in grid (when set to autodetect)", - "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "宫格图行数;使用-1进行自动检测,使用0使其与每批数量相同/Grid row count; use -1 for autodetect and 0 for it to be same as batch size", - "Save text information about generation parameters as chunks to png files": "将有关生成参数的文本信息,以块的形式保存到PNG图片文件中/Save text information about generation parameters as chunks to png files", - "Create a text file next to every image with generation parameters.": "保存图像时,在每个图像旁边创建一个文本文件储存生成参数/Create a text file next to every image with generation parameters.", - "Save a copy of image before doing face restoration.": "在面部修复前保存原始图像副本/Save a copy of image before doing face restoration.", - "Save a copy of image before applying highres fix.": "在高分辨率修复前保存原始图像副本/Save a copy of image before applying highres fix.", - "Save a copy of image before applying color correction to img2img results": "在对图生图结果应用颜色校正之前保存图像副本/Save a copy of image before applying color correction to img2img results", - "Quality for saved jpeg images": "保存JPEG图像的质量/Quality for saved jpeg images", - "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "如果PNG图像大于4MB或任何尺寸大于4000,缩小尺寸并保存为JPG/If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG", - "Use original name for output filename during batch process in extras tab": "在附加功能选项卡中的批量处理过程中,使用原始名称作为输出文件名/Use original name for output filename during batch process in extras tab", - "Use upscaler name as filename suffix in the extras tab": "在附加功能选项卡中使用高清化算法作为文件名后缀/Use upscaler name as filename suffix in the extras tab", - "When using 'Save' button, only save a single selected image": "使用“保存”按钮时,只保存一个选定的图像/When using 'Save' button, only save a single selected image", - "Do not add watermark to images": "不在图像中添加水印/Do not add watermark to images", - "Directory for temporary images; leave empty for default": "临时图像目录,默认为空/Directory for temporary images; leave empty for default", - "Cleanup non-default temporary directory when starting webui": "启动WebUI时清理非默认临时目录/Cleanup non-default temporary directory when starting webui", - "Output directory for images; if empty, defaults to three directories below": "图像的输出目录;如果为空,默认为以下三个目录/Output directory for images; if empty, defaults to three directories below", - "Output directory for txt2img images": "文生图的输出目录/Output directory for txt2img images", - "Output directory for img2img images": "图生图的输出目录/Output directory for img2img images", - "Output directory for images from extras tab": "附加功能选项卡的输出目录/Output directory for images from extras tab", - "Output directory for grids; if empty, defaults to two directories below": "宫格图的输出目录;如果为空,默认为以下两个目录/Output directory for grids; if empty, defaults to two directories below", - "Output directory for txt2img grids": "文生图宫格的输出目录/Output directory for txt2img grids", - "Output directory for img2img grids": "图生图宫格的输出目录/Output directory for img2img grids", - "Directory for saving images using the Save button": "使用保存按钮保存图像的目录/Directory for saving images using the Save button", - "Save images to a subdirectory": "将图像保存到子目录/Save images to a subdirectory", - "Save grids to a subdirectory": "将宫格图保存到子目录/Save grids to a subdirectory", - "When using \"Save\" button, save images to a subdirectory": "使用\"保存\"按钮时,将图像保存到子目录/When using \"Save\" button, save images to a subdirectory", - "Directory name pattern": "目录名称格式/Directory name pattern", - "Max prompt words for [prompt_words] pattern": "[prompt_words]格式的最大提示词数量/Max prompt words for [prompt_words] pattern", - "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGAN的图块尺寸,0为不分块/Tile size for ESRGAN upscalers. 0 = no tiling.", - "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGAN的图块重叠范围,低值=可见接缝/Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.", - "Upscaler for img2img": "图生图的高清化算法/Upscaler for img2img", - "LDSR processing steps. Lower = faster": "LDSR处理步数,低步数=高速度/LDSR processing steps. Lower = faster", - "Cache LDSR model in memory": "把LDSR模型缓存在内存中/Cache LDSR model in memory", - "Tile size for all SwinIR.": "SwinIR模型的无缝拼接图像尺寸/Tile size for all SwinIR.", - "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "图块重叠范围,拼接像素来自SwinIR模型,低值=可见接缝/Tile overlap, in pixels for SwinIR. Low values = visible seam.", - "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer面部修复权重参数;0=效果最大;1=效果最小/CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect", - "Move face restoration model from VRAM into RAM after processing": "面部修复处理完成后,将其模型从显存移至内存中/Move face restoration model from VRAM into RAM after processing", - "Show warnings in console.": "将警告信息输出到控制台/Show warnings in console.", - "VRAM usage polls per second during generation. Set to 0 to disable.": "在生成过程中每秒询问一次显存状况.设置为0表示禁用/VRAM usage polls per second during generation. Set to 0 to disable.", - "Always print all generation info to standard output": "始终将所有生成信息打印到标准输出/Always print all generation info to standard output", - "Add a second progress bar to the console that shows progress for an entire job.": "向控制台添加第二个进度条,显示整个作业的进度/Add a second progress bar to the console that shows progress for an entire job.", - "Print extra hypernetwork information to console.": "将额外的超网络信息输出到控制台/Print extra hypernetwork information to console.", - "Move VAE and CLIP to RAM when training if possible. Saves VRAM.": "训练时将 VAE 和 CLIP 从显存(VRAM)移放到内存(RAM)如果可行的话,节省显存(VRAM)/Move VAE and CLIP to RAM when training if possible. Saves VRAM.", - "Turn on pin_memory for DataLoader. Makes training slightly faster but can increase memory usage.": "启用DataLoader的pin_memory.可以使训练速度稍微更快,但可能会增加内存使用./Turn on pin_memory for DataLoader. Makes training slightly faster but can increase memory usage.", - "Saves Optimizer state as separate *.optim file. Training of embedding or HN can be resumed with the matching optim file.": "将优化器状态保存为单独的*.optim文件.可以使用匹配的optim文件恢复embedding或HN的训练/Saves Optimizer state as separate *.optim file. Training of embedding or HN can be resumed with the matching optim file.", - "Save textual inversion and hypernet settings to a text file whenever training starts.": "在每次训练开始时将文本倒置(textual inversion)和超网络设置保存到文本文件中/Save textual inversion and hypernet settings to a text file whenever training starts.", - "Filename word regex": "文件名用词的正则表达式/Filename word regex", - "Filename join string": "文件名连接用字符串/Filename join string", - "Number of repeats for a single input image per epoch; used only for displaying epoch number": "每期(epoch)中单个输入图像的重复次数;仅用于显示训练代数/Number of repeats for a single input image per epoch; used only for displaying epoch number", - "Save an csv containing the loss to log directory every N steps, 0 to disable": "每N步保存一个包含损失函数(loss)的csv文件到日志目录,0为禁用/Save an csv containing the loss to log directory every N steps, 0 to disable", - "Use cross attention optimizations while training": "使用cross attention优化进行训练/Use cross attention optimizations while training", - "Enable tensorboard logging.": "启用TensorBoard记录日志/Enable tensorboard logging.", - "Save generated images within tensorboard.": "将生成的图像保存在TensorBoard中/Save generated images within tensorboard.", - "How often, in seconds, to flush the pending tensorboard events and summaries to disk.": "每过...秒就刷新待处理的TensorBoard事件和摘要到磁盘中一次/How often, in seconds, to flush the pending tensorboard events and summaries to disk.", - "Checkpoints to cache in RAM": "缓存在内存中的模型数量/Checkpoints to cache in RAM", - "VAE Checkpoints to cache in RAM": "在内存中缓存的VAE数量/VAE Checkpoints to cache in RAM", - "SD VAE": "模型的VAE/SD VAE", - "Automatic": "Automatic", - "Ignore selected VAE for stable diffusion checkpoints that have their own .vae.pt next to them": "对于拥有同名.vae.pt 的模型,忽略掉选中的VAE/Ignore selected VAE for stable diffusion checkpoints that have their own .vae.pt next to them", - "Inpainting conditioning mask strength": "局部绘制时图像调节的蒙版屏蔽强度/Inpainting conditioning mask strength", - "Noise multiplier for img2img": "图生图噪声倍率/Noise multiplier for img2img", - "Apply color correction to img2img results to match original colors.": "对图生图结果应用颜色校正以匹配原始颜色/Apply color correction to img2img results to match original colors.", - "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "在进行图生图的时候,完全执行滑块指定的迭代步数(正常情况下更弱的绘制强度需要更少的迭代步数)/With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).", - "With img2img, fill image's transparent parts with this color.": "在图生图中使用以下颜色填充透明区域/With img2img, fill image's transparent parts with this color.", - "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "在K-diffusion采样器中启用量化以获得更清晰简洁的结果.这可能会改变现有的图像生成种子,需要保存设置并重启才能应用/Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.", - "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "强调符:模型更加注重于(文本)内的文本,较少注重于[文本]内的文本/Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention", - "Make K-diffusion samplers produce same images in a batch as when making a single image": "使用K-diffusion采样器批量生成与生成单个图像时,生成相同的图像/Make K-diffusion samplers produce same images in a batch as when making a single image", - "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "当使用超过75个词元(tokens)时,通过从n个词元中的最后一个逗号留空来提高一致性/Increase coherency by padding from the last comma within n tokens when using more than 75 tokens", - "Upcast cross attention layer to float32": "将cross attention层上升为float32类型/Upcast cross attention layer to float32", - "Use old emphasis implementation. Can be useful to reproduce old seeds.": "使用旧的强调符实现。可用于复现旧随机数种子/Use old emphasis implementation. Can be useful to reproduce old seeds.", - "Use old karras scheduler sigmas (0.1 to 10).": "使用旧的Karras调度器sigma值(0.1-10)/Use old karras scheduler sigmas (0.1 to 10).", - "For hires fix, use width/height sliders to set final resolution rather than first pass (disables Upscale by, Resize width/height to).": "在高分辨率修复中,使用长宽滑块设置最终分辨率(恢复旧版高分辨率修复界面,关闭放大倍率和自适应分辨率设置)/For hires fix, use width/height sliders to set final resolution rather than first pass (disables Upscale by, Resize width/height to).", - "Interrogate: keep models in VRAM": "反推:将模型保存在显存(VRAM)中/Interrogate: keep models in VRAM", - "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "反推:在生成结果中包含与模型标签(tags)相匹配的等级(对基于生成自然语言描述的反推没有影响)/Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).", - "Interrogate: num_beams for BLIP": "反推:来自BLIP的集数数量/Interrogate: num_beams for BLIP", - "Interrogate: minimum description length (excluding artists, etc..)": "反推:最小描述长度(不包括艺术家等)/Interrogate: minimum description length (excluding artists, etc..)", - "Interrogate: maximum description length": "反推:最大描述长度/Interrogate: maximum description length", - "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP:文本文件中的最大行数(0=无限制)/CLIP: maximum number of lines in text file (0 = No limit)", - "CLIP: skip inquire categories": "CLIP:跳过查询类别/CLIP: skip inquire categories", - "Interrogate: deepbooru score threshold": "反推:deepbooru分数阈值/Interrogate: deepbooru score threshold", - "Interrogate: deepbooru sort alphabetically": "反推:deepbooru 按字母顺序排序/Interrogate: deepbooru sort alphabetically", - "use spaces for tags in deepbooru": "在deepbooru中为tags使用空格/use spaces for tags in deepbooru", - "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "在deepbooru中使用转义 (\\) 括号(使其用作括号字符而不是强调符)/escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)", - "filter out those tags from deepbooru output (separated by comma)": "从deepdanbooru的标签库中过滤掉以下标签,用逗号分隔/filter out those tags from deepbooru output (separated by comma)", - "Default view for Extra Networks": "附加网络默认视图/Default view for Extra Networks", - "cards": "卡牌式/cards", - "thumbs": "小图式/thumbs", - "Multiplier for extra networks": "附加网络默认倍率/Multiplier for extra networks", - "Add hypernetwork to prompt": "加载超网络至提示词/Add hypernetwork to prompt", - "Add Lora to prompt": "加载lora至提示词/Add Lora to prompt", - "Apply Lora to outputs rather than inputs when possible (experimental)": "在可能的情况下,加载lora用于输入而非输出(实验性功能)/Apply Lora to outputs rather than inputs when possible (experimental)", - "Show grid in results for web": "在网页的结果中显示宫格图/Show grid in results for web", - "Do not show any images in results for web": "网页不显示任何生成图像的结果/Do not show any images in results for web", - "Add model hash to generation information": "将模型的哈希值添加到生成信息/Add model hash to generation information", - "Add model name to generation information": "将模型名称添加到生成信息/Add model name to generation information", - "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "从文本读取图像生成参数到用户界面(从PNG图片信息或粘贴文本)时,不要更改选定的模型(ckpt)/When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.", - "Send seed when sending prompt or image to other interface": "将提示词或者图像发送到 >> 其他界面时,把随机种子也传送过去/Send seed when sending prompt or image to other interface", - "Send size when sending prompt or image to another interface": "将提示词或者图像发送到 >> 其他界面时,把尺寸数据也传送过去/Send size when sending prompt or image to another interface", - "Font for image grids that have text": "宫格图使用的字体/Font for image grids that have text", - "Enable full page image viewer": "启用整页图像查看界面/Enable full page image viewer", - "Show images zoomed in by default in full page image viewer": "在整页图像查看器中,默认放大显示图像/Show images zoomed in by default in full page image viewer", - "Show generation progress in window title.": "在窗口标题中显示生成进度/Show generation progress in window title.", - "Use dropdown for sampler selection instead of radio group": "使用下拉菜单取代单选列表/Use dropdown for sampler selection instead of radio group", - "Show Width/Height and Batch sliders in same row": "将批次与批量设置整合到长宽设置的右侧/Show Width/Height and Batch sliders in same row", - "Ctrl+up/down precision when editing (attention:1.1)": "使用Ctrl+↑/↓设置“(tag:1.1)”时的精度/Ctrl+up/down precision when editing (attention:1.1)", - "Ctrl+up/down precision when editing ": "使用Ctrl+↑/↓设置“”时的精度/Ctrl+up/down precision when editing ", - "Quicksettings list": "快捷设置列表/Quicksettings list", - "txt2img/img2img UI item order": "文生图/图生图界面UI顺序/txt2img/img2img UI item order", - "Extra networks tab order": "附加网络标签的顺序/Extra networks tab order", - "Localization (requires restart)": "语言文件(需要保存设置并重启)/Localization (requires restart)", - "Show progressbar": "显示进度条/Show progressbar", - "Show live previews of the created image": "显示已生成图像的实时预览/Show live previews of the created image", - "Show previews of all images generated in a batch as a grid": "以宫格图的形式,预览批量生成的所有图像/Show previews of all images generated in a batch as a grid", - "Show new live preview image every N sampling steps. Set to -1 to show after completion of batch.": "每N个采样步骤更新一次实时预览图像,设置为-1以在每批次完成后显示,设置为0关闭实时预览/Show new live preview image every N sampling steps. Set to -1 to show after completion of batch.", - "Image creation progress preview mode": "图像生成过程预览的模式/Image creation progress preview mode", - "Full": "Full", - "Approx NN": "Approx NN", - "Approx cheap": "Approx cheap", - "Live preview subject": "实时预览的主题/Live preview subject", - "Combined": "都显示/Combined", - "Progressbar/preview update period, in milliseconds": "进度条/预览更新周期(毫秒)/Progressbar/preview update period, in milliseconds", - "Hide samplers in user interface (requires restart)": "在用户界面中隐藏采样器(需要保存设置并重启)/Hide samplers in user interface (requires restart)", - "eta (noise multiplier) for DDIM": "DDIM的噪声乘数eta/eta (noise multiplier) for DDIM", - "eta (noise multiplier) for ancestral samplers": "ancestral采样器的噪声乘数eta/eta (noise multiplier) for ancestral samplers", - "img2img DDIM discretize": "图生图DDIM离散化/img2img DDIM discretize", - "uniform": "均匀(uniform)/uniform", - "quad": "二阶(quad)/quad", - "sigma churn": "sigma混乱强度/sigma churn", - "sigma tmin": "sigma下限值/sigma tmin", - "sigma noise": "sigma噪声强度/sigma noise", - "Eta noise seed delta": "Eta噪声种子偏移/Eta noise seed delta", - "Always discard next-to-last sigma": "始终舍弃倒数第二个sigma/Always discard next-to-last sigma", - "Enable postprocessing operations in txt2img and img2img tabs": "在txt2img和img2img选项卡中启用后处理操作/Enable postprocessing operations in txt2img and img2img tabs", - "Postprocessing operation order": "后处理操作顺序/Postprocessing operation order", - "Maximum number of images in upscaling cache": "图像高清化缓存中的最大图片数量/Maximum number of images in upscaling cache", - "Config file for Control Net models": "ControlNet模型的配置文件/Config file for Control Net models", - "Config file for Adapter models": "“输入模型的配置文件/Config file for Adapter models", - "Extra path to scan for ControlNet models (e.g. training output directory)": "扫描ControlNet模型的额外路径(例如训练输出目录)/Extra path to scan for ControlNet models (e.g. training output directory)", - "Apply transfer control when loading models": "加载模型时应用转移控制/Apply transfer control when loading models", - "Use mid-layer control on highres pass (second pass)": "在高分辨率通道上使用中间层控制(第二通道)/Use mid-layer control on highres pass (second pass)", - "Do not append detectmap to output": "不要输出检测结果图像/Do not append detectmap to output", - "Allow other script to control this extension": "允许其他插件控制这个拓展插件/Allow other script to control this extension", - "Skip img2img processing when using img2img initial image": "在图生图使用控制网时,跳过图生图处理/Skip img2img processing when using img2img initial image", - "Request browser notifications": "请求浏览器通知/Request browser notifications", - "Download localization template": "下载本地化模板/Download localization template", - "Reload custom script bodies (No ui updates, No restart)": "重新加载自定义脚本主体(不更新UI,也不重新启动)/Reload custom script bodies (No ui updates, No restart)", - "CodeFormer": "CodeFormer", - "Parts of CodeFormer code had to be copied to be compatible with GFPGAN.": "Parts of CodeFormer code had to be copied to be compatible with GFPGAN.", - "S-Lab License 1.0\n\nCopyright 2022 S-Lab\n\nRedistribution and use for non-commercial purpose in source and\nbinary forms, with or without modification, are permitted provided\nthat the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived\n from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nIn the event that redistribution and/or use for commercial purpose in\nsource or binary forms, with or without modification is required,\nplease contact the contributor(s) of the work.": "S-Lab License 1.0\n\nCopyright 2022 S-Lab\n\nRedistribution and use for non-commercial purpose in source and\nbinary forms, with or without modification, are permitted provided\nthat the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived\n from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nIn the event that redistribution and/or use for commercial purpose in\nsource or binary forms, with or without modification is required,\nplease contact the contributor(s) of the work.", - "ESRGAN": "ESRGAN", - "Code for architecture and reading models copied.": "Code for architecture and reading models copied.", - "MIT License\n\nCopyright (c) 2021 victorca25\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.": "MIT License\n\nCopyright (c) 2021 victorca25\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", - "Real-ESRGAN": "Real-ESRGAN", - "Some code is copied to support ESRGAN models.": "Some code is copied to support ESRGAN models.", - "BSD 3-Clause License\n\nCopyright (c) 2021, Xintao Wang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.": "BSD 3-Clause License\n\nCopyright (c) 2021, Xintao Wang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", - "InvokeAI": "InvokeAI", - "Some code for compatibility with OSX is taken from lstein's repository.": "Some code for compatibility with OSX is taken from lstein's repository.", - "MIT License\n\nCopyright (c) 2022 InvokeAI Team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.": "MIT License\n\nCopyright (c) 2022 InvokeAI Team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", - "Code added by contirubtors, most likely copied from this repository.": "Code added by contirubtors, most likely copied from this repository.", - "MIT License\n\nCopyright (c) 2022 Machine Vision and Learning Group, LMU Munich\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.": "MIT License\n\nCopyright (c) 2022 Machine Vision and Learning Group, LMU Munich\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", - "CLIP Interrogator": "CLIP Interrogator", - "Some small amounts of code borrowed and reworked.": "Some small amounts of code borrowed and reworked.", - "MIT License\n\nCopyright (c) 2022 pharmapsychotic\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.": "MIT License\n\nCopyright (c) 2022 pharmapsychotic\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", - "SwinIR": "SwinIR", - "Code added by contributors, most likely copied from this repository.": "Code added by contributors, most likely copied from this repository.", - "Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [2021] [SwinIR Authors]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.": "Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [2021] [SwinIR Authors]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.", - "Memory Efficient Attention": "Memory Efficient Attention", - "The sub-quadratic cross attention optimization uses modified code from the Memory Efficient Attention package that Alex Birch optimized for 3D tensors. This license is updated to reflect that.": "The sub-quadratic cross attention optimization uses modified code from the Memory Efficient Attention package that Alex Birch optimized for 3D tensors. This license is updated to reflect that.", - "MIT License\n\nCopyright (c) 2023 Alex Birch\nCopyright (c) 2023 Amin Rezaei\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.": "MIT License\n\nCopyright (c) 2023 Alex Birch\nCopyright (c) 2023 Amin Rezaei\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.", - "Show all pages": "显示所有页面/Show all pages", - "Installed": "已安装/Installed", - "Available": "可用/Available", - "Install from URL": "从网址安装/Install from URL", - "Apply and restart UI": "应用并重启用户界面/Apply and restart UI", - "Check for updates": "检查更新/Check for updates", - "Extension": "扩展插件/Extension", - "URL": "网址/URL", - "Update": "更新/Update", - "unknown": "未知/unknown", - "built-in": "built-in", - "ScuNET": "ScuNET", - "prompt-bracket-checker": "prompt-bracket-checker", - "Load from:": "加载自:/Load from:", - "Extension index URL": "扩展列表网址/Extension index URL", - "Hide extensions with tags": "隐藏含有以下标签的扩展/Hide extensions with tags", - "script": "script", - "ads": "含广告/ads", - "localization": "localization", - "installed": "installed", - "Order": "排序/Order", - "newest first": "从新排序/newest first", - "oldest first": "从旧排序/oldest first", - "a-z": "a-z", - "z-a": "z-a", - "internal order": "内部排序/internal order", - "URL for extension's git repository": "扩展插件的git仓库网址/URL for extension's git repository", - "Local directory name": "本地目录名/Local directory name", - "Install": "安装/Install", - "API": "API", - "•": "・", - "Github": "Github", - "Gradio": "Gradio", - "python:": "python:", - "N/A": "N/A", - "Change checkpoint": "Change checkpoint", - "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "提示词(按Ctrl+Enter或Alt+Enter生成)\nPrompt/Prompt (press Ctrl+Enter or Alt+Enter to generate)", - "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "反向提示词(按Ctrl+Enter或Alt+Enter生成)\nNegative prompt/Negative prompt (press Ctrl+Enter or Alt+Enter to generate)", - "Stop processing images and return any results accumulated so far.": "停止处理图像,并返回目前为止的结果/Stop processing images and return any results accumulated so far.", - "Stop processing current image and continue processing.": "停止处理当前图像,并继续处理下一个/Stop processing current image and continue processing.", - "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "从提示词中读取生成参数,如果提示词为空,则读取上一次的生成参数到用户界面/Read generation parameters from prompt or last generation if prompt is empty into user interface.", - "Clear prompt": "清空提示词/Clear prompt", - "Show extra networks": "展开可选用的附加网络填充脚本(Embedding,Hypernework和LoRA)/Show extra networks", - "Apply selected styles to current prompt": "将所选模板风格,应用于当前提示词/Apply selected styles to current prompt", - "Save style": "储存为模版风格/Save style", - "Remove All": "全部删除/Remove All", - "Search...": "搜索.../Search...", - "Which algorithm to use to produce the image": "使用哪种算法生成图像/Which algorithm to use to produce the image", - "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help": "Euler A-非常有创意,每一张都可以根据步数得到完全不同的图片,设置步数高于30-40没用/Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help", - "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results": "迭代改进生成的图像多少次;更高的值需要更长的时间;非常低的值会产生不好的结果/How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results", - "Produce an image that can be tiled.": "生成可用于平铺的图像/Produce an image that can be tiled.", - "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "仅使用2步来创建一个小分辨率且高解析度的图像,然后在不改变构图的情况下改进图像细节/Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition", - "Number of sampling steps for upscaled picture. If 0, uses same as for original.": "设置进行高分辨率修复时的采样迭代次数,0表示沿用原始采样迭代次数/Number of sampling steps for upscaled picture. If 0, uses same as for original.", - "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "决定算法对图像内容的影响程度。为0时,什么都不会改变。为1时,你讲会得到一个毫不相关的图像。\n值低于1时,处理的迭代步数将少于\"采样步数\"滑块指定的步数/Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.", - "Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.": "按比例放大原分辨率,单独设定目标长宽时被忽略/Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.", - "Resizes image to this width. If 0, width is inferred from either of two nearby sliders.": "将宽度调整到此值,0表示根据目标高度或放大倍率自适应调整/Resizes image to this width. If 0, width is inferred from either of two nearby sliders.", - "Resizes image to this height. If 0, height is inferred from either of two nearby sliders.": "将高度调整到此值,0表示根据目标宽度或放大倍率自适应调整/Resizes image to this height. If 0, height is inferred from either of two nearby sliders.", - "How many batches of images to create": "创建多少批次的图像/How many batches of images to create", - "How many image to create in a single batch": "每批创建多少图像/How many image to create in a single batch", - "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "分类器引导系数-表示生成的图像应该多大程度符合提示词描述-值越低,生成的图像越有创意/Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results", - "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "一个固定随机数生成器输出的值 - 以相同参数和随机种子生成的图像会得到相同的结果\n🎲 将随机种子设置为-1,则每次都会使用一个新的随机数\n♻️ 重用上一次使用的随机种子,如果想要固定输出结果就会很有用/A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result", - "Set seed to -1, which will cause a new random number to be used every time": "将随机种子设置为 -1,则每次都会使用一个新的随机数/Set seed to -1, which will cause a new random number to be used every time", - "Reuse seed from last generation, mostly useful if it was randomed": "重用上一次使用的随机种子,如果想要固定结果就会很有用/Reuse seed from last generation, mostly useful if it was randomed", - "Seed of a different picture to be mixed into the generation.": "将要参与生成的另一张图的随机种子/Seed of a different picture to be mixed into the generation.", - "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "想要产生多强烈的变化。设为 0 时,将没有效果。设为 1 时,你将获得完全产自差异随机种子的图像(此功能对带有 a 后缀的采样器无效)/How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).", - "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "尝试生成与指定分辨率下相同图像生成种子生成的图像相似的图像/Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution", - "Do not do anything special": "什么都不做/Do not do anything special", - "Separate values for X axis using commas.": "使用逗号分隔X轴的值/Separate values for X axis using commas.", - "Paste available values into the field": "将可用值粘贴到字段中/Paste available values into the field", - "Separate values for Y axis using commas.": "使用逗号分隔Y轴的值/Separate values for Y axis using commas.", - "Open images output directory": "打开图像输出目录/Open images output directory", - "Write image to a directory (default - log/images) and generation parameters into csv file.": "将图像写入目录(默认 - log/images)并将生成参数写入 csv 表格文件/Write image to a directory (default - log/images) and generation parameters into csv file.", - "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "将图像大小调整为目标分辨率。除非高度和宽度匹配,否则你将获得不正确的纵横比/Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.", - "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "调整图像大小,使整个目标分辨率都被图像填充。裁剪多出来的部分/Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.", - "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "调整图像大小,使整个图像在目标分辨率内。用图像的颜色填充空白区域/Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.", - "How much to blur the mask before processing, in pixels.": "处理前要对蒙版进行多强的模糊,以像素为单位/How much to blur the mask before processing, in pixels.", - "What to put inside the masked area before processing it with Stable Diffusion.": "在使用 Stable Diffusion 处理蒙版区域之前要在蒙版区域内放置什么/What to put inside the masked area before processing it with Stable Diffusion.", - "fill it with colors of the image": "用图像的颜色(高强度模糊)填充它/fill it with colors of the image", - "keep whatever was there originally": "保留原来的图像/keep whatever was there originally", - "fill it with latent space noise": "用潜空间噪声填充/fill it with latent space noise", - "fill it with latent space zeroes": "用潜空间零填充/fill it with latent space zeroes", - "How many times to repeat processing an image and using it as input for the next iteration": "重复处理一张图像,并用作下一次迭代输入的次数/How many times to repeat processing an image and using it as input for the next iteration", - "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "在图像迭代模式下,在每一次循环中,绘制强度都会乘以该值。小于1表示减少多样性,所以你的图像序列会逐渐收敛在固定的图像上。大于1表示增加多样性,所以你的图像序列会变得越来越混乱/In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.", - "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "使用SD放大时,贴图之间应该有多少像素重叠。因为是切片重叠,所以当它们合并回一张图像时,没有清晰可见的接缝/For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.", - "A directory on the same machine where the server is running.": "服务器主机上某一目录/A directory on the same machine where the server is running.", - "Leave blank to save images to the default path.": "留空将保存图像到默认路径/Leave blank to save images to the default path.", - "Result = A": "结果=A模型/Result = A", - "Result = A * (1 - M) + B * M": "结果=A*(1-M)+B*M/Result = A * (1 - M) + B * M", - "Result = A + (B - C) * M": "结果=A+(B-C)*M/Result = A + (B - C) * M", - "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.": "与写入内容名称匹配的权重信息将不会写入输出的模型,可以通过写入\"^model_ema\"以舍弃模型中的EMA信息/Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.", - "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors", - "1st and last digit must be 1. ex:'1, 2, 1'": "第一个和最后一个数字必须是 1。例:'1, 2, 1'/1st and last digit must be 1. ex:'1, 2, 1'", - "1st and last digit must be 0 and values should be between 0 and 1. ex:'0, 0.01, 0'": "1st and last digit must be 0 and values should be between 0 and 1. ex:'0, 0.01, 0'", - "Gradient clip value": "Gradient clip value", - "Path to directory with input images": "带有输入图像的目录路径/Path to directory with input images", - "Path to directory where to write outputs": "进行输出的目录路径/Path to directory where to write outputs", - "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime