├── Kernel ├── Formatter.m ├── init.m └── !Template.sh ├── Packages ├── Readme.md ├── WaifuIR │ ├── Readme.md │ ├── Sharpen.m │ └── Denoise.m ├── WaifuSR │ ├── Readme.md │ └── Resize.m ├── WaifuSY │ ├── Readme.md │ └── Tang.m ├── Main.m ├── WaifuCU │ └── Name.m ├── Plugins.m ├── Ready.m └── Directory.m ├── Documentation └── Readme.md ├── docs ├── Start │ ├── Readme.md │ └── template.md ├── WaifuCU │ └── Readme.md ├── WaifuIR │ ├── Model.md │ └── Readme.md ├── WaifuSY │ ├── Model.md │ └── Readme.md ├── .vuepress │ ├── override.styl │ └── config.js ├── Readme.md └── WaifuSR │ ├── Readme.md │ ├── Model.md │ └── Benchmark.md ├── .gitattributes ├── Config ├── LoadInfo.m └── BundleInfo.m ├── PacletInfo.m ├── .editorconfig ├── package.json ├── .gitignore ├── README.md ├── License └── WaifuLoader.m /Kernel/Formatter.m: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Packages/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Documentation/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Packages/WaifuIR/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Packages/WaifuSR/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Packages/WaifuSY/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Start/Readme.md: -------------------------------------------------------------------------------- 1 | # 功能展示 2 | 3 | -------------------------------------------------------------------------------- /docs/WaifuCU/Readme.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.nb filter=lfs diff=lfs merge=lfs -text 2 | *.jpg filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /Kernel/init.m: -------------------------------------------------------------------------------- 1 | If[ 2 | !TrueQ[Waifu`PackageScope`Private`$LoadCompleted], 3 | << Waifu`WaifuLoader` 4 | ]; 5 | -------------------------------------------------------------------------------- /Config/LoadInfo.m: -------------------------------------------------------------------------------- 1 | (* Created with the Wolfram Language : www.wolfram.com *) 2 | {"PreLoad" -> None, "FEHidden" -> {}, "PackageScope" -> None} 3 | -------------------------------------------------------------------------------- /PacletInfo.m: -------------------------------------------------------------------------------- 1 | Paclet[ 2 | Name -> "Waifu", 3 | Version -> "0.2.5", 4 | Extensions -> { 5 | { 6 | "Kernel", 7 | "Root" -> ".", 8 | "Context" -> {"Waifu`"} 9 | } 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | indent_size = 4 7 | end_of_line = CRLF 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "vuepress": "^0.10.2" 4 | }, 5 | "scripts": { 6 | "docs:dev": "vuepress dev docs", 7 | "docs:build": "vuepress build docs" 8 | }, 9 | "dependencies": { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/WaifuIR/Model.md: -------------------------------------------------------------------------------- 1 | # Models 2 | 3 | 如果你想使用其他模型, 可以调用内部函数或者调整以下模型. 4 | 5 | 该项目的本体与源码在: [Moe-Net/Waifu-SY](https://github.com/Moe-Net/Waifu-IR) 6 | 7 | ::: warning Attention 8 | 注意, 所有模块都是惰性加载的 9 | 10 | 因此入口函数之一必须被调用过, 否则以下函数都无法被找到. 11 | ::: 12 | -------------------------------------------------------------------------------- /docs/Start/template.md: -------------------------------------------------------------------------------- 1 | ## Magic 2 | 3 | ### 参数说明 4 | 5 | ::: tip Sudoku[n,dim:2] 6 | - n 类型为 `Integer`, 表示幻方的阶 7 | ::: 8 | 9 | ### 可选项 10 | 11 | 待定, 支持其他种类幻方 12 | 13 | ### 返回值 14 | 15 | `MagicObject` 16 | 17 | ### 标准示例 18 | 19 | #### 测试代码: 20 | ```haskell 21 | Import[] 22 | ``` 23 | 24 | #### 测试输出: 25 | -------------------------------------------------------------------------------- /Config/BundleInfo.m: -------------------------------------------------------------------------------- 1 | (* Created with the Wolfram Language : www.wolfram.com *) 2 | { 3 | "RemovePaths" -> { 4 | ".git", 5 | ".idea", 6 | "docs/*", 7 | "Packages/__Future__/*" 8 | }, 9 | "RemovePatterns" -> { 10 | "yarn.lock", 11 | "*.git", 12 | "package.json", 13 | ".DS_Store" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/WaifuSY/Model.md: -------------------------------------------------------------------------------- 1 | # Models 2 | 3 | 如果你想使用其他诗歌生成模型, 可以调用内部函数或者调整以下模型. 4 | 5 | 该项目的本体与源码在: [Moe-Net/Waifu-SY](https://github.com/Moe-Net/Waifu-SY) 6 | 7 | ::: warning Attention 8 | 注意, 所有模块都是惰性加载的 9 | 10 | 因此入口函数之一必须被调用过, 否则以下函数都无法被找到. 11 | ::: 12 | 13 | ## Tang-7 14 | 15 | ## Tang-5 16 | 17 | ## Tang-4 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # yarn 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | 7 | # Build Temp 8 | Thumbs.db 9 | .DS_Store 10 | docs/.build/ 11 | docs/.vuepress/public/ 12 | 13 | # idea 配置文件 14 | *.iml 15 | .idea/* 16 | 17 | # 模型文件 18 | *.7z 19 | *.rar 20 | *.zip 21 | *.wxf 22 | *.wlnet 23 | *.wmlf 24 | *.onnx -------------------------------------------------------------------------------- /docs/.vuepress/override.styl: -------------------------------------------------------------------------------- 1 | $accentColor = #FF69B4 //Hot pink 2 | $textColor = #2c3e50 3 | $borderColor = #eaecef 4 | $codeBgColor = #282c34 5 | // 代码库重置 6 | .content pre { 7 | margin: 0 !important; 8 | } 9 | 10 | h2 { 11 | font-size: 2rem; 12 | color: #2c3e50; 13 | } 14 | 15 | h3 { 16 | font-size: 1.2rem; 17 | margin-top: 0; 18 | padding-top: 10px; 19 | padding-bottom: 0; 20 | } 21 | 22 | h4 { 23 | color: #6196CC; 24 | font-size: 14px; 25 | margin-top: 0; 26 | padding-top: 10px; 27 | padding-bottom: 10px; 28 | } 29 | -------------------------------------------------------------------------------- /docs/WaifuSY/Readme.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | 诗云模块 4 | 5 | 6 | ## WaifuTang 7 | ### 参数说明 8 | 9 | ::: tip WaifuTang[length:5,line:4] 10 | - length 类型为 `Integer`, 表示几言诗 11 | - line 类型为 `Integer`, 表示有几句 12 | ::: 13 | 14 | ::: tip WaifuTang[length:5,head] 15 | - length 类型为 `Integer`, 表示几言诗 16 | - head 类型为 `String`, 藏头诗的句首 17 | ::: 18 | 19 | ### 可选项 20 | 21 | 无 22 | 23 | ### 返回值 24 | 25 | `TableForm` 26 | 27 | 具体来说是一个 `List`, 每个元素是 `Text`. 28 | 29 | ### 标准示例 30 | 31 | #### 测试代码: 32 | ```haskell 33 | Import[] 34 | ``` 35 | 36 | #### 测试输出: 37 | -------------------------------------------------------------------------------- /Packages/Main.m: -------------------------------------------------------------------------------- 1 | Waifu::usage = ""; 2 | Begin["`Private`"]; 3 | (*PackageLoadPacletDependency["NeuralNetworks`"];*) 4 | (*PackageLoadPacletDependency["MXNetLink`"];*) 5 | (*PackageExtendContextPath[*) 6 | (*{*) 7 | (*"Developer`",*) 8 | (*"MXNetLink`",*) 9 | (*"NeuralNetworks`",*) 10 | (*"GeneralUtilities`"*) 11 | (*}*) 12 | (*];*) 13 | If[$CharacterEncoding =!= "UTF-8", 14 | $CharacterEncoding = "UTF-8"; 15 | Print[{ 16 | Style["$CharacterEncoding has been changed to UTF-8 to avoid problems.", Red], 17 | Style["Because ChineseNLP only works under UTF-8"] 18 | } // TableForm]; 19 | st = OpenAppend[FindFile["init.m"]]; 20 | WriteString[st, "$CharacterEncoding=\"UTF-8\";"]; 21 | Close[st]; 22 | ]; 23 | End[]; 24 | -------------------------------------------------------------------------------- /docs/Readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | actionText: Get Started → 4 | actionLink: /Start/ 5 | footer: MPL2.0 Licensed | Copyright © 2018-2018 GalAster 6 | --- 7 | 8 | ### 一键安装 9 | 10 | ```haskell 11 | PacletInstall["Waifu","Site"->"http://m.vers.site/"] 12 | ``` 13 | 14 | 当然更新和卸载也是一键搞定 15 | 16 | ```haskell 17 | PacletUpdate["Waifu","Site"->"http://m.vers.site/"] 18 | PacletUninstall["Waifu"] 19 | ``` 20 | 21 | ::: warning 兼容性要求 22 | [![Release Vision](https://img.shields.io/badge/release-v0.3.x-ff69b4.svg)](https://github.com/Moe-Net/BilibiliLink/releases) 23 | [![Mathematica](https://img.shields.io/badge/Mathematica-%3E%3D11.3-brightgreen.svg)](https://www.wolfram.com/mathematica/) 24 | [![Mathematica](https://img.shields.io/badge/Encode-UTF8-red.svg)](https://www.wolfram.com/mathematica/) 25 | ::: 26 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dest: 'docs/.build', 3 | locales: { 4 | '/': { 5 | lang: 'zh-CN', 6 | title: 'WaifuX', 7 | description: 'No game no life ♕' 8 | } 9 | }, 10 | head: [ 11 | ['link', {rel: 'icon', href: '/favicon.png'}] 12 | ], 13 | themeConfig: { 14 | repo: 'Moe-Net/Waifu-X', 15 | editLinks: true, 16 | docsDir: 'docs', 17 | markdown: { 18 | lineNumbers: true 19 | }, 20 | sidebar: [ 21 | { 22 | title: 'Readme', 23 | children: [ 24 | '/Start/' 25 | ] 26 | }, 27 | { 28 | title: 'Waifu-SR', 29 | children: [ 30 | '/WaifuSR/', 31 | '/WaifuSR/Model.md', 32 | '/WaifuSR/Benchmark.md' 33 | ] 34 | }, 35 | { 36 | title: 'Waifu-IR', 37 | children: [ 38 | '/WaifuIR/', 39 | '/WaifuIR/Model.md' 40 | ] 41 | }, 42 | { 43 | title: 'Waifu-CU', 44 | children: [ 45 | '/WaifuCU/' 46 | ] 47 | }, 48 | { 49 | title: 'Waifu-SY', 50 | children: [ 51 | '/WaifuSY/' 52 | ] 53 | } 54 | ] 55 | }, 56 | serviceWorker: true 57 | }; 58 | -------------------------------------------------------------------------------- /docs/WaifuSR/Readme.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | 超分辨率重建模块 4 | 5 | ## WaifuSR 6 | ### 参数说明 7 | 8 | ::: tip WaifuSR[i,zoom:2] 9 | - i 类型为 `Image`, 表示要放大的图片 10 | - zoom 的类型为 `Real`, 表示要放大的倍数 11 | - 1 < zoom <= 4 12 | - 若 zoom = 1, 等价于 WaifuSharpen 的 `"Soft"` 模式. 13 | - 更高倍数请在 Models 中寻找合适的模型. 14 | ::: 15 | 16 | ### 可选项 17 | 18 | - TargetDevice -> "GPU" 19 | - 运算单元, 可选 "CPU" 或者 "GPU" 20 | 21 | ### 返回值 22 | 23 | `Image` 24 | 25 | 注意, `WaifuSR[i,4]` 不等价于 `WaifuSR[WaifuSR[i,2],2]` 26 | 27 | 前者无论是速度还是得分都比后者要好一点. 28 | 29 | 30 | ### 标准示例 31 | 32 | #### 测试代码: 33 | 34 | ```haskell 35 | test=Import["https://i.loli.net/2018/09/09/5b94b9b6e2574.png"]; 36 | WaifuSR[test,2] 37 | ImageResize[test,Scaled[2]] 38 | WaifuSR[test,4] 39 | ImageResize[test,Scaled[4]] 40 | ``` 41 | 42 | #### 原始图像: 43 | 44 | ![sr0.png](https://i.loli.net/2018/09/09/5b94b9b6e2574.png) 45 | 46 | #### 2x: 传统算法 vs WaifuSR 超分辨率重建 47 | 48 | ![sr2.png](https://i.loli.net/2018/09/09/5b94b9b7b2d5d.png) 49 | ![sr1.png](https://i.loli.net/2018/09/09/5b94b9b7b9c1c.png) 50 | 51 | #### 4x: 传统算法 vs WaifuSR 超分辨率重建 52 | 53 | ![sr4.png](https://i.loli.net/2018/09/09/5b94b9b9208ea.png) 54 | ![sr3.png](https://i.loli.net/2018/09/09/5b94b9b9d1b00.png) 55 | -------------------------------------------------------------------------------- /docs/WaifuIR/Readme.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | 图像修复模块. 4 | 5 | ## WaifuDenoise 6 | ### 参数说明 7 | 8 | ::: tip WaifuDenoise[img] 9 | - img 类型为 `Image`, 表示要降噪的图片 10 | ::: 11 | 12 | ### 可选项 13 | 14 | Method -> "Soft" 15 | - 模式, 可选 "Soft"|"Hard"|"Mixed" 16 | - "Soft", 轻柔, 正常情况使用轻柔即可 17 | - "Hard", 强力, 轻柔无法处理时使用, 不推荐 18 | - "Mixed", 自适应, 但其实没法很完美的自动识别 19 | TargetDevice -> "GPU" 20 | - 运算单元, 可选 "CPU" 或者 "GPU" 21 | 22 | ### 返回值 23 | 24 | `Image` 25 | 26 | ### 标准示例 27 | 28 | #### 测试代码: 29 | ```haskell 30 | Import[] 31 | ``` 32 | 33 | #### 测试输出: 34 | 35 | 36 | 37 | ## WaifuSharpen 38 | ### 参数说明 39 | 40 | ::: tip WaifuSharpen[img] 41 | - img 类型为 `Image`, 表示要锐化的图片 42 | ::: 43 | 44 | ### 可选项 45 | 46 | - Method -> "Soft" 47 | - 模式, 可选 "Soft"|"Hard" 48 | - "Soft", 轻柔, 正常情况使用轻柔即可 49 | - "Hard", 强力, 轻柔无法处理时使用 50 | - TargetDevice -> "GPU" 51 | - 运算单元, 可选 "CPU" 或者 "GPU" 52 | 53 | ### 返回值 `Image` 54 | 55 | ::: danger EXPERIMENTAL 56 | 57 | 实验级, 即便无法使用也不要提交 issue. 58 | 59 | *Soft* 适用于那些已经被拉伸过了的模糊图片, 尤其是不清楚拉伸倍数的情况. 60 | 61 | 效果比 `WaifuSR` 压到一半再拉伸回来要好很多. 62 | 63 | *Hard* 提供比 *Soft* 更强力的修正, 但容易修正过度, 导致图片出现色块. 64 | ::: 65 | 66 | ### 标准示例 67 | 68 | #### 测试代码: 69 | ```haskell 70 | Import[] 71 | ``` 72 | 73 | #### 测试输出: 74 | -------------------------------------------------------------------------------- /Packages/WaifuCU/Name.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Subchapter:: *) 3 | (*WaifuName*) 4 | (* ::Text:: *) 5 | (* $Updated = "2018-09-16"; *) 6 | 7 | 8 | (* ::Subsubsection:: *) 9 | (*Models*) 10 | Waifu`Models`Resnet::usage = ""; 11 | Waifu`Models`Resnet := Ready[$Waifus["Resnet50", "Remote"]]; 12 | 13 | 14 | (* ::Subsubsection:: *) 15 | (*Main*) 16 | Options[WaifuName$API] = {Method -> "Soft", TargetDevice -> "GPU"}; 17 | WaifuName$API[img_Image, OptionsPattern[]] := Block[ 18 | {catch}, 19 | catch = Switch[OptionValue[Method], 20 | _, WaifuResnet[img, OptionValue[TargetDevice]] 21 | ]; 22 | If[ 23 | MissingQ[catch], 24 | Return[Missing["NotAvailable"]], 25 | Return[catch] 26 | ] 27 | ]; 28 | 29 | 30 | (* ::Subsubsection::Closed:: *) 31 | (*Resnet50*) 32 | WaifuResnet[img_, device_ : "GPU"] := Block[ 33 | {top}, 34 | If[ 35 | MissingQ[Waifu`Models`Resnet], 36 | Return[Missing["NotAvailable"]] 37 | ]; 38 | top = Select[Waifu`Models`Resnet[img, "Probabilities", TargetDevice -> "GPU"], # > 0.001&]; 39 | Dataset[ToString@Floor[100#, 0.01] <> "%"& /@ Take[ReverseSort@top, UpTo[10]]] 40 | ]; 41 | 42 | 43 | (* ::Subchapter:: *) 44 | (*Additional*) 45 | SetAttributes[ 46 | {WaifuName$API}, 47 | {Protected, ReadProtected} 48 | ] 49 | -------------------------------------------------------------------------------- /Packages/Plugins.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Title:: *) 3 | (*组件注册(Components)*) 4 | (* ::Subchapter:: *) 5 | (*程序包介绍*) 6 | (* ::Text:: *) 7 | (*Mathematica Package*) 8 | (*Created by Mathematica Plugin for IntelliJ IDEA*) 9 | (*Establish from GalAster's template(v1.3)*) 10 | (**) 11 | (* ::Text:: *) 12 | (*Author:Aster*) 13 | (*Creation Date:2018-09-11*) 14 | (*Copyright: Mozilla Public License Version 2.0*) 15 | (* ::Program:: *) 16 | (*1.软件产品再发布时包含一份原始许可声明和版权声明。*) 17 | (*2.提供快速的专利授权。*) 18 | (*3.不得使用其原始商标。*) 19 | (*4.如果修改了源代码,包含一份代码修改说明。*) 20 | (**) 21 | (* ::Section:: *) 22 | (*Registry*) 23 | 24 | 25 | (* ::Text:: *) 26 | (*WaifuSR*) 27 | Waifu`WaifuSR::usage = ""; 28 | Waifu`WaifuSR = Waifu`WaifuSR`WaifuSR$API; 29 | 30 | 31 | (* ::Text:: *) 32 | (*WaifuIR*) 33 | Waifu`WaifuDenoise::usage = ""; 34 | Waifu`WaifuDenoise = Waifu`WaifuIR`WaifuDenoise$API; 35 | Waifu`WaifuSharpen::usage = ""; 36 | Waifu`WaifuSharpen = Waifu`WaifuIR`WaifuSharpen$API; 37 | 38 | 39 | (* ::Text:: *) 40 | (*WaifuCU*) 41 | Waifu`WaifuName::usage = ""; 42 | Waifu`WaifuName = Waifu`WaifuCU`WaifuName$API; 43 | 44 | 45 | (* ::Text:: *) 46 | (*WaifuSY*) 47 | Waifu`WaifuTang::usage = "生成古诗"; 48 | Waifu`WaifuTang = Waifu`WaifuSY`WaifuTang$API; 49 | Waifu`$TangShiComplex::usage = "生成古诗用字的生僻程度"; 50 | (* Global Constant *) 51 | -------------------------------------------------------------------------------- /Kernel/!Template.sh: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Title:: *) 3 | (*${NAME}(${NAME})*) 4 | (* ::Subchapter:: *) 5 | (*程序包介绍*) 6 | (* ::Text:: *) 7 | (*Mathematica Package*) 8 | (*Created by Mathematica Plugin for IntelliJ IDEA*) 9 | (*Establish from GalAster's template(v1.3)*) 10 | (**) 11 | (* ::Text:: *) 12 | (*Author:${USER}*) 13 | (*Creation Date:${YEAR}-${MONTH}-${DAY}*) 14 | (*Copyright: Mozilla Public License Version 2.0*) 15 | (* ::Program:: *) 16 | (*1.软件产品再发布时包含一份原始许可声明和版权声明。*) 17 | (*2.提供快速的专利授权。*) 18 | (*3.不得使用其原始商标。*) 19 | (*4.如果修改了源代码,包含一份代码修改说明。*) 20 | (**) 21 | (* ::Text:: *) 22 | (*这里应该填这个函数的介绍*) 23 | (* ::Section:: *) 24 | (*函数说明*) 25 | ExampleFunction::usage = "这里应该填这个函数的说明,如果要换行用\"\\r\"\r就像这样"; 26 | (* ::Section:: *) 27 | (*程序包正体*) 28 | (* ::Subsection::Closed:: *) 29 | (*主设置*) 30 | ExNumber::usage = "程序包的说明,这里抄一遍"; 31 | Begin["`${NAME}`"]; 32 | (* ::Subsection::Closed:: *) 33 | (*主体代码*) 34 | Version$${NAME}="V1.0"; 35 | Updated$${NAME}="${YEAR}-${MONTH}-${DAY}"; 36 | (* ::Subsubsection:: *) 37 | (*功能块 1*) 38 | ExampleFunction[1]="我就是个示例函数,什么功能都没有"; 39 | 40 | 41 | 42 | (* ::Subsubsection:: *) 43 | (*功能块 2*) 44 | ExampleFunction[2]="我就是个示例函数,什么功能都没有"; 45 | 46 | 47 | (* ::Subsection::Closed:: *) 48 | (*附加设置*) 49 | SetAttributes[ 50 | { }, 51 | {Protected,ReadProtected} 52 | ] 53 | End[] -------------------------------------------------------------------------------- /docs/WaifuSR/Model.md: -------------------------------------------------------------------------------- 1 | # Models 2 | 3 | 如果你想使用其他超分辨率重建模型, 可以调用内部函数或者调整以下模型. 4 | 5 | 该项目的本体与源码在: [Moe-Net/Waifu-SR](https://github.com/Moe-Net/Waifu-SR) 6 | 7 | ::: warning Attention 8 | 注意, 所有模块都是惰性加载的 9 | 10 | 接口函数 ``Waifu`WaifuSR`WaifuSR$API[]`` 必须被调用过至少一次, 否则以下函数都无法被找到. 11 | ::: 12 | 13 | ## VGGSR 14 | ### Model 15 | 16 | Waifu2X 所使用的模型, 使用 VGG 架构. 17 | 18 | - Cite: [Waifu2X](https://github.com/nagadomi/waifu2x) 19 | 20 | - ``Waifu`Models`VGGSR`` 21 | 22 | ### Function 23 | 24 | ```haskell 25 | Waifu`WaifuSR`WaifuSR$API[]; 26 | WaifuVGGSR[img, "GPU"] 27 | ``` 28 | 29 | ## VDSR 30 | ### Model 31 | 32 | 深层神经网络模型, 至少在当时是深层神经网络. 33 | 34 | - Cite 35 | 36 | - ``Waifu`Models`VDSR`` 37 | 38 | ![VDSR](https://i.loli.net/2018/09/20/5ba31764647a2.png) 39 | 40 | ### Function 41 | 42 | 43 | 44 | ## LapSRN 45 | 46 | ## ByNet 47 | 48 | ![ByNet](https://i.loli.net/2018/09/20/5ba317648a5e0.png) 49 | 50 | 51 | ## SRResNet 52 | ### Model 53 | 54 | ::: danger EXPERIMENTAL 55 | 56 | 实验级, 即便无法使用也不要提交 issue. 57 | 58 | 残差神经网络在超分辨率上的运用. 59 | 60 | - Cite: [Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network](https://arxiv.org/pdf/1609.04802v5.pdf) 61 | 62 | ::: 63 | 64 | ### Function 65 | 66 | ```haskell 67 | Needs["MXNetLink`"]; 68 | Waifu`WaifuSR`WaifuSR$API[]; 69 | "2x 放大倍率"; 70 | Waifu`WaifuSR`WaifuSRResNet[img, "GPU"] 71 | "3x 放大倍率"; 72 | Waifu`WaifuSR`WaifuSRResNet[img, "GPU"] 73 | "4x 放大倍率"; 74 | Waifu`WaifuSR`WaifuSRResNet[img, "GPU"] 75 | "8x 放大倍率"; 76 | Waifu`WaifuSR`WaifuSRResNet[img, "GPU"] 77 | ``` 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Waifu:X 2 | 3 | [![Mathematica](https://img.shields.io/badge/Mathematica-%3E%3D11.3.5-brightgreen.svg)](https://www.wolfram.com/mathematica/) 4 | [![Release Vision](https://img.shields.io/badge/release-v0.2.x-ff69b4.svg)](https://github.com/Moe-Net/Waifu-X/releases) 5 | [![Repo Size](https://img.shields.io/github/repo-size/Moe-Net/Waifu-X.svg)](https://github.com/Moe-Net/Waifu-X.git) 6 | [![Code Size](https://img.shields.io/github/languages/code-size/Moe-Net/Waifu-X.svg)](https://github.com/Moe-Net/Waifu-X.git) 7 | 8 | ## Install +1s 9 | 10 | One-Key Installation: 11 | 12 | ```Mathematica 13 | PacletUninstall["Waifu"] 14 | PacletInstall@"https://github.com/Moe-Net/Waifu-X/releases/download/v0.2.x/Waifu-0.2.x.paclet" 15 | ``` 16 | 17 | 因为 API 快速变动, 不建议使用一键安装, 请按以下步骤手动安装 18 | 19 | 打开以下文件夹 20 | ```Mathematica 21 | SystemOpen[FileNameJoin@{$UserBaseDirectory, "Paclets", "Repository"}] 22 | ``` 23 | 24 | 接着使用 git 同步以下目录: 25 | ```bash 26 | git clone https://github.com/Moe-Net/Waifu-X.git Waifu --depth 1 --branch master 27 | ``` 28 | 29 | 手动下载压缩包安装的话也是解压到这个目录, 以后更新手动覆盖即可. 30 | 31 | 最终的目录结构为: 32 | 33 | ```yaml 34 | - Configuration/ 35 | - Repository/ 36 | - Waifu/ 37 | - Kernel/ 38 | - PacletInfo.m 39 | - WaifuLoader.m 40 | - Temporary/ 41 | ``` 42 | 43 | ## Patchouli♂Go 44 | 45 | Use a notebook, starting with the following codes! 46 | 47 | ```Mathematica 48 | < ©Copyright by **Mozilla Public License Version 2.0**. 57 | -------------------------------------------------------------------------------- /docs/WaifuSR/Benchmark.md: -------------------------------------------------------------------------------- 1 | # BenchMark 2 | 3 | 成绩来自: [Moe-Net/Waifu-SR/Models/Readme.md](https://github.com/Moe-Net/Waifu-SR/blob/8fee83987e2e2d28aff08c23e618c85b0e66841d/Models/Readme.md) 4 | 5 | ## WaifuSR 6 | 7 | ### Quantity score 8 | 9 | Name|size|paras|layers|nodes|speed|FLOPS| 10 | ----|----|-----|------|-----|-----|-----| 11 | Nearest|None|None|None|None|1.141 ms|136.9 M 12 | Linear|None|None|None|None|4.184 ms|486.1 M 13 | Cubic|None|None|None|None|10.83 ms|1.380 G 14 | o-MOMS|None|None|None|None|9.975 ms|1.292 G 15 | VGGSR|2.11 MB|552.5 K|13|-|97.57 ms|63.20 G 16 | VDSR|2.54 MB|665.9 K|40|82|344.1 ms|222.9 G 17 | ByNet+|4.36 MB|1.145 M|63|99|455 ms|249.9 G 18 | SESR|1.19 MB|312.5 K|65|-|358.9 ms|232.5 G 19 | SESR+|-|-|-|-|-|- 20 | LapSRN|1.66 MB|435.3 K|28|92|381.4 ms|247.0 G 21 | LapSRN+|3.32 MB|870.1 K|53|174|1.085 s|703.0 G 22 | RED30|15.7 MB|4.135 M|68|130|807.1 ms|522.7 G 23 | -|-|-|-|-|-|- 24 | 25 | ### Quality score 26 | 27 | Name|Zoom|-SAD-|+PSNR+|+SSIM+|+FSIM+|+GMSD+ 28 | ----|----|-----|------|------|------|------| 29 | Nearest|Auto|15617.3|27.0725|0.80129|-|- 30 | Linear|Auto|14525.1|28.2834|0.83432|-|- 31 | Cubic|Auto|12699.4|30.0381|0.88529|-|- 32 | o-MOMS|Auto|12697.5|30.3557|-|-|- 33 | VGGSR|×2|78561.5|14.8726|-|-|- 34 | **VDSR**|Auto|11215.1|30.8817|-|-|- 35 | **ByNet+**|Auto|11516.5|31.1093|-|-|- 36 | **SESR**|×2|14200.5|28.9835|-|-|- 37 | **SESR+**|×4|-|-|-|-|- 38 | LapSRN|×2|8671.42|33.6572|-|-|- 39 | LapSRN+|×4|8315.27|33.6519|-|-|- 40 | **RED30**|Auto|12119.1|30.8003|-|-|- 41 | -|-|-|-|-|-|- 42 | 43 | - Bold: **YCbCr Only**, single-channel rendering in YCbCr space, speed up but quality lost. 44 | - Auto: **AutoZoom**, non-fixed magnification, can be scaled at any magnification 45 | -------------------------------------------------------------------------------- /Packages/WaifuIR/Sharpen.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Subchapter:: *) 3 | (*Sharpen *) 4 | (* ::Text:: *) 5 | (*$Updated = "2018-09-19";*) 6 | 7 | 8 | (* ::Subchapter:: *) 9 | (*WaifuSharpen*) 10 | (* ::Subsubsection:: *) 11 | (*Models*) 12 | DRRN := Ready[$Waifus["DRRN9", "Remote"]]; 13 | DRRN2 := Ready[$Waifus["DRRN25", "Remote"]]; 14 | 15 | 16 | (* ::Subsubsection:: *) 17 | (*Main*) 18 | Options[WaifuSharpen$API] = {Method -> "Soft", TargetDevice -> "GPU"}; 19 | WaifuSharpen$API[img_Image, OptionsPattern[]] := Block[ 20 | {catch}, 21 | catch = Switch[OptionValue[Method], 22 | "Soft", WaifuDRRN[img, OptionValue[TargetDevice]], 23 | _, WaifuDnCNN2[img, OptionValue[TargetDevice]] 24 | ]; 25 | If[ 26 | MissingQ[catch], 27 | Return[Missing["NotAvailable"]], 28 | Return[catch] 29 | ] 30 | ]; 31 | 32 | 33 | (* ::Subsubsection::Closed:: *) 34 | (*DRRN*) 35 | WaifuDRRN[img_, device_ : "GPU"] := Block[ 36 | {ne, nd, geass}, 37 | If[MissingQ[DRRN], Return[Missing["NotAvailable"]]]; 38 | ne = NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}]; 39 | nd = NetDecoder[{"Image", ColorSpace -> "Grayscale"}]; 40 | geass = MXNetBoost[DRRN, TargetDevice -> device]; 41 | ColorCombine[nd@geass[ne@#] & /@ ColorSeparate[img]] 42 | ]; 43 | WaifuDRRN2[img_, device_ : "GPU"] := Block[ 44 | {ne, nd, geass}, 45 | If[MissingQ[DRRN2], Return[Missing["NotAvailable"]]]; 46 | ne = NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}]; 47 | nd = NetDecoder[{"Image", ColorSpace -> "Grayscale"}]; 48 | geass = MXNetBoost[DRRN2, TargetDevice -> device]; 49 | ColorCombine[nd@geass[ne@#] & /@ ColorSeparate[img]] 50 | ]; 51 | 52 | (* ::Subchapter:: *) 53 | (*Additional*) 54 | SetAttributes[ 55 | {WaifuSharpen$API}, 56 | {Protected, ReadProtected} 57 | ] 58 | -------------------------------------------------------------------------------- /Packages/WaifuSY/Tang.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Subchapter:: *) 3 | (*Version*) 4 | Version$WaifuSY = "V1.0"; 5 | Updated$WaifuSY = "2018-08-27"; 6 | 7 | 8 | (* ::Subchapter:: *) 9 | (*WaifuTang*) 10 | (* ::Subsubsection:: *) 11 | (*Models*) 12 | Waifu`$TangShiComplex = 10; 13 | Waifu`Models`Tang4::usage = ""; 14 | Waifu`Models`Tang4 := Ready[$Waifus["Tang-4", "Remote"], Echo -> True]; 15 | Waifu`Models`Tang5::usage = ""; 16 | Waifu`Models`Tang5 := Ready[$Waifus["Tang-5", "Remote"], Echo -> True]; 17 | Waifu`Models`Tang7::usage = ""; 18 | Waifu`Models`Tang7 := Ready[$Waifus["Tang-7", "Remote"], Echo -> True]; 19 | 20 | 21 | (* ::Subsubsection:: *) 22 | (*Main*) 23 | WaifuTang$API[l_Integer : 5, len_Integer : 4] := Block[ 24 | { 25 | net, choose, next, one, head, shi 26 | }, 27 | If[Or @@ { 28 | MissingQ[Waifu`Models`Tang4], 29 | MissingQ[Waifu`Models`Tang5], 30 | MissingQ[Waifu`Models`Tang7] 31 | }, 32 | Return[Missing["NotAvailable"]] 33 | ]; 34 | net = NetStateObject@Switch[l, 35 | 7, Waifu`Models`Tang4, 36 | 5, Waifu`Models`Tang5, 37 | _, Waifu`Models`Tang4 38 | ]; 39 | choose[asc_, str_] := Block[ 40 | {keys = Rest@KeyDrop[asc, Append[{",", "。", "?", _}, StringTake[str, -1]]]}, 41 | RandomChoice[Sqrt[Values@keys] -> Keys@keys] 42 | ]; 43 | next[str_] := choose[net[str, {"TopProbabilities", Waifu`$TangShiComplex + 4}], str]; 44 | one[char_] := Nest[StringJoin[#, next[#]]&, Nest[StringJoin[#, next[#]]&, char, l - 1] <> ",", l] <> "。"; 45 | head = choose[net["_", {"TopProbabilities", 10 Waifu`$TangShiComplex + 100}], "_"]; 46 | shi = NestList[one@next[StringTake[#, {-1 - l, -2}] <> ","]&, one@head, len - 1]; 47 | TableForm[Text /@ shi] 48 | ]; 49 | WaifuTang$API[l_Integer : 5, len_String] := Block[ 50 | {net, choose, next, one, shi}, 51 | If[Or @@ { 52 | MissingQ[Waifu`Models`Tang4], 53 | MissingQ[Waifu`Models`Tang5], 54 | MissingQ[Waifu`Models`Tang7] 55 | }, 56 | Return[Missing["NotAvailable"]] 57 | ]; 58 | net = NetStateObject@Switch[l, 59 | 7, Waifu`Models`Tang7, 60 | 5, Waifu`Models`Tang5, 61 | _, Waifu`Models`Tang4 62 | ]; 63 | choose[asc_, str_] := Block[ 64 | {keys = Rest@KeyDrop[asc, Append[{",", "。", "?", _}, StringTake[str, -1]]]}, 65 | RandomChoice[Sqrt[Values@keys] -> Keys@keys] 66 | ]; 67 | next[str_] := choose[net[str, {"TopProbabilities", Waifu`$TangShiComplex + 4}], str]; 68 | one[char_] := Nest[StringJoin[#, next[#]]&, Nest[StringJoin[#, next[#]]&, char, l - 1] <> ",", l] <> "。"; 69 | shi = one /@ Characters@len; 70 | TableForm[Text /@ shi] 71 | ]; 72 | 73 | 74 | (* ::Subsection::Closed:: *) 75 | (*Additional*) 76 | SetAttributes[ 77 | {WaifuTang$API}, 78 | {Protected, ReadProtected} 79 | ] 80 | -------------------------------------------------------------------------------- /Packages/WaifuIR/Denoise.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Subchapter:: *) 3 | (*Version*) 4 | Version$WaifuIR = "V1.0"; 5 | Updated$WaifuIR = "2018-09-11"; 6 | 7 | 8 | (* ::Subchapter:: *) 9 | (*WaifuDenoise*) 10 | (* ::Subsubsection:: *) 11 | (*Models*) 12 | Waifu`Models`DnCNN::usage = ""; 13 | Waifu`Models`DnCNN := Ready[$Waifus["DnCNN-S15", "Remote"]]; 14 | Waifu`Models`DnCNN::usage = ""; 15 | Waifu`Models`DnCNN2 := Ready[$Waifus["DnCNN-S50", "Remote"]]; 16 | Waifu`Models`DnCNN::usage = ""; 17 | Waifu`Models`DnCNN3 := Ready[$Waifus["DnCNN-B", "Remote"]]; 18 | 19 | 20 | (* ::Subsubsection:: *) 21 | (*Main*) 22 | Options[WaifuDenoise$API] = {Method -> "Soft", TargetDevice -> "GPU"}; 23 | WaifuDenoise$API[img_Image, OptionsPattern[]] := Block[ 24 | {catch}, 25 | catch = Switch[OptionValue[Method], 26 | "Soft", WaifuDnCNN[img, OptionValue[TargetDevice]], 27 | "Hard", WaifuDnCNN2[img, OptionValue[TargetDevice]], 28 | _, WaifuDnCNN3[img, OptionValue[TargetDevice]] 29 | ]; 30 | If[ 31 | MissingQ[catch], 32 | Return[Missing["NotAvailable"]], 33 | Return[catch] 34 | ] 35 | ]; 36 | 37 | 38 | (* ::Subsubsection::Closed:: *) 39 | (*DnCNN*) 40 | WaifuDnCNN[img_, device_ : "GPU"] := Block[ 41 | {getN, getNoise, noise}, 42 | If[MissingQ[Waifu`Models`DnCNN], Return[Missing["NotAvailable"]]]; 43 | getN = NetReplacePart[Waifu`Models`DnCNN, { 44 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}], 45 | "Output" -> NetDecoder[{"Image", ColorSpace -> "Grayscale"}] 46 | }]; 47 | getNoise = getN[#, TargetDevice -> device]&; 48 | noise = ColorCombine[getNoise /@ ColorSeparate[img]]; 49 | img - noise 50 | ]; 51 | WaifuDnCNN2[img_, device_ : "GPU"] := Block[ 52 | {getN, getNoise, noise}, 53 | If[MissingQ[Waifu`Models`DnCNN2], Return[Missing["NotAvailable"]]]; 54 | getN = NetReplacePart[Waifu`Models`DnCNN2, { 55 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}], 56 | "Output" -> NetDecoder[{"Image", ColorSpace -> "Grayscale"}] 57 | }]; 58 | getNoise = getN[#, TargetDevice -> device]&; 59 | noise = ColorCombine[getNoise /@ ColorSeparate[img]]; 60 | img - noise 61 | ]; 62 | WaifuDnCNN3[img_, device_ : "GPU"] := Block[ 63 | {getN, getNoise, noise}, 64 | If[MissingQ[Waifu`Models`DnCNN3], Return[Missing["NotAvailable"]]]; 65 | getN = NetReplacePart[Waifu`Models`DnCNN3, { 66 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}], 67 | "Output" -> NetDecoder[{"Image", ColorSpace -> "Grayscale"}] 68 | }]; 69 | getNoise = getN[#, TargetDevice -> device]&; 70 | noise = ColorCombine[getNoise /@ ColorSeparate[img]]; 71 | img - noise 72 | ]; 73 | 74 | 75 | (* ::Subchapter:: *) 76 | (*Additional*) 77 | SetAttributes[ 78 | {WaifuDenoise$API}, 79 | {Protected, ReadProtected} 80 | ] 81 | -------------------------------------------------------------------------------- /Packages/Ready.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Title:: *) 3 | (*Ready!*) 4 | (* ::Subchapter:: *) 5 | (*Package Introduce*) 6 | (* ::Text:: *) 7 | (*Mathematica Package*) 8 | (*Created by Mathematica Plugin for IntelliJ IDEA*) 9 | (*Establish from GalAster's template(v1.3)*) 10 | (**) 11 | (* ::Text:: *) 12 | (*Author:Aster*) 13 | (*Creation Date:2018-09-09*) 14 | (*Copyright: Mozilla Public License Version 2.0*) 15 | (* ::Program:: *) 16 | (*Keep this License, thanks.*) 17 | Ready::offline = "The Wolfram Language is currently configured not to use the Internet. To allow Internet use, check the \"Allow the Wolfram Language to use the Internet\" box in the Help \[FilledRightTriangle] Internet Connectivity dialog."; 18 | Ready::usage = "Ready for File!"; 19 | MXNetBoost::usage = "Speed up by MXNet!"; 20 | (* ::Subsection::Closed:: *) 21 | (*Main*) 22 | Begin["`Ready`"]; 23 | Version$Ready = "V1.2.0"; 24 | Updated$Ready = "2018-09-20"; 25 | (* ::Subsubsection:: *) 26 | (*Functions*) 27 | (*Ready /: Set[x_, Ready[y__]] := SetReady[y, Symbol -> x];*) 28 | (*Ready /: SetDelayed[x_, Ready[y__]] := SetReady[y, Symbol -> x];*) 29 | (*Message[NeuralNetworks`Private`NetModel`head::offline]*) 30 | Options[Ready] = {Format -> True, Echo -> False}; 31 | Ready[url_String, ops : OptionsPattern[]] := Block[ 32 | {fmt, print}, 33 | {fmt, print} = OptionValue[{Format, Echo}]; 34 | If[FileExistsQ@URL2Local[url], Return@CheckImport[Ready[url, ops], URL2Local[url], fmt]]; 35 | SetReadyDownload[url, URL2Local[url], Echo -> print]; 36 | Return@Missing["NotAvailable"] 37 | ]; 38 | Ready[url_String, local_String, ops : OptionsPattern[]] := Block[ 39 | {fmt, print}, 40 | {fmt, print} = OptionValue[{Format, Echo}]; 41 | If[FileExistsQ@local, Return@CheckImport[Ready[url, local, ops], local, fmt]]; 42 | CheckDirectory@local;CheckInternet; 43 | SetReadyDownload[url, local, Echo -> print]; 44 | Return@Missing["NotAvailable"] 45 | ]; 46 | URL2Local[url_String, OptionsPattern[]] := Block[ 47 | {file = Last@StringSplit[url, "/"]}, 48 | FileNameJoin[{$UserBaseDirectory, "ApplicationData", "WaifuX", file}] 49 | ]; 50 | CheckDirectory[dir_] := If[!DirectoryQ@dir, CreateDirectory[dir]]; 51 | CheckInternet := If[ 52 | !PacletManager`$AllowInternet, 53 | Message[Ready::offline]; 54 | Return[$Failed] 55 | ]; 56 | SetAttributes[CheckImport, HoldFirst]; 57 | CheckImport[var_, f_, fmt_] := var = If[TrueQ@fmt, Import[f], Import[f, fmt]]; 58 | Options[SetReadyDownload] = {Echo -> True}; 59 | SetReadyDownload[url_String, local_String, OptionsPattern[]] := Module[ 60 | {manifest}, 61 | manifest = <||>; 62 | downloadStart[manifest][url, local]; 63 | If[TrueQ@OptionValue[Echo], Echo[FileNameTake[local], "Downloading: "]]; 64 | downloadVisualize[manifest] 65 | ]; 66 | SetAttributes[{downloadProgress, downloadFinished, downloadStart, downloadVisualize}, HoldFirst]; 67 | downloadProgress[manifest_][event_] := manifest = <|manifest, event["Task"] -> event|>; 68 | downloadFinished[manifest_][event_] := manifest = {}; 69 | Options[downloadStart] = {Symbol -> Null}; 70 | downloadStart[manifest_][src_String, dest_String, OptionsPattern[]] := URLDownloadSubmit[ 71 | HTTPRequest[src, FollowRedirects -> True], 72 | CreateFile@dest, 73 | HandlerFunctions -> <| 74 | "ConnectionFailed" -> connectionFailed[manifest], 75 | "CookiesReceived" -> cookiesReceived[manifest], 76 | "HeadersReceived" -> headersReceived[manifest], 77 | "TaskFinished" -> downloadFinished[manifest], 78 | "TaskProgress" -> downloadProgress[manifest], 79 | "TaskStatusChanged" -> taskStatusChanged[manifest] 80 | |>, 81 | HandlerFunctionsKeys -> { 82 | "Task", "TaskStatus", "File", 83 | "ByteCountTotal", "ByteCountDownloaded", "FractionComplete" 84 | } 85 | ]; 86 | downloadVisualize[manifest_] := Print@Dynamic@Which[ 87 | manifest === <||>, 88 | GeneralUtilities`ProgressPanel[Style["Checking the connection...", 14]], 89 | 90 | !AssociationQ[manifest], 91 | GeneralUtilities`ProgressPanel[Style["Download Success!", 14]], 92 | 93 | True, 94 | GeneralUtilities`ProgressPanel[ 95 | Style[StringJoin[FileNameTake[#File], " Downloading..."], 14], 96 | StringJoin[ToString /@ { 97 | Floor[#ByteCountTotal / 2^20, 0.001], "MB/", 98 | Floor[#ByteCountDownloaded / 2^20, 0.001], "MB" 99 | }], 100 | #FractionComplete 101 | ]&[First@Values[manifest]] 102 | ]; 103 | (* ::Subsubsection:: *) 104 | (*MXNetBoost*) 105 | Options[MXNetBoost] = {TargetDevice -> "GPU"}; 106 | MXNetBoost[dm_Association, OptionsPattern[]] := Module[ 107 | {exe, device, port}, 108 | device = NeuralNetworks`Private`ParseContext @OptionValue[TargetDevice]; 109 | Function[input, 110 | exe = NeuralNetworks`Private`ToNetExecutor[ 111 | NeuralNetworks`NetPlan[<| 112 | "Symbol" -> MXNetLink`MXSymbolFromJSON@dm["Graph"], 113 | "WeightArrays" -> dm["Weight"], 114 | "FixedArrays" -> dm["Fixed"], 115 | "BatchedArrayDims" -> <|dm["<<"] -> {BatchSize, Sequence @@ Dimensions[input]}|>, 116 | "ZeroArrays" -> {}, 117 | "AuxilliaryArrays" -> dm["Auxilliary"], 118 | "Inputs" -> <|"Input" -> dm["<<"]|>, 119 | "Outputs" -> <|"Output" -> dm[">>"]|>, 120 | "InputStates" -> <||>, 121 | "OutputStates" -> <||>, 122 | "Metrics" -> <||>, 123 | "LogicalWeights" -> <||>, 124 | "ReshapeTemplate" -> None, 125 | "NodeCount" -> dm["nodes"] 126 | |>], 127 | 1, "Context" -> device, "ArrayCaching" -> True 128 | ]; 129 | port = ToExpression@StringDelete[ToString[exe["Arrays", "Inputs", "Input"]], {"NDArray[", "]"}]; 130 | MXNetLink`NDArray`PackagePrivate`mxWritePackedArrayToNDArrayChecked[input, port]; 131 | NeuralNetworks`NetExecutorForward[exe, False]; 132 | exe["Arrays", "Outputs", "Output"] // MXNetLink`NDArrayGetFlat 133 | ] 134 | ]; 135 | (* ::Subsection::Closed:: *) 136 | (*Additional*) 137 | End[]; 138 | SetAttributes[ 139 | {Ready, MXNetBoost}, 140 | {ReadProtected} 141 | ] 142 | -------------------------------------------------------------------------------- /Packages/Directory.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Title:: *) 3 | (*Directories(Directories)*) 4 | (* ::Subchapter:: *) 5 | (*程序包介绍*) 6 | (* ::Text:: *) 7 | (*Mathematica Package*) 8 | (*Created by Mathematica Plugin for IntelliJ IDEA*) 9 | (*Establish from GalAster's template(v1.3)*) 10 | (**) 11 | (* ::Text:: *) 12 | (*Author:Aster*) 13 | (*Creation Date:2018-08-21*) 14 | (*Copyright: Mozilla Public License Version 2.0*) 15 | (* ::Program:: *) 16 | (*1.软件产品再发布时包含一份原始许可声明和版权声明。*) 17 | (*2.提供快速的专利授权。*) 18 | (*3.不得使用其原始商标。*) 19 | (*4.如果修改了源代码,包含一份代码修改说明。*) 20 | (**) 21 | (* ::Text:: *) 22 | (*这里应该填这个函数的介绍*) 23 | (* ::Section:: *) 24 | (*函数说明*) 25 | $WaifuDirectory::usage = "WaifuX 的安装路径."; 26 | $WaifuData::usage = "WaifuX 的数据存放位置."; 27 | $Waifus::usage = "WaifuX 的远程资源映射表"; 28 | (* ::Section:: *) 29 | (*程序包正体*) 30 | (* ::Subsection::Closed:: *) 31 | (*主设置*) 32 | Begin["`Directories`"]; 33 | (* ::Subsection::Closed:: *) 34 | (*主体代码*) 35 | Version$Directories = "V1.3"; 36 | Updated$Directories = "2018-09-11"; 37 | (* ::Subsubsection:: *) 38 | (*功能块 1*) 39 | $WaifuDirectory = DirectoryName[FindFile["Waifu`Kernel`"], 2]; 40 | $WaifuData = FileNameJoin[{$UserBaseDirectory, "ApplicationData", "WaifuX"}]; 41 | (*If[ 42 | MissingQ[var = Ready[$Waifus[name, "Remote"], $Waifus[name, "Local"]]], 43 | Return[Missing[NotAvailable]] 44 | ];*) 45 | UrlSR = Hyperlink["WaifuSR", "https://github.com/Moe-Net/Waifu-SR"]; 46 | UrlIR = Hyperlink["WaifuIR", "https://github.com/Moe-Net/Waifu-IR"]; 47 | UrlCU = Hyperlink["WaifuSY", "https://github.com/Moe-Net/Waifu-CU"]; 48 | UrlSY = Hyperlink["WaifuSY", "https://github.com/Moe-Net/Waifu-SY"]; 49 | $Waifus = <| 50 | "VGGSR" -> <| 51 | "Project" -> UrlSR, 52 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-VGGSR.WMLF", 53 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-VGGSR.WMLF"}] 54 | |>, 55 | "VDSR" -> <| 56 | "Project" -> UrlSR, 57 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-VDSR.WMLF", 58 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-VDSR.WMLF"}] 59 | |>, 60 | "LapSRN2x" -> <| 61 | "Project" -> UrlSR, 62 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-LapSRN2x.WMLF", 63 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-LapSRN2x.WMLF"}] 64 | |>, 65 | "LapSRN4x" -> <| 66 | "Project" -> UrlSR, 67 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-LapSRN4x.WMLF", 68 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-LapSRN4x.WMLF"}] 69 | |>, 70 | "SESR" -> <| 71 | "Project" -> UrlSR, 72 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-SESR.WMLF", 73 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-SESR.WMLF"}] 74 | |>, 75 | "ByNet9" -> <| 76 | "Project" -> UrlSR, 77 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-ByNet9.WMLF", 78 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-ByNet9.WMLF"}] 79 | |>, 80 | "RED30-SR" -> <| 81 | "Project" -> UrlSR, 82 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-RED30.WMLF", 83 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-RED30.WMLF"}] 84 | |>, 85 | "SRResNet2x" -> <| 86 | "Project" -> UrlSR, 87 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-SRResNet2x.WXF", 88 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-SRResNet2x.WXF"}] 89 | |>, 90 | "SRResNet3x" -> <| 91 | "Project" -> UrlSR, 92 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-SRResNet3x.WXF", 93 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-SRResNet2x.WXF"}] 94 | |>, 95 | "SRResNet4x" -> <| 96 | "Project" -> UrlSR, 97 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-SRResNet4x.WXF", 98 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-SRResNet2x.WXF"}] 99 | |>, 100 | "SRResNet8x" -> <| 101 | "Project" -> UrlSR, 102 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-SRResNet8x.WXF", 103 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-SRResNet2x.WXF"}] 104 | |>, 105 | 106 | 107 | 108 | "DnCNN-S15" -> <| 109 | "Project" -> UrlIR, 110 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-DnCNN-S15.WMLF", 111 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-DnCNN-S15.WMLF"}] 112 | |>, 113 | "DnCNN-S50" -> <| 114 | "Project" -> UrlIR, 115 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-DnCNN-S50.WMLF", 116 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-DnCNN-S50.WMLF"}] 117 | |>, 118 | "DnCNN-B" -> <| 119 | "Project" -> UrlIR, 120 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-DnCNN-B.WMLF", 121 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-DnCNN-B.WMLF"}] 122 | |>, 123 | "DRRN9" -> <| 124 | "Project" -> UrlIR, 125 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-DRRN9.WXF", 126 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-DRRN9.WXF"}] 127 | |>, 128 | "DRRN25" -> <| 129 | "Project" -> UrlIR, 130 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-DRRN25.WXF", 131 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-DRRN25.WXF"}] 132 | |>, 133 | 134 | 135 | 136 | "Resnet50" -> <| 137 | "Project" -> UrlCU, 138 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-Resnet50.WMLF", 139 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-Resnet50.WMLF"}] 140 | |>, 141 | 142 | 143 | 144 | "Tang-4" -> <| 145 | "Project" -> UrlSY, 146 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-Tang-4.WMLF", 147 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-Tang-4.WMLF"}] 148 | |>, 149 | "Tang-5" -> <| 150 | "Project" -> UrlSY, 151 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-Tang-5.WMLF", 152 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-Tang-5.WMLF"}] 153 | |>, 154 | "Tang-7" -> <| 155 | "Project" -> UrlSY, 156 | "Remote" -> "https://m.vers.site/Resources/WaifuX/Waifu-Tang-7.WMLF", 157 | "Local" -> FileNameJoin[{$WaifuData, "Waifu-Tang-7.WMLF"}] 158 | |> 159 | |>; 160 | (* ::Subsection::Closed:: *) 161 | (*附加设置*) 162 | SetAttributes[ 163 | {$Waifus}, 164 | {ReadProtected} 165 | ]; 166 | End[] 167 | -------------------------------------------------------------------------------- /Packages/WaifuSR/Resize.m: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | (* ::Subchapter:: *) 3 | (*WaifuSR*) 4 | (* ::Text:: *) 5 | (*$Updated = "2018-09-19";*) 6 | 7 | 8 | (* ::Subsubsection:: *) 9 | (*Models*) 10 | Waifu`Models`LapSRN := Ready[$Waifus["LapSRN2x", "Remote"]]; 11 | Waifu`Models`LapSRN2 := Ready[$Waifus["LapSRN4x", "Remote"]]; 12 | Waifu`Models`RED30 := Ready[$Waifus["RED30-SR", "Remote"]]; 13 | Waifu`Models`VDSR := Ready[$Waifus["VDSR", "Remote"]]; 14 | Waifu`Models`SESR := Ready[$Waifus["SESR", "Remote"]]; 15 | Waifu`Models`VGGSR := Ready[$Waifus["VGGSR", "Remote"]]; 16 | Waifu`Models`ByNet := Ready[$Waifus["ByNet9", "Remote"]]; 17 | SRResNet := Ready[$Waifus["SRResNet2x", "Remote"]]; 18 | SRResNet2 := Ready[$Waifus["SRResNet3x", "Remote"]]; 19 | SRResNet3 := Ready[$Waifus["SRResNet4x", "Remote"]]; 20 | SRResNet4 := Ready[$Waifus["SRResNet8x", "Remote"]]; 21 | 22 | 23 | (* ::Subsubsection:: *) 24 | (*Main*) 25 | rgbMatrix = {{0.257, 0.504, 0.098}, {-0.148, -0.291, 0.439}, {0.439, -0.368, -0.071}}; 26 | rgbMatrixT = {{1.164, 0., 1.596}, {1.164, -0.392, -0.813}, {1.164, 2.017, 0.}}; 27 | Options[WaifuSR$API] = {TargetDevice -> "GPU"}; 28 | WaifuSR$API[___] := True; 29 | WaifuSR$API[i_Image, zoom_ : 2, OptionsPattern[]] := Block[ 30 | { 31 | device = OptionValue[TargetDevice], 32 | img = ColorConvert[RemoveAlphaChannel@i, "RGB"], 33 | catch 34 | }, 35 | catch = Which[ 36 | zoom == 1, Waifu`WaifuSharpen[img, device], 37 | 1 < zoom <= 2, WaifuLapSRN[img, device], 38 | 2 < zoom <= 4, WaifuLapSRN2[img, device], 39 | True, img 40 | ]; 41 | If[ 42 | MissingQ[catch], 43 | Return[Missing["NotAvailable"]] 44 | ]; 45 | Which[ 46 | zoom == 1, catch, 47 | 1 < zoom <= 2, ImageResize[catch, zoom ImageDimensions[i]], 48 | zoom == 2, catch, 49 | 2 < zoom <= 4, ImageResize[catch, zoom ImageDimensions[i]], 50 | zoom == 4, catch, 51 | True, Return[$Failed] 52 | ] 53 | ]; 54 | 55 | 56 | (* ::Subsubsection::Closed:: *) 57 | (*Traditional*) 58 | WaifuNearset[img_, zoom_] := ImageResize[img, Scaled[zoom], Resampling -> "Nearest"] ; 59 | WaifuLinear[img_, zoom_] := ImageResize[img, Scaled[zoom], Resampling -> "Linear"] ; 60 | WaifuCubic[img_, zoom_] := ImageResize[img, Scaled[zoom], Resampling -> "Cubic"] ; 61 | WaifuOMOMS[img_, zoom_] := ImageResize[img, Scaled[zoom], Resampling -> {"OMOMS", 7}] ; 62 | 63 | 64 | (* ::Subsubsection::Closed:: *) 65 | (*LapSRN*) 66 | WaifuLapSRN[img_, device_ : "GPU"] := Block[ 67 | {render}, 68 | If[MissingQ[Waifu`Models`LapSRN], Return[Missing["NotAvailable"]]]; 69 | render[channel_] := Image[NetReplacePart[Waifu`Models`LapSRN, { 70 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}] 71 | }][channel, TargetDevice -> device]]; 72 | ColorCombine[render /@ ColorSeparate[img]] 73 | ]; 74 | WaifuLapSRN2[img_, device_ : "GPU"] := Block[ 75 | {render}, 76 | If[MissingQ[Waifu`Models`LapSRN2], Return[Missing["NotAvailable"]]]; 77 | render[channel_] := Image[NetReplacePart[Waifu`Models`LapSRN2, { 78 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}] 79 | }][channel, TargetDevice -> device]]; 80 | ColorCombine[render /@ ColorSeparate[img]] 81 | ]; 82 | 83 | 84 | (* ::Subsubsection::Closed:: *) 85 | (*RED30*) 86 | WaifuRED30[img_, zoom_ : 2, device_ : "GPU"] := Block[ 87 | {upsample, ycbcr, channels, netResize, adjust}, 88 | If[MissingQ[Waifu`Models`RED30], Return[Missing["NotAvailable"]]]; 89 | upsample = ImageResize[img, Scaled[zoom], Resampling -> "Cubic"]; 90 | ycbcr = ImageApply[rgbMatrix.# + {0.063, 0.502, 0.502}&, upsample]; 91 | netResize = NetReplacePart[Waifu`Models`RED30, 92 | "Input" -> NetEncoder[{"Image", ImageDimensions@upsample, ColorSpace -> "Grayscale"}] 93 | ]; 94 | adjust = ColorCombine[{#1 + Image@netResize[#1, TargetDevice -> device], #2, #3}]&; 95 | ImageApply[rgbMatrixT.# + {-0.874, 0.532, -1.086}&, adjust @@ ColorSeparate[ycbcr]] 96 | ]; 97 | 98 | 99 | 100 | (* ::Subsubsection::Closed:: *) 101 | (*VDSR*) 102 | WaifuVDSR[img_, zoom_ : 2, device_ : "GPU"] := Block[ 103 | {upsample, ycbcr, channels, netResize, adjust}, 104 | If[MissingQ[Waifu`Models`VDSR], Return[Missing["NotAvailable"]]]; 105 | upsample = ImageResize[img, Scaled[zoom], Resampling -> "Cubic"]; 106 | ycbcr = ImageApply[rgbMatrix.# + {0.063, 0.502, 0.502}&, upsample]; 107 | netResize = NetReplacePart[Waifu`Models`VDSR, 108 | "Input" -> NetEncoder[{"Image", ImageDimensions@upsample, ColorSpace -> "Grayscale"}] 109 | ]; 110 | adjust = ColorCombine[{#1 + Image@netResize[#1, TargetDevice -> device], #2, #3}]&; 111 | ImageApply[rgbMatrixT.# + {-0.874, 0.532, -1.086}&, adjust @@ ColorSeparate[ycbcr]] 112 | ]; 113 | 114 | 115 | 116 | (* ::Subsubsection::Closed:: *) 117 | (*ByNet+*) 118 | WaifuByNet[img_, zoom_ : 2, device_ : "GPU"] := Block[ 119 | {upsample, ycbcr, channels, netResize, adjust}, 120 | If[MissingQ[Waifu`Models`ByNet], Return[Missing["NotAvailable"]]]; 121 | upsample = ImageResize[img, Scaled[zoom], Resampling -> "Cubic"]; 122 | ycbcr = ImageApply[rgbMatrix.# + {0.063, 0.502, 0.502}&, upsample]; 123 | netResize = NetReplacePart[Waifu`Models`ByNet, 124 | "Input" -> NetEncoder[{"Image", ImageDimensions@upsample, ColorSpace -> "Grayscale"}] 125 | ]; 126 | adjust = ColorCombine[{#1 + Image@netResize[#1, TargetDevice -> device], #2, #3}]&; 127 | ImageApply[rgbMatrixT.# + {-0.874, 0.532, -1.086}&, adjust @@ ColorSeparate[ycbcr]] 128 | ]; 129 | 130 | 131 | 132 | (* ::Subsubsection::Closed:: *) 133 | (*VGGSR*) 134 | WaifuVGGSR[img_, device_ : "GPU"] := Module[ 135 | {covImg, covNet, x, y}, 136 | If[MissingQ[Waifu`Models`VGGSR], Return[Missing["NotAvailable"]]]; 137 | {x, y} = ImageDimensions[img]; 138 | covImg = ColorCombine[Reverse@ColorSeparate[ImageResize[img, {x + 14, y + 14}]]]; 139 | covNet = NetReplacePart[Waifu`Models`VGGSR, "Input" -> NetEncoder[{"Image", ImageDimensions@covImg}]]; 140 | covNet[covImg, TargetDevice -> device] 141 | ]; 142 | 143 | 144 | 145 | (* ::Subsubsection::Closed:: *) 146 | (*SESR*) 147 | WaifuSESR[img_, device_ : "GPU"] := Block[ 148 | {upsample, ycbcr, netResize, adjust}, 149 | If[MissingQ[Waifu`Models`SESR], Return[Missing["NotAvailable"]]]; 150 | upsample = ImageResize[img, Scaled[2], Resampling -> "Cubic"]; 151 | ycbcr = ImageApply[rgbMatrix.# + {0.063, 0.502, 0.502}&, upsample]; 152 | netResize = NetReplacePart[Waifu`Models`SESR, { 153 | "Input" -> NetEncoder[{"Image", ImageDimensions@img, ColorSpace -> "Grayscale"}] 154 | }]; 155 | adjust = ColorCombine[{Image@netResize[#1, TargetDevice -> device], #2, #3}]&; 156 | ImageApply[rgbMatrixT.# + {-0.874, 0.532, -1.086}&, adjust @@ ColorSeparate[ycbcr]] 157 | ]; 158 | 159 | 160 | (* ::Subsubsection::Closed:: *) 161 | (*SRResNet*) 162 | WaifuSRResNet[img_, device_ : "GPU"] := Block[ 163 | {ne, nd, geass}, 164 | If[MissingQ[SRResNet], Return@Missing["NotAvailable"]]; 165 | ne = NetEncoder[{"Image", Ceiling@ImageDimensions[img]}]; 166 | nd = NetDecoder[{"Image"}]; 167 | GeassSRResNet := MXNetBoost[SRResNet, TargetDevice -> device]; 168 | nd@GeassSRResNet[ne@img] 169 | ]; 170 | WaifuSRResNet2[img_, device_ : "GPU"] := Block[ 171 | {ne, nd, geass}, 172 | If[MissingQ[SRResNet2], Return@Missing["NotAvailable"]]; 173 | ne = NetEncoder[{"Image", Ceiling@ImageDimensions[img]}]; 174 | nd = NetDecoder[{"Image"}]; 175 | GeassSRResNet2 := MXNetBoost[SRResNet2, TargetDevice -> device]; 176 | nd@GeassSRResNet2[ne@img] 177 | ]; 178 | WaifuSRResNet3[img_, device_ : "GPU"] := Block[ 179 | {ne, nd, geass}, 180 | If[MissingQ[SRResNet3], Return@Missing["NotAvailable"]]; 181 | ne = NetEncoder[{"Image", Ceiling@ImageDimensions[img]}]; 182 | nd = NetDecoder[{"Image"}]; 183 | GeassSRResNet3 := MXNetBoost[SRResNet3, TargetDevice -> device]; 184 | nd@GeassSRResNet3[ne@img] 185 | ]; 186 | WaifuSRResNet4[img_, device_ : "GPU"] := Block[ 187 | {ne, nd, geass}, 188 | If[MissingQ[SRResNet4], Return@Missing["NotAvailable"]]; 189 | ne = NetEncoder[{"Image", Ceiling@ImageDimensions[img]}]; 190 | nd = NetDecoder[{"Image"}]; 191 | GeassSRResNet3 := MXNetBoost[SRResNet3, TargetDevice -> device]; 192 | nd@GeassSRResNet3[ne@img] 193 | ]; 194 | 195 | 196 | (* ::Subsection::Closed:: *) 197 | (*Additional*) 198 | SetAttributes[ 199 | {WaifuSR$API}, 200 | {Protected, ReadProtected} 201 | ] 202 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- /WaifuLoader.m: -------------------------------------------------------------------------------- 1 | (* ::Title:: *) 2 | (*Waifu`*) 3 | 4 | 5 | (* ::Text::GrayLevel[0.5]:: *) 6 | (* Autogenerated Waifu loader file *) 7 | 8 | 9 | Unprotect[Waifu`PackageScope`Private`$TopLevelLoad]; 10 | Waifu`PackageScope`Private`$TopLevelLoad = MemberQ[$ContextPath, "Global`"]; 11 | 12 | 13 | BeginPackage["Waifu`"]; 14 | 15 | 16 | ClearAll[Waifu]; 17 | Waifu::usage = "Waifu is a manager head for the Waifu package"; 18 | 19 | 20 | (* ::Subsubsection::Closed:: *) 21 | (*$ContextPath*) 22 | 23 | 24 | System`Private`NewContextPath@ 25 | Join[ 26 | $ContextPath, 27 | "Waifu`" <> 28 | StringReplace[ 29 | FileNameDrop[#, FileNameDepth@DirectoryName@$InputFileName], 30 | $PathnameSeparator -> "`" 31 | ]& /@ 32 | Select[ 33 | DirectoryQ@# && 34 | StringMatchQ[ 35 | StringReplace[ 36 | FileNameDrop[#, FileNameDepth@DirectoryName@$InputFileName], 37 | $PathnameSeparator -> "`" 38 | ], 39 | ("$" | WordCharacter).. 40 | ] 41 | &]@ 42 | FileNames["*", 43 | FileNameJoin@{ 44 | DirectoryName@$InputFileName, 45 | "Packages" 46 | }, 47 | Infinity 48 | ] 49 | ] 50 | 51 | 52 | (* ::Section:: *) 53 | (* Package Functions *) 54 | 55 | 56 | Unprotect["`PackageScope`Private`*"]; 57 | Begin["`PackageScope`Private`"]; 58 | AppendTo[$ContextPath, $Context]; 59 | 60 | 61 | (* ::Subsection:: *) 62 | (*Constants*) 63 | 64 | 65 | $PackageDirectory::usage = ""; 66 | $PackageName::usage = ""; 67 | $PackageListing::usage = "The listing of packages"; 68 | $PackagePackagesDirectory::usage = "The directory to look for packages under"; 69 | $PackageContexts::usage = "The list of contexts exposed to all packages"; 70 | $PackageDeclared::usage = "Whether the package has been auto-loaded or not"; 71 | $PackageFEHiddenSymbols::usage = ""; 72 | $PackageScopedSymbols::usage = ""; 73 | $PackageLoadSpecs::usage = ""; 74 | $AllowPackageSymbolDefinitions::usage = ""; 75 | $AllowPackageRescoping::usage = ""; 76 | $AllowPackageRecoloring::usage = ""; 77 | $AllowPackageAutocompletions::usage = ""; 78 | 79 | 80 | (* ::Subsubsection::Closed:: *) 81 | (*Begin*) 82 | 83 | 84 | Begin["`Constants`"]; 85 | 86 | 87 | (* ::Subsubsection::Closed:: *) 88 | (*Naming*) 89 | 90 | 91 | Waifu["Directory"] := 92 | $PackageDirectory; 93 | $PackageDirectory = 94 | DirectoryName@$InputFileName; 95 | 96 | 97 | Waifu["Name"] := 98 | $PackageName; 99 | $PackageName = 100 | "Waifu"; 101 | 102 | 103 | (* ::Subsubsection::Closed:: *) 104 | (*Load Specs*) 105 | 106 | 107 | Waifu["LoadingParameters"] := $PackageLoadSpecs 108 | $PackageLoadSpecs = 109 | Merge[ 110 | { 111 | With[ 112 | { 113 | f = 114 | Append[ 115 | FileNames[ 116 | "LoadInfo." ~~ "m" | "wl", 117 | FileNameJoin@{$PackageDirectory, "Config"} 118 | ], 119 | None 120 | ][[1]] 121 | }, 122 | Replace[ 123 | Quiet[ 124 | Import@f, 125 | { 126 | Import::nffil, 127 | Import::chtype 128 | } 129 | ], 130 | Except[KeyValuePattern[{}]] :> 131 | {} 132 | ] 133 | ], 134 | With[ 135 | { 136 | f = 137 | Append[ 138 | FileNames[ 139 | "LoadInfo." ~~ "m" | "wl", 140 | FileNameJoin@{$PackageDirectory, "Private", "Config"} 141 | ], 142 | None 143 | ][[1]]}, 144 | Replace[ 145 | Quiet[ 146 | Import@f, 147 | { 148 | Import::nffil, 149 | Import::chtype 150 | } 151 | ], 152 | Except[KeyValuePattern[{}]] :> 153 | {} 154 | ] 155 | ] 156 | }, 157 | Last 158 | ]; 159 | 160 | 161 | (* ::Subsubsection::Closed:: *) 162 | (*Loading*) 163 | 164 | 165 | Waifu["PackageListing"] := $PackageListing; 166 | $PackageListing = <||>; 167 | Waifu["Contexts"] := $PackageContexts; 168 | If[!ListQ@$PackageContexts, 169 | $PackageContexts = 170 | { 171 | "Waifu`", 172 | "Waifu`PackageScope`Private`", 173 | "Waifu`PackageScope`Package`" 174 | } 175 | ]; 176 | $PackageDeclared = 177 | TrueQ[$PackageDeclared]; 178 | 179 | 180 | $PackagePackagesDirectory = 181 | Replace[ 182 | Lookup[$PackageLoadSpecs, "PackagesDirectory"], 183 | Except[s_String?(Directory@FileNameJoin@{$PackageDirectory, #}&)] -> "Packages" 184 | ] 185 | 186 | 187 | (* ::Subsubsection::Closed:: *) 188 | (*Scoping*) 189 | 190 | 191 | Waifu["FEScopedSymbols"] := $PackageFEHiddenSymbols; 192 | $PackageFEHiddenSymbols = {}; 193 | Waifu["PackageScopedSymbols"] := $PackageScopedSymbols; 194 | $PackageScopedSymbols = {}; 195 | 196 | 197 | (* ::Subsubsection::Closed:: *) 198 | (*Allow flags*) 199 | 200 | 201 | $AllowPackageSymbolDefinitions = 202 | Replace[ 203 | Lookup[$PackageLoadSpecs, "PackageSymbolDefinitions"], 204 | Except[True | False | None] -> True 205 | ]; 206 | Waifu["AllowRescoping"] := $AllowPackageRescoping; 207 | $AllowPackageRescoping = 208 | Replace[ 209 | Lookup[$PackageLoadSpecs, "AllowRescoping"], 210 | Except[True | False] -> $TopLevelLoad 211 | ]; 212 | Waifu["AllowRecoloring"] := $AllowPackageRecoloring; 213 | $AllowPackageRecoloring = 214 | Replace[ 215 | Lookup[$PackageLoadSpecs, "AllowRecoloring"], 216 | Except[True | False] -> $TopLevelLoad 217 | ]; 218 | Waifu["AllowAutocompletions"] := $AllowPackageAutocompletions; 219 | $AllowPackageAutocompletions = 220 | Replace[ 221 | Lookup[$PackageLoadSpecs, "AllowAutocompletions"], 222 | Except[True | False] -> $TopLevelLoad 223 | ]; 224 | 225 | 226 | (* ::Subsubsection::Closed:: *) 227 | (*End*) 228 | 229 | 230 | End[] 231 | (* ::Subsection:: *) 232 | (*Paths*) 233 | 234 | 235 | PackageFilePath::usage = ""; 236 | PackageFEFile::usage = ""; 237 | 238 | 239 | (* ::Subsubsection::Closed:: *) 240 | (*Begin*) 241 | 242 | 243 | Begin["`Paths`"] 244 | 245 | 246 | (* ::Subsubsection::Closed:: *) 247 | (*PackageFilePath*) 248 | 249 | 250 | PackageFilePath[p__] := 251 | FileNameJoin[Flatten@{ 252 | $PackageDirectory, 253 | p 254 | }]; 255 | 256 | 257 | (* ::Subsubsection::Closed:: *) 258 | (*PackageFEFile*) 259 | 260 | 261 | PackageFEFile[p___, f_] := 262 | FrontEnd`FileName[ 263 | Evaluate@ 264 | Flatten@{ 265 | $PackageName, 266 | p 267 | }, 268 | f 269 | ]; 270 | 271 | 272 | (* ::Subsubsection::Closed:: *) 273 | (*PackagePathSymbol*) 274 | 275 | 276 | PackagePathSymbol[parts___String, sym_String] := 277 | ToExpression[StringRiffle[{$PackageName, parts, sym}, "`"], StandardForm, HoldPattern]; 278 | PackagePathSymbol[parts___String, sym_Symbol] := 279 | PackagePathSymbol[parts, Evaluate@SymbolName@Unevaluated[sym]]; 280 | PackagePathSymbol ~ SetAttributes ~ HoldRest; 281 | 282 | 283 | (* ::Subsubsection::Closed:: *) 284 | (*End*) 285 | 286 | 287 | End[] 288 | (* ::Subsection:: *) 289 | (*Loading*) 290 | 291 | 292 | $PackageFileContexts::usage = "The contexts for files in the package"; 293 | $DeclaredPackages::usage = "The set of packages found and declared via the autoloader"; 294 | $LoadedPackages::usage = "The set of loaded packages"; 295 | 296 | 297 | PackageExecute::usage = "Executes something with the package contexts exposed"; 298 | PackageLoadPackage::usage = "Loads a package via PackageExecute"; 299 | PackageLoadDeclare::usage = "Declares a package"; 300 | 301 | 302 | PackageAppLoad::usage = ""; 303 | PackageAppGet::usage = ""; 304 | PackageAppNeeds::usage = ""; 305 | 306 | 307 | PackageScopeBlock::usage = ""; 308 | PackageFERehideSymbols::usage = "Predeclared here..."; 309 | PackageDecontext::usage = ""; 310 | PackageRecontext::usage = ""; 311 | 312 | 313 | (* ::Subsubsection::Closed:: *) 314 | (*Begin*) 315 | 316 | 317 | Begin["`Loading`"] 318 | 319 | 320 | (* ::Subsubsection::Closed:: *) 321 | (*Constants*) 322 | 323 | 324 | Waifu["FileContexts"] := $PackageFileContexts; 325 | If[Not@AssociationQ@$PackageFileContexts, 326 | $PackageFileContexts = 327 | <||> 328 | ]; 329 | 330 | 331 | Waifu["DeclaredPackages"] := $DeclaredPackages; 332 | If[Not@AssociationQ@$DeclaredPackages, 333 | $DeclaredPackages = 334 | <||> 335 | ]; 336 | 337 | 338 | Waifu["LoadedPackages"] := $LoadedPackages; 339 | If[Not@ListQ@$LoadedPackages, 340 | $LoadedPackages = {} 341 | ]; 342 | 343 | 344 | (* ::Subsubsection::Closed:: *) 345 | (*PackageFileContext*) 346 | 347 | 348 | PackageFileContextPath[f_String?DirectoryQ] := 349 | FileNameSplit[FileNameDrop[f, FileNameDepth[$PackageDirectory] + 1]]; 350 | PackageFileContextPath[f_String?FileExistsQ] := 351 | PackageFileContextPath[DirectoryName@f]; 352 | 353 | 354 | PackageFileContext[f_String?DirectoryQ] := 355 | With[{s = PackageFileContextPath[f]}, 356 | StringRiffle[Append[""]@Prepend[s, Waifu], "`"] 357 | ]; 358 | PackageFileContext[f_String?FileExistsQ] := 359 | PackageFileContext[DirectoryName[f]]; 360 | 361 | 362 | (* ::Subsubsection::Closed:: *) 363 | (*PackageExecute*) 364 | 365 | 366 | PackageExecute[expr_] := 367 | Internal`WithLocalSettings[ 368 | Begin[$PackageContexts[[1]]]; 369 | System`Private`NewContextPath@ 370 | Prepend[ 371 | $PackageContexts, 372 | "System`" 373 | ];, 374 | expr, 375 | System`Private`RestoreContextPath[]; 376 | End[]; 377 | ]; 378 | PackageExecute ~ SetAttributes ~ HoldFirst 379 | 380 | 381 | (* ::Subsubsection::Closed:: *) 382 | (*PackagePullDeclarations*) 383 | 384 | 385 | PackagePullDeclarationsAction // Clear 386 | PackagePullDeclarationsAction[ 387 | Hold[ 388 | _Begin | _BeginPackage | 389 | CompoundExpression[_Begin | _BeginPackage, ___] 390 | ] 391 | ] := 392 | Throw[Begin]; 393 | PackagePullDeclarationsAction[ 394 | p : 395 | Hold[ 396 | _PackageFEHiddenBlock | _PackageScopeBlock | 397 | CompoundExpression[ 398 | _PackageFEHiddenBlock | _PackageScopeBlock, 399 | ___] 400 | ] 401 | ] /; TrueQ[$AllowPackageRescoping] := 402 | ( 403 | ReleaseHold[p]; 404 | Sow[p]; 405 | ); 406 | PackagePullDeclarationsAction[e : Except[Hold[Expression]]] := 407 | Sow@e; 408 | 409 | 410 | PackagePullDeclarations[pkgFile_] := 411 | pkgFile -> 412 | Cases[ 413 | Reap[ 414 | With[{f = OpenRead[pkgFile]}, 415 | Catch@ 416 | Do[ 417 | If[ 418 | Length[ 419 | ReadList[ 420 | f, 421 | PackagePullDeclarationsAction@Hold[Expression], 422 | 1 423 | ] 424 | ] === 0, 425 | Throw[EndOfFile] 426 | ], 427 | Infinity 428 | ]; 429 | Close[f] 430 | ] 431 | ][[2, 1]], 432 | s_Symbol?( 433 | Function[Null, 434 | Quiet[Context[#] === $Context], 435 | HoldAllComplete 436 | ] 437 | ) :> 438 | HoldPattern[s], 439 | Infinity 440 | ] 441 | 442 | 443 | (* ::Subsubsection::Closed:: *) 444 | (*PackageLoadPackage*) 445 | 446 | 447 | PackageLoadPackage[heldSym_, context_, pkgFile_ -> syms_] := 448 | Block[{ 449 | $loadingChain = 450 | If[ListQ@$loadingChain, $loadingChain, {}], 451 | $inLoad = TrueQ[$inLoad] 452 | }, 453 | Internal`WithLocalSettings[ 454 | System`Private`NewContextPath@$ContextPath, 455 | If[!MemberQ[$loadingChain, pkgFile], 456 | AppendTo[$loadingChain, pkgFile]; 457 | With[{$$inLoad = $inLoad}, 458 | $inLoad = True; 459 | If[$AllowPackageRecoloring, 460 | Internal`SymbolList[False] 461 | ]; 462 | Replace[Thread[syms, HoldPattern], 463 | Verbatim[HoldPattern][{s__}] :> Clear[s] 464 | ]; 465 | If[Not@MemberQ[$ContextPath, context], 466 | $ContextPath = Prepend[$ContextPath, context]; 467 | ]; 468 | Block[{PackageFEHiddenBlock = Null}, 469 | PackageAppGet[context, pkgFile]; 470 | ]; 471 | Unprotect[$LoadedPackages]; 472 | AppendTo[$LoadedPackages, pkgFile]; 473 | Protect[$LoadedPackages]; 474 | If[!$$inLoad && $AllowPackageRecoloring, 475 | Internal`SymbolList[True] 476 | ]; 477 | ReleaseHold[heldSym] 478 | ] 479 | ], 480 | System`Private`RestoreContextPath[] 481 | ] 482 | ]; 483 | 484 | 485 | (* ::Subsubsection::Closed:: *) 486 | (*PackageDeclarePackage*) 487 | 488 | 489 | PackageDeclarePackage[pkgFile_ -> syms_] := 490 | With[{c = $Context}, 491 | $DeclaredPackages[pkgFile] = syms; 492 | $PackageFileContexts[pkgFile] = c; 493 | Map[ 494 | If[True, 495 | # := PackageLoadPackage[#, c, pkgFile -> syms] 496 | ]&, 497 | syms 498 | ] 499 | ]; 500 | 501 | 502 | (* ::Subsubsection::Closed:: *) 503 | (*PackageLoadDeclare*) 504 | 505 | 506 | PackageLoadDeclare[pkgFile_String] := 507 | If[!MemberQ[$LoadedPackages, pkgFile], 508 | If[!KeyMemberQ[$DeclaredPackages, pkgFile], 509 | PackageDeclarePackage@ 510 | PackagePullDeclarations[pkgFile] 511 | ], 512 | PackageAppGet[pkgFile] 513 | ]; 514 | 515 | 516 | (* ::Subsubsection::Closed:: *) 517 | (*PackageAppLoad*) 518 | 519 | 520 | Waifu["Load", args___] := 521 | PackageAppLoad[args] 522 | 523 | 524 | packageAppLoad[dir_, listing_] := 525 | With[ 526 | { 527 | fileNames = 528 | Select[ 529 | FileNames["*", dir], 530 | DirectoryQ@# || MatchQ[FileExtension[#], "m" | "wl"]& 531 | ] 532 | }, 533 | Replace[ 534 | Select[fileNames, 535 | StringMatchQ[ 536 | ToLowerCase@FileNameTake[#], 537 | "__pre__." ~~ ("m" | "wl") 538 | ]& 539 | ], 540 | {f_} :> Get[f] 541 | ]; 542 | PackageAppLoad[ 543 | $PackageListing[listing] = 544 | Select[fileNames, StringFreeQ["__"]@*FileBaseName] 545 | ]; 546 | Replace[ 547 | Select[fileNames, 548 | StringMatchQ[ 549 | ToLowerCase@FileNameTake[#], 550 | "__post__." ~~ ("m" | "wl") 551 | ]& 552 | ], 553 | {f_} :> Get[f] 554 | ]; 555 | ]; 556 | 557 | 558 | PackageAppLoad[dir_String?DirectoryQ] := 559 | If[StringMatchQ[FileBaseName@dir, (WordCharacter | "$")..], 560 | Internal`WithLocalSettings[ 561 | Begin["`" <> FileBaseName[dir] <> "`"], 562 | AppendTo[$PackageContexts, $Context]; 563 | packageAppLoad[dir, FileNameDrop[dir, FileNameDepth[$PackageDirectory] + 1]], 564 | End[]; 565 | ] 566 | ]; 567 | PackageAppLoad[file_String?FileExistsQ] := 568 | PackageLoadDeclare[file]; 569 | PackageAppLoad[] := 570 | PackageExecute@ 571 | packageAppLoad[ 572 | FileNameJoin@{$PackageDirectory, $PackagePackagesDirectory}, 573 | $PackageName 574 | ]; 575 | PackageAppLoad ~ SetAttributes ~ Listable; 576 | 577 | 578 | (* ::Subsubsection::Closed:: *) 579 | (*PackageAppGet*) 580 | 581 | 582 | Waifu["Get", f__] := 583 | PackageAppGet[f]; 584 | PackageAppGet[f_] := 585 | PackageExecute@ 586 | With[{fBase = 587 | If[FileExistsQ@f, 588 | f, 589 | PackageFilePath[$PackagePackagesDirectory, f <> ".m"] 590 | ] 591 | }, 592 | With[{cont = 593 | Most@ 594 | FileNameSplit[ 595 | FileNameDrop[fBase, 596 | FileNameDepth[PackageFilePath[$PackagePackagesDirectory]] 597 | ] 598 | ]}, 599 | If[Length[cont] > 0, 600 | Begin[StringRiffle[Append[""]@Prepend[""]@cont, "`"]]; 601 | (End[];#)&@Get[fBase], 602 | Get[fBase] 603 | ] 604 | ] 605 | ]; 606 | PackageAppGet[c_, f_] := 607 | PackageExecute[ 608 | Begin[c]; 609 | (End[];#)&@ 610 | If[FileExistsQ@f, 611 | Get@f;, 612 | Get@PackageFilePath[$PackagePackagesDirectory, f <> ".m"] 613 | ] 614 | ]; 615 | 616 | 617 | (* ::Subsubsection::Closed:: *) 618 | (*PackageAppNeeds*) 619 | 620 | 621 | Waifu["Needs", f___] := 622 | PackageAppNeeds[f]; 623 | 624 | 625 | PackageAppNeeds[pkgFile_String?FileExistsQ] := 626 | If[!MemberQ[$LoadedPackages, pkgFile], 627 | If[KeyMemberQ[$DeclaredPackages, pkgFile], 628 | PackageLoadDeclare[pkgFile], 629 | Do[PackageLoadDeclare[pkgFile], 2] 630 | ]; 631 | ]; 632 | 633 | 634 | PackageAppNeeds[pkg_String] := 635 | If[FileExistsQ@PackageFilePath[$PackagePackagesDirectory, pkg <> ".m"], 636 | PackageAppNeeds[PackageFilePath[$PackagePackagesDirectory, pkg <> ".m"]], 637 | $Failed 638 | ]; 639 | 640 | 641 | (* ::Subsubsection::Closed:: *) 642 | (*PackageScopeBlock*) 643 | 644 | 645 | $PackageScopeBlockEvalExpr = TrueQ[$PackageScopeBlockEvalExpr]; 646 | PackageScopeBlock[ 647 | e_, 648 | scope : _String?(StringFreeQ["`"]) : "Package", 649 | context : _String?(StringEndsQ["`"]) : "`PackageScope`" 650 | ] /; TrueQ[$AllowPackageRescoping] := 651 | With[{ 652 | newcont = 653 | If[StringStartsQ[context, "`"], 654 | "Waifu" <> context <> scope <> "`", 655 | context <> scope <> "`" 656 | ], 657 | res = If[$PackageScopeBlockEvalExpr, e] 658 | }, 659 | If[!MemberQ[$PackageContexts, newcont], 660 | Unprotect[$PackageContexts]; 661 | AppendTo[$PackageContexts, newcont]; 662 | ]; 663 | Replace[ 664 | Thread[ 665 | Cases[ 666 | HoldComplete[e], 667 | sym_Symbol?( 668 | Function[Null, 669 | MemberQ[$PackageContexts, Quiet[Context[#]]], 670 | HoldAllComplete 671 | ] 672 | ) :> 673 | HoldComplete[sym], 674 | \[Infinity] 675 | ], 676 | HoldComplete 677 | ], 678 | HoldComplete[{s__}] :> 679 | If[!$PackageDeclared && ListQ@$PackageScopedSymbols, 680 | $PackageScopedSymbols = 681 | { 682 | $PackageScopedSymbols, 683 | newcont -> 684 | HoldComplete[s] 685 | }, 686 | Block[{$AllowPackageRecoloring = True}, 687 | PackageFERehideSymbols[s] 688 | ]; 689 | Map[ 690 | Function[Null, 691 | Quiet[ 692 | Check[ 693 | Set[Context[#], newcont], 694 | Remove[#], 695 | Context::cxdup 696 | ], 697 | Context::cxdup 698 | ], 699 | HoldAllComplete 700 | ], 701 | HoldComplete[s] 702 | ] // ReleaseHold; 703 | ] 704 | ]; 705 | res 706 | ]; 707 | PackageScopeBlock[e_, scope_String : "Package"] /; Not@TrueQ[$AllowPackageRescoping] := 708 | If[$PackageScopeBlockEvalExpr, e]; 709 | PackageScopeBlock ~ SetAttributes ~ HoldFirst; 710 | 711 | 712 | (* ::Subsubsection::Closed:: *) 713 | (*PackageDecontext*) 714 | 715 | 716 | PackageDecontext[ 717 | pkgFile_String?(KeyMemberQ[$DeclaredPackages, #]&), 718 | scope : _String?(StringFreeQ["`"]) : "Package", 719 | context : _String?(StringEndsQ["`"]) : "`PackageScope`" 720 | ] /; TrueQ[$AllowPackageRescoping] := 721 | With[{ 722 | names = $DeclaredPackages[pkgFile], 723 | ctx = 724 | If[StringStartsQ[context, "`"], 725 | "Waifu" <> context <> scope <> "`", 726 | context <> scope <> "`" 727 | ] 728 | }, 729 | Replace[names, 730 | Verbatim[HoldPattern][s_] :> 731 | Set[Context[s], ctx], 732 | 1 733 | ] 734 | ]; 735 | 736 | 737 | (* ::Subsubsection::Closed:: *) 738 | (*PackageRecontext*) 739 | 740 | 741 | PackageRecontext[ 742 | pkgFile_String?(KeyMemberQ[$DeclaredPackages, #]&) 743 | ] /; TrueQ[$AllowPackageRescoping] := 744 | With[{ 745 | names = $DeclaredPackages[pkgFile], 746 | ctx = PackageFileContext[pkgFile] 747 | }, 748 | Replace[names, 749 | Verbatim[HoldPattern][s_] :> 750 | Set[Context[s], ctx], 751 | 1 752 | ] 753 | ]; 754 | 755 | 756 | (* ::Subsubsection::Closed:: *) 757 | (*End*) 758 | 759 | 760 | End[] 761 | (* ::Subsection:: *) 762 | (*Dependencies*) 763 | 764 | 765 | Waifu::nodep = "Couldn't load dependency `` of type ``"; 766 | Waifu::nodup = "Couldn't update dependency `` of type ``"; 767 | 768 | 769 | PackageExtendContextPath::usage = ""; 770 | PackageInstallPackageDependency::usage = ""; 771 | PackageLoadPackageDependency::usage = ""; 772 | PackageCheckPacletDependency::usage = ""; 773 | PackageInstallPacletDependency::usage = ""; 774 | PackageLoadPacletDependency::usage = ""; 775 | PackageUpdatePacletDependency::usage = ""; 776 | PackageLoadResourceDependency::usage = ""; 777 | 778 | 779 | (* ::Subsubsection::Closed:: *) 780 | (*Begin*) 781 | 782 | 783 | Begin["`Dependencies`"]; 784 | 785 | 786 | (* ::Subsubsection::Closed:: *) 787 | (*PackageExtendContextPath*) 788 | 789 | 790 | PackageExtendContextPath[cp : {__String}] := 791 | ( 792 | Unprotect[$PackageContexts]; 793 | $PackageContexts = 794 | DeleteCases[ 795 | DeleteDuplicates@ 796 | Join[$PackageContexts, cp], 797 | "System`" | "Global`" 798 | ]; 799 | (* Should I protect it again? *) 800 | ) 801 | 802 | 803 | (* ::Subsubsection::Closed:: *) 804 | (*PackageInstallPackageDependency*) 805 | 806 | 807 | Options[PackageInstallPackageDependency] = 808 | { 809 | "Permanent" -> False 810 | }; 811 | PackageInstallPackageDependency[dep_String, ops : OptionsPattern[]] := 812 | Block[{retcode, site, path, file, tmp}, 813 | path = 814 | StringSplit[StringTrim[dep, "`"] <> If[FileExtension[dep] == "", ".m", ""], "`"]; 815 | site = 816 | Replace[OptionValue["Site"], 817 | { 818 | s_String?( 819 | URLParse[#, "Domain"] === "github.com"& 820 | ) :> 821 | URLBuild@ 822 | <| 823 | "Scheme" -> "http", 824 | "Domain" -> "raw.githubusercontent.com", 825 | "Path" -> 826 | Function[If[Length[#] == 2, Append[#, "master"], #]]@ 827 | DeleteCases[""]@URLParse[s, "Path"] 828 | |>, 829 | _ -> 830 | "http://raw.githubusercontent.com/paclets/PackageServer/master/Listing" 831 | } 832 | ]; 833 | file = 834 | If[TrueQ@OptionValue["Permanent"], 835 | FileNameJoin@{$UserBaseDirectory, "Applications", Last@path}, 836 | FileNameJoin@{$TemporaryDirectory, "Applications", Last@path} 837 | ]; 838 | tmp = CreateFile[]; 839 | Monitor[ 840 | retcode = URLDownload[URLBuild[Prepend[site], path], tmp, "StatusCode"], 841 | Internal`LoadingPanel[ 842 | TemplateApply[ 843 | "Loading package `` from site ``", 844 | {URLBuild@path, site} 845 | ] 846 | ] 847 | ]; 848 | If[retcode < 300, 849 | CopyFile[tmp, file, 850 | OverwriteTarget -> Not@TrueQ@OptionValue["Permanent"] 851 | ]; 852 | DeleteFile[tmp]; 853 | file, 854 | Message[Waifu::nodep, dep, "Package"]; 855 | DeleteFile[tmp]; 856 | $Failed 857 | ] 858 | ]; 859 | 860 | 861 | (* ::Subsubsection::Closed:: *) 862 | (*PackageLoadPackageDependency*) 863 | 864 | 865 | Options[PackageLoadPackageDependency] = 866 | Options[PackageInstallPackageDependency]; 867 | PackageLoadPackageDependency[dep_String, ops : OptionsPattern[]] := 868 | Internal`WithLocalSettings[ 869 | BeginPackage[dep];, 870 | If[Quiet@Check[Needs[dep], $Failed] === $Failed && 871 | Quiet@Check[ 872 | Get[FileNameJoin @@ 873 | StringSplit[ 874 | StringTrim[dep, "`"] <> If[FileExtension[dep] == "", ".m", ""], 875 | "`" 876 | ] 877 | ], 878 | $Failed] === $Failed, 879 | Replace[PackageInstallPacletDependency[dep, ops], 880 | f : _String | _File :> Get[f] 881 | ] 882 | ]; 883 | PackageExtendContextPath@ 884 | Select[$Packages, StringStartsQ[dep]];, 885 | EndPackage[]; 886 | ] 887 | 888 | 889 | (* ::Subsubsection::Closed:: *) 890 | (*PackageCheckPacletDependency*) 891 | 892 | 893 | PackageCheckPacletDependency[dep_] := 894 | Length@PacletManager`PacletFind[StringDelete[dep, "`"]] > 0 895 | 896 | 897 | (* ::Subsubsection::Closed:: *) 898 | (*PackageInstallPacletDependency*) 899 | 900 | 901 | Options[PackageInstallPacletDependency] = 902 | Options[PacletManager`PacletInstall]; 903 | PackageInstallPacletDependency[ 904 | deps : {__String?( 905 | StringMatchQ[ 906 | (LetterCharacter | "_" | "`") ~~ (WordCharacter | "_" | "`").. 907 | ] 908 | )}, 909 | ops : OptionsPattern[] 910 | ] := 911 | Block[{site, pacs, pac}, 912 | pacs = 913 | StringDelete[deps, "`"]; 914 | site = 915 | Replace[OptionValue["Site"], 916 | { 917 | s_String?( 918 | URLParse[#, "Domain"] === "github.com"& 919 | ) :> 920 | URLBuild@ 921 | <| 922 | "Scheme" -> "http", 923 | "Domain" -> "raw.githubusercontent.com", 924 | "Path" -> 925 | Function[If[Length[#] == 2, Append[#, "master"], #]]@ 926 | DeleteCases[""]@URLParse[s, "Path"] 927 | |>, 928 | None -> 929 | Automatic, 930 | _ -> 931 | "http://raw.githubusercontent.com/paclets/PacletServer/master" 932 | } 933 | ]; 934 | pac = First@pacs; 935 | Monitor[ 936 | MapThread[ 937 | Check[ 938 | PacletManager`PacletInstall[ 939 | pac = #, 940 | "Site" -> site, 941 | ops 942 | ], 943 | Message[Waifu::nodep, #2, "Paclet"]; 944 | $Failed 945 | ]&, 946 | { 947 | pacs, 948 | deps 949 | } 950 | ], 951 | Internal`LoadingPanel[ 952 | TemplateApply[ 953 | "Loading paclet `` from site ``", 954 | {pac, site} 955 | ] 956 | ] 957 | ] 958 | ] 959 | 960 | 961 | PackageInstallPacletDependency[ 962 | dep : _String?( 963 | StringMatchQ[ 964 | (LetterCharacter | "_" | "`") ~~ (WordCharacter | "_" | "`").. 965 | ] 966 | ), 967 | ops : OptionsPattern[] 968 | ] := First@PackageInstallPacletDependency[{dep}, ops] 969 | 970 | 971 | (* ::Subsubsection::Closed:: *) 972 | (*PackageLoadPacletDependency*) 973 | 974 | 975 | Options[PackageLoadPacletDependency] = 976 | Join[ 977 | Options[PackageInstallPacletDependency], 978 | { 979 | "Update" -> False 980 | } 981 | ]; 982 | PackageLoadPacletDependency[dep_String?(StringEndsQ["`"]), ops : OptionsPattern[]] := 983 | Internal`WithLocalSettings[ 984 | System`Private`NewContextPath[{dep, "System`"}];, 985 | If[PackageCheckPacletDependency[dep], 986 | If[TrueQ@OptionValue["Update"], 987 | PackageUpdatePacletDependency[dep, 988 | "Sites" -> Replace[OptionValue["Site"], s_String :> {s}] 989 | ] 990 | ], 991 | PackageInstallPacletDependency[dep, ops] 992 | ]; 993 | Needs[dep]; 994 | PackageExtendContextPath@ 995 | Select[$Packages, 996 | StringStartsQ[#, dep] && StringFreeQ[#, "`Private`"]& 997 | ];, 998 | System`Private`RestoreContextPath[]; 999 | ] 1000 | 1001 | 1002 | (* ::Subsubsection::Closed:: *) 1003 | (*PackageUpdatePacletDependency*) 1004 | 1005 | 1006 | Options[PackageUpdatePacletDependency] = 1007 | { 1008 | "Sites" -> Automatic 1009 | }; 1010 | PackageUpdatePacletDependency[ 1011 | deps : {__String?(StringMatchQ[(LetterCharacter | "_") ~~ (WordCharacter | "_")..])}, 1012 | ops : OptionsPattern[] 1013 | ] := 1014 | Block[ 1015 | { 1016 | added = <||>, 1017 | ps = PacletManager`PacletSites[], 1018 | pac 1019 | }, 1020 | Replace[ 1021 | Replace[OptionValue["Sites"], 1022 | Automatic :> "http://raw.githubusercontent.com/paclets/PacletServer/master" 1023 | ], 1024 | { 1025 | s_String :> 1026 | If[!MemberQ[ps, PacletManager`PacletSite[s, ___]], 1027 | added[s] = True 1028 | ], 1029 | p : PacletManager`PacletSite[__] :> 1030 | If[!MemberQ[ps, p], 1031 | added[p] = True 1032 | ] 1033 | }, 1034 | 1 1035 | ]; 1036 | pac = StringDelete[deps[[1]], "`"]; 1037 | Internal`WithLocalSettings[ 1038 | KeyMap[PacletManager`PacletSiteAdd, added], 1039 | Monitor[ 1040 | MapThread[ 1041 | Check[ 1042 | PacletManager`PacletCheckUpdate[pac = #], 1043 | Message[Waifu::nodup, #2, "Paclet"]; 1044 | $Failed 1045 | ]&, 1046 | { 1047 | StringDelete[deps, "`"], 1048 | deps 1049 | } 1050 | ], 1051 | Internal`LoadingPanel[ 1052 | "Updating paclet ``" ~ TemplateApply ~ pac 1053 | ] 1054 | ], 1055 | KeyMap[PacletManager`PacletSiteRemove, added] 1056 | ] 1057 | ]; 1058 | 1059 | 1060 | PackageUpdatePacletDependency[ 1061 | dep : _String?(StringMatchQ[(LetterCharacter | "_") ~~ (WordCharacter | "_")..]), 1062 | ops : OptionsPattern[] 1063 | ] := 1064 | First@PackageUpdatePacletDependency[{dep}, ops] 1065 | 1066 | 1067 | (* ::Subsubsection::Closed:: *) 1068 | (*PackageLoadResourceDependency*) 1069 | 1070 | 1071 | (* ::Text:: *) 1072 | (*Nothing I've implemented yet, but could be very useful for installing resources for a paclet*) 1073 | 1074 | 1075 | (* ::Subsubsection:: *) 1076 | (*End*) 1077 | 1078 | 1079 | End[] 1080 | (* ::Subsection:: *) 1081 | (*Exceptions*) 1082 | 1083 | 1084 | $PackageExceptionTag::usage = ""; 1085 | PackageExceptionBlock::usage = ""; 1086 | 1087 | 1088 | PackageThrowException::usage = ""; 1089 | PackageCatchException::usage = ""; 1090 | PackageCatchExceptionCallback::usage = ""; 1091 | 1092 | 1093 | PackageThrowMessage::usage = ""; 1094 | PackageCatchMessage::usage = ""; 1095 | 1096 | 1097 | PackageFailureException::usage = ""; 1098 | PackageRaiseException::usage = ""; 1099 | 1100 | 1101 | (* ::Subsubsection::Closed:: *) 1102 | (*Begin*) 1103 | 1104 | 1105 | Begin["`Exceptions`Private`"] 1106 | 1107 | 1108 | (* ::Subsubsection::Closed:: *) 1109 | (*PackageThrowException*) 1110 | 1111 | 1112 | PackageThrowException[value : Except[_Failure], tag : _String : "Failure"] := 1113 | Throw[value, $PackageName <> tag]; 1114 | PackageThrowException[f_Failure] := 1115 | Throw[f, f[[1]]]; 1116 | 1117 | 1118 | (* ::Subsubsection::Closed:: *) 1119 | (*PackageCatchException*) 1120 | 1121 | 1122 | $PackageCatchCallback = (#&); 1123 | 1124 | 1125 | PackageCatchExceptionHandler[tag_] := 1126 | $PackageCatchCallback; 1127 | 1128 | 1129 | PackageCatchException[ 1130 | expr : Except[_String], 1131 | tag : _String : "Failure", 1132 | callback_ : Automatic 1133 | ] := 1134 | Catch[expr, 1135 | $PackageName <> tag, 1136 | Replace[callback, Automatic :> PackageCatchExceptionHandler[tag]] 1137 | ]; 1138 | PackageCatchException[tag_String, callback_ : Automatic] := 1139 | Function[Null, 1140 | PackageCatchException[#, tag, callback], 1141 | HoldFirst 1142 | ]; 1143 | PackageCatchException ~ SetAttributes ~ HoldFirst 1144 | 1145 | 1146 | (* ::Subsubsection::Closed:: *) 1147 | (*PackageThrowMessage*) 1148 | 1149 | 1150 | $PackageErrorMessage = 1151 | "Waifu encountered exception ``"; 1152 | 1153 | 1154 | Options[PackageThrowMessage] = 1155 | { 1156 | "MessageParameters" :> {} 1157 | }; 1158 | PackageThrowMessage[ 1159 | msg_MessageName, 1160 | body : _?StringQ, 1161 | ops : OptionsPattern[] 1162 | ] := 1163 | ( 1164 | Set[msg, body]; 1165 | Message[msg, Sequence @@ OptionValue["MessageParameters"]] 1166 | ); 1167 | PackageThrowMessage[ 1168 | tag_?StringQ, 1169 | body_String, 1170 | ops : OptionsPattern[] 1171 | ] := 1172 | PackageThrowMessage[ 1173 | MessageName[Waifu, tag], 1174 | body, 1175 | ops 1176 | ]; 1177 | PackageThrowMessage[ 1178 | tag_?StringQ 1179 | ] := 1180 | PackageThrowMessage[ 1181 | MessageName[Waifu, tag], 1182 | $PackageErrorMessage, 1183 | "MessageParameters" -> {tag} 1184 | ]; 1185 | PackageThrowMessage ~ SetAttributes ~ HoldAll 1186 | 1187 | 1188 | (* ::Subsubsection::Closed:: *) 1189 | (*PackageCatchMessage*) 1190 | 1191 | 1192 | $PackageCatchMessageMessage = 1193 | "Check caught exceptions ``"; 1194 | 1195 | 1196 | $PackageCatchMessageCallback = 1197 | Function[ 1198 | PackageRaiseException[ 1199 | "Check", 1200 | $PackageCatchMessageMessage, 1201 | "MessageParameters" -> Thread[HoldForm[$MessageList]] 1202 | ] 1203 | ]; 1204 | 1205 | 1206 | PackageCatchMessage[ 1207 | expr_, 1208 | failexpr_ : Automatic, 1209 | msg : {___String} : {} 1210 | ] := 1211 | Replace[ 1212 | Thread[Map[Hold[MessageName[Waifu, #]]&, msg], Hold], 1213 | { 1214 | {} :> 1215 | Check[expr, 1216 | Replace[failexpr, {Automatic :> $PackageCatchMessageCallback[]}] 1217 | ], 1218 | Hold[msgs_] :> 1219 | Check[expr, 1220 | Replace[failexpr, {Automatic :> $PackageCatchMessageCallback[]}], 1221 | msgs 1222 | ], 1223 | _ :> 1224 | Replace[failexpr, {Automatic :> $PackageCatchMessageCallback[]}] 1225 | } 1226 | ]; 1227 | PackageCatchMessage ~ SetAttributes ~ HoldAll; 1228 | 1229 | 1230 | (* ::Subsubsection::Closed:: *) 1231 | (*PackageFailureException*) 1232 | 1233 | 1234 | Options[PackageFailureException] = 1235 | Options[PackageThrowMessage]; 1236 | PackageFailureException[ 1237 | msg_MessageName, 1238 | body_?StringQ, 1239 | ops : OptionsPattern[] 1240 | ] := 1241 | Replace[ 1242 | OptionValue[Automatic, Automatic, "MessageParameters", Hold], 1243 | Hold[params_] :> 1244 | Failure[ 1245 | $PackageName <> Hold[msg][[1, 2]], 1246 | <| 1247 | "MessageTemplate" :> 1248 | msg, 1249 | "MessageParameters" :> 1250 | params 1251 | |> 1252 | ] 1253 | ]; 1254 | PackageFailureException[ 1255 | tag : _?StringQ : "Exception", 1256 | body_?StringQ, 1257 | ops : OptionsPattern[] 1258 | ] := 1259 | ( 1260 | Set[MessageName[Waifu, tag], body]; 1261 | PackageFailureException[ 1262 | MessageName[Waifu, tag], 1263 | body, 1264 | ops 1265 | ] 1266 | ); 1267 | PackageFailureException ~ SetAttributes ~ HoldFirst 1268 | 1269 | 1270 | (* ::Subsubsection::Closed:: *) 1271 | (*PackageRaiseException*) 1272 | 1273 | 1274 | PackageRaiseException // Clear; 1275 | Options[PackageRaiseException] = 1276 | Options[PackageFailureException] 1277 | PackageRaiseException[ 1278 | msg_MessageName, 1279 | body_?StringQ, 1280 | ops : OptionsPattern[] 1281 | ] := 1282 | ( 1283 | PackageThrowMessage[msg, body, 1284 | Evaluate@FilterRules[{ops}, Options[PackageThrowMessage]] 1285 | ]; 1286 | PackageThrowException[ 1287 | PackageFailureException[msg, body, ops] 1288 | ] 1289 | ); 1290 | PackageRaiseException[ 1291 | tag_?StringQ, 1292 | body_?StringQ, 1293 | ops : OptionsPattern[] 1294 | ] := 1295 | PackageRaiseException[ 1296 | MessageName[Waifu, tag], 1297 | body, 1298 | ops 1299 | ]; 1300 | PackageRaiseException[ 1301 | tag : _?(StringQ[#] && StringMatchQ[#, WordCharacter..]&), 1302 | ops : OptionsPattern[] 1303 | ] := 1304 | PackageRaiseException[ 1305 | tag, 1306 | $PackageErrorMessage, 1307 | { 1308 | ops, 1309 | "MessageParameters" -> {tag} 1310 | } 1311 | ]; 1312 | PackageRaiseException[ 1313 | Optional[Automatic, Automatic], 1314 | body : _?StringQ, 1315 | ops : OptionsPattern[] 1316 | ] := 1317 | PackageRaiseException[ 1318 | Evaluate@$PackageExceptionTag, 1319 | body, 1320 | ops 1321 | ]; 1322 | PackageRaiseException[ 1323 | tag : Automatic | _String, 1324 | body_String, 1325 | args : __?(Not@*OptionQ) 1326 | ] := 1327 | PackageRaiseException[tag, body, "MessageParameters" -> {args}]; 1328 | PackageRaiseException ~ SetAttributes ~ HoldFirst 1329 | 1330 | 1331 | (* ::Subsubsection::Closed:: *) 1332 | (*PackageExceptionBlock*) 1333 | 1334 | 1335 | $PackageExceptionStack = {}; 1336 | Protect[$PackageExceptionStack]; 1337 | 1338 | 1339 | $PackageExceptionTag = "Failure"; 1340 | 1341 | 1342 | PackageExceptionBlock // Clear 1343 | (*PackageExceptionBlock/: 1344 | HoldPattern[ 1345 | SetDelayed[lhs_, 1346 | peb:PackageExceptionBlock[_, _String] 1347 | ] 1348 | ]:= 1349 | SetDelayed[lhs, 1350 | Block[{$PackageExceptionBlockResult}, 1351 | $PackageExceptionBlockResult=peb; 1352 | peb/;!FailureQ@peb 1353 | ] 1354 | ];*) 1355 | PackageExceptionBlock[ 1356 | expr_, 1357 | tag : _String 1358 | ] := 1359 | Block[ 1360 | { 1361 | $PackageExceptionTag = tag, 1362 | $PackageExceptionStack = 1363 | Append[$PackageExceptionStack, tag], 1364 | result 1365 | }, 1366 | result = PackageCatchException[expr, tag, #&]; 1367 | If[MatchQ[result, Failure[_String?(StringEndsQ[tag]), _]] && 1368 | MemberQ[Most@$PackageExceptionStack, tag], 1369 | PackageThrowException[result] 1370 | ]; 1371 | result(*/;!FailureQ@result*) 1372 | ]; 1373 | PackageExceptionBlock[tag_String] := 1374 | Function[Null, PackageExceptionBlock[#, tag], HoldFirst]; 1375 | PackageExceptionBlock[Optional[Automatic, Automatic]] := 1376 | Function[Null, PackageExceptionBlock[#, $PackageExceptionTag], HoldFirst]; 1377 | PackageExceptionBlock ~ SetAttributes ~ HoldFirst; 1378 | 1379 | 1380 | (* ::Subsubsection::Closed:: *) 1381 | (*End*) 1382 | 1383 | 1384 | End[] 1385 | (* ::Subsection:: *) 1386 | (*Autocompletion*) 1387 | 1388 | 1389 | PackageAddAutocompletions::usage = ""; 1390 | 1391 | 1392 | (* ::Subsubsection::Closed:: *) 1393 | (*Begin*) 1394 | 1395 | 1396 | Begin["`Autocomplete`"]; 1397 | 1398 | 1399 | (* ::Subsubsection::Closed:: *) 1400 | (*Formats*) 1401 | 1402 | 1403 | $PackageAutoCompletionFormats = 1404 | Alternatives @@ Join @@ { 1405 | Range[0, 9], 1406 | { 1407 | _String?(FileExtension[#] === "trie"&), 1408 | { 1409 | _String | (Alternatives @@ Range[0, 9]) | {__String}, 1410 | (("URI" | "DependsOnArgument") -> _)... 1411 | }, 1412 | { 1413 | _String | (Alternatives @@ Range[0, 9]) | {__String}, 1414 | (("URI" | "DependsOnArgument") -> _)..., 1415 | (_String | (Alternatives @@ Range[0, 9]) | {__String}) 1416 | }, 1417 | { 1418 | __String 1419 | } 1420 | }, 1421 | { 1422 | "codingNoteFontCom", 1423 | "ConvertersPath", 1424 | "ExternalDataCharacterEncoding", 1425 | "MenuListCellTags", 1426 | "MenuListConvertFormatTypes", 1427 | "MenuListDisplayAsFormatTypes", 1428 | "MenuListFonts", 1429 | "MenuListGlobalEvaluators", 1430 | "MenuListHelpWindows", 1431 | "MenuListNotebookEvaluators", 1432 | "MenuListNotebooksMenu", 1433 | "MenuListPackageWindows", 1434 | "MenuListPalettesMenu", 1435 | "MenuListPaletteWindows", 1436 | "MenuListPlayerWindows", 1437 | "MenuListPrintingStyleEnvironments", 1438 | "MenuListQuitEvaluators", 1439 | "MenuListScreenStyleEnvironments", 1440 | "MenuListStartEvaluators", 1441 | "MenuListStyleDefinitions", 1442 | "MenuListStyles", 1443 | "MenuListStylesheetWindows", 1444 | "MenuListTextWindows", 1445 | "MenuListWindows", 1446 | "PrintingStyleEnvironment", 1447 | "ScreenStyleEnvironment", 1448 | "Style" 1449 | } 1450 | }; 1451 | 1452 | 1453 | (* ::Subsubsection::Closed:: *) 1454 | (*AddAutocompletions Base*) 1455 | 1456 | 1457 | PackageAddAutocompletions[pats : {(_String -> {$PackageAutoCompletionFormats..})..}] /; 1458 | TrueQ[$AllowPackageAutocompletions] := 1459 | If[$Notebooks && 1460 | Internal`CachedSystemInformation["FrontEnd", "VersionNumber"] > 10.0, 1461 | FrontEndExecute@FrontEnd`Value@ 1462 | Map[ 1463 | FEPrivate`AddSpecialArgCompletion[#]&, 1464 | pats 1465 | ], 1466 | $Failed 1467 | ]; 1468 | PackageAddAutocompletions[pat : (_String -> {$PackageAutoCompletionFormats..})] /; 1469 | TrueQ[$AllowPackageAutocompletions] := 1470 | PackageAddAutocompletions[{pat}]; 1471 | 1472 | 1473 | (* ::Subsubsection::Closed:: *) 1474 | (*AddAutocompletions Helpers*) 1475 | 1476 | 1477 | $PackageAutocompletionAliases = 1478 | { 1479 | "None" | None | Normal -> 0, 1480 | "AbsoluteFileName" | AbsoluteFileName -> 2, 1481 | "FileName" | File | FileName -> 3, 1482 | "Color" | RGBColor | Hue | XYZColor -> 4, 1483 | "Package" | Package -> 7, 1484 | "Directory" | Directory -> 8, 1485 | "Interpreter" | Interpreter -> 9, 1486 | "Notebook" | Notebook -> "MenuListNotebooksMenu", 1487 | "StyleSheet" -> "MenuListStylesheetMenu", 1488 | "Palette" -> "MenuListPalettesMenu", 1489 | "Evaluator" | Evaluator -> "MenuListGlobalEvaluators", 1490 | "FontFamily" | FontFamily -> "MenuListFonts", 1491 | "CellTag" | CellTags -> "MenuListCellTags", 1492 | "FormatType" | FormatType -> "MenuListDisplayAsFormatTypes", 1493 | "ConvertFormatType" -> "MenuListConvertFormatTypes", 1494 | "DisplayAsFormatType" -> "MenuListDisplayAsFormatTypes", 1495 | "GlobalEvaluator" -> "MenuListGlobalEvaluators", 1496 | "HelpWindow" -> "MenuListHelpWindows", 1497 | "NotebookEvaluator" -> "MenuListNotebookEvaluators", 1498 | "PrintingStyleEnvironment" | PrintingStyleEnvironment -> 1499 | "PrintingStyleEnvironment", 1500 | "ScreenStyleEnvironment" | ScreenStyleEnvironment -> 1501 | ScreenStyleEnvironment, 1502 | "QuitEvaluator" -> "MenuListQuitEvaluators", 1503 | "StartEvaluator" -> "MenuListStartEvaluators", 1504 | "StyleDefinitions" | StyleDefinitions -> 1505 | "MenuListStyleDefinitions", 1506 | "CharacterEncoding" | CharacterEncoding | 1507 | ExternalDataCharacterEncoding -> 1508 | "ExternalDataCharacterEncoding", 1509 | "Style" | Style -> "Style", 1510 | "Window" -> "MenuListWindows" 1511 | }; 1512 | 1513 | 1514 | (* ::Subsubsection::Closed:: *) 1515 | (*AddAutocompletions Convenience*) 1516 | 1517 | 1518 | $PackageAutocompletionTable = { 1519 | f : $PackageAutoCompletionFormats :> f, 1520 | Sequence @@ $PackageAutocompletionAliases, 1521 | s_String :> {s} 1522 | }; 1523 | 1524 | 1525 | PackageAddAutocompletions[o : {__Rule}] /; ( 1526 | TrueQ[$AllowPackageAutocompletions] && !TrueQ@$recursionProtect 1527 | ) := 1528 | Block[{$recursionProtect = True}, 1529 | Replace[ 1530 | PackageAddAutocompletions@ 1531 | Replace[o, 1532 | (s_ -> v_) :> 1533 | (Replace[s, _Symbol :> SymbolName[s]] -> 1534 | Replace[ 1535 | Flatten[{v}, 1], 1536 | $PackageAutocompletionTable, 1537 | 1 1538 | ]), 1539 | 1 1540 | ], 1541 | _PackageAddAutocompletions -> $Failed 1542 | ] 1543 | ]; 1544 | PackageAddAutocompletions[s : Except[_List], v_] /; TrueQ[$AllowPackageAutocompletions] := 1545 | PackageAddAutocompletions[{s -> v}]; 1546 | PackageAddAutocompletions[l_, v_] /; TrueQ[$AllowPackageAutocompletions] := 1547 | PackageAddAutocompletions@ 1548 | Flatten@{ 1549 | Quiet@ 1550 | Check[ 1551 | Thread[l -> v], 1552 | Map[l -> #&, v] 1553 | ] 1554 | }; 1555 | 1556 | 1557 | (*PackageAddAutocompletions[PackageAddAutocompletions, 1558 | {None, 1559 | Join[ 1560 | Replace[Keys[$PackageAutocompletionAliases], 1561 | Verbatim[Alternatives][s_,___]:>s, 1562 | 1 1563 | ], 1564 | {FileName,AbsoluteFileName}/.$PackageAutocompletionAliases 1565 | ] 1566 | } 1567 | ]*) 1568 | 1569 | 1570 | (* ::Subsubsection::Closed:: *) 1571 | (* PackageSetAutocompletionData *) 1572 | 1573 | 1574 | PackageSetAutocompletionData[] := 1575 | If[DirectoryQ@ 1576 | FileNameJoin@{ 1577 | $PackageDirectory, 1578 | "Resources", 1579 | "FunctionalFrequency" 1580 | }, 1581 | CurrentValue[ 1582 | $FrontEndSession, 1583 | {PrivatePaths, "AutoCompletionData"} 1584 | ] = 1585 | DeleteDuplicates@ 1586 | Append[ 1587 | CurrentValue[ 1588 | $FrontEndSession, 1589 | {PrivatePaths, "AutoCompletionData"} 1590 | ], 1591 | FileNameJoin@{ 1592 | $PackageDirectory, 1593 | "Resources", 1594 | "FunctionalFrequency" 1595 | } 1596 | ] 1597 | ]; 1598 | 1599 | 1600 | (* ::Subsubsection::Closed:: *) 1601 | (*End*) 1602 | 1603 | 1604 | End[] 1605 | (* ::Subsection:: *) 1606 | (*FrontEnd*) 1607 | 1608 | 1609 | PackageFEHiddenBlock::usage = ""; 1610 | PackageFEUnhideSymbols::usage = ""; 1611 | PackageFERehideSymbols::usage = ""; 1612 | PackageFEUnhidePackage::usage = ""; 1613 | PackageFERehidePackage::usage = ""; 1614 | 1615 | 1616 | (* ::Subsubsection::Closed:: *) 1617 | (*Begin*) 1618 | 1619 | 1620 | Begin["`FrontEnd`"] 1621 | 1622 | 1623 | (* ::Subsubsection::Closed:: *) 1624 | (*PackageFEInstallStylesheets *) 1625 | 1626 | 1627 | PackageFEInstallStylesheets[] := 1628 | With[{ 1629 | base = 1630 | FileNameJoin@{ 1631 | $PackageDirectory, 1632 | "FrontEnd", 1633 | "StyleSheets", 1634 | $PackageName 1635 | }, 1636 | target = 1637 | FileNameJoin@{ 1638 | $UserBaseDirectory, 1639 | "SystemFiles", 1640 | "FrontEnd", 1641 | "StyleSheets", 1642 | $PackageName} 1643 | }, 1644 | If[DirectoryQ@base, 1645 | Do[ 1646 | Quiet@ 1647 | CreateFile[ 1648 | FileNameJoin@{ 1649 | target, 1650 | FileNameDrop[f, FileNameDepth[base]] 1651 | }, 1652 | CreateIntermediateDirectories -> True 1653 | ]; 1654 | CopyFile[f, 1655 | FileNameJoin@{ 1656 | target, 1657 | FileNameDrop[f, FileNameDepth[base]] 1658 | }, 1659 | OverwriteTarget -> True], 1660 | {f, FileNames["*.nb", base, \[Infinity]]} 1661 | ] 1662 | ] 1663 | ]; 1664 | 1665 | 1666 | (* ::Subsubsection::Closed:: *) 1667 | (*PackageFEInstallPalettes *) 1668 | 1669 | 1670 | PackageFEInstallPalettes[] := 1671 | With[{ 1672 | base = 1673 | FileNameJoin@{ 1674 | $PackageDirectory, 1675 | "FrontEnd", 1676 | "Palettes", 1677 | $PackageName 1678 | }, 1679 | target = 1680 | FileNameJoin@{ 1681 | $UserBaseDirectory, 1682 | "SystemFiles", 1683 | "FrontEnd", 1684 | "Palettes", 1685 | $PackageName} 1686 | }, 1687 | If[DirectoryQ@base, 1688 | Do[ 1689 | Quiet@ 1690 | CreateFile[ 1691 | FileNameJoin@{ 1692 | target, 1693 | FileNameDrop[f, FileNameDepth[base]] 1694 | }, 1695 | CreateIntermediateDirectories -> True 1696 | ]; 1697 | CopyFile[f, 1698 | FileNameJoin@{ 1699 | target, 1700 | FileNameDrop[f, FileNameDepth[base]] 1701 | }, 1702 | OverwriteTarget -> True], 1703 | {f, FileNames["*.nb", base, \[Infinity]]} 1704 | ] 1705 | ] 1706 | ]; 1707 | 1708 | 1709 | (* ::Subsubsection::Closed:: *) 1710 | (*PackageFEHiddenBlock*) 1711 | 1712 | 1713 | $PackageFEHideExprSymbols = TrueQ[$PackageFEHideExprSymbols]; 1714 | $PackageFEHideEvalExpr = TrueQ[$PackageFEHideEvalExpr]; 1715 | PackageFEHiddenBlock[expr_, 1716 | hide : True | False | Automatic : Automatic, 1717 | eval : True | False | Automatic : Automatic 1718 | ] /; TrueQ[$AllowPackageRecoloring] := 1719 | If[!$PackageDeclared && ListQ@$PackageFEHiddenSymbols, 1720 | With[{ 1721 | s = 1722 | Cases[ 1723 | HoldComplete[expr], 1724 | sym_Symbol?( 1725 | Function[Null, 1726 | MemberQ[$PackageContexts, Quiet[Context[#]]], 1727 | HoldAllComplete 1728 | ] 1729 | ) :> 1730 | HoldPattern[sym], 1731 | \[Infinity] 1732 | ] 1733 | }, 1734 | $PackageFEHiddenSymbols = 1735 | { 1736 | $PackageFEHiddenSymbols, 1737 | s 1738 | } 1739 | ], 1740 | Block[{feBlockReturn}, 1741 | Internal`SymbolList[False]; 1742 | feBlockReturn = If[Replace[eval, Automatic :> $PackageFEHideEvalExpr], expr]; 1743 | If[Replace[hide, Automatic :> $PackageFEHideExprSymbols], 1744 | With[{ 1745 | s = 1746 | Cases[ 1747 | HoldComplete[expr], 1748 | sym_Symbol?( 1749 | Function[Null, 1750 | MemberQ[$PackageContexts, Quiet[Context[#]]], 1751 | HoldAllComplete 1752 | ] 1753 | ) :> 1754 | HoldPattern[sym], 1755 | \[Infinity] 1756 | ] 1757 | }, 1758 | Replace[Thread[s, HoldPattern], 1759 | Verbatim[HoldPattern][{sym__}] :> 1760 | PackageFERehideSymbols[sym] 1761 | ] 1762 | ] 1763 | ]; 1764 | Internal`SymbolList[True]; 1765 | feBlockReturn 1766 | ] 1767 | ]; 1768 | PackageFEHiddenBlock[expr_, 1769 | hide : True | False | Automatic : Automatic, 1770 | eval : True | False | Automatic : Automatic 1771 | ] /; Not@TrueQ[$AllowPackageRecoloring] := 1772 | If[eval, expr]; 1773 | PackageFEHiddenBlock ~ SetAttributes ~ HoldFirst 1774 | 1775 | 1776 | (* ::Subsubsection::Closed:: *) 1777 | (*PackageFEUnhideSymbols*) 1778 | 1779 | 1780 | PackageFEUnhideSymbols[syms__Symbol, 1781 | cpath : {__String} | Automatic : Automatic, 1782 | mode : "Update" | "Set" : "Update" 1783 | ] /; TrueQ[$AllowPackageRecoloring] := 1784 | With[{stuff = 1785 | Map[ 1786 | Function[Null, 1787 | {Context@#, SymbolName@Unevaluated@#}, 1788 | HoldAllComplete], 1789 | HoldComplete[syms] 1790 | ] // Apply[List] 1791 | }, 1792 | KeyValueMap[ 1793 | FrontEndExecute@ 1794 | If[mode === "Update", 1795 | FrontEnd`UpdateKernelSymbolContexts, 1796 | FrontEnd`SetKernelSymbolContexts 1797 | ][ 1798 | #, 1799 | Replace[cpath, Automatic -> $ContextPath], 1800 | {{#, {}, {}, #2, {}}} 1801 | ]&, 1802 | GroupBy[stuff, First -> Last] 1803 | ]; 1804 | ]; 1805 | PackageFEUnhideSymbols[names_String, 1806 | mode : "Update" | "Set" : "Update"] /; TrueQ[$AllowPackageRecoloring] := 1807 | Replace[ 1808 | Thread[ToExpression[Names@names, StandardForm, Hold], Hold], 1809 | Hold[{s__}] :> PackageFEUnhideSymbols[s, mode] 1810 | ]; 1811 | PackageFEUnhideSymbols ~ SetAttributes ~ HoldAllComplete; 1812 | 1813 | 1814 | (* ::Subsubsection::Closed:: *) 1815 | (*PackageFERehideSymbols*) 1816 | 1817 | 1818 | PackageFERehideSymbols[syms__Symbol, 1819 | cpath : {__String} | Automatic : Automatic, 1820 | mode : "Update" | "Set" : "Update"] /; TrueQ[$AllowPackageRecoloring] := 1821 | With[{stuff = 1822 | Map[ 1823 | Function[Null, 1824 | {Context@#, SymbolName@Unevaluated@#}, 1825 | HoldAllComplete], 1826 | HoldComplete[syms] 1827 | ] // Apply[List] 1828 | }, 1829 | KeyValueMap[ 1830 | FrontEndExecute@ 1831 | If[mode === "Update", 1832 | FrontEnd`UpdateKernelSymbolContexts, 1833 | FrontEnd`SetKernelSymbolContexts 1834 | ][ 1835 | #, 1836 | Replace[cpath, 1837 | Automatic -> $ContextPath 1838 | ], 1839 | {{#, {}, #2, {}, {}}} 1840 | ]&, 1841 | GroupBy[stuff, First -> Last] 1842 | ]; 1843 | ]; 1844 | PackageFERehideSymbols[names_String, 1845 | mode : "Update" | "Set" : "Update"] /; TrueQ[$AllowPackageRecoloring] := 1846 | Replace[ 1847 | Thread[ToExpression[Names@names, StandardForm, Hold], Hold], 1848 | Hold[{s__}] :> PackageFERehideSymbols[s, mode] 1849 | ]; 1850 | PackageFERehideSymbols ~ SetAttributes ~ HoldAllComplete; 1851 | 1852 | 1853 | (* ::Subsubsection::Closed:: *) 1854 | (*PackageFEUnhidePackage*) 1855 | 1856 | 1857 | PackageFEUnhidePackage[ 1858 | package_String?FileExistsQ, 1859 | a___ 1860 | ] /; TrueQ[$AllowPackageRecoloring] := 1861 | Replace[Thread[Lookup[$DeclaredPackages, package, {}], HoldPattern], 1862 | Verbatim[HoldPattern][{syms__}] :> 1863 | PackageFEUnhideSymbols[syms, a] 1864 | ]; 1865 | PackageFEUnhidePackage[spec : _String | _List, a___] /; TrueQ[$AllowPackageRecoloring] := 1866 | PackageFEUnhidePackage[PackageFilePath@Flatten@{"Packages", spec}, a]; 1867 | 1868 | 1869 | (* ::Subsubsection::Closed:: *) 1870 | (*PackageFERehidePackage*) 1871 | 1872 | 1873 | PackageFERehidePackage[ 1874 | package_String?FileExistsQ, 1875 | a___ 1876 | ] /; TrueQ[$AllowPackageRecoloring] := 1877 | Replace[Thread[Lookup[$DeclaredPackages, package, {}], HoldPattern], 1878 | Verbatim[HoldPattern][{syms__}] :> 1879 | PackageFERehideSymbols[syms, a] 1880 | ]; 1881 | PackageFERehidePackage[spec : _String | _List, a___] /; TrueQ[$AllowPackageRecoloring] := 1882 | PackageFERehidePackage[PackageFilePath@Flatten@{"Packages", spec}, a]; 1883 | 1884 | 1885 | (* ::Subsubsection::Closed:: *) 1886 | (*End*) 1887 | 1888 | 1889 | End[] 1890 | 1891 | 1892 | (* ::Subsection:: *) 1893 | (*Post-Processing*) 1894 | 1895 | 1896 | PackagePostProcessPrepSpecs::usage = ""; 1897 | PackagePrepPackageSymbol::usage = ""; 1898 | PackagePostProcessExposePackages::usage = ""; 1899 | PackagePostProcessRehidePackages::usage = ""; 1900 | PackagePostProcessDecontextPackages::usage = ""; 1901 | PackagePostProcessContextPathReassign::usage = ""; 1902 | PackageAttachMainAutocomplete::usage = ""; 1903 | PackagePreemptShadowing::usage = ""; 1904 | 1905 | 1906 | Begin["`PostProcess`"]; 1907 | 1908 | 1909 | (* ::Subsubsection::Closed:: *) 1910 | (*PrepFileName*) 1911 | 1912 | 1913 | PackagePostProcessFileNamePrep[fn_] := 1914 | Replace[ 1915 | FileNameSplit@ 1916 | FileNameDrop[fn, 1917 | FileNameDepth@ 1918 | PackageFilePath["Packages"] 1919 | ], { 1920 | {f_} :> 1921 | f | fn | StringTrim[f, ".m" | ".wl"], 1922 | {p__, f_} :> 1923 | FileNameJoin@{p, f} | fn | {p, StringTrim[f, ".m" | ".wl"]} 1924 | }] 1925 | 1926 | 1927 | (* ::Subsubsection::Closed:: *) 1928 | (*PrepSpecs*) 1929 | 1930 | 1931 | PackagePostProcessPrepSpecs[] := 1932 | ( 1933 | Unprotect[ 1934 | $PackagePreloadedPackages, 1935 | $PackageHiddenPackages, 1936 | $PackageHiddenContexts, 1937 | $PackageExposedContexts, 1938 | $PackageDecontextedPackages 1939 | ]; 1940 | Replace[ 1941 | $PackageLoadSpecs, 1942 | specs : {__Rule} | _Association :> 1943 | CompoundExpression[ 1944 | $PackagePreloadedPackages = 1945 | Replace[ 1946 | Lookup[specs, "PreLoad"], 1947 | Except[{__String}] -> {} 1948 | ], 1949 | $PackageHiddenPackages = 1950 | Replace[ 1951 | Lookup[specs, "FEHidden"], 1952 | Except[{__String}] -> {} 1953 | ], 1954 | $PackageDecontextedPackages = 1955 | Replace[ 1956 | Lookup[specs, "PackageScope"], 1957 | Except[{__String}] -> {} 1958 | ], 1959 | $PackageExposedContexts = 1960 | Replace[ 1961 | Lookup[specs, "ExposedContexts"], 1962 | Except[{__String}] -> {} 1963 | ] 1964 | ] 1965 | ] 1966 | ); 1967 | 1968 | 1969 | (* ::Subsubsection::Closed:: *) 1970 | (*ExposePackages*) 1971 | 1972 | 1973 | PackagePostProcessExposePackages[] /; TrueQ[$AllowPackageRecoloring] := 1974 | ( 1975 | PackageAppGet /@ 1976 | $PackagePreloadedPackages; 1977 | With[{ 1978 | syms = 1979 | If[ 1980 | !MemberQ[$PackageHiddenPackages, 1981 | PackagePostProcessFileNamePrep[#] 1982 | ], 1983 | $DeclaredPackages[#], 1984 | {} 1985 | ]& /@ Keys@$DeclaredPackages // Flatten 1986 | }, 1987 | Replace[ 1988 | Thread[ 1989 | If[ListQ@$PackageFEHiddenSymbols, 1990 | DeleteCases[syms, 1991 | Alternatives @@ 1992 | (Verbatim[HoldPattern] /@ Flatten@$PackageFEHiddenSymbols) 1993 | ], 1994 | syms 1995 | ], 1996 | HoldPattern], 1997 | Verbatim[HoldPattern][{s__}] :> 1998 | PackageFEUnhideSymbols[s] 1999 | ] 2000 | ] 2001 | ) 2002 | 2003 | 2004 | 2005 | 2006 | (* ::Subsubsection::Closed:: *) 2007 | (*Rehide Packages*) 2008 | 2009 | 2010 | PackagePostProcessRehidePackages[] /; TrueQ[$AllowPackageRecoloring] := 2011 | If[ 2012 | MemberQ[$PackageHiddenPackages, 2013 | PackagePostProcessFileNamePrep[#] 2014 | ], 2015 | PackageFERehidePackage@# 2016 | ]& /@ Keys@$DeclaredPackages 2017 | 2018 | 2019 | (* ::Subsubsection::Closed:: *) 2020 | (*Decontext*) 2021 | 2022 | 2023 | PackagePostProcessDecontextPackages[] /; TrueQ[$AllowPackageRecoloring] := 2024 | ( 2025 | If[ 2026 | MemberQ[$PackageDecontextedPackages, 2027 | PackagePostProcessFileNamePrep[#] 2028 | ], 2029 | PackageFERehidePackage@#; 2030 | PackageDecontext@# 2031 | ]& /@ Keys@$DeclaredPackages; 2032 | If[ListQ@$PackageScopedSymbols, 2033 | KeyValueMap[ 2034 | With[{newcont = #}, 2035 | Replace[Join @@ #2, 2036 | HoldComplete[s__] :> 2037 | ( 2038 | PackageFERehideSymbols[s]; 2039 | Map[ 2040 | Function[Null, 2041 | Quiet[ 2042 | Check[ 2043 | Set[Context[#], newcont], 2044 | Remove[#], 2045 | Context::cxdup 2046 | ], 2047 | Context::cxdup 2048 | ], 2049 | HoldAllComplete 2050 | ], 2051 | HoldComplete[s] 2052 | ] // ReleaseHold; 2053 | ) 2054 | ] 2055 | ]&, 2056 | GroupBy[Flatten@$PackageScopedSymbols, First -> Last] 2057 | ]; 2058 | ] 2059 | ) 2060 | 2061 | 2062 | 2063 | 2064 | (* ::Subsubsection::Closed:: *) 2065 | (*ContextPathReassign*) 2066 | 2067 | 2068 | PackagePostProcessContextPathReassign[] := 2069 | With[{cp = $ContextPath}, 2070 | If[MemberQ[cp], 2071 | "Waifu`", 2072 | $ContextPath = 2073 | Join[ 2074 | Replace[ 2075 | Flatten@{$PackageExposedContexts}, 2076 | Except[_String?(StringEndsQ["`"])] -> Nothing, 2077 | 1 2078 | ], 2079 | $ContextPath 2080 | ]; 2081 | If[TrueQ[$AllowPackageRecoloring], 2082 | FrontEnd`Private`GetUpdatedSymbolContexts[] 2083 | ]; 2084 | ] 2085 | ] 2086 | 2087 | 2088 | (* ::Subsubsection::Closed:: *) 2089 | (*AttachMainAutocomplete*) 2090 | 2091 | 2092 | PackageAttachMainAutocomplete[] := 2093 | PackageAddAutocompletions[Waifu, 2094 | Table[ 2095 | Replace[{} -> None]@ 2096 | Cases[ 2097 | DownValues[Waifu], 2098 | Nest[ 2099 | Insert[#, _, {1, 1, 1}]&, 2100 | (HoldPattern[Verbatim[HoldPattern]][ 2101 | Waifu[s_String, ___] 2102 | ] :> _), 2103 | n - 1 2104 | ] :> s, 2105 | Infinity 2106 | ], 2107 | {n, 5} 2108 | ] 2109 | ]; 2110 | 2111 | 2112 | (* ::Subsubsection::Closed:: *) 2113 | (*PreventShadowing*) 2114 | 2115 | 2116 | PackagePreemptShadowing[] := 2117 | Replace[ 2118 | Hold[{m___}] :> 2119 | Off[m] 2120 | ]@ 2121 | Thread[ 2122 | ToExpression[ 2123 | Map[# <> "$"&, Names["`PackageScope`Private`*"] 2124 | ], 2125 | StandardForm, 2126 | Function[Null, 2127 | Hold[MessageName[#, "shdw"]], 2128 | HoldAllComplete 2129 | ] 2130 | ], 2131 | Hold 2132 | ] 2133 | 2134 | 2135 | (* ::Subsubsection::Closed:: *) 2136 | (*PackagePrepPackageSymbol*) 2137 | 2138 | 2139 | PackagePrepPackageSymbol[] := 2140 | Switch[$AllowPackageSymbolDefinitions, 2141 | None, 2142 | Remove[Waifu], 2143 | False, 2144 | Clear[Waifu], 2145 | _, 2146 | PackageAttachMainAutocomplete[] 2147 | ] 2148 | 2149 | 2150 | End[]; 2151 | 2152 | 2153 | (* ::Subsection:: *) 2154 | (*End*) 2155 | 2156 | 2157 | $ContextPath = DeleteCases[$ContextPath, $Context]; 2158 | End[]; 2159 | 2160 | 2161 | (* ::Section:: *) 2162 | (* Load *) 2163 | 2164 | 2165 | If[`PackageScope`Private`$AllowPackageRecoloring, 2166 | Internal`SymbolList[False] 2167 | ]; 2168 | 2169 | 2170 | (* ::Subsubsection::Closed:: *) 2171 | (*Basic Load*) 2172 | 2173 | 2174 | `PackageScope`Private`$loadAbort = False; 2175 | CheckAbort[ 2176 | `PackageScope`Private`PackageAppLoad[]; 2177 | `PackageScope`Private`$PackageFEHideExprSymbols = True; 2178 | `PackageScope`Private`$PackageFEHideEvalExpr = True; 2179 | `PackageScope`Private`$PackageScopeBlockEvalExpr = True; 2180 | `PackageScope`Private`$PackageDeclared = True;, 2181 | `PackageScope`Private`$loadAbort = True; 2182 | EndPackage[]; 2183 | ]; 2184 | Protect["`PackageScope`Private`*"]; 2185 | Unprotect[`PackageScope`Private`$loadAbort]; 2186 | 2187 | 2188 | (* ::Subsubsection::Closed:: *) 2189 | (*Post-Process*) 2190 | 2191 | 2192 | If[!`PackageScope`Private`$loadAbort, 2193 | `PackageScope`Private`PackagePostProcessPrepSpecs[]; 2194 | `PackageScope`Private`PackagePrepPackageSymbol[]; 2195 | `PackageScope`Private`PackagePostProcessExposePackages[]; 2196 | `PackageScope`Private`PackagePostProcessRehidePackages[]; 2197 | `PackageScope`Private`PackagePostProcessDecontextPackages[]; 2198 | ] 2199 | 2200 | 2201 | Unprotect[`PackageScope`Private`$PackageFEHiddenSymbols]; 2202 | Clear[`PackageScope`Private`$PackageFEHiddenSymbols]; 2203 | Unprotect[`PackageScope`Private`$PackageScopedSymbols]; 2204 | Clear[`PackageScope`Private`$PackageScopedSymbols]; 2205 | 2206 | 2207 | (* Hide `PackageScope`Private` shadowing *) 2208 | `PackageScope`Private`PackagePreemptShadowing[] 2209 | 2210 | 2211 | (* ::Subsubsection:: *) 2212 | (*EndPackage / Reset $ContextPath*) 2213 | 2214 | 2215 | System`Private`RestoreContextPath[] 2216 | EndPackage[]; 2217 | 2218 | 2219 | If[ 2220 | (Clear@Waifu`PackageScope`Private`$loadAbort;!#)&@ 2221 | Waifu`PackageScope`Private`$loadAbort, 2222 | Unprotect[Waifu`PackageScope`Private`$LoadCompleted]; 2223 | Waifu`PackageScope`Private`$LoadCompleted = True; 2224 | Waifu`PackageScope`Private`PackagePostProcessContextPathReassign[] 2225 | ] --------------------------------------------------------------------------------