diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100755 index 0000000..d6e0348 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: emersonfelipesp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21c7c4e..52ae576 100755 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.6, 3.7, 3.8] + python-version: ['3.8', '3.9', '3.10'] steps: - name: Check out repo diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100755 index 0000000..e72d1d6 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: docs +on: + push: + branches: + - develop + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - uses: actions/cache@v2 + with: + key: ${{ github.ref }} + path: .cache + - name: Install APT packages + run: | + sudo apt install python3-pip python3-apt python3-cffi python3-brotli -y + sudo apt install libharfbuzz0b libpangoft2-1.0-0 libgtk-3-dev gcc -y + - name: Install PIP packages + run: | + sudo pip3 install Markdown==3.3 + sudo pip3 install mkdocs-material + sudo pip3 install mkdocs-minify-plugin + sudo pip3 install mkdocs-redirects + sudo pip3 install pillow cairosvg + - name: Deploy MkDocs Page + run: sudo mkdocs gh-deploy --force + - name: Git Commit staged + run: | + sudo git config --global --add user.name emersonfelipesp + sudo git config --global --add user.email emersonfelipe.2003@gmail.com + sudo git add . + sudo git commit -m "Saves 'site' html pages" + - name: Git checkout to 'gh-pages' branch + run: | + sudo git checkout gh-pages + sudo git push --set-upstream origin gh-pages + - name: Change custom domain + run: | + sudo echo 'proxbox.netbox.dev.br' > CNAME + sudo git add CNAME + sudo git commit -m "Change custom domain to 'proxbox.netbox.dev.br'" + sudo git push diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml new file mode 100755 index 0000000..33c404f --- /dev/null +++ b/.github/workflows/pypi.yml @@ -0,0 +1,32 @@ +name: Upload Python Package + +on: + release: + types: + - created + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel build + + - name: Build distributable + run: | + python -m build + + - name: Publish a Python distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/CNAME b/CNAME new file mode 100755 index 0000000..a3cebbe --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +proxbox.netbox.dev.br \ No newline at end of file diff --git a/FASTAPI.md b/FASTAPI.md new file mode 100755 index 0000000..7270cbe --- /dev/null +++ b/FASTAPI.md @@ -0,0 +1,22 @@ +# Deploy FastAPI + +Using **[uvicorn](https://www.uvicorn.org/)** to deploy Proxbox backend using **[FastAPI](https://fastapi.tiangolo.com/)** on port **9000** using development mode with --reload. + +### It's not ready for PRODUCTION! + +FastAPI was chosen to replace the current Django Backend, but it's not fully implemented and tested. + +``` +cd /opt/netbox/netbox +uvicorn netbox-proxbox.netbox_proxbox.api.main:app --reload --port 9000 +``` + +## Testing FastAPI + +Access the following URL **http://HOST:PORT/proxmox/cluster/resources** to view all VMs/Nodes/Storages of your environment. +Docs: **http://HOST:PORT/docs** or **http://HOST:PORT/redoc** + +## Security + +The password is not securely stored yet, but I will fix it. +About the integration, we only use **GET HTTP methods** and we do not modify anything of your environment using **POST / PUT** methods, even though the token allows it or not. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in old mode 100644 new mode 100755 diff --git a/Pipfile b/Pipfile new file mode 100755 index 0000000..6982807 --- /dev/null +++ b/Pipfile @@ -0,0 +1,34 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +poetry = "*" +invoke = "*" +requests = ">=2" +pynetbox = ">=5" +paramiko = ">=2" +proxmoxer = "*" +fastapi = {extras = ["all"], version = "*"} +typing = "*" +starlette = "*" +uvicorn = "*" +pydantic = "*" +anyio = "*" +websockets = "*" +jinja2 = "*" +ujson = ">=5.7.0" +orjson = ">=3.8.9" +httpcore = "*" +pytest = ">=3.7" +check-manifest = "*" +twine = "*" +netbox-proxbox = "*" +setuptools = "*" +gunicorn = "*" + +[dev-packages] + +[requires] +python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100755 index 0000000..d0c1e94 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,1738 @@ +{ + "_meta": { + "hash": { + "sha256": "13f0132cce9eb935f621d2125a287a38be5663622269f909283fb2218f860c68" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.12" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "annotated-types": { + "hashes": [ + "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", + "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" + ], + "markers": "python_version >= '3.8'", + "version": "==0.7.0" + }, + "anyio": { + "hashes": [ + "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", + "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==4.6.2.post1" + }, + "bcrypt": { + "hashes": [ + "sha256:01746eb2c4299dd0ae1670234bf77704f581dd72cc180f444bfe74eb80495b64", + "sha256:037c5bf7c196a63dcce75545c8874610c600809d5d82c305dd327cd4969995bf", + "sha256:094fd31e08c2b102a14880ee5b3d09913ecf334cd604af27e1013c76831f7b05", + "sha256:0d4cf6ef1525f79255ef048b3489602868c47aea61f375377f0d00514fe4a78c", + "sha256:193bb49eeeb9c1e2db9ba65d09dc6384edd5608d9d672b4125e9320af9153a15", + "sha256:2505b54afb074627111b5a8dc9b6ae69d0f01fea65c2fcaea403448c503d3991", + "sha256:2ee15dd749f5952fe3f0430d0ff6b74082e159c50332a1413d51b5689cf06623", + "sha256:31adb9cbb8737a581a843e13df22ffb7c84638342de3708a98d5c986770f2834", + "sha256:3a5be252fef513363fe281bafc596c31b552cf81d04c5085bc5dac29670faa08", + "sha256:3d3b317050a9a711a5c7214bf04e28333cf528e0ed0ec9a4e55ba628d0f07c1a", + "sha256:48429c83292b57bf4af6ab75809f8f4daf52aa5d480632e53707805cc1ce9b74", + "sha256:4a8bea4c152b91fd8319fef4c6a790da5c07840421c2b785084989bf8bbb7455", + "sha256:4fb253d65da30d9269e0a6f4b0de32bd657a0208a6f4e43d3e645774fb5457f3", + "sha256:551b320396e1d05e49cc18dd77d970accd52b322441628aca04801bbd1d52a73", + "sha256:5f7cd3399fbc4ec290378b541b0cf3d4398e4737a65d0f938c7c0f9d5e686611", + "sha256:6004f5229b50f8493c49232b8e75726b568535fd300e5039e255d919fc3a07f2", + "sha256:6717543d2c110a155e6821ce5670c1f512f602eabb77dba95717ca76af79867d", + "sha256:6cac78a8d42f9d120b3987f82252bdbeb7e6e900a5e1ba37f6be6fe4e3848286", + "sha256:8a893d192dfb7c8e883c4576813bf18bb9d59e2cfd88b68b725990f033f1b978", + "sha256:8cbb119267068c2581ae38790e0d1fbae65d0725247a930fc9900c285d95725d", + "sha256:9f8ea645eb94fb6e7bea0cf4ba121c07a3a182ac52876493870033141aa687bc", + "sha256:c4c8d9b3e97209dd7111bf726e79f638ad9224b4691d1c7cfefa571a09b1b2d6", + "sha256:cb9c707c10bddaf9e5ba7cdb769f3e889e60b7d4fea22834b261f51ca2b89fed", + "sha256:d84702adb8f2798d813b17d8187d27076cca3cd52fe3686bb07a9083930ce650", + "sha256:ec3c2e1ca3e5c4b9edb94290b356d082b721f3f50758bce7cce11d8a7c89ce84", + "sha256:f44a97780677e7ac0ca393bd7982b19dbbd8d7228c1afe10b128fd9550eef5f1", + "sha256:f5698ce5292a4e4b9e5861f7e53b1d89242ad39d54c3da451a93cac17b61921a" + ], + "markers": "python_version >= '3.7'", + "version": "==4.1.3" + }, + "build": { + "hashes": [ + "sha256:526263f4870c26f26c433545579475377b2b7588b6f1eac76a001e873ae3e19d", + "sha256:75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4" + ], + "markers": "python_version >= '3.8'", + "version": "==1.2.1" + }, + "cachecontrol": { + "extras": [ + "filecache" + ], + "hashes": [ + "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938", + "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" + }, + "certifi": { + "hashes": [ + "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", + "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==2024.7.4" + }, + "cffi": { + "hashes": [ + "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", + "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", + "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1", + "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", + "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", + "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", + "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", + "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", + "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", + "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc", + "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", + "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", + "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", + "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", + "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", + "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", + "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b", + "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", + "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", + "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c", + "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", + "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", + "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", + "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8", + "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1", + "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", + "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", + "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", + "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", + "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", + "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", + "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", + "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", + "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", + "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", + "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", + "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", + "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964", + "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", + "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", + "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", + "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", + "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", + "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", + "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", + "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", + "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", + "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", + "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", + "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", + "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", + "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9", + "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", + "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", + "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", + "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", + "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", + "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", + "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", + "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", + "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" + ], + "markers": "platform_python_implementation != 'PyPy'", + "version": "==1.17.1" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "check-manifest": { + "hashes": [ + "sha256:058cd30057714c39b96ce4d83f254fc770e3145c7b1932b5940b4e3efb5521ef", + "sha256:64a640445542cf226919657c7b78d02d9c1ca5b1c25d7e66e0e1ff325060f416" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.49" + }, + "cleo": { + "hashes": [ + "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523", + "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.1.0" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "crashtest": { + "hashes": [ + "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce", + "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==0.4.1" + }, + "cryptography": { + "hashes": [ + "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", + "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", + "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", + "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", + "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2", + "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", + "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", + "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", + "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", + "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", + "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d", + "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", + "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2", + "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", + "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", + "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", + "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", + "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", + "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", + "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", + "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", + "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", + "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", + "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", + "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", + "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", + "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==43.0.1" + }, + "distlib": { + "hashes": [ + "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", + "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64" + ], + "version": "==0.3.8" + }, + "dnspython": { + "hashes": [ + "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", + "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc" + ], + "markers": "python_version >= '3.8'", + "version": "==2.6.1" + }, + "docutils": { + "hashes": [ + "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2" + ], + "markers": "python_version >= '3.9'", + "version": "==0.21.2" + }, + "dulwich": { + "hashes": [ + "sha256:0fc3078a1ba04c588fabb0969d3530efd5cd1ce2cf248eefb6baf7cbc15fc285", + "sha256:10893105c6566fc95bc2a67b61df7cc1e8f9126d02a1df6a8b2b82eb59db8ab9", + "sha256:12d61334a575474e707614f2e93d6ed4cdae9eb47214f9277076d9e5615171d3", + "sha256:2590e9b431efa94fc356ae33b38f5e64f1834ec3a94a6ac3a64283b206d07aa3", + "sha256:25c3ab8fb2e201ad2031ddd32e4c68b7c03cb34b24a5ff477b7a7dcef86372f5", + "sha256:274c18ec3599a92a9b67abaf110e4f181a4f779ee1aaab9e23a72e89d71b2bd9", + "sha256:29bb5c1d70eba155ded41ed8a62be2f72edbb3c77b08f65b89c03976292f6d1b", + "sha256:2bc12697f0918bee324c18836053644035362bb3983dc1b210318f2fed1d7132", + "sha256:2e2c66888207b71cd1daa2acb06d3984a6bc13787b837397a64117aa9fc5936a", + "sha256:404b8edeb3c3a86c47c0a498699fc064c93fa1f8bab2ffe919e8ab03eafaaad3", + "sha256:40dcbd29ba30ba2c5bfbab07a61a5f20095541d5ac66d813056c122244df4ac0", + "sha256:460b3849d5c3d3818a80743b4f7a0094c893c559f678e56a02fff570b49a644a", + "sha256:460ba74bdb19f8d498786ae7776745875059b1178066208c0fd509792d7f7bfc", + "sha256:4637cbd8ed1012f67e1068aaed19fcc8b649bcf3e9e26649826a303298c89b9d", + "sha256:471305af74790827fcbafe330fc2e8bdcee4fb56ca1177c8c481b1c8f806c4a4", + "sha256:4a043b90958cec866b4edc6aef5fe3c2c96a664d0b357e1682a46f6c477273c4", + "sha256:4b09bc3a64fb70132ec14326ecbe6e0555381108caff3496898962c4136a48c6", + "sha256:4bc4c5366eaf26dda3fdffe160a3b515666ed27c2419f1d483da285ac1411de0", + "sha256:4c51058ec4c0b45dc5189225b9e0c671b96ca9713c1daf71d622c13b0ab07681", + "sha256:4f18f0a311fb7734b033a3101292b932158cade54b74d1c44db519e42825e5a2", + "sha256:61e3451bd3d3844f2dca53f131982553be4d1b1e1ebd9db701843dd76c4dba31", + "sha256:62bfb26bdce869cd40be443dfd93143caea7089b165d2dcc33de40f6ac9d812a", + "sha256:675a612ce913081beb0f37b286891e795d905691dfccfb9bf73721dca6757cde", + "sha256:6bd69921fdd813b7469a3c77bc75c1783cc1d8d72ab15a406598e5a3ba1a1503", + "sha256:6c589468e5c0cd84e97eb7ec209ab005a2cb69399e8c5861c3edfe38989ac3a8", + "sha256:6de6f8de4a453fdbae8062a6faa652255d22a3d8bce0cd6d2d6701305c75f2b3", + "sha256:739b191f61e1c4ce18ac7d520e7a7cbda00e182c3489552408237200ce8411ad", + "sha256:74700e4c7d532877355743336c36f51b414d01e92ba7d304c4f8d9a5946dbc81", + "sha256:7836da3f4110ce684dcd53489015fb7fa94ed33c5276e3318b8b1cbcb5b71e08", + "sha256:7bca4b86e96d6ef18c5bc39828ea349efb5be2f9b1f6ac9863f90589bac1084d", + "sha256:7d8ab29c660125db52106775caa1f8f7f77a69ed1fe8bc4b42bdf115731a25bf", + "sha256:808e8b9cc0aa9ac74870b49db4f9f39a52fb61694573f84b9c0613c928d4caf8", + "sha256:817822f970e196e757ae01281ecbf21369383285b9f4a83496312204cf889b8c", + "sha256:8278835e168dd097089f9e53088c7a69c6ca0841aef580d9603eafe9aea8c358", + "sha256:858842b30ad6486aacaa607d60bab9c9a29e7c59dc2d9cb77ae5a94053878c08", + "sha256:869eb7be48243e695673b07905d18b73d1054a85e1f6e298fe63ba2843bb2ca1", + "sha256:8869fc8ec3dda743e03d06d698ad489b3705775fe62825e00fa95aa158097fc0", + "sha256:8929c37986c83deb4eb500c766ee28b6670285b512402647ee02a857320e377c", + "sha256:a0650ec77d89cb947e3e4bbd4841c96f74e52b4650830112c3057a8ca891dc2f", + "sha256:a7b5624b02ef808cdc62dabd47eb10cd4ac15e8ac6df9e2e88b6ac6b40133673", + "sha256:a9e9c66833cea580c3ac12927e4b9711985d76afca98da971405d414de60e968", + "sha256:b0d2e4485b98695bf95350ce9d38b1bb0aaac2c34ad00a0df789aa33c934469b", + "sha256:c01a735b9a171dcb634a97a3cec1b174cfbfa8e840156870384b633da0460f18", + "sha256:c3a539b4696a42fbdb7412cb7b66a4d4d332761299d3613d90a642923c7560e1", + "sha256:c3d1685f320907a52c40fd5890627945c51f3a5fa4bcfe10edb24fec79caadec", + "sha256:c92e72c43c9e9e936b01a57167e0ea77d3fd2d82416edf9489faa87278a1cdf7", + "sha256:cc1e11be527ac06316539b57a7688bcb1b6a3e53933bc2f844397bc50734e9ae", + "sha256:ce8db196e79c1f381469410d26fb1d8b89c6b87a4e7f00ff418c22a35121405c", + "sha256:d05d3c781bc74e2c2a2a8f4e4e2ed693540fbe88e6ac36df81deac574a6dad99", + "sha256:d097e963eb6b9fa53266146471531ad9c6765bf390849230311514546ed64db2", + "sha256:d4a2d76c96426e791556836ef43542b639def81be4f1d6d4322cd886c115eae1", + "sha256:d4c0110798099bb7d36a110090f2688050703065448895c4f53ade808d889dd3", + "sha256:d54c9d0e845be26f65f954dff13a1cd3f2b9739820c19064257b8fd7435ab263", + "sha256:d5882e70b74ac3c736a42d3fdd4f5f2e6570637f59ad5d3e684760290b58f041", + "sha256:d62446797163317a397a10080c6397ffaaca51a7804c0120b334f8165736c56a", + "sha256:d96ca5e0dde49376fbcb44f10eddb6c30284a87bd03bb577c59bb0a1f63903fa", + "sha256:e0064363bd5e814359657ae32517fa8001e8573d9d040bd997908d488ab886ed", + "sha256:e138d516baa6b5bafbe8f030eccc544d0d486d6819b82387fc0e285e62ef5261", + "sha256:e1957b65f96e36c301e419d7adaadcff47647c30eb072468901bb683b1000bc5", + "sha256:e25953c7acbbe4e19650d0225af1c0c0e6882f8bddd2056f75c1cc2b109b88ad", + "sha256:e274cebaf345f0b1e3b70197f2651de92b652386b68020cfd3bf61bc30f6eaaa", + "sha256:e598d743c6c0548ebcd2baf94aa9c8bfacb787ea671eeeb5828cfbd7d56b552f", + "sha256:e84cc606b1f581733df4350ca4070e6a8b30be3662bbb81a590b177d0c996c91", + "sha256:ecd315847dea406a4decfa39d388a2521e4e31acde3bd9c2609c989e817c6d62", + "sha256:ed60d1f610ef6437586f7768254c2a93820ccbd4cfdac7d182cf2d6e615969bb", + "sha256:f34bf9b9fa9308376263fd9ac43143c7c09da9bc75037bb75c6c2423a151b92c", + "sha256:f6c88acb60a1f4d31bd6d13bfba465853b3df940ee4a0f2a3d6c7a0778c705b7", + "sha256:fa4d14767cf7a49c9231c2e52cb2a3e90d0c83f843eb6a2ca2b5d81d254cf6b9", + "sha256:ffc27fb063f740712e02b4d2f826aee8bbed737ed799962fef625e2ce56e2d29" + ], + "markers": "python_version >= '3.7'", + "version": "==0.21.7" + }, + "email-validator": { + "hashes": [ + "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", + "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.0" + }, + "fastapi": { + "extras": [ + "all" + ], + "hashes": [ + "sha256:97ecbf994be0bcbdadedf88c3150252bed7b2087075ac99735403b1b76cc8fc0", + "sha256:b9db9dd147c91cb8b769f7183535773d8741dd46f9dc6676cd82eab510228cd7" + ], + "markers": "python_version >= '3.8'", + "version": "==0.111.0" + }, + "fastapi-cli": { + "hashes": [ + "sha256:a2552f3a7ae64058cdbb530be6fa6dbfc975dc165e4fa66d224c3d396e25e809", + "sha256:e2e9ffaffc1f7767f488d6da34b6f5a377751c996f397902eb6abb99a67bde32" + ], + "markers": "python_version >= '3.8'", + "version": "==0.0.4" + }, + "fastjsonschema": { + "hashes": [ + "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23", + "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a" + ], + "version": "==2.20.0" + }, + "filelock": { + "hashes": [ + "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb", + "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7" + ], + "version": "==3.15.4" + }, + "gunicorn": { + "hashes": [ + "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9", + "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==22.0.0" + }, + "h11": { + "hashes": [ + "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", + "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" + }, + "httpcore": { + "hashes": [ + "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", + "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.0.5" + }, + "httptools": { + "hashes": [ + "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563", + "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142", + "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d", + "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b", + "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4", + "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb", + "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658", + "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084", + "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2", + "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97", + "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837", + "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3", + "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58", + "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da", + "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d", + "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90", + "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0", + "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1", + "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2", + "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e", + "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0", + "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf", + "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc", + "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3", + "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503", + "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a", + "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3", + "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949", + "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84", + "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb", + "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a", + "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f", + "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e", + "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81", + "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185", + "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3" + ], + "version": "==0.6.1" + }, + "httpx": { + "hashes": [ + "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", + "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5" + ], + "markers": "python_version >= '3.8'", + "version": "==0.27.0" + }, + "idna": { + "hashes": [ + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + ], + "markers": "python_version >= '3.6'", + "version": "==3.10" + }, + "importlib-metadata": { + "hashes": [ + "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68", + "sha256:ffef94b0b66046dd8ea2d619b701fe978d9264d38f3998bc4c27ec3b146a87c8" + ], + "markers": "python_version >= '3.8'", + "version": "==7.2.1" + }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "installer": { + "hashes": [ + "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631" + ], + "markers": "python_version >= '3.7'", + "version": "==0.7.0" + }, + "invoke": { + "hashes": [ + "sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820", + "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==2.2.0" + }, + "itsdangerous": { + "hashes": [ + "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", + "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" + ], + "version": "==2.2.0" + }, + "jaraco.classes": { + "hashes": [ + "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" + ], + "markers": "python_version >= '3.8'", + "version": "==3.4.0" + }, + "jeepney": { + "hashes": [ + "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", + "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755" + ], + "markers": "sys_platform == 'linux'", + "version": "==0.8.0" + }, + "jinja2": { + "hashes": [ + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==3.1.4" + }, + "keyring": { + "hashes": [ + "sha256:c3327b6ffafc0e8befbdb597cacdb4928ffe5c1212f7645f186e6d9957a898db", + "sha256:df38a4d7419a6a60fea5cef1e45a948a3e8430dd12ad88b0f423c5c143906218" + ], + "markers": "python_version >= '3.8'", + "version": "==24.3.1" + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "markupsafe": { + "hashes": [ + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.5" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "more-itertools": { + "hashes": [ + "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463", + "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320" + ], + "markers": "python_version >= '3.8'", + "version": "==10.3.0" + }, + "msgpack": { + "hashes": [ + "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982", + "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3", + "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40", + "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee", + "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693", + "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950", + "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151", + "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24", + "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305", + "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b", + "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c", + "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659", + "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d", + "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18", + "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746", + "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868", + "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2", + "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba", + "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228", + "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2", + "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273", + "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c", + "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653", + "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a", + "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596", + "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd", + "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8", + "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa", + "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85", + "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc", + "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836", + "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3", + "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58", + "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128", + "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db", + "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f", + "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77", + "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad", + "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13", + "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8", + "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b", + "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a", + "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543", + "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b", + "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce", + "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d", + "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a", + "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c", + "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f", + "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e", + "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011", + "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04", + "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480", + "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a", + "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d", + "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d" + ], + "markers": "python_version >= '3.8'", + "version": "==1.0.8" + }, + "netbox-proxbox": { + "hashes": [ + "sha256:7fa4a3cb7ceaa1f2f374ed2ffbf765457aa94e1b456df17023131dcb1c2f9cde", + "sha256:ab0e6cabb367b7d6f41745322b266aa421b8d8a9b0d987b249b2e3d7da0ab6ee" + ], + "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==0.0.5" + }, + "nh3": { + "hashes": [ + "sha256:0316c25b76289cf23be6b66c77d3608a4fdf537b35426280032f432f14291b9a", + "sha256:1a814dd7bba1cb0aba5bcb9bebcc88fd801b63e21e2450ae6c52d3b3336bc911", + "sha256:1aa52a7def528297f256de0844e8dd680ee279e79583c76d6fa73a978186ddfb", + "sha256:22c26e20acbb253a5bdd33d432a326d18508a910e4dcf9a3316179860d53345a", + "sha256:40015514022af31975c0b3bca4014634fa13cb5dc4dbcbc00570acc781316dcc", + "sha256:40d0741a19c3d645e54efba71cb0d8c475b59135c1e3c580f879ad5514cbf028", + "sha256:551672fd71d06cd828e282abdb810d1be24e1abb7ae2543a8fa36a71c1006fe9", + "sha256:66f17d78826096291bd264f260213d2b3905e3c7fae6dfc5337d49429f1dc9f3", + "sha256:85cdbcca8ef10733bd31f931956f7fbb85145a4d11ab9e6742bbf44d88b7e351", + "sha256:a3f55fabe29164ba6026b5ad5c3151c314d136fd67415a17660b4aaddacf1b10", + "sha256:b4427ef0d2dfdec10b641ed0bdaf17957eb625b2ec0ea9329b3d28806c153d71", + "sha256:ba73a2f8d3a1b966e9cdba7b211779ad8a2561d2dba9674b8a19ed817923f65f", + "sha256:c21bac1a7245cbd88c0b0e4a420221b7bfa838a2814ee5bb924e9c2f10a1120b", + "sha256:c551eb2a3876e8ff2ac63dff1585236ed5dfec5ffd82216a7a174f7c5082a78a", + "sha256:c790769152308421283679a142dbdb3d1c46c79c823008ecea8e8141db1a2062", + "sha256:d7a25fd8c86657f5d9d576268e3b3767c5cd4f42867c9383618be8517f0f022a" + ], + "version": "==0.2.17" + }, + "orjson": { + "hashes": [ + "sha256:03b565c3b93f5d6e001db48b747d31ea3819b89abf041ee10ac6988886d18e01", + "sha256:099e81a5975237fda3100f918839af95f42f981447ba8f47adb7b6a3cdb078fa", + "sha256:10c0eb7e0c75e1e486c7563fe231b40fdd658a035ae125c6ba651ca3b07936f5", + "sha256:1146bf85ea37ac421594107195db8bc77104f74bc83e8ee21a2e58596bfb2f04", + "sha256:1670fe88b116c2745a3a30b0f099b699a02bb3482c2591514baf5433819e4f4d", + "sha256:185c394ef45b18b9a7d8e8f333606e2e8194a50c6e3c664215aae8cf42c5385e", + "sha256:1ad1de7fef79736dde8c3554e75361ec351158a906d747bd901a52a5c9c8d24b", + "sha256:235dadefb793ad12f7fa11e98a480db1f7c6469ff9e3da5e73c7809c700d746b", + "sha256:28afa96f496474ce60d3340fe8d9a263aa93ea01201cd2bad844c45cd21f5268", + "sha256:2d97531cdfe9bdd76d492e69800afd97e5930cb0da6a825646667b2c6c6c0211", + "sha256:338fd4f071b242f26e9ca802f443edc588fa4ab60bfa81f38beaedf42eda226c", + "sha256:36a10f43c5f3a55c2f680efe07aa93ef4a342d2960dd2b1b7ea2dd764fe4a37c", + "sha256:3d21b9983da032505f7050795e98b5d9eee0df903258951566ecc358f6696969", + "sha256:51bbcdea96cdefa4a9b4461e690c75ad4e33796530d182bdd5c38980202c134a", + "sha256:53ed1c879b10de56f35daf06dbc4a0d9a5db98f6ee853c2dbd3ee9d13e6f302f", + "sha256:545d493c1f560d5ccfc134803ceb8955a14c3fcb47bbb4b2fee0232646d0b932", + "sha256:584c902ec19ab7928fd5add1783c909094cc53f31ac7acfada817b0847975f26", + "sha256:5a35455cc0b0b3a1eaf67224035f5388591ec72b9b6136d66b49a553ce9eb1e6", + "sha256:5df58d206e78c40da118a8c14fc189207fffdcb1f21b3b4c9c0c18e839b5a214", + "sha256:64c9cc089f127e5875901ac05e5c25aa13cfa5dbbbd9602bda51e5c611d6e3e2", + "sha256:68f85ecae7af14a585a563ac741b0547a3f291de81cd1e20903e79f25170458f", + "sha256:6970ed7a3126cfed873c5d21ece1cd5d6f83ca6c9afb71bbae21a0b034588d96", + "sha256:6b68742c469745d0e6ca5724506858f75e2f1e5b59a4315861f9e2b1df77775a", + "sha256:7a5baef8a4284405d96c90c7c62b755e9ef1ada84c2406c24a9ebec86b89f46d", + "sha256:7d10cc1b594951522e35a3463da19e899abe6ca95f3c84c69e9e901e0bd93d38", + "sha256:85c89131d7b3218db1b24c4abecea92fd6c7f9fab87441cfc342d3acc725d807", + "sha256:8a11d459338f96a9aa7f232ba95679fc0c7cedbd1b990d736467894210205c09", + "sha256:8c13ca5e2ddded0ce6a927ea5a9f27cae77eee4c75547b4297252cb20c4d30e6", + "sha256:9cd684927af3e11b6e754df80b9ffafd9fb6adcaa9d3e8fdd5891be5a5cad51e", + "sha256:b2efbd67feff8c1f7728937c0d7f6ca8c25ec81373dc8db4ef394c1d93d13dc5", + "sha256:b39e006b00c57125ab974362e740c14a0c6a66ff695bff44615dcf4a70ce2b86", + "sha256:b6c8e30adfa52c025f042a87f450a6b9ea29649d828e0fec4858ed5e6caecf63", + "sha256:be79e2393679eda6a590638abda16d167754393f5d0850dcbca2d0c3735cebe2", + "sha256:c05f16701ab2a4ca146d0bca950af254cb7c02f3c01fca8efbbad82d23b3d9d4", + "sha256:c4057c3b511bb8aef605616bd3f1f002a697c7e4da6adf095ca5b84c0fd43595", + "sha256:c4a65310ccb5c9910c47b078ba78e2787cb3878cdded1702ac3d0da71ddc5228", + "sha256:ca0b3a94ac8d3886c9581b9f9de3ce858263865fdaa383fbc31c310b9eac07c9", + "sha256:cc28e90a7cae7fcba2493953cff61da5a52950e78dc2dacfe931a317ee3d8de7", + "sha256:cdf7365063e80899ae3a697def1277c17a7df7ccfc979990a403dfe77bb54d40", + "sha256:d69858c32f09c3e1ce44b617b3ebba1aba030e777000ebdf72b0d8e365d0b2b3", + "sha256:dbead71dbe65f959b7bd8cf91e0e11d5338033eba34c114f69078d59827ee139", + "sha256:dcbe82b35d1ac43b0d84072408330fd3295c2896973112d495e7234f7e3da2e1", + "sha256:dfc91d4720d48e2a709e9c368d5125b4b5899dced34b5400c3837dadc7d6271b", + "sha256:eded5138cc565a9d618e111c6d5c2547bbdd951114eb822f7f6309e04db0fb47", + "sha256:f4324929c2dd917598212bfd554757feca3e5e0fa60da08be11b4aa8b90013c1", + "sha256:fb66215277a230c456f9038d5e2d84778141643207f85336ef8d2a9da26bd7ca" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.10.5" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "paramiko": { + "hashes": [ + "sha256:43f0b51115a896f9c00f59618023484cb3a14b98bbceab43394a39c6739b7ee7", + "sha256:aac08f26a31dc4dffd92821527d1682d99d52f9ef6851968114a8728f3c274d3" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==3.4.0" + }, + "pexpect": { + "hashes": [ + "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", + "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" + ], + "version": "==4.9.0" + }, + "pkginfo": { + "hashes": [ + "sha256:2e0dca1cf4c8e39644eed32408ea9966ee15e0d324c62ba899a393b3c6b467aa", + "sha256:bfa76a714fdfc18a045fcd684dbfc3816b603d9d075febef17cb6582bea29573" + ], + "markers": "python_version >= '3.8'", + "version": "==1.11.1" + }, + "platformdirs": { + "hashes": [ + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" + ], + "markers": "python_version >= '3.8'", + "version": "==4.2.2" + }, + "pluggy": { + "hashes": [ + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" + ], + "markers": "python_version >= '3.8'", + "version": "==1.5.0" + }, + "poetry": { + "hashes": [ + "sha256:67f4eb68288eab41e841cc71a00d26cf6bdda9533022d0189a145a34d0a35f48", + "sha256:88191c69b08d06f9db671b793d68f40048e8904c0718404b63dcc2b5aec62d13" + ], + "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==1.8.3" + }, + "poetry-core": { + "hashes": [ + "sha256:4e0c9c6ad8cf89956f03b308736d84ea6ddb44089d16f2adc94050108ec1f5a1", + "sha256:fa7a4001eae8aa572ee84f35feb510b321bd652e5cf9293249d62853e1f935a2" + ], + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==1.9.0" + }, + "poetry-plugin-export": { + "hashes": [ + "sha256:1fa6168a85d59395d835ca564bc19862a7c76061e60c3e7dfaec70d50937fc61", + "sha256:adbe232cfa0cc04991ea3680c865cf748bff27593b9abcb1f35fb50ed7ba2c22" + ], + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==1.8.0" + }, + "proxmoxer": { + "hashes": [ + "sha256:088923f1a81ee27631e88314c609bfe22b33d8a41271b5f02e86f996f837fe31", + "sha256:badb3095507e486b76dfda75177545dd85da608a3aef8590d362901253f10576" + ], + "index": "pypi", + "version": "==2.0.1" + }, + "ptyprocess": { + "hashes": [ + "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", + "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" + ], + "version": "==0.7.0" + }, + "pycparser": { + "hashes": [ + "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" + ], + "markers": "python_version >= '3.8'", + "version": "==2.22" + }, + "pydantic": { + "hashes": [ + "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52", + "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.7.4" + }, + "pydantic-core": { + "hashes": [ + "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3", + "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8", + "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8", + "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30", + "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a", + "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8", + "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d", + "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc", + "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2", + "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab", + "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077", + "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e", + "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9", + "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9", + "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef", + "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1", + "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507", + "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528", + "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558", + "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b", + "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154", + "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724", + "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695", + "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9", + "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851", + "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805", + "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a", + "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5", + "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94", + "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c", + "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d", + "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef", + "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26", + "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2", + "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c", + "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0", + "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2", + "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4", + "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d", + "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2", + "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce", + "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34", + "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f", + "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d", + "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b", + "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07", + "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312", + "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057", + "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d", + "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af", + "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb", + "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd", + "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78", + "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b", + "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223", + "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a", + "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4", + "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5", + "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23", + "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a", + "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4", + "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8", + "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d", + "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443", + "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e", + "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f", + "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e", + "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d", + "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc", + "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443", + "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be", + "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2", + "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee", + "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f", + "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae", + "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864", + "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4", + "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951", + "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc" + ], + "markers": "python_version >= '3.8'", + "version": "==2.18.4" + }, + "pydantic-extra-types": { + "hashes": [ + "sha256:4d2b3c52c1e2e4dfa31bf1d5a37b841b09e3c5a08ec2bffca0e07fc2ad7d5c4a", + "sha256:f2400b3c3553fb7fa09a131967b4edf2d53f01ad9fa89d158784653f2e5c13d1" + ], + "version": "==2.8.2" + }, + "pydantic-settings": { + "hashes": [ + "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a", + "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7" + ], + "version": "==2.3.4" + }, + "pygments": { + "hashes": [ + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + ], + "markers": "python_version >= '3.8'", + "version": "==2.18.0" + }, + "pynacl": { + "hashes": [ + "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", + "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", + "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", + "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", + "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", + "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", + "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", + "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", + "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", + "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543" + ], + "markers": "python_version >= '3.6'", + "version": "==1.5.0" + }, + "pynetbox": { + "hashes": [ + "sha256:9bc25f83ff126f12d26976e544a2f0f6c7c898c261e6d47f8a4144ab47686d81", + "sha256:b0bcef4c3a019516d2425ae0ce5509eae7f4f11ad4510c9fe9527d468f22529b" + ], + "index": "pypi", + "version": "==7.3.3" + }, + "pyproject-hooks": { + "hashes": [ + "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965", + "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2" + ], + "markers": "python_version >= '3.7'", + "version": "==1.1.0" + }, + "pytest": { + "hashes": [ + "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", + "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==8.2.2" + }, + "python-dotenv": { + "hashes": [ + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" + ], + "markers": "python_version >= '3.8'", + "version": "==1.0.1" + }, + "python-multipart": { + "hashes": [ + "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026", + "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215" + ], + "markers": "python_version >= '3.8'", + "version": "==0.0.9" + }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "version": "==6.0.1" + }, + "rapidfuzz": { + "hashes": [ + "sha256:05ee0696ebf0dfe8f7c17f364d70617616afc7dafe366532730ca34056065b8a", + "sha256:0c34139df09a61b1b557ab65782ada971b4a3bce7081d1b2bee45b0a52231adb", + "sha256:0d055da0e801c71dd74ba81d72d41b2fa32afa182b9fea6b4b199d2ce937450d", + "sha256:119c010e20e561249b99ca2627f769fdc8305b07193f63dbc07bca0a6c27e892", + "sha256:143caf7247449055ecc3c1e874b69e42f403dfc049fc2f3d5f70e1daf21c1318", + "sha256:14c9f268ade4c88cf77ab007ad0fdf63699af071ee69378de89fff7aa3cae134", + "sha256:153f23c03d4917f6a1fc2fb56d279cc6537d1929237ff08ee7429d0e40464a18", + "sha256:15e4158ac4b3fb58108072ec35b8a69165f651ba1c8f43559a36d518dbf9fb3f", + "sha256:17ff7f7eecdb169f9236e3b872c96dbbaf116f7787f4d490abd34b0116e3e9c8", + "sha256:21047f55d674614eb4b0ab34e35c3dc66f36403b9fbfae645199c4a19d4ed447", + "sha256:256e07d3465173b2a91c35715a2277b1ee3ae0b9bbab4e519df6af78570741d0", + "sha256:282d55700a1a3d3a7980746eb2fcd48c9bbc1572ebe0840d0340d548a54d01fe", + "sha256:2bc8391749e5022cd9e514ede5316f86e332ffd3cfceeabdc0b17b7e45198a8c", + "sha256:2c1d3ef3878f871abe6826e386c3d61b5292ef5f7946fe646f4206b85836b5da", + "sha256:35b7286f177e4d8ba1e48b03612f928a3c4bdac78e5651379cec59f95d8651e6", + "sha256:3617d1aa7716c57d120b6adc8f7c989f2d65bc2b0cbd5f9288f1fc7bf469da11", + "sha256:378d1744828e27490a823fc6fe6ebfb98c15228d54826bf4e49e4b76eb5f5579", + "sha256:3bb6546e7b6bed1aefbe24f68a5fb9b891cc5aef61bca6c1a7b1054b7f0359bb", + "sha256:3d8a57261ef7996d5ced7c8cba9189ada3fbeffd1815f70f635e4558d93766cb", + "sha256:3e6d27dad8c990218b8cd4a5c99cbc8834f82bb46ab965a7265d5aa69fc7ced7", + "sha256:41a81a9f311dc83d22661f9b1a1de983b201322df0c4554042ffffd0f2040c37", + "sha256:505d99131afd21529293a9a7b91dfc661b7e889680b95534756134dc1cc2cd86", + "sha256:51fa1ba84653ab480a2e2044e2277bd7f0123d6693051729755addc0d015c44f", + "sha256:5276df395bd8497397197fca2b5c85f052d2e6a66ffc3eb0544dd9664d661f95", + "sha256:53c7f27cdf899e94712972237bda48cfd427646aa6f5d939bf45d084780e4c16", + "sha256:53e06e4b81f552da04940aa41fc556ba39dee5513d1861144300c36c33265b76", + "sha256:5410dc848c947a603792f4f51b904a3331cf1dc60621586bfbe7a6de72da1091", + "sha256:57e7c5bf7b61c7320cfa5dde1e60e678d954ede9bb7da8e763959b2138391401", + "sha256:58c6a4936190c558d5626b79fc9e16497e5df7098589a7e80d8bff68148ff096", + "sha256:5b422c0a6fe139d5447a0766268e68e6a2a8c2611519f894b1f31f0a392b9167", + "sha256:5c7ca5b6050f18fdcacdada2dc5fb7619ff998cd9aba82aed2414eee74ebe6cd", + "sha256:5d0abbacdb06e27ff803d7ae0bd0624020096802758068ebdcab9bd49cf53115", + "sha256:5d0cb272d43e6d3c0dedefdcd9d00007471f77b52d2787a4695e9dd319bb39d2", + "sha256:5d6a210347d6e71234af5c76d55eeb0348b026c9bb98fe7c1cca89bac50fb734", + "sha256:5e2b827258beefbe5d3f958243caa5a44cf46187eff0c20e0b2ab62d1550327a", + "sha256:5e33f779391caedcba2ba3089fb6e8e557feab540e9149a5c3f7fea7a3a7df37", + "sha256:604e0502a39cf8e67fa9ad239394dddad4cdef6d7008fdb037553817d420e108", + "sha256:6073a46f61479a89802e3f04655267caa6c14eb8ac9d81a635a13805f735ebc1", + "sha256:6175682a829c6dea4d35ed707f1dadc16513270ef64436568d03b81ccb6bdb74", + "sha256:65f45be77ec82da32ce5709a362e236ccf801615cc7163b136d1778cf9e31b14", + "sha256:67201c02efc596923ad950519e0b75ceb78d524177ea557134d6567b9ac2c283", + "sha256:754b719a4990735f66653c9e9261dcf52fd4d925597e43d6b9069afcae700d21", + "sha256:77b5c4f3e72924d7845f0e189c304270066d0f49635cf8a3938e122c437e58de", + "sha256:790b0b244f3213581d42baa2fed8875f9ee2b2f9b91f94f100ec80d15b140ba9", + "sha256:802ca2cc8aa6b8b34c6fdafb9e32540c1ba05fca7ad60b3bbd7ec89ed1797a87", + "sha256:8319838fb5b7b5f088d12187d91d152b9386ce3979ed7660daa0ed1bff953791", + "sha256:83ea7ca577d76778250421de61fb55a719e45b841deb769351fc2b1740763050", + "sha256:858ba57c05afd720db8088a8707079e8d024afe4644001fe0dbd26ef7ca74a65", + "sha256:8709918da8a88ad73c9d4dd0ecf24179a4f0ceba0bee21efc6ea21a8b5290349", + "sha256:875b581afb29a7213cf9d98cb0f98df862f1020bce9d9b2e6199b60e78a41d14", + "sha256:87bb8d84cb41446a808c4b5f746e29d8a53499381ed72f6c4e456fe0f81c80a8", + "sha256:8add34061e5cd561c72ed4febb5c15969e7b25bda2bb5102d02afc3abc1f52d0", + "sha256:8f917eaadf5388466a95f6a236f678a1588d231e52eda85374077101842e794e", + "sha256:930b4e6fdb4d914390141a2b99a6f77a52beacf1d06aa4e170cba3a98e24c1bc", + "sha256:93981895602cf5944d89d317ae3b1b4cc684d175a8ae2a80ce5b65615e72ddd0", + "sha256:959a15186d18425d19811bea86a8ffbe19fd48644004d29008e636631420a9b7", + "sha256:964c08481aec2fe574f0062e342924db2c6b321391aeb73d68853ed42420fd6d", + "sha256:a24603dd05fb4e3c09d636b881ce347e5f55f925a6b1b4115527308a323b9f8e", + "sha256:a39890013f6d5b056cc4bfdedc093e322462ece1027a57ef0c636537bdde7531", + "sha256:a4fc7b784cf987dbddc300cef70e09a92ed1bce136f7bb723ea79d7e297fe76d", + "sha256:a56da3aff97cb56fe85d9ca957d1f55dbac7c27da927a86a2a86d8a7e17f80aa", + "sha256:a93250bd8fae996350c251e1752f2c03335bb8a0a5b0c7e910a593849121a435", + "sha256:a96c5225e840f1587f1bac8fa6f67562b38e095341576e82b728a82021f26d62", + "sha256:aca21c0a34adee582775da997a600283e012a608a107398d80a42f9a57ad323d", + "sha256:acbe4b6f1ccd5b90c29d428e849aa4242e51bb6cab0448d5f3c022eb9a25f7b1", + "sha256:ad04a3f5384b82933213bba2459f6424decc2823df40098920856bdee5fd6e88", + "sha256:afe7c72d3f917b066257f7ff48562e5d462d865a25fbcabf40fca303a9fa8d35", + "sha256:b300708c917ce52f6075bdc6e05b07c51a085733650f14b732c087dc26e0aaad", + "sha256:b398ea66e8ed50451bce5997c430197d5e4b06ac4aa74602717f792d8d8d06e2", + "sha256:b3bd0d9632088c63a241f217742b1cf86e2e8ae573e01354775bd5016d12138c", + "sha256:b5bc0fdbf419493163c5c9cb147c5fbe95b8e25844a74a8807dcb1a125e630cf", + "sha256:b770f85eab24034e6ef7df04b2bfd9a45048e24f8a808e903441aa5abde8ecdd", + "sha256:b777cd910ceecd738adc58593d6ed42e73f60ad04ecdb4a841ae410b51c92e0e", + "sha256:b80eb7cbe62348c61d3e67e17057cddfd6defab168863028146e07d5a8b24a89", + "sha256:b8ab0fa653d9225195a8ff924f992f4249c1e6fa0aea563f685e71b81b9fcccf", + "sha256:bc1991b4cde6c9d3c0bbcb83d5581dc7621bec8c666c095c65b4277233265a82", + "sha256:bdb8c5b8e29238ec80727c2ba3b301efd45aa30c6a7001123a6647b8e6f77ea4", + "sha256:c52970f7784518d7c82b07a62a26e345d2de8c2bd8ed4774e13342e4b3ff4200", + "sha256:c6e65a301fcd19fbfbee3a514cc0014ff3f3b254b9fd65886e8a9d6957fb7bca", + "sha256:c8444e921bfc3757c475c4f4d7416a7aa69b2d992d5114fe55af21411187ab0d", + "sha256:cbe93ba1725a8d47d2b9dca6c1f435174859427fbc054d83de52aea5adc65729", + "sha256:cde6b9d9ba5007077ee321ec722fa714ebc0cbd9a32ccf0f4dd3cc3f20952d71", + "sha256:d36447d21b05f90282a6f98c5a33771805f9222e5d0441d03eb8824e33e5bbb4", + "sha256:d861bf326ee7dabc35c532a40384541578cd1ec1e1b7db9f9ecbba56eb76ca22", + "sha256:dc1037507810833646481f5729901a154523f98cbebb1157ba3a821012e16402", + "sha256:dd789100fc852cffac1449f82af0da139d36d84fd9faa4f79fc4140a88778343", + "sha256:de077c468c225d4c18f7188c47d955a16d65f21aab121cbdd98e3e2011002c37", + "sha256:e53ed2e9b32674ce96eed80b3b572db9fd87aae6742941fb8e4705e541d861ce", + "sha256:e6e4b9380ed4758d0cb578b0d1970c3f32dd9e87119378729a5340cb3169f879", + "sha256:efe6e200a75a792d37b960457904c4fce7c928a96ae9e5d21d2bd382fe39066e", + "sha256:f50fed4a9b0c9825ff37cf0bccafd51ff5792090618f7846a7650f21f85579c9", + "sha256:f57e8305c281e8c8bc720515540e0580355100c0a7a541105c6cafc5de71daae", + "sha256:fd84b7f652a5610733400307dc732f57c4a907080bef9520412e6d9b55bc9adc" + ], + "markers": "python_version >= '3.8'", + "version": "==3.9.3" + }, + "readme-renderer": { + "hashes": [ + "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311", + "sha256:19db308d86ecd60e5affa3b2a98f017af384678c63c88e5d4556a380e674f3f9" + ], + "markers": "python_version >= '3.8'", + "version": "==43.0" + }, + "requests": { + "hashes": [ + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.32.3" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.0.0" + }, + "rfc3986": { + "hashes": [ + "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "rich": { + "hashes": [ + "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==13.7.1" + }, + "secretstorage": { + "hashes": [ + "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", + "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99" + ], + "markers": "sys_platform == 'linux'", + "version": "==3.3.3" + }, + "setuptools": { + "hashes": [ + "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650", + "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==70.1.1" + }, + "shellingham": { + "hashes": [ + "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", + "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de" + ], + "markers": "python_version >= '3.7'", + "version": "==1.5.4" + }, + "sniffio": { + "hashes": [ + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "starlette": { + "hashes": [ + "sha256:1a3139688fb298ce5e2d661d37046a66ad996ce94be4d4983be019a23a04ea35", + "sha256:c494a22fae73805376ea6bf88439783ecfba9aac88a43911b48c653437e784c4" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.40.0" + }, + "tomlkit": { + "hashes": [ + "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f", + "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c" + ], + "markers": "python_version >= '3.7'", + "version": "==0.12.5" + }, + "trove-classifiers": { + "hashes": [ + "sha256:8a6242bbb5c9ae88d34cf665e816b287d2212973c8777dfaef5ec18d72ac1d03", + "sha256:c43ade18704823e4afa3d9db7083294bc4708a5e02afbcefacd0e9d03a7a24ef" + ], + "version": "==2024.5.22" + }, + "twine": { + "hashes": [ + "sha256:4d74770c88c4fcaf8134d2a6a9d863e40f08255ff7d8e2acb3cbbd57d25f6e9d", + "sha256:fe1d814395bfe50cfbe27783cb74efe93abeac3f66deaeb6c8390e4e92bacb43" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==5.1.0" + }, + "typer": { + "hashes": [ + "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914", + "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482" + ], + "markers": "python_version >= '3.7'", + "version": "==0.12.3" + }, + "typing": { + "hashes": [ + "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9", + "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5" + ], + "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.7.4.3" + }, + "typing-extensions": { + "hashes": [ + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.2" + }, + "ujson": { + "hashes": [ + "sha256:0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e", + "sha256:129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b", + "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6", + "sha256:232cc85f8ee3c454c115455195a205074a56ff42608fd6b942aa4c378ac14dd7", + "sha256:2544912a71da4ff8c4f7ab5606f947d7299971bdd25a45e008e467ca638d13c9", + "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd", + "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569", + "sha256:2987713a490ceb27edff77fb184ed09acdc565db700ee852823c3dc3cffe455f", + "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51", + "sha256:2a890b706b64e0065f02577bf6d8ca3b66c11a5e81fb75d757233a38c07a1f20", + "sha256:2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1", + "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf", + "sha256:38665e7d8290188b1e0d57d584eb8110951a9591363316dd41cf8686ab1d0abc", + "sha256:38d5d36b4aedfe81dfe251f76c0467399d575d1395a1755de391e58985ab1c2e", + "sha256:3ff201d62b1b177a46f113bb43ad300b424b7847f9c5d38b1b4ad8f75d4a282a", + "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539", + "sha256:4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27", + "sha256:4c4fc16f11ac1612f05b6f5781b384716719547e142cfd67b65d035bd85af165", + "sha256:502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126", + "sha256:57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1", + "sha256:59e02cd37bc7c44d587a0ba45347cc815fb7a5fe48de16bf05caa5f7d0d2e816", + "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64", + "sha256:5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8", + "sha256:604a046d966457b6cdcacc5aa2ec5314f0e8c42bae52842c1e6fa02ea4bda42e", + "sha256:618efd84dc1acbd6bff8eaa736bb6c074bfa8b8a98f55b61c38d4ca2c1f7f287", + "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3", + "sha256:61e1591ed9376e5eddda202ec229eddc56c612b61ac6ad07f96b91460bb6c2fb", + "sha256:621e34b4632c740ecb491efc7f1fcb4f74b48ddb55e65221995e74e2d00bbff0", + "sha256:6627029ae4f52d0e1a2451768c2c37c0c814ffc04f796eb36244cf16b8e57043", + "sha256:67079b1f9fb29ed9a2914acf4ef6c02844b3153913eb735d4bf287ee1db6e557", + "sha256:6dea1c8b4fc921bf78a8ff00bbd2bfe166345f5536c510671bccececb187c80e", + "sha256:6e32abdce572e3a8c3d02c886c704a38a1b015a1fb858004e03d20ca7cecbb21", + "sha256:7223f41e5bf1f919cd8d073e35b229295aa8e0f7b5de07ed1c8fddac63a6bc5d", + "sha256:73814cd1b9db6fc3270e9d8fe3b19f9f89e78ee9d71e8bd6c9a626aeaeaf16bd", + "sha256:7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0", + "sha256:7663960f08cd5a2bb152f5ee3992e1af7690a64c0e26d31ba7b3ff5b2ee66337", + "sha256:78778a3aa7aafb11e7ddca4e29f46bc5139131037ad628cc10936764282d6753", + "sha256:7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804", + "sha256:7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f", + "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f", + "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5", + "sha256:98ba15d8cbc481ce55695beee9f063189dce91a4b08bc1d03e7f0152cd4bbdd5", + "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1", + "sha256:a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00", + "sha256:a65b6af4d903103ee7b6f4f5b85f1bfd0c90ba4eeac6421aae436c9988aa64a2", + "sha256:a984a3131da7f07563057db1c3020b1350a3e27a8ec46ccbfbf21e5928a43050", + "sha256:a9d2edbf1556e4f56e50fab7d8ff993dbad7f54bac68eacdd27a8f55f433578e", + "sha256:ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4", + "sha256:ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8", + "sha256:ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996", + "sha256:b0111b27f2d5c820e7f2dbad7d48e3338c824e7ac4d2a12da3dc6061cc39c8e6", + "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1", + "sha256:b9500e61fce0cfc86168b248104e954fead61f9be213087153d272e817ec7b4f", + "sha256:ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1", + "sha256:ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4", + "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b", + "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88", + "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518", + "sha256:c66962ca7565605b355a9ed478292da628b8f18c0f2793021ca4425abf8b01e5", + "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770", + "sha256:cc6139531f13148055d691e442e4bc6601f6dba1e6d521b1585d4788ab0bfad4", + "sha256:d2c75269f8205b2690db4572a4a36fe47cd1338e4368bc73a7a0e48789e2e35a", + "sha256:d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76", + "sha256:d4dc2fd6b3067c0782e7002ac3b38cf48608ee6366ff176bbd02cf969c9c20fe", + "sha256:d7d0e0ceeb8fe2468c70ec0c37b439dd554e2aa539a8a56365fd761edb418988", + "sha256:d8640fb4072d36b08e95a3a380ba65779d356b2fee8696afeb7794cf0902d0a1", + "sha256:dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5", + "sha256:dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b", + "sha256:e1402f0564a97d2a52310ae10a64d25bcef94f8dd643fcf5d310219d915484f7", + "sha256:e7ce306a42b6b93ca47ac4a3b96683ca554f6d35dd8adc5acfcd55096c8dfcb8", + "sha256:e82d4bb2138ab05e18f089a83b6564fee28048771eb63cdecf4b9b549de8a2cc", + "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a", + "sha256:f00ea7e00447918ee0eff2422c4add4c5752b1b60e88fcb3c067d4a21049a720", + "sha256:f3caf9cd64abfeb11a3b661329085c5e167abbe15256b3b68cb5d914ba7396f3", + "sha256:f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b", + "sha256:f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9", + "sha256:f8ccb77b3e40b151e20519c6ae6d89bfe3f4c14e8e210d910287f778368bb3d1", + "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==5.10.0" + }, + "urllib3": { + "hashes": [ + "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", + "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.2.2" + }, + "uvicorn": { + "extras": [ + "standard" + ], + "hashes": [ + "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81", + "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.30.1" + }, + "uvloop": { + "hashes": [ + "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", + "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", + "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", + "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", + "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", + "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", + "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", + "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", + "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", + "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", + "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", + "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", + "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", + "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", + "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", + "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", + "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", + "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", + "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", + "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", + "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", + "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", + "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", + "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", + "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", + "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", + "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", + "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", + "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", + "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", + "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" + ], + "version": "==0.19.0" + }, + "virtualenv": { + "hashes": [ + "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a", + "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589" + ], + "markers": "python_version >= '3.7'", + "version": "==20.26.3" + }, + "watchfiles": { + "hashes": [ + "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b", + "sha256:00ad0bcd399503a84cc688590cdffbe7a991691314dde5b57b3ed50a41319a31", + "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1", + "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab", + "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249", + "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd", + "sha256:0b04a2cbc30e110303baa6d3ddce8ca3664bc3403be0f0ad513d1843a41c97d1", + "sha256:0bc3b2f93a140df6806c8467c7f51ed5e55a931b031b5c2d7ff6132292e803d6", + "sha256:0c8e0aa0e8cc2a43561e0184c0513e291ca891db13a269d8d47cb9841ced7c71", + "sha256:103622865599f8082f03af4214eaff90e2426edff5e8522c8f9e93dc17caee13", + "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171", + "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1", + "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1", + "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c", + "sha256:25c817ff2a86bc3de3ed2df1703e3d24ce03479b27bb4527c57e722f8554d971", + "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb", + "sha256:280a4afbc607cdfc9571b9904b03a478fc9f08bbeec382d648181c695648202f", + "sha256:28324d6b28bcb8d7c1041648d7b63be07a16db5510bea923fc80b91a2a6cbed6", + "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27", + "sha256:28f393c1194b6eaadcdd8f941307fc9bbd7eb567995232c830f6aef38e8a6e88", + "sha256:2abeb79209630da981f8ebca30a2c84b4c3516a214451bfc5f106723c5f45843", + "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a", + "sha256:2f350cbaa4bb812314af5dab0eb8d538481e2e2279472890864547f3fe2281ed", + "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84", + "sha256:3973145235a38f73c61474d56ad6199124e7488822f3a4fc97c72009751ae3b0", + "sha256:3a0d883351a34c01bd53cfa75cd0292e3f7e268bacf2f9e33af4ecede7e21d1d", + "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2", + "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797", + "sha256:4cc382083afba7918e32d5ef12321421ef43d685b9a67cc452a6e6e18920890e", + "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35", + "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6", + "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e", + "sha256:5834e1f8b71476a26df97d121c0c0ed3549d869124ed2433e02491553cb468c2", + "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550", + "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e", + "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c", + "sha256:72a44e9481afc7a5ee3291b09c419abab93b7e9c306c9ef9108cb76728ca58d2", + "sha256:7a74436c415843af2a769b36bf043b6ccbc0f8d784814ba3d42fc961cdb0a9dc", + "sha256:8597b6f9dc410bdafc8bb362dac1cbc9b4684a8310e16b1ff5eee8725d13dcd6", + "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96", + "sha256:8c3e3675e6e39dc59b8fe5c914a19d30029e36e9f99468dddffd432d8a7b1c93", + "sha256:8dc1fc25a1dedf2dd952909c8e5cb210791e5f2d9bc5e0e8ebc28dd42fed7562", + "sha256:8fdebb655bb1ba0122402352b0a4254812717a017d2dc49372a1d47e24073795", + "sha256:9165bcab15f2b6d90eedc5c20a7f8a03156b3773e5fb06a790b54ccecdb73385", + "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f", + "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848", + "sha256:96eec15e5ea7c0b6eb5bfffe990fc7c6bd833acf7e26704eb18387fb2f5fd087", + "sha256:97b94e14b88409c58cdf4a8eaf0e67dfd3ece7e9ce7140ea6ff48b0407a593ec", + "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb", + "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232", + "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696", + "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2", + "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e", + "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67", + "sha256:b610fb5e27825b570554d01cec427b6620ce9bd21ff8ab775fc3a32f28bba63e", + "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68", + "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb", + "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be", + "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71", + "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c", + "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da", + "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39", + "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea", + "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a", + "sha256:d048ad5d25b363ba1d19f92dcf29023988524bee6f9d952130b316c5802069cb", + "sha256:d3e1f3cf81f1f823e7874ae563457828e940d75573c8fbf0ee66818c8b6a9099", + "sha256:d47e9ef1a94cc7a536039e46738e17cce058ac1593b2eccdede8bf72e45f372a", + "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538", + "sha256:dc1b9b56f051209be458b87edb6856a449ad3f803315d87b2da4c93b43a6fe72", + "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1", + "sha256:dc92d2d2706d2b862ce0568b24987eba51e17e14b79a1abcd2edc39e48e743c8", + "sha256:dd64f3a4db121bc161644c9e10a9acdb836853155a108c2446db2f5ae1778c3d", + "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d", + "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c", + "sha256:fe82d13461418ca5e5a808a9e40f79c1879351fcaeddbede094028e74d836e86" + ], + "version": "==0.22.0" + }, + "websockets": { + "hashes": [ + "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b", + "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6", + "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", + "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", + "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205", + "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892", + "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53", + "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", + "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", + "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c", + "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", + "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", + "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931", + "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", + "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370", + "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", + "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec", + "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", + "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62", + "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", + "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", + "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", + "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123", + "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9", + "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", + "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", + "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", + "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", + "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438", + "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137", + "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", + "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", + "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", + "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", + "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", + "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", + "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967", + "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", + "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d", + "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def", + "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", + "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", + "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2", + "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", + "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b", + "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28", + "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7", + "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d", + "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", + "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468", + "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8", + "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae", + "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611", + "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", + "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9", + "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", + "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", + "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2", + "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", + "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", + "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6", + "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", + "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", + "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", + "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", + "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399", + "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", + "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", + "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", + "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", + "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8", + "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==12.0" + }, + "zipp": { + "hashes": [ + "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19", + "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c" + ], + "markers": "python_version >= '3.8'", + "version": "==3.19.2" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index 82c60a1..fec04a7 100755 --- a/README.md +++ b/README.md @@ -1,20 +1,34 @@ -
- -
+> Although **Proxbox is under constant development**, I do it with **best effort** and **spare time**. I have no financial gain with this and hope you guys understand, as I know it is pretty useful to some people. If you want to **speed up its development**, solve the problem or create new features with your own code and create a **[Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests)** so that I can **review** it. **I also would like to appreciate the people who already contributed with code or/and bug reports.** Without this help, surely Proxbox would be much less useful as it is already today to several environments! +- -
- - -## Usage - -Compare Netbox and Proxmox information and update VM on Netbox, if any difference found using the **Netbox VM ID** - -```python ->>> from netbox_proxbox import proxbox_api - ->>> json_result = proxbox.update.virtual_machine(id = 1) ->>> print(json_result) -{ - "name": "Netbox", - "changes": { - "status": false, - "custom_fiedls": false, - "local_context": false, - "resources": false - }, - "result": true -} -``` -Compare Netbox and Proxmox information and update VM on Netbox, if any difference found using the **Proxmox VM ID** - -```python ->>> from netbox_proxbox import proxbox_api - ->>> json_result = proxbox.update.virtual_machine(proxmox_id = 414) ->>> print(json_result) -{ - "name": "Netbox", - "changes": { - "status": false, - "custom_fiedls": false, - "local_context": false, - "resources": false - }, - "result": true -} -``` - -Compare Netbox and Proxmox information and update VM on Netbox, if any difference found using the **VM Name** - -```python ->>> from netbox_proxbox import proxbox_api - ->>> json_result = proxbox.update.virtual_machine(name = 'Netbox') ->>> print(json_result) -{ - "name": "Netbox", - "changes": { - "status": true, - "custom_fiedls": false, - "local_context": false, - "resources": false - }, - "result": true -} -``` - -Updates all VM's at once on Netbox with the information gotten from Proxmox - -```python ->>> import proxbox - ->>> json_result = proxbox.update.all() ->>> print(json_result) -{ - "name": "Netbox", - "changes": { - "status": false, - "custom_fiedls": false, - "local_context": false, - "resources": false - }, - "result": true -}, -{ - "name": "GRAYLOG", - "changes": { - "status": false, - "custom_fiedls": false, - "local_context": false, - "resources": true - }, - "result": true -}, -{ - "name": "ZABBIX", - "changes": { - "status": false, - "custom_fiedls": true, - "local_context": true, - "resources": false - }, - "result": true -} -``` - -Compare all VM's on Netbox with Proxmox and delete VM on Netbox if it doesn't exist on Proxmox. - -```python ->>> from netbox_proxbox import proxbox_api - ->>> json_result = proxbox.remove.all() ->>> print(json_result) -[ - { - "name": "vm01", - "result": false, - "log": [ - "[OK] VM existe em ambos sistemas -> nfsen-debian" - ] - }, - { - "name": "vm02", - "result": false, - "log": [ - "[OK] VM existe em ambos sistemas -> nmt-backend" - ] - }, - { - "name": "vm03", - "result": true, - "log": [ - "[WARNING] VM existe no Netbox, mas não no Proxmox. Deletar a VM! -> teste123", - "[OK] VM removida do Netbox com sucesso" - ] - } -] -``` diff --git a/netbox_proxbox/proxbox_api/__init__.py b/netbox_proxbox/proxbox_api/__init__.py deleted file mode 100755 index 0b8d82a..0000000 --- a/netbox_proxbox/proxbox_api/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from . import ( - update, - create, - updates, - remove, - plugins_config, -) - - - - - - - - diff --git a/netbox_proxbox/proxbox_api/create/__init__.py b/netbox_proxbox/proxbox_api/create/__init__.py deleted file mode 100755 index a87e385..0000000 --- a/netbox_proxbox/proxbox_api/create/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from . import ( - dcim, - virtualization, - extras, -) \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/create/dcim.py b/netbox_proxbox/proxbox_api/create/dcim.py deleted file mode 100755 index 6aad84b..0000000 --- a/netbox_proxbox/proxbox_api/create/dcim.py +++ /dev/null @@ -1,165 +0,0 @@ -# PLUGIN_CONFIG variables -from ..plugins_config import ( - NETBOX_SESSION as nb, - NETBOX_NODE_ROLE_ID, - NETBOX_SITE_ID, -) - -from . import ( - extras, - virtualization, -) - - - -# -# dcim.manufacturers -# -def manufacturer(): - proxbox_manufacturer_name = 'Proxbox Basic Manufacturer' - proxbox_manufacturer_slug = 'proxbox-manufacturer' - proxbox_manufacturer_desc = 'Manufacturer Proxbox will use if none is configured by user in PLUGINS_CONFIG' - - # Check if Proxbox manufacturer already exists. - proxbox_manufacturer = nb.dcim.manufacturers.get( - name = proxbox_manufacturer_name, - slug = proxbox_manufacturer_slug, - ) - - if proxbox_manufacturer == None: - try: - # If Proxbox manufacturer does not exist, create one. - manufacturer = nb.dcim.manufacturers.create( - name = proxbox_manufacturer_name, - slug = proxbox_manufacturer_slug, - description = proxbox_manufacturer_desc - ) - except: - return "Error creating the '{0}' manufacturer. Possible errors: the name '{0}' or slug '{1}' is already used.".format(proxbox_manufacturer_name, proxbox_manufacturer_slug) - - else: - manufacturer = proxbox_manufacturer - - return manufacturer - - - - - -# -# dcim.device_types -# -def device_type(): - proxbox_device_type_model = 'Proxbox Model' - proxbox_device_type_slug = 'proxbox-model' - proxbox_device_type_comments = "Device Type Proxbox will use when creating the Cluster's Nodes. When the Node is created, you can change the device type to the actual server model." - - # Check if Proxbox manufacturer already exists. - proxbox_device_types = nb.dcim.device_types.get( - model = proxbox_device_type_model, - slug = proxbox_device_type_slug - ) - - if proxbox_device_types == None: - try: - # If Proxbox manufacturer does not exist, create one. - device_type = nb.dcim.device_types.create( - manufacturer = manufacturer().id, - model = proxbox_device_type_model, - slug = proxbox_device_type_slug, - comments = proxbox_device_type_comments, - tags = [extras.tag().id] - ) - except: - return "Error creating the '{0}' device type. Possible errors: the model '{0}' or slug '{1}' is already used.".format(proxbox_device_type_model, proxbox_device_type_slug) - - else: - device_type = proxbox_device_types - - return device_type - - - - - -# -# dcim.sites -# -def site(**kwargs): - # If site_id equals to 0, consider it is not configured by user and must be created by Proxbox - site_id = kwargs.get('site_id', 0) - - if not isinstance(site_id, int): - return 'Site ID must be INTEGER. Netbox PLUGINS_CONFIG is configured incorrectly.' - - # If user configured SITE_ID in Netbox's PLUGINS_CONFIG, use it. - if site_id > 0: - site = nb.dcim.sites.get(id = site_id) - - if site == None: - return "Role ID of Virtual Machine or Node invalid. Maybe the ID passed does not exist or it is not a integer!" - - elif site_id == 0: - site_proxbox_name = "Proxbox Basic Site" - site_proxbox_slug = 'proxbox-basic-site' - - # Verify if basic site is already created - site_proxbox = nb.dcim.sites.get( - name = site_proxbox_name, - slug = site_proxbox_slug - ) - - # Create a basic Proxbox site if not created yet. - if site_proxbox == None: - try: - site = nb.dcim.sites.create( - name = site_proxbox_name, - slug = site_proxbox_slug, - status = 'active', - tags = [extras.tag().id] - ) - except: - return "Error creating the '{0}' site. Possible errors: the name '{0}' or slug '{1}' is already used.".format(site_proxbox_name, site_proxbox_slug) - - # If basic site already created, use it. - else: - site = site_proxbox - - else: - return 'Site ID configured is invalid.' - - return site - - - - - - -# -# dcim.devices (nodes) -# -def node(proxmox_node): - # Create json with basic NODE information - node_json = {} - node_json["name"] = proxmox_node['name'] - node_json["device_role"] = extras.role(role_id = NETBOX_NODE_ROLE_ID).id - node_json["device_type"] = device_type().id - node_json["site"] = site(site_id = NETBOX_SITE_ID).id - node_json["status"] = 'active' - node_json["tags"] = [extras.tag().id] - node_json["cluster"] = virtualization.cluster().id - - # Create Node with json 'node_json' - try: - netbox_obj = nb.dcim.devices.create(node_json) - - except: - print("[proxbox_api.create.node] Creation of NODE failed.") - netbox_obj = None - - else: - return netbox_obj - - # In case nothing works, returns error - netbox_obj = None - return netbox_obj \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/create/extras.py b/netbox_proxbox/proxbox_api/create/extras.py deleted file mode 100755 index 67da512..0000000 --- a/netbox_proxbox/proxbox_api/create/extras.py +++ /dev/null @@ -1,87 +0,0 @@ -# PLUGIN_CONFIG variables -from ..plugins_config import ( - NETBOX_SESSION as nb, -) - -# -# extras.tags -# -def tag(): - proxbox_tag_name = 'Proxbox' - proxbox_tag_slug = 'proxbox' - - # Check if Proxbox tag already exists. - proxbox_tag = nb.extras.tags.get( - name = proxbox_tag_name, - slug = proxbox_tag_slug - ) - - if proxbox_tag == None: - try: - # If Proxbox tag does not exist, create one. - tag = nb.extras.tags.create( - name = proxbox_tag_name, - slug = proxbox_tag_slug, - color = 'ff5722', - description = "Proxbox Identifier (used to identify the items the plugin created)" - ) - except: - return "Error creating the '{0}' tag. Possible errors: the name '{0}' or slug '{1}' is already used.".format(proxbox_tag_name, proxbox_tag_slug) - else: - tag = proxbox_tag - - return tag - - - - - -# -# dcim.device_roles -# -# OBS: this function is here and not in ./dcim.py since it is used by both NODE and VIRTUAL MACHINE. -def role(**kwargs): - # If role_id equals to 0, consider it is not configured by user and must be created by Proxbox - role_id = kwargs.get("role_id", 0) - - if not isinstance(role_id, int): - return 'Role ID must be INTEGER. Netbox PLUGINS_CONFIG is configured incorrectly.' - - # If user configured ROLE_ID in Netbox's PLUGINS_CONFIG, use it. - if role_id > 0: - role = nb.dcim.device_roles.get(id = role_id) - - if role == None: - return "Role ID of Virtual Machine or Node invalid. Maybe the ID passed does not exist or it is not a integer!" - - elif role_id == 0: - role_proxbox_name = "Proxbox Basic Role" - role_proxbox_slug = 'proxbox-basic-role' - - # Verify if basic role is already created - role_proxbox = nb.dcim.device_roles.get( - name = role_proxbox_name, - slug = role_proxbox_slug - ) - - # Create a basic Proxbox VM/Node Role if not created yet. - if role_proxbox == None: - - try: - role = nb.dcim.device_roles.create( - name = role_proxbox_name, - slug = role_proxbox_slug, - color = 'ff5722', - vm_role = True - ) - except: - return "Error creating the '{0}' role. Possible errors: the name '{0}' or slug '{1}' is already used.".format(role_proxbox_name, role_proxbox_slug) - - # If basic role already created, use it. - else: - role = role_proxbox - - else: - return 'Role ID configured is invalid.' - - return role \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/create/virtualization.py b/netbox_proxbox/proxbox_api/create/virtualization.py deleted file mode 100755 index 4466bb7..0000000 --- a/netbox_proxbox/proxbox_api/create/virtualization.py +++ /dev/null @@ -1,129 +0,0 @@ -import sys - -# PLUGIN_CONFIG variables -from ..plugins_config import ( - NETBOX_SESSION as nb, - PROXMOX_SESSION as proxmox, - NETBOX_VM_ROLE_ID, - -) - -from . import ( - extras, -) - -# -# virtualization.cluster_types -# -def cluster_type(): - # - # Cluster Type - # - cluster_type_name = 'Proxmox' - cluster_type_slug = 'proxmox' - - cluster_type_proxbox = nb.virtualization.cluster_types.get( - name = cluster_type_name, - slug = cluster_type_slug - ) - - # If no 'cluster_type' found, create one - if cluster_type_proxbox == None: - - try: - cluster_type = nb.virtualization.cluster_types.create( - name = cluster_type_name, - slug = cluster_type_slug, - description = 'Proxmox Virtual Environment. Open-source server management platform' - ) - except Exception as request_error: - raise RuntimeError("Error creating the '{0}' cluster type.".format(cluster_type_name)) from request_error - - else: - cluster_type = cluster_type_proxbox - - return cluster_type - - - - - - -# -# virtualization.clusters -# -def cluster(): - # - # Cluster - # - # Search cluster name on Proxmox - proxmox_cluster = proxmox.cluster.status.get() - proxmox_cluster_name = proxmox_cluster[0].get("name") - - # Verify if there any cluster created with: - # Name equal to Proxmox's Cluster name - # Cluster type equal to 'proxmox' - cluster_proxbox = nb.virtualization.clusters.get( - name = proxmox_cluster_name, - type = cluster_type().slug - ) - - # If no 'cluster' found, create one using the name from Proxmox - if cluster_proxbox == None: - - try: - # Create the cluster with only name and cluster_type - cluster = nb.virtualization.clusters.create( - name = proxmox_cluster_name, - type = cluster_type().id, - tags = [extras.tag().id] - ) - except: - return "Error creating the '{0}' cluster. Possible errors: the name '{0}' is already used.".format(proxmox_cluster_name) - - else: - cluster = cluster_proxbox - - - return cluster - - - - - - - - -# -# virtualization.virtual_machines -# -def virtual_machine(proxmox_vm): - # Create json with basic VM/CT information - vm_json = {} - - if proxmox_vm['status'] == 'running': - vm_json["status"] = 'active' - elif proxmox_vm == 'stopped': - vm_json["status"] = 'offline' - - - vm_json["name"] = proxmox_vm['name'] - vm_json["status"] = 'active' - vm_json["cluster"] = cluster().id - vm_json["role"] = extras.role(role_id = NETBOX_VM_ROLE_ID).id - vm_json["tags"] = [extras.tag().id] - - # Create VM/CT with json 'vm_json' - try: - netbox_obj = nb.virtualization.virtual_machines.create(vm_json) - - except: - print("[proxbox.create.virtual_machine] Creation of VM/CT failed.") - netbox_obj = None - - else: - return netbox_obj - - # In case nothing works, returns error - netbox_obj = None - return netbox_obj \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/plugins_config.py b/netbox_proxbox/proxbox_api/plugins_config.py deleted file mode 100755 index a9a580c..0000000 --- a/netbox_proxbox/proxbox_api/plugins_config.py +++ /dev/null @@ -1,159 +0,0 @@ -# Proxmox -from proxmoxer import ProxmoxAPI - -# Netbox -import pynetbox - -# Default Plugins settings -from netbox_proxbox import ProxboxConfig - -# PLUGIN_CONFIG variable defined by user in Netbox 'configuration.py' file -from netbox.settings import PLUGINS_CONFIG - -#################################################################################################### -# # -# DEFAULT VARIABLES DEFINED BY ProxboxConfig CLASS ON PROXBOX PLUGIN CONFIGURATION (__init__.py) # -# # -#################################################################################################### - -DEFAULT_PLUGINS_CONFIG = ProxboxConfig.default_settings -DEFAULT_PROXMOX_SETTING = DEFAULT_PLUGINS_CONFIG.get("proxmox") -DEFAULT_NETBOX_SETTING = DEFAULT_PLUGINS_CONFIG.get("netbox") - -# -# Proxmox related settings -# -# API URI -DEFAULT_PROXMOX = DEFAULT_PROXMOX_SETTING.get("domain") -DEFAULT_PROXMOX_PORT = DEFAULT_PROXMOX_SETTING.get("http_port") -DEFAULT_PROXMOX_SSL = DEFAULT_PROXMOX_SETTING.get("ssl") - -# ACCESS -DEFAULT_PROXMOX_USER = DEFAULT_PROXMOX_SETTING.get("user") -DEFAULT_PROXMOX_PASSWORD = DEFAULT_PROXMOX_SETTING.get("password") - -DEFAULT_PROXMOX_TOKEN = DEFAULT_PROXMOX_SETTING.get("token") -DEFAULT_PROXMOX_TOKEN_NAME = DEFAULT_PROXMOX_TOKEN.get("name", None) -DEFAULT_PROXMOX_TOKEN_VALUE = DEFAULT_PROXMOX_TOKEN.get("value", None) - -# -# NETBOX RELATED SETTINGS -# -# API URI -# -DEFAULT_NETBOX = DEFAULT_NETBOX_SETTING.get("domain") -DEFAULT_NETBOX_PORT = DEFAULT_NETBOX_SETTING.get("http_port") -DEFAULT_NETBOX_SSL = DEFAULT_NETBOX_SETTING.get("ssl") - -# ACCESS -DEFAULT_NETBOX_TOKEN = DEFAULT_NETBOX_SETTING.get("token") - -# SETTINGS -DEFAULT_NETBOX_SETTINGS = DEFAULT_NETBOX_SETTING.get("settings") -DEFAULT_NETBOX_VM_ROLE_ID = DEFAULT_NETBOX_SETTINGS.get("virtualmachine_role_id", 0) -DEFAULT_NETBOX_NODE_ROLE_ID = DEFAULT_NETBOX_SETTINGS.get("node_role_id", 0) -DEFAULT_NETBOX_SITE_ID = DEFAULT_NETBOX_SETTINGS.get("site_id", 0) - -#################################################################################################### -# # -# VARIABLES FROM PLUGINS_CONFIG DEFINED BY USER ON NETBOX configuration.py # -# # -#################################################################################################### - -# Get Proxmox credentials values from PLUGIN_CONFIG -USER_PLUGINS_CONFIG = PLUGINS_CONFIG.get("netbox_proxbox") -PROXMOX_SETTING = USER_PLUGINS_CONFIG.get("proxmox", DEFAULT_PROXMOX_SETTING) -NETBOX_SETTING = USER_PLUGINS_CONFIG.get("netbox", DEFAULT_NETBOX_SETTING) - -# -# Proxmox related settings -# -# API URI -PROXMOX = PROXMOX_SETTING.get("domain", DEFAULT_PROXMOX) -PROXMOX_PORT = PROXMOX_SETTING.get("http_port", DEFAULT_PROXMOX_PORT) -PROXMOX_SSL = PROXMOX_SETTING.get("ssl", DEFAULT_PROXMOX_SSL) - -# ACCESS -PROXMOX_USER = PROXMOX_SETTING.get("user", DEFAULT_PROXMOX_USER) -PROXMOX_PASSWORD = PROXMOX_SETTING.get("password", DEFAULT_PROXMOX_PASSWORD) - -PROXMOX_TOKEN = PROXMOX_SETTING.get("token", DEFAULT_PROXMOX_TOKEN) -if PROXMOX_TOKEN != None: - PROXMOX_TOKEN_NAME = PROXMOX_TOKEN.get("name", DEFAULT_PROXMOX_TOKEN_NAME) - PROXMOX_TOKEN_VALUE = PROXMOX_TOKEN.get("value", DEFAULT_PROXMOX_TOKEN_VALUE) - -# -# NETBOX RELATED SETTINGS -# -# API URI -# -NETBOX = NETBOX_SETTING.get("domain", DEFAULT_NETBOX) -NETBOX_PORT = NETBOX_SETTING.get("http_port", DEFAULT_NETBOX_PORT) -NETBOX_SSL = NETBOX_SETTING.get("ssl", DEFAULT_NETBOX_SSL) - -# ACCESS -NETBOX_TOKEN = NETBOX_SETTING.get("token", DEFAULT_NETBOX_TOKEN) - -# SETTINGS -NETBOX_SETTINGS = NETBOX_SETTING.get("settings", DEFAULT_NETBOX_SETTINGS) - -if NETBOX_SETTINGS != None: - NETBOX_VM_ROLE_ID = NETBOX_SETTINGS.get("virtualmachine_role_id", DEFAULT_NETBOX_VM_ROLE_ID) - NETBOX_NODE_ROLE_ID = NETBOX_SETTINGS.get("node_role_id", DEFAULT_NETBOX_NODE_ROLE_ID) - NETBOX_SITE_ID = NETBOX_SETTINGS.get("site_id", DEFAULT_NETBOX_SITE_ID) - - -#################################################################################################### -# # -# WITH PLUGIN CONFIGURED, STARTS BOTH PROXMOX AND NETBOX SESSION # -# # -#################################################################################################### - -# -# PROXMOX SESSION -# -# Check if token was provided -if PROXMOX_TOKEN_VALUE != None and len(PROXMOX_TOKEN_VALUE) > 0: - try: - # Start PROXMOX session using TOKEN - PROXMOX_SESSION = ProxmoxAPI( - PROXMOX, - user=PROXMOX_USER, - token_name=PROXMOX_TOKEN_NAME, - token_value=PROXMOX_TOKEN_VALUE, - verify_ssl=PROXMOX_SSL - ) - except: - print('Error trying to initialize Proxmox Session using TOKEN provided') - -# If token not provided, start session using user and passwd -else: - try: - # Start PROXMOX session using USER CREDENTIALS - PROXMOX_SESSION = ProxmoxAPI( - PROXMOX, - user=PROXMOX_USER, - password=PROXMOX_PASSWORD, - verify_ssl=PROXMOX_SSL - ) - except: - print('Error trying to initialize Proxmox Session using USER and PASSWORD') - -# -# NETBOX SESSION -# -if NETBOX_SSL == False: - try: - NETBOX = 'http://{}:{}'.format(NETBOX, NETBOX_PORT) - # Inicia sessão com NETBOX - NETBOX_SESSION = pynetbox.api( - NETBOX, - token=NETBOX_TOKEN - ) - except: - print('Error trying to initialize Netbox Session using TOKEN provided') -elif NETBOX_SSL == True: - print("Netbox using SSL not developed yet, try using HTTP without SSL.") - -else: - print('Unexpected Error ocurred') \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/remove.py b/netbox_proxbox/proxbox_api/remove.py deleted file mode 100755 index 71e9e6b..0000000 --- a/netbox_proxbox/proxbox_api/remove.py +++ /dev/null @@ -1,180 +0,0 @@ -from . import updates - -# PLUGIN_CONFIG variables -from .plugins_config import ( - PROXMOX_SESSION as proxmox, - NETBOX_SESSION as nb, -) - -# Verify if VM/CT exists on Proxmox -def is_vm_on_proxmox(netbox_vm): - # Get json of all virtual machines from Proxmox - all_proxmox_vms = proxmox.cluster.resources.get(type='vm') - - # Netbox name - netbox_name = netbox_vm.name - - # Search Netbox local_context - local_context = netbox_vm.local_context_data - - # Analyze local_context of VM - if local_context == None: - print('[WARNING] "local_context_data" not filled. -> {}'.format(netbox_name)) - - else: - # "proxmox" key of "local_context_data" - proxmox_json = local_context.get("proxmox") - - # If null value, returns error - if proxmox_json == None: - print("[WARNING] 'local_context_data' does not have 'proxmox' json key -> {}".format(netbox_name)) - - else: - # Netbox VM/CT ID - netbox_id = proxmox_json.get("id") - - # If null value, returns error - if netbox_id == None: - print("[WARNING] 'proxmox' doest not have 'id' key -> {}".format(netbox_name)) - - - # List names of VM/CT's from Proxmox - names = [] - - # List ID's of VM/CT's from Proxmox - vmids = [] - - # Compare Netbox VM with all Proxmox VMs and verify if Netbox VM exist on Proxmox. - for i in range(len(all_proxmox_vms)): - name = all_proxmox_vms[i].get("name") - names.append(name) - - vm_id = all_proxmox_vms[i].get("vmid") - vmids.append(vm_id) - - - name_on_px = False - id_on_px = False - - # Search VM on Proxmox by using name - try: - name_index = names.index(netbox_name) - except: - name_on_px = False - else: - # NAME exists on Proxmox - name_on_px = True - - # If 'local_context' is null, try updating it to be able to get ID from VM - if local_context == None: - local_context_updated = updates.local_context_data(netbox_vm, all_proxmox_vms[name_index]) - - if local_context_updated == True: - local_context = netbox_vm.local_context_data - - if local_context != None: - print("[OK] 'local_context' updated' -> {}".format(netbox_name)) - proxmox_json = local_context.get("proxmox") - netbox_id = proxmox_json.get("id") - - else: - print("[ERROR] 'local_context' is empty -> {}".format(netbox_name)) - else: - print("[WARNING] 'local_context' was not updated (error or already updated) -> {}".format(netbox_name)) - - - # Search VM on Proxmox by using ID - try: - id_index = vmids.index(netbox_id) - except: - id_on_px = False - else: - # NAME exists on Proxmox - id_on_px = True - - # Verify if VM exists - if name_on_px == True: - if id_on_px == True: - return True - else: - print("[WARNING] NAME exists on Proxmox, but ID does not. -> {}".format(netbox_name)) - return True - - # Comparison failed, not able to find VM on Proxmox - return False - -def all(): - json_vm_all = [] - - # Get all VM/CTs from Netbox - netbox_all_vms = nb.virtualization.virtual_machines.all() - - for nb_vm_each in netbox_all_vms: - json_vm = {} - log = [] - - netbox_obj = nb_vm_each - netbox_name = netbox_obj.name - json_vm["name"] = netbox_name - - # Verify if VM exists on Proxmox - vm_on_proxmox = is_vm_on_proxmox(nb_vm_each) - - if vm_on_proxmox == True: - log_message = '[OK] VM exists on both systems (Netbox and Proxmox) -> {}'.format(netbox_name) - print(log_message) - log.append(log_message) - - json_vm["result"] = False - - # If VM does not exist on Proxmox, delete VM on Netbox. - elif vm_on_proxmox == False: - log_message = "[WARNING] VM exists on Netbox, but not on Proxmox. Delete it! -> {}".format(netbox_name) - print(log_message) - log.append(log_message) - - # Only delete VM that has proxbox tag registered - delete_vm = False - - if len(netbox_obj.tags) > 0: - for tag in netbox_obj.tags: - - if tag.name == 'Proxbox' and tag.slug == 'proxbox': - - # - # DELETE THE VM/CT - # - delete_vm = netbox_obj.delete() - - else: - log_message = "[ERROR] VM will not be removed because the 'Proxbox' tag was not found. -> {}".format(netbox_name) - print(log_message) - log.append(log_message) - - elif len(netbox_obj.tags) == 0: - log_message = "[ERROR] VM will not be removed because the 'Proxbox' tag was not found. There is no tag configured.-> {}".format(netbox_name) - print(log_message) - log.append(log_message) - - - if delete_vm == True: - log_message = "[OK] VM successfully removed from Netbox." - print(log_message) - log.append(log_message) - - json_vm["result"] = True - - else: - log_message = '[ERROR] Unexpected error trying to verify if VM exist on Proxmox' - print(log_message) - log.append(log_message) - - json_vm["result"] = False - - json_vm["log"] = log - - json_vm_all.append(json_vm) - - return json_vm_all - - \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/update.py b/netbox_proxbox/proxbox_api/update.py deleted file mode 100755 index c4ce002..0000000 --- a/netbox_proxbox/proxbox_api/update.py +++ /dev/null @@ -1,472 +0,0 @@ -# PLUGIN_CONFIG variables -from .plugins_config import ( - PROXMOX, - PROXMOX_PORT, - PROXMOX_USER, - PROXMOX_PASSWORD, - PROXMOX_SSL, - NETBOX, - NETBOX_TOKEN, - PROXMOX_SESSION as proxmox, - NETBOX_SESSION as nb, -) - -from . import ( - updates, - create, - remove, -) - - - -# Call all functions to update Virtual Machine -def vm_full_update(netbox_vm, proxmox_vm): - changes = {} - - # Update 'status' field, if necessary. - status_updated = updates.virtual_machine.status(netbox_vm, proxmox_vm) - - # Update 'custom_fields' field, if necessary. - custom_fields_updated = updates.virtual_machine.custom_fields(netbox_vm, proxmox_vm) - - # Update 'local_context_data' json, if necessary. - local_context_updated = updates.virtual_machine.local_context_data(netbox_vm, proxmox_vm) - - # Update 'resources', like CPU, Memory and Disk, if necessary. - resources_updated = updates.virtual_machine.resources(netbox_vm, proxmox_vm) - - tag_updated = updates.extras.tag(netbox_vm) - - #changes = [custom_fields_updated, status_updated, local_context_updated, resources_updated] - changes = { - "status" : status_updated, - "custom_fields" : custom_fields_updated, - "local_context" : local_context_updated, - "resources" : resources_updated, - "tag" : tag_updated - } - - return changes - - - -def node_full_update(netbox_node, proxmox_json, proxmox_cluster): - changes = {} - - status_updated = updates.node.status(netbox_node, proxmox_json) - cluster_updated = updates.node.cluster(netbox_node, proxmox_json, proxmox_cluster) - - changes = { - "status" : status_updated, - "cluster" : cluster_updated - } - - return changes - - - -# Verify if VM/CT exist on Netbox -def is_vm_on_netbox(netbox_vm): - # Search VM on Netbox by using VM Name gotten from Proxmox - # VM doesn't exist on Netbox - if netbox_vm == None: - vm_on_netbox = False - - # VM already exist on Netbox - else: - vm_on_netbox = True - - return vm_on_netbox - - - -def search_by_proxmox_id(proxmox_id): - all_proxmox_vms = proxmox.cluster.resources.get(type='vm') - - for px_vm in all_proxmox_vms: - px_id = px_vm.get("vmid") - - if px_id == proxmox_id: - proxmox_vm = px_vm - return proxmox_vm - - # If JSON not found, return None. - return None - - - -def search_by_proxmox_name(proxmox_name): - all_proxmox_vms = proxmox.cluster.resources.get(type='vm') - - for px_vm in all_proxmox_vms: - px_name = px_vm.get("name") - - if proxmox_name == px_name: - proxmox_vm = px_vm - return proxmox_vm - - # If JSON not found, return None. - return None - - - -def search_by_id(id): - # Save Netbox VirtualMachine object - netbox_obj = nb.virtualization.virtual_machines.get(id) - - proxmox_name = netbox_obj.name - - # Search Proxmox ID on Netbox - local_context = netbox_obj.local_context_data - if local_context != None: - proxmox_json = local_context.get("proxmox") - - if proxmox_json != None: - proxmox_id = proxmox_json.get("id") - - if proxmox_id != None: - return proxmox_id - - # Return Proxmox Name in case ID not found. - return proxmox_name - - - -# Makes all necessary checks so that VM/CT exist on Netbox. -def virtual_machine(**kwargs): - # JSON containing the result of the VM changes - json_vm = {} - - # args: - # proxmox_json - # id - # proxmox_id - # name - # - # Save args and validate types - # - # Save arg - proxmox_id = kwargs.get('proxmox_id') - - # Validate type - if proxmox_id != None: - proxmox_id_type = type(proxmox_id) - if 'int' not in str(proxmox_id_type): - print('[ERROR] "proxmox_id" MUST be integer. Type used: {}'.format(proxmox_id_type)) - #return False - json_vm["result"] = False - - # Save arg - id = kwargs.get('id') - - # Validate type - if id != None: - id_type = type(id) - if 'int' not in str(id_type): - print('[ERROR] "id" MUST be integer. Type used: {}'.format(id_type)) - #return False - json_vm["result"] = False - - - # Save arg - name = kwargs.get('name') - - # Validate type - if name != None: - name_type = type(name) - if 'str' not in str(name_type): - print('[ERROR] "name" MUST be string. Type used: {}'.format(name_type)) - #return False - json_vm["result"] = False - - # Save arg - proxmox_json = kwargs.get('proxmox_json') - - proxmox_vm_name = None - - # Decide whether 'proxmox_json' or other args (id, proxmox_id and proxmox_name) will be used - if proxmox_json != None: - proxmox_vm_name = proxmox_json['name'] - json_vm["name"] = proxmox_json['name'] - - # If 'proxmox_json' was not passed as argument, use other args - else: - # - # With arguments passed on the function, search for JSON of VM on Proxmox - # Searching priorirty: - # 1° = id - # 2° = proxmox_id - # 3° = proxmox_name - # - # Search JSON of VM on Proxmox by using "id" argument - if id != None: - # Search result returns Proxmox ID or Proxmox Name, if ID doesn't exist - search_result = search_by_id(id) - - # Verify type of the result: - # If 'int' = Proxmox ID - # If 'str' = Proxmox Name - search_result_type = type(search_result) - - # Search using Proxmox ID - if 'int' in str(search_result_type): - proxmox_json = search_by_proxmox_id(search_result) - - # Analyze search result and returns error, if null value. - if proxmox_json == None: - print("[ERROR] Error to get Proxmox Virtual Machine using 'proxmox_id'") - json_vm["result"] = False - - proxmox_vm_name = proxmox_json['name'] - json_vm["name"] = proxmox_json['name'] - - # Search using Proxmox NAME - elif 'str' in str(search_result_type): - proxmox_json = search_by_proxmox_name(search_result) - - # Analyze search result and returns error, if null value. - if proxmox_json == None: - print("[ERROR] Error to get Proxmox Virtual Machine using 'proxmox_name'") - json_vm["result"] = False - - proxmox_vm_name = proxmox_json['name'] - json_vm["name"] = proxmox_json['name'] - - else: - # Search VM JSON of Proxmox using argument 'proxmox_id' - if proxmox_id != None: - proxmox_json = search_by_proxmox_id(proxmox_id) - - # Analyze search result and returns error, if null value. - if proxmox_json == None: - print("[ERROR] Error to get Proxmox Virtual Machine using 'proxmox_id'") - json_vm["result"] = False - - proxmox_vm_name = proxmox_json['name'] - json_vm["name"] = proxmox_json['name'] - - else: - # Search using Proxmox NAME - if name != None: - proxmox_json = search_by_proxmox_name(name) - - # Analyze search result and returns error, if null value. - if proxmox_json == None: - print("[ERROR] Error to get Proxmox Virtual Machine using 'proxmox_name'") - json_vm["result"] = False - - proxmox_vm_name = proxmox_json['name'] - json_vm["name"] = proxmox_json['name'] - - if proxmox_vm_name == None: - return False - - # Search Netbox object by name gotten from Proxmox - netbox_vm = nb.virtualization.virtual_machines.get(name = proxmox_vm_name) - - # Analyze if VM exist on Netbox - # If VM/CT already exist on Proxmox, check VM and update it, if necessary. - vm_on_netbox = is_vm_on_netbox(netbox_vm) - - if vm_on_netbox == True: - # Update Netbox information - full_update = vm_full_update(netbox_vm, proxmox_json) - json_vm["changes"] = full_update - - full_update_list = list(full_update.values()) - - # Analyze if VM needed to be updated on Netbox - if True in full_update_list: - print('[OK] VM updated. -> {}'.format(proxmox_vm_name)) - else: - print('[OK] VM already updated. -> {}'.format(proxmox_vm_name)) - - # In case none of condition works, return True anyway, since VM already exist. - json_vm["result"] = True - - # If VM does not exist, create it on Netbox - elif vm_on_netbox == False: - print('[OK] VM does not exist on Netbox -> {}'.format(proxmox_vm_name)) - - - # Analyze if VM was sucessfully created. - netbox_vm = create.virtualization.virtual_machine(proxmox_json) - - # VM created with basic information - if netbox_vm != None: - # Update rest of configuration - full_update = vm_full_update(netbox_vm, proxmox_json) - json_vm["changes"] = full_update - - full_update_list = list(full_update.values()) - - # Analyze if update was successful - if True in full_update_list: - print('[OK] VM created -> {}'.format(proxmox_vm_name)) - - - # VM fully updated - json_vm["result"] = True - - else: - print('[OK] VM created, but full update failed -> {}'.format(proxmox_vm_name)) - - # VM created with basic information - json_vm["result"] = True - - else: - print('[ERROR] VM not created. -> {}'.format(proxmox_vm_name)) - - # VM not created - json_vm["result"] = False - - else: - print("[ERROR] Unexpected error -> {}".format(proxmox_vm_name)) - - # Unexpected error - json_vm["result"] = False - - return json_vm - - - -def nodes(**kwargs): - proxmox_cluster = kwargs.get('proxmox_cluster') - proxmox_json = kwargs.get('proxmox_json') - - proxmox_node_name = proxmox_json.get("name") - - json_node = {} - - # Search netbox using VM name - netbox_search = nb.dcim.devices.get(name = proxmox_node_name) - - # Search node on Netbox with Proxmox node name gotten - if nb.dcim.devices.get(name = proxmox_node_name) == None: - # If node does not exist, create it. - netbox_node = create.dcim.node(proxmox_json) - - # Node created - if netbox_node != None: - print("[OK] Node created! -> {}".format(proxmox_node_name)) - - # Update rest of configuration - full_update = node_full_update(netbox_node, proxmox_json, proxmox_cluster) - json_node["changes"] = full_update - - full_update_list = list(full_update.values()) - - # Analyze if update was successful - if True in full_update_list: - print('[OK] NODE updated. -> {}'.format(proxmox_node_name)) - else: - print('[OK] NODE already updated. -> {}'.format(proxmox_node_name)) - - # return True as the node was successfully created. - json_node["result"] = True - - # Error with node creation - else: - print('[ERROR] Something went wrong when creating the node.-> {}'.format(proxmox_node_name)) - json_node["result"] = False - - else: - # If node already exist, try updating it. - netbox_node = netbox_search - - # Update Netbox node information, if necessary. - full_update = node_full_update(netbox_node, proxmox_json, proxmox_cluster) - json_node["changes"] = full_update - - full_update_list = list(full_update.values()) - - # Analyze if update was successful - if True in full_update_list: - print('[OK] NODE updated. -> {}'.format(proxmox_node_name)) - else: - print('[OK] NODE already updated. -> {}'.format(proxmox_node_name)) - - # return True as the node was successfully created. - json_node["result"] = True - - - - return json_node - - - -# Makes everything needed so that VIRTUAL MACHINES / CONTAINERS, NODES and CLUSTER exists on Netbox -def all(**kwargs): - print("[Proxbox - Netbox plugin | Update All]") - cluster_all = proxmox.cluster.status.get() - - # - # CLUSTER - # - cluster = create.virtualization.cluster() - print('\n\n\nCLUSTER...') - print('[OK] CLUSTER created. -> {}'.format(cluster.name)) - - proxmox_cluster = cluster_all[0] - # - # NODES - # - print('\n\n\nNODES...') - nodes_list = [] - proxmox_nodes = cluster_all[1:] - - # Get all NODES from Proxmox - for px_node_each in proxmox_nodes: - node_updated = nodes(proxmox_json = px_node_each, proxmox_cluster = proxmox_cluster) - - nodes_list.append(node_updated) - - - # - # VIRTUAL MACHINES / CONTAINERS - # - print('\n\n\nVIRTUAL MACHINES...') - virtualmachines_list = [] - - print('\nUPDATE ALL...') - # Get all VM/CTs from Proxmox - for px_vm_each in proxmox.cluster.resources.get(type='vm'): - vm_updated = virtual_machine(proxmox_json = px_vm_each) - - virtualmachines_list.append(vm_updated) - - # Get "remove_unused" passed on function call - remove_unused = kwargs.get("remove_unused", False) - - # Remove Netbox's old data - if remove_unused == True: - print('\nREMOVE UNUSED DATA...') - remove_info = remove.all() - - # - # BUILD JSON RESULT - # - result = {} - result["virtualmachines"] = virtualmachines_list - result["nodes"] = nodes_list - result["remove_unused"] = remove_info - - return result - - - -# Runs if script executed directly -if __name__ == "__main__": - print('#\n# COMPARE PROXMOX WITH NETBOX\n#') - all() - - print('____________________________________\n') - print('#\n# COMPARE PROXMOX WITH NETBOX\n#') - remove.all() - - - - - - - diff --git a/netbox_proxbox/proxbox_api/updates/__init__.py b/netbox_proxbox/proxbox_api/updates/__init__.py deleted file mode 100755 index 2a3d725..0000000 --- a/netbox_proxbox/proxbox_api/updates/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from . import ( - node, - virtual_machine, - extras, -) diff --git a/netbox_proxbox/proxbox_api/updates/extras.py b/netbox_proxbox/proxbox_api/updates/extras.py deleted file mode 100755 index 8658b0d..0000000 --- a/netbox_proxbox/proxbox_api/updates/extras.py +++ /dev/null @@ -1,27 +0,0 @@ -from .. import ( - create, -) - -def tag(netbox_vm): - # Get current tags - tags = netbox_vm.tags - - # Get tag names from tag objects - tags_name = [] - for tag in tags: - tags_name.append(tag.name) - - - # If Proxbox not found int Netbox tag's list, update object with the tag. - if create.extras.tag().name not in tags_name: - tags.append(create.extras.tag().id) - - netbox_vm.tags = tags - - # Save new tag to object - if netbox_vm.save() == True: - return True - else: - return False - - return False \ No newline at end of file diff --git a/netbox_proxbox/proxbox_api/updates/node.py b/netbox_proxbox/proxbox_api/updates/node.py deleted file mode 100755 index 03f0789..0000000 --- a/netbox_proxbox/proxbox_api/updates/node.py +++ /dev/null @@ -1,84 +0,0 @@ -from .. import ( - create, -) - -# Update STATUS field on /dcim/device/{id} -def status(netbox_node, proxmox_node): - # - # Compare STATUS - # - if proxmox_node['online'] == 1: - # If Proxmox is 'online' and Netbox is 'offline', update it. - if netbox_node.status.value == 'offline': - netbox_node.status.value = 'active' - - if netbox_node.save() == True: - status_updated = True - else: - status_updated = False - - else: - status_updated = False - - - elif proxmox_node['online'] == 0: - # If Proxmox is 'offline' and Netbox' is 'active', update it. - if netbox_node.status.value == 'active': - netbox_node.status.value = 'offline' - - if netbox_node.save() == True: - status_updated = True - else: - status_updated = False - - else: - status_updated = False - - else: - status_updated = False - - return status_updated - - - - -# Update CLUSTER field on /dcim/device/{id} -def cluster(netbox_node, proxmox_node, proxmox_cluster): - # - # Compare CLUSTER - # - if proxmox_cluster != None: - # If cluster is filled, but different from actual cluster, update it. - if netbox_node.cluster.name != proxmox_cluster['name']: - # Search for Proxmox Cluster using create.cluster() function - cluster_id = create.virtualization.cluster().id - - # Use Cluster ID to update NODE information - netbox_node.cluster.id = cluster_id - - if netbox_node.save() == True: - cluster_updated = True - else: - cluster_updated = False - - else: - cluster_updated = False - - # If cluster is empty, update it. - elif proxmox_cluster == None: - # Search for Proxmox Cluster using create.cluster() function - cluster_id = create.virtualization.cluster().id - - # Use Cluster ID to update NODE information - netbox_node.cluster.id = cluster_id - - if netbox_node.save() == True: - cluster_updated = True - else: - cluster_updated = False - - # If cluster was not empty and also not different, do not make any change. - else: - cluster_updated = False - - return cluster_updated diff --git a/netbox_proxbox/proxbox_api/updates/virtual_machine.py b/netbox_proxbox/proxbox_api/updates/virtual_machine.py deleted file mode 100755 index 6f1a717..0000000 --- a/netbox_proxbox/proxbox_api/updates/virtual_machine.py +++ /dev/null @@ -1,285 +0,0 @@ -import requests -import json - -# PLUGIN_CONFIG variables -from ..plugins_config import ( - PROXMOX, - PROXMOX_PORT, - PROXMOX_USER, - PROXMOX_PASSWORD, - PROXMOX_SSL, - NETBOX, - NETBOX_TOKEN, - PROXMOX_SESSION as proxmox, - NETBOX_SESSION as nb, -) - -from .. import ( - create, -) - - - - -# Update "status" field on Netbox Virtual Machine based on Proxmox information -def status(netbox_vm, proxmox_vm): - # False = status not changed on Netbox - # True = status changed on Netbox - status_updated = False - - # [ running, stopped ] - proxmox_status = proxmox_vm['status'] - - # [ offline, active, planned, staged, failed, decommissioning ] - netbox_status = netbox_vm.status.value - - if (proxmox_status == 'running' and netbox_status == 'active') or (proxmox_status == 'stopped' and netbox_status == 'offline'): - # Status not updated - status_updated = False - - # Change status to active on Netbox if it's offline - elif proxmox_status == 'stopped' and netbox_status == 'active': - netbox_vm.status.value = 'offline' - netbox_vm.save() - - # Status updated - status_updated = True - - # Change status to offline on Netbox if it's active - elif proxmox_status == 'running' and netbox_status == 'offline': - netbox_vm.status.value = 'active' - netbox_vm.save() - - # Status updated - status_updated = True - - # Status not expected - else: - # Status doesn't need to change - status_updated = False - - return status_updated - - - -def site(**kwargs): - # If site_id equals to 0, consider it is not configured by user and must be created by Proxbox - site_id = kwargs.get('site_id', 0) - - -# Function that modifies 'custom_field' of Netbox Virtual Machine. -# It uses HTTP Request and not Pynetbox (as I was not able to). -def http_update_custom_fields(**kwargs): - # Saves kwargs variables - domain_with_http = kwargs.get('domain_with_http') - token = kwargs.get('token') - vm_id = kwargs.get('vm_id', 0) - vm_name = kwargs.get('vm_name') - vm_cluster = kwargs.get('vm_cluster') - custom_fields = kwargs.get('custom_fields') - - # - # HTTP PATCH Request (partially update) - # - # URL - url = '{}/api/virtualization/virtual-machines/{}/'.format(domain_with_http, vm_id) - - # HTTP Request Headers - headers = { - "Authorization": "Token {}".format(token), - "Content-Type" : "application/json" - } - - # HTTP Request Body - body = { - "name": vm_name, - "cluster": vm_cluster, - "custom_fields": custom_fields - } - - # Makes the request and saves it to var - r = requests.patch(url, data = json.dumps(body), headers = headers) - - # Return HTTP Status Code - return r.status_code - - - -# Update 'custom_fields' field on Netbox Virtual Machine based on Proxbox -def custom_fields(netbox_vm, proxmox_vm): - # Create the new 'custom_field' with info from Proxmox - custom_fields_update = {} - - # Check if there is 'custom_field' configured on Netbox - if len(netbox_vm.custom_fields) == 0: - print("[ERROR] There's no 'Custom Fields' registered by the Netbox Plugin user") - - # If any 'custom_field' configured, get it and update, if necessary. - elif len(netbox_vm.custom_fields) > 0: - - # Get current configured custom_fields - custom_fields_names = list(netbox_vm.custom_fields.keys()) - - # - # VERIFY IF CUSTOM_FIELDS EXISTS AND THEN UPDATE INFORMATION, IF NECESSARY. - # - # Custom Field 'proxmox_id' - if 'proxmox_id' in custom_fields_names: - if netbox_vm.custom_fields.get("proxmox_id") != proxmox_vm['vmid']: - custom_fields_update["proxmox_id"] = proxmox_vm['vmid'] - else: - print("[ERROR] 'proxmox_id' custom field not registered yet or configured incorrectly]") - - # Custom Field 'proxmox_node' - if 'proxmox_node' in custom_fields_names: - if netbox_vm.custom_fields.get("proxmox_node") != proxmox_vm['node']: - custom_fields_update["proxmox_node"] = proxmox_vm['node'] - else: - print("[ERROR] 'proxmox_node' custom field not registered yet or configured incorrectly") - - # Custom Field 'proxmox_type' - if 'proxmox_type' in custom_fields_names: - if netbox_vm.custom_fields.get("proxmox_type") != proxmox_vm['type']: - custom_fields_update["proxmox_type"] = proxmox_vm['type'] - else: - print("[ERROR] 'proxmox_type' custom field not registered yet or configured incorrectly") - - - - # Only updates information if changes found - if len(custom_fields_update) > 0: - - # As pynetbox does not have a way to update custom_fields, use API HTTP request - custom_field_updated = http_update_custom_fields( - domain_with_http = NETBOX, - token = NETBOX_TOKEN, - vm_id = netbox_vm.id, - vm_name = netbox_vm.name, - vm_cluster = netbox_vm.cluster.id, - custom_fields = custom_fields_update - ) - - # Verify HTTP reply CODE - if custom_field_updated != 200: - print("[ERROR] Some error occured trying to update 'custom_fields' through HTTP Request. HTTP Code: {}. -> {}".format(custom_field_updated, netbox_vm.name)) - return False - - else: - # If none error occured, considers VM updated. - return True - - return False - - - - - -# Update 'local_context_data' field on Netbox Virtual Machine based on Proxbox -def local_context_data(netbox_vm, proxmox_vm): - current_local_context = netbox_vm.local_context_data - - proxmox_values = {} - - # Add and change values from Proxmox - proxmox_values["name"] = proxmox_vm["name"] - proxmox_values["url"] = "https://{}:{}".format(PROXMOX, PROXMOX_PORT) # URL - proxmox_values["id"] = proxmox_vm["vmid"] # VM ID - proxmox_values["node"] = proxmox_vm["node"] - proxmox_values["type"] = proxmox_vm["type"] - - maxmem = int(int(proxmox_vm["maxmem"]) / 1000000000) # Convert bytes to gigabytes - proxmox_values["memory"] = "{} {}".format(maxmem, 'GB') # Add the 'GB' unit of measurement - - maxdisk = int(int(proxmox_vm["maxdisk"]) / 1000000000) # Convert bytes to gigabytes - proxmox_values["disk"] = "{} {}".format(maxdisk, 'GB') # Add the 'GB' unit of measurement - - proxmox_values["vcpu"] = proxmox_vm["maxcpu"] # Add the 'GB' unit of measurement - - - # Verify if 'local_context' is empty and if true, creates initial values. - if current_local_context == None: - netbox_vm.local_context_data = {"proxmox" : proxmox_values} - netbox_vm.save() - return True - - # Compare current Netbox values with Porxmox values - elif current_local_context.get('proxmox') != proxmox_values: - # Update 'proxmox' key on 'local_context_data' - current_local_context.update(proxmox = proxmox_values) - - netbox_vm.local_context_data = current_local_context - netbox_vm.save() - return True - - # If 'local_context_data' already updated - else: - return False - - return False - - - - - - - -# Updates following fields based on Proxmox: "vcpus", "memory", "disk", if necessary. -def resources(netbox_vm, proxmox_vm): - # Save values from Proxmox - vcpus = float(proxmox_vm["maxcpu"]) - - # Convert bytes to megabytes and then convert float to integer - memory_Mb = proxmox_vm["maxmem"] - memory_Mb = int(memory_Mb / 1000000) - - # Convert bytes to gigabytes and then convert float to integer - disk_Gb = proxmox_vm["maxdisk"] - disk_Gb = int(disk_Gb / 1000000000) - - # JSON with new resources info - new_resources_json = {} - - - - # Compare VCPU - if netbox_vm.vcpus != None: - # Convert Netbox VCPUs to float, since it is coming as string from Netbox - netbox_vm.vcpus = float(netbox_vm.vcpus) - - if netbox_vm.vcpus != vcpus: - new_resources_json["vcpus"] = vcpus - - elif netbox_vm.vcpus == None: - new_resources_json["vcpus"] = vcpus - - - - # Compare Memory - if netbox_vm.memory != None: - if netbox_vm.memory != memory_Mb: - new_resources_json["memory"] = memory_Mb - - elif netbox_vm.memory == None: - new_resources_json["memory"] = memory_Mb - - - - # Compare Disk - if netbox_vm.disk != None: - if netbox_vm.disk != disk_Gb: - new_resources_json["disk"] = disk_Gb - - elif netbox_vm.disk == None: - new_resources_json["disk"] = disk_Gb - - - - # If new information found, save it to Netbox object. - if len(new_resources_json) > 0: - resources_updated = netbox_vm.update(new_resources_json) - - if resources_updated == True: - return True - else: - return False - diff --git a/netbox_proxbox/static/netbox_proxbox/discord-banner.png b/netbox_proxbox/static/netbox_proxbox/discord-banner.png new file mode 100755 index 0000000..f30594a Binary files /dev/null and b/netbox_proxbox/static/netbox_proxbox/discord-banner.png differ diff --git a/netbox_proxbox/static/netbox_proxbox/discord.png b/netbox_proxbox/static/netbox_proxbox/discord.png new file mode 100755 index 0000000..c71fe21 Binary files /dev/null and b/netbox_proxbox/static/netbox_proxbox/discord.png differ diff --git a/netbox_proxbox/static/netbox_proxbox/fastapi_logo.png b/netbox_proxbox/static/netbox_proxbox/fastapi_logo.png new file mode 100755 index 0000000..f6c6d93 Binary files /dev/null and b/netbox_proxbox/static/netbox_proxbox/fastapi_logo.png differ diff --git a/netbox_proxbox/static/netbox_proxbox/github.png b/netbox_proxbox/static/netbox_proxbox/github.png new file mode 100755 index 0000000..9490ffc Binary files /dev/null and b/netbox_proxbox/static/netbox_proxbox/github.png differ diff --git a/netbox_proxbox/static/netbox_proxbox/home.js b/netbox_proxbox/static/netbox_proxbox/home.js new file mode 100755 index 0000000..f9426ca --- /dev/null +++ b/netbox_proxbox/static/netbox_proxbox/home.js @@ -0,0 +1,204 @@ +/* +This script works, but is not being used as there's not official support +to link external script on head element to plugins. +*/ + +/* +const uvicorn_host = document.getElementById("uvicorn-host") +const uvicorn_port = document.getElementById("uvicorn-port") + +console.log("uvicorn_host", uvicorn_host) +console.log("uvicorn_port", uvicorn_port) + + +const fastapi_endpoint = `http://${uvicorn_host}:${uvicorn_port}` +const websocket_endpoint = `ws://${uvicorn_host}:${uvicorn_port}/ws` + +var ws = new WebSocket(websocket_endpoint); +ws.onmessage = function(event) { + // Add WebSockets Messages came from FasstAPI backend on GUI + + var messages = document.getElementById('messages') + var message = document.createElement('li') + + message.style.lineHeight = '170%' + + message.innerHTML = event.data + messages.appendChild(message) + + var test = document.getElementById('scrollable-div') + test.scrollTop = test.scrollHeight + +}; + +ws.onerror = function(error) { + console.log("WebSocket error observed: ", error); + + fullUpdateButton = document.getElementById('full-update-button') + fullUpdateButton.className = "btn btn-red" + + fullUpdateMessage = document.getElementById('full-update-error-message') + fullUpdateMessage.className = "text-red" + + let errorMessage = ` +
+ WebSocket communication failed with ${error.currentTarget.url}
+
The most probably cause is Proxbox Backend not running properly.
+
Message: ${response.message}
Detail: ${response.message}
Python Exception: ${response.python_exception}
"+bs(e[t].content)+"
"};Ia.code_block=function(e,t,r,n,a){var o=e[t];return""+bs(e[t].content)+`
+`};Ia.fence=function(e,t,r,n,a){var o=e[t],s=o.info?wY(o.info).trim():"",l="",d,h,v,b;return s&&(l=s.split(/\s+/g)[0]),r.highlight?d=r.highlight(o.content,l)||bs(o.content):d=bs(o.content),d.indexOf(""+d+`
+`):""+d+`
+`};Ia.image=function(e,t,r,n,a){var o=e[t];return o.attrs[o.attrIndex("alt")][1]=a.renderInlineAsText(o.children,r,n),a.renderToken(e,t,r)};Ia.hardbreak=function(e,t,r){return r.xhtmlOut?`=Q,m=[t.sCount[r]],t.sCount[r]=A-d,k=[t.tShift[r]],t.tShift[r]=z-t.bMarks[r],D=t.md.block.ruler.getRules("blockquote"),_=t.parentType,t.parentType="blockquote",M=!1,T=r+1;T=Q));T++){if(t.src.charCodeAt(z++)===62&&!M){for(d=A=t.sCount[T]+z-(t.bMarks[T]+t.tShift[T]),t.src.charCodeAt(z)===32?(z++,d++,A++,o=!1,w=!0):t.src.charCodeAt(z)===9?(w=!0,(t.bsCount[T]+A)%4==3?(z++,d++,A++,o=!1):o=!0):w=!1,L.push(t.bMarks[T]),t.bMarks[T]=z;z =Q,S.push(t.bsCount[T]),t.bsCount[T]=t.sCount[T]+1+(w?1:0),m.push(t.sCount[T]),t.sCount[T]=A-d,k.push(t.tShift[T]),t.tShift[T]=z-t.bMarks[T];continue}if(v)break;for(C=!1,l=0,h=D.length;l",R.map=b=[r,0],t.md.block.tokenize(t,r,T),R=t.push("blockquote_close","blockquote",-1),R.markup=">",t.lineMax=q,t.parentType=_,b[1]=t.line,l=0;l {"use strict";var KY=Ct().isSpace;LF.exports=function(t,r,n,a){var o,s,l,d,h=t.bMarks[r]+t.tShift[r],v=t.eMarks[r];if(t.sCount[r]-t.blkIndent>=4||(o=t.src.charCodeAt(h++),o!==42&&o!==45&&o!==95))return!1;for(s=1;h {"use strict";var IF=Ct().isSpace;function RF(e,t){var r,n,a,o;return n=e.bMarks[t]+e.tShift[t],a=e.eMarks[t],r=e.src.charCodeAt(n++),r!==42&&r!==45&&r!==43||n=o||(r=e.src.charCodeAt(a++),r<48||r>57))return-1;for(;;){if(a>=o)return-1;if(r=e.src.charCodeAt(a++),r>=48&&r<=57){if(a-n>=10)return-1;continue}if(r===41||r===46)break;return-1}return a =4||t.listIndent>=0&&t.sCount[r]-t.listIndent>=4&&t.sCount[r] =t.blkIndent&&(Ce=!0),(Q=FF(t,r))>=0){if(b=!0,j=t.bMarks[r]+t.tShift[r],_=Number(t.src.substr(j,Q-j-1)),Ce&&_!==1)return!1}else if((Q=RF(t,r))>=0)b=!1;else return!1;if(Ce&&t.skipSpaces(Q)>=t.eMarks[r])return!1;if(y=t.src.charCodeAt(Q-1),a)return!0;for(S=t.tokens.length,b?(be=t.push("ordered_list_open","ol",1),_!==1&&(be.attrs=[["start",_]])):be=t.push("bullet_list_open","ul",1),be.map=L=[r,0],be.markup=String.fromCharCode(y),k=r,G=!1,ke=t.md.block.ruler.getRules("list"),D=t.parentType,t.parentType="list";k =m?h=1:h=w-v,h>4&&(h=1),d=v+h,be=t.push("list_item_open","li",1),be.markup=String.fromCharCode(y),be.map=T=[r,0],q=t.tight,M=t.tShift[r],R=t.sCount[r],C=t.listIndent,t.listIndent=t.blkIndent,t.blkIndent=d,t.tight=!0,t.tShift[r]=s-t.bMarks[r],t.sCount[r]=w,s>=m&&t.isEmpty(r+1)?t.line=Math.min(t.line+2,n):t.md.block.tokenize(t,r,n,!0),(!t.tight||G)&&(we=!1),G=t.line-r>1&&t.isEmpty(t.line-1),t.blkIndent=t.listIndent,t.listIndent=C,t.tShift[r]=M,t.sCount[r]=R,t.tight=q,be=t.push("list_item_close","li",-1),be.markup=String.fromCharCode(y),k=r=t.line,T[1]=k,s=t.bMarks[r],k>=n||t.sCount[k] =4)break;for(ce=!1,l=0,A=ke.length;l{"use strict";var zY=Ct().normalizeReference,ym=Ct().isSpace;MF.exports=function(t,r,n,a){var o,s,l,d,h,v,b,T,A,L,S,y,_,m,k,w,C=0,D=t.bMarks[r]+t.tShift[r],R=t.eMarks[r],M=r+1;if(t.sCount[r]-t.blkIndent>=4||t.src.charCodeAt(D)!==91)return!1;for(;++D 3)&&!(t.sCount[M]<0)){for(m=!1,v=0,b=k.length;v{"use strict";var BF=Ct().isSpace;VF.exports=function(t,r,n,a){var o,s,l,d,h=t.bMarks[r]+t.tShift[r],v=t.eMarks[r];if(t.sCount[r]-t.blkIndent>=4||(o=t.src.charCodeAt(h),o!==35||h>=v))return!1;for(s=1,o=t.src.charCodeAt(++h);o===35&&h 6||h h&&BF(t.src.charCodeAt(l-1))&&(v=l),t.line=r+1,d=t.push("heading_open","h"+String(s),1),d.markup="########".slice(0,s),d.map=[r,t.line],d=t.push("inline","",0),d.content=t.src.slice(h,v).trim(),d.map=[r,t.line],d.children=[],d=t.push("heading_close","h"+String(s),-1),d.markup="########".slice(0,s)),!0)}});var QF=U(($ie,GF)=>{"use strict";GF.exports=function(t,r,n){var a,o,s,l,d,h,v,b,T,A=r+1,L,S=t.md.block.ruler.getRules("paragraph");if(t.sCount[r]-t.blkIndent>=4)return!1;for(L=t.parentType,t.parentType="paragraph";A 3)){if(t.sCount[A]>=t.blkIndent&&(h=t.bMarks[A]+t.tShift[A],v=t.eMarks[A],h =v)))){b=T===61?1:2;break}if(!(t.sCount[A]<0)){for(o=!1,s=0,l=S.length;s {"use strict";KF.exports=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","meta","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]});var TD=U((tae,bD)=>{"use strict";var WY="[a-zA-Z_:][a-zA-Z0-9:._-]*",YY="[^\"'=<>`\\x00-\\x20]+",JY="'[^']*'",XY='"[^"]*"',ZY="(?:"+YY+"|"+JY+"|"+XY+")",$Y="(?:\\s+"+WY+"(?:\\s*=\\s*"+ZY+")?)",zF="<[A-Za-z][A-Za-z0-9\\-]*"+$Y+"*\\s*\\/?>",WF="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",eJ="|",tJ="<[?].*?[?]>",rJ="]*>",nJ="",iJ=new RegExp("^(?:"+zF+"|"+WF+"|"+eJ+"|"+tJ+"|"+rJ+"|"+nJ+")"),aJ=new RegExp("^(?:"+zF+"|"+WF+")");bD.exports.HTML_TAG_RE=iJ;bD.exports.HTML_OPEN_CLOSE_TAG_RE=aJ});var JF=U((rae,YF)=>{"use strict";var oJ=HF(),uJ=TD().HTML_OPEN_CLOSE_TAG_RE,pc=[[/^<(script|pre|style)(?=(\s|>|$))/i,/<\/(script|pre|style)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[new RegExp("^?("+oJ.join("|")+")(?=(\\s|/?>|$))","i"),/^$/,!0],[new RegExp(uJ.source+"\\s*$"),/^$/,!1]];YF.exports=function(t,r,n,a){var o,s,l,d,h=t.bMarks[r]+t.tShift[r],v=t.eMarks[r];if(t.sCount[r]-t.blkIndent>=4||!t.md.options.html||t.src.charCodeAt(h)!==60)return!1;for(d=t.src.slice(h,v),o=0;o {"use strict";XF.exports=function(t,r){var n,a,o,s,l,d,h=r+1,v=t.md.block.ruler.getRules("paragraph"),b=t.lineMax;for(d=t.parentType,t.parentType="paragraph";h3)&&!(t.sCount[h]<0)){for(a=!1,o=0,s=v.length;o {"use strict";var $F=mm(),bm=Ct().isSpace;function Ra(e,t,r,n){var a,o,s,l,d,h,v,b;for(this.src=e,this.md=t,this.env=r,this.tokens=n,this.bMarks=[],this.eMarks=[],this.tShift=[],this.sCount=[],this.bsCount=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.ddIndent=-1,this.listIndent=-1,this.parentType="root",this.level=0,this.result="",o=this.src,b=!1,s=l=h=v=0,d=o.length;l0&&this.level++,this.tokens.push(n),n};Ra.prototype.isEmpty=function(t){return this.bMarks[t]+this.tShift[t]>=this.eMarks[t]};Ra.prototype.skipEmptyLines=function(t){for(var r=this.lineMax;t r;)if(!bm(this.src.charCodeAt(--t)))return t+1;return t};Ra.prototype.skipChars=function(t,r){for(var n=this.src.length;t n;)if(r!==this.src.charCodeAt(--t))return t+1;return t};Ra.prototype.getLines=function(t,r,n,a){var o,s,l,d,h,v,b,T=t;if(t>=r)return"";for(v=new Array(r-t),o=0;T n?v[o]=new Array(s-n+1).join(" ")+this.src.slice(d,h):v[o]=this.src.slice(d,h)}return v.join("")};Ra.prototype.Token=$F;ej.exports=Ra});var nj=U((aae,rj)=>{"use strict";var sJ=vm(),Tm=[["table",SF(),["paragraph","reference"]],["code",kF()],["fence",CF(),["paragraph","reference","blockquote","list"]],["blockquote",NF(),["paragraph","reference","blockquote","list"]],["hr",xF(),["paragraph","reference","blockquote","list"]],["list",PF(),["paragraph","reference","blockquote"]],["reference",qF()],["heading",UF(),["paragraph","reference","blockquote"]],["lheading",QF()],["html_block",JF(),["paragraph","reference","blockquote"]],["paragraph",ZF()]];function Em(){this.ruler=new sJ;for(var e=0;e =r||e.sCount[l] =h){e.line=r;break}for(a=0;a {"use strict";function lJ(e){switch(e){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}ij.exports=function(t,r){for(var n=t.pos;n{"use strict";var cJ=Ct().isSpace;oj.exports=function(t,r){var n,a,o=t.pos;if(t.src.charCodeAt(o)!==10)return!1;for(n=t.pending.length-1,a=t.posMax,r||(n>=0&&t.pending.charCodeAt(n)===32?n>=1&&t.pending.charCodeAt(n-1)===32?(t.pending=t.pending.replace(/ +$/,""),t.push("hardbreak","br",0)):(t.pending=t.pending.slice(0,-1),t.push("softbreak","br",0)):t.push("softbreak","br",0)),o++;o{"use strict";var fJ=Ct().isSpace,ED=[];for(_D=0;_D<256;_D++)ED.push(0);var _D;"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(e){ED[e.charCodeAt(0)]=1});sj.exports=function(t,r){var n,a=t.pos,o=t.posMax;if(t.src.charCodeAt(a)!==92)return!1;if(a++,a {"use strict";cj.exports=function(t,r){var n,a,o,s,l,d,h=t.pos,v=t.src.charCodeAt(h);if(v!==96)return!1;for(n=h,h++,a=t.posMax;h{"use strict";SD.exports.tokenize=function(t,r){var n,a,o,s,l,d=t.pos,h=t.src.charCodeAt(d);if(r||h!==126||(a=t.scanDelims(t.pos,!0),s=a.length,l=String.fromCharCode(h),s<2))return!1;for(s%2&&(o=t.push("text","",0),o.content=l,s--),n=0;n {"use strict";kD.exports.tokenize=function(t,r){var n,a,o,s=t.pos,l=t.src.charCodeAt(s);if(r||l!==95&&l!==42)return!1;for(a=t.scanDelims(t.pos,l===42),n=0;n=0;r--)n=t[r],!(n.marker!==95&&n.marker!==42)&&n.end!==-1&&(a=t[n.end],l=r>0&&t[r-1].end===n.end+1&&t[r-1].token===n.token-1&&t[n.end+1].token===a.token+1&&t[r-1].marker===n.marker,s=String.fromCharCode(n.marker),o=e.tokens[n.token],o.type=l?"strong_open":"em_open",o.tag=l?"strong":"em",o.nesting=1,o.markup=l?s+s:s,o.content="",o=e.tokens[a.token],o.type=l?"strong_close":"em_close",o.tag=l?"strong":"em",o.nesting=-1,o.markup=l?s+s:s,o.content="",l&&(e.tokens[t[r-1].token].content="",e.tokens[t[n.end+1].token].content="",r--))}kD.exports.postProcess=function(t){var r,n=t.tokens_meta,a=t.tokens_meta.length;for(pj(t,t.delimiters),r=0;r{"use strict";var dJ=Ct().normalizeReference,CD=Ct().isSpace;hj.exports=function(t,r){var n,a,o,s,l,d,h,v,b,T,A="",L=t.pos,S=t.posMax,y=t.pos,_=!0;if(t.src.charCodeAt(t.pos)!==91||(l=t.pos+1,s=t.md.helpers.parseLinkLabel(t,t.pos,!0),s<0))return!1;if(d=s+1,d =S)return!1;for(y=d,h=t.md.helpers.parseLinkDestination(t.src,d,t.posMax),h.ok&&(A=t.md.normalizeLink(h.str),t.md.validateLink(A)?d=h.pos:A=""),y=d;d=S||t.src.charCodeAt(d)!==41)&&(_=!0),d++}if(_){if(typeof t.env.references=="undefined")return!1;if(d=0?o=t.src.slice(y,d++):d=s+1):d=s+1,o||(o=t.src.slice(l,s)),v=t.env.references[dJ(o)],!v)return t.pos=L,!1;A=v.href,b=v.title}return r||(t.pos=l,t.posMax=s,T=t.push("link_open","a",1),T.attrs=n=[["href",A]],b&&n.push(["title",b]),t.md.inline.tokenize(t),T=t.push("link_close","a",-1)),t.pos=d,t.posMax=S,!0}});var mj=U((pae,gj)=>{"use strict";var pJ=Ct().normalizeReference,wD=Ct().isSpace;gj.exports=function(t,r){var n,a,o,s,l,d,h,v,b,T,A,L,S,y="",_=t.pos,m=t.posMax;if(t.src.charCodeAt(t.pos)!==33||t.src.charCodeAt(t.pos+1)!==91||(d=t.pos+2,l=t.md.helpers.parseLinkLabel(t,t.pos+1,!1),l<0))return!1;if(h=l+1,h=m)return!1;for(S=h,b=t.md.helpers.parseLinkDestination(t.src,h,t.posMax),b.ok&&(y=t.md.normalizeLink(b.str),t.md.validateLink(y)?h=b.pos:y=""),S=h;h =m||t.src.charCodeAt(h)!==41)return t.pos=_,!1;h++}else{if(typeof t.env.references=="undefined")return!1;if(h =0?s=t.src.slice(S,h++):h=l+1):h=l+1,s||(s=t.src.slice(d,l)),v=t.env.references[pJ(s)],!v)return t.pos=_,!1;y=v.href,T=v.title}return r||(o=t.src.slice(d,l),t.md.inline.parse(o,t.md,t.env,L=[]),A=t.push("image","img",0),A.attrs=n=[["src",y],["alt",""]],A.children=L,A.content=o,T&&n.push(["title",T])),t.pos=h,t.posMax=m,!0}});var Ej=U((hae,Tj)=>{"use strict";var yj=/^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,bj=/^<([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)>/;Tj.exports=function(t,r){var n,a,o,s,l,d,h=t.pos;return t.src.charCodeAt(h)!==60||(n=t.src.slice(h),n.indexOf(">")<0)?!1:bj.test(n)?(a=n.match(bj),s=a[0].slice(1,-1),l=t.md.normalizeLink(s),t.md.validateLink(l)?(r||(d=t.push("link_open","a",1),d.attrs=[["href",l]],d.markup="autolink",d.info="auto",d=t.push("text","",0),d.content=t.md.normalizeLinkText(s),d=t.push("link_close","a",-1),d.markup="autolink",d.info="auto"),t.pos+=a[0].length,!0):!1):yj.test(n)?(o=n.match(yj),s=o[0].slice(1,-1),l=t.md.normalizeLink("mailto:"+s),t.md.validateLink(l)?(r||(d=t.push("link_open","a",1),d.attrs=[["href",l]],d.markup="autolink",d.info="auto",d=t.push("text","",0),d.content=t.md.normalizeLinkText(s),d=t.push("link_close","a",-1),d.markup="autolink",d.info="auto"),t.pos+=o[0].length,!0):!1):!1}});var Sj=U((vae,_j)=>{"use strict";var hJ=TD().HTML_TAG_RE;function vJ(e){var t=e|32;return t>=97&&t<=122}_j.exports=function(t,r){var n,a,o,s,l=t.pos;return!t.md.options.html||(o=t.posMax,t.src.charCodeAt(l)!==60||l+2>=o)||(n=t.src.charCodeAt(l+1),n!==33&&n!==63&&n!==47&&!vJ(n))||(a=t.src.slice(l).match(hJ),!a)?!1:(r||(s=t.push("html_inline","",0),s.content=t.src.slice(l,l+a[0].length)),t.pos+=a[0].length,!0)}});var Cj=U((gae,Oj)=>{"use strict";var Dj=fD(),gJ=Ct().has,mJ=Ct().isValidEntityCode,kj=Ct().fromCodePoint,yJ=/^((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,bJ=/^&([a-z][a-z0-9]{1,31});/i;Oj.exports=function(t,r){var n,a,o,s=t.pos,l=t.posMax;if(t.src.charCodeAt(s)!==38)return!1;if(s+1 {"use strict";function wj(e,t){var r,n,a,o,s,l,d,h,v={},b=t.length;for(r=0;rs;n-=o.jump+1)if(o=t[n],o.marker===a.marker&&(l===-1&&(l=n),o.open&&o.end<0&&o.level===a.level&&(d=!1,(o.close||a.open)&&(o.length+a.length)%3==0&&(o.length%3!=0||a.length%3!=0)&&(d=!0),!d))){h=n>0&&!t[n-1].open?t[n-1].jump+1:0,a.jump=r-n+h,a.open=!1,o.end=r,o.jump=h,o.close=!1,l=-1;break}l!==-1&&(v[a.marker][(a.length||0)%3]=l)}}Aj.exports=function(t){var r,n=t.tokens_meta,a=t.tokens_meta.length;for(wj(t,t.delimiters),r=0;r{"use strict";Lj.exports=function(t){var r,n,a=0,o=t.tokens,s=t.tokens.length;for(r=n=0;r 0&&a++,o[r].type==="text"&&r+1{"use strict";var AD=mm(),Ij=Ct().isWhiteSpace,Rj=Ct().isPunctChar,Fj=Ct().isMdAsciiPunct;function fp(e,t,r,n){this.src=e,this.env=r,this.md=t,this.tokens=n,this.tokens_meta=Array(n.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[]}fp.prototype.pushPending=function(){var e=new AD("text","",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending="",e};fp.prototype.push=function(e,t,r){this.pending&&this.pushPending();var n=new AD(e,t,r),a=null;return r<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),n.level=this.level,r>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],a={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(n),this.tokens_meta.push(a),n};fp.prototype.scanDelims=function(e,t){var r=e,n,a,o,s,l,d,h,v,b,T=!0,A=!0,L=this.posMax,S=this.src.charCodeAt(e);for(n=e>0?this.src.charCodeAt(e-1):32;r{"use strict";var Mj=vm(),ND=[["text",aj()],["newline",uj()],["escape",lj()],["backticks",fj()],["strikethrough",DD().tokenize],["emphasis",OD().tokenize],["link",vj()],["image",mj()],["autolink",Ej()],["html_inline",Sj()],["entity",Cj()]],LD=[["balance_pairs",Nj()],["strikethrough",DD().postProcess],["emphasis",OD().postProcess],["text_collapse",xj()]];function dp(){var e;for(this.ruler=new Mj,e=0;e =o)break;continue}e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()};dp.prototype.parse=function(e,t,r,n){var a,o,s,l=new this.State(e,t,r,n);for(this.tokenize(l),o=this.ruler2.getRules(""),s=o.length,a=0;a {"use strict";Vj.exports=function(e){var t={};t.src_Any=pD().source,t.src_Cc=hD().source,t.src_Z=vD().source,t.src_P=cm().source,t.src_ZPCc=[t.src_Z,t.src_P,t.src_Cc].join("|"),t.src_ZCc=[t.src_Z,t.src_Cc].join("|");var r="[><\uFF5C]";return t.src_pseudo_letter="(?:(?!"+r+"|"+t.src_ZPCc+")"+t.src_Any+")",t.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",t.src_auth="(?:(?:(?!"+t.src_ZCc+"|[@/\\[\\]()]).)+@)?",t.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",t.src_host_terminator="(?=$|"+r+"|"+t.src_ZPCc+")(?!-|_|:\\d|\\.-|\\.(?!$|"+t.src_ZPCc+"))",t.src_path="(?:[/?#](?:(?!"+t.src_ZCc+"|"+r+`|[()[\\]{}.,"'?!\\-]).|\\[(?:(?!`+t.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+t.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+t.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+t.src_ZCc+`|["]).)+\\"|\\'(?:(?!`+t.src_ZCc+"|[']).)+\\'|\\'(?="+t.src_pseudo_letter+"|[-]).|\\.{2,4}[a-zA-Z0-9%/]|\\.(?!"+t.src_ZCc+"|[.]).|"+(e&&e["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+"\\,(?!"+t.src_ZCc+").|\\!(?!"+t.src_ZCc+"|[!]).|\\?(?!"+t.src_ZCc+"|[?]).)+|\\/)?",t.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*',t.src_xn="xn--[a-z0-9\\-]{1,59}",t.src_domain_root="(?:"+t.src_xn+"|"+t.src_pseudo_letter+"{1,63})",t.src_domain="(?:"+t.src_xn+"|(?:"+t.src_pseudo_letter+")|(?:"+t.src_pseudo_letter+"(?:-|"+t.src_pseudo_letter+"){0,61}"+t.src_pseudo_letter+"))",t.src_host="(?:(?:(?:(?:"+t.src_domain+")\\.)*"+t.src_domain+"))",t.tpl_host_fuzzy="(?:"+t.src_ip4+"|(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%)))",t.tpl_host_no_ip_fuzzy="(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%))",t.src_host_strict=t.src_host+t.src_host_terminator,t.tpl_host_fuzzy_strict=t.tpl_host_fuzzy+t.src_host_terminator,t.src_host_port_strict=t.src_host+t.src_port+t.src_host_terminator,t.tpl_host_port_fuzzy_strict=t.tpl_host_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_port_no_ip_fuzzy_strict=t.tpl_host_no_ip_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+t.src_ZPCc+"|>|$))",t.tpl_email_fuzzy="(^|"+r+'|"|\\(|'+t.src_ZCc+")("+t.src_email_name+"@"+t.tpl_host_fuzzy_strict+")",t.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+t.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+t.tpl_host_port_fuzzy_strict+t.src_path+")",t.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+t.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+t.tpl_host_port_no_ip_fuzzy_strict+t.src_path+")",t}});var Wj=U((_ae,zj)=>{"use strict";function xD(e){var t=Array.prototype.slice.call(arguments,1);return t.forEach(function(r){!r||Object.keys(r).forEach(function(n){e[n]=r[n]})}),e}function _m(e){return Object.prototype.toString.call(e)}function TJ(e){return _m(e)==="[object String]"}function EJ(e){return _m(e)==="[object Object]"}function _J(e){return _m(e)==="[object RegExp]"}function Gj(e){return _m(e)==="[object Function]"}function SJ(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}var Qj={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};function DJ(e){return Object.keys(e||{}).reduce(function(t,r){return t||Qj.hasOwnProperty(r)},!1)}var kJ={"http:":{validate:function(e,t,r){var n=e.slice(t);return r.re.http||(r.re.http=new RegExp("^\\/\\/"+r.re.src_auth+r.re.src_host_port_strict+r.re.src_path,"i")),r.re.http.test(n)?n.match(r.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(e,t,r){var n=e.slice(t);return r.re.no_http||(r.re.no_http=new RegExp("^"+r.re.src_auth+"(?:localhost|(?:(?:"+r.re.src_domain+")\\.)+"+r.re.src_domain_root+")"+r.re.src_port+r.re.src_host_terminator+r.re.src_path,"i")),r.re.no_http.test(n)?t>=3&&e[t-3]===":"||t>=3&&e[t-3]==="/"?0:n.match(r.re.no_http)[0].length:0}},"mailto:":{validate:function(e,t,r){var n=e.slice(t);return r.re.mailto||(r.re.mailto=new RegExp("^"+r.re.src_email_name+"@"+r.re.src_host_strict,"i")),r.re.mailto.test(n)?n.match(r.re.mailto)[0].length:0}}},OJ="a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]",CJ="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");function wJ(e){e.__index__=-1,e.__text_cache__=""}function AJ(e){return function(t,r){var n=t.slice(r);return e.test(n)?n.match(e)[0].length:0}}function Kj(){return function(e,t){t.normalize(e)}}function Sm(e){var t=e.re=Uj()(e.__opts__),r=e.__tlds__.slice();e.onCompile(),e.__tlds_replaced__||r.push(OJ),r.push(t.src_xn),t.src_tlds=r.join("|");function n(l){return l.replace("%TLDS%",t.src_tlds)}t.email_fuzzy=RegExp(n(t.tpl_email_fuzzy),"i"),t.link_fuzzy=RegExp(n(t.tpl_link_fuzzy),"i"),t.link_no_ip_fuzzy=RegExp(n(t.tpl_link_no_ip_fuzzy),"i"),t.host_fuzzy_test=RegExp(n(t.tpl_host_fuzzy_test),"i");var a=[];e.__compiled__={};function o(l,d){throw new Error('(LinkifyIt) Invalid schema "'+l+'": '+d)}Object.keys(e.__schemas__).forEach(function(l){var d=e.__schemas__[l];if(d!==null){var h={validate:null,link:null};if(e.__compiled__[l]=h,EJ(d)){_J(d.validate)?h.validate=AJ(d.validate):Gj(d.validate)?h.validate=d.validate:o(l,d),Gj(d.normalize)?h.normalize=d.normalize:d.normalize?o(l,d):h.normalize=Kj();return}if(TJ(d)){a.push(l);return}o(l,d)}}),a.forEach(function(l){!e.__compiled__[e.__schemas__[l]]||(e.__compiled__[l].validate=e.__compiled__[e.__schemas__[l]].validate,e.__compiled__[l].normalize=e.__compiled__[e.__schemas__[l]].normalize)}),e.__compiled__[""]={validate:null,normalize:Kj()};var s=Object.keys(e.__compiled__).filter(function(l){return l.length>0&&e.__compiled__[l]}).map(SJ).join("|");e.re.schema_test=RegExp("(^|(?!_)(?:[><\uFF5C]|"+t.src_ZPCc+"))("+s+")","i"),e.re.schema_search=RegExp("(^|(?!_)(?:[><\uFF5C]|"+t.src_ZPCc+"))("+s+")","ig"),e.re.pretest=RegExp("("+e.re.schema_test.source+")|("+e.re.host_fuzzy_test.source+")|@","i"),wJ(e)}function NJ(e,t){var r=e.__index__,n=e.__last_index__,a=e.__text_cache__.slice(r,n);this.schema=e.__schema__.toLowerCase(),this.index=r+t,this.lastIndex=n+t,this.raw=a,this.text=a,this.url=a}function Hj(e,t){var r=new NJ(e,t);return e.__compiled__[r.schema].normalize(r,e),r}function Ri(e,t){if(!(this instanceof Ri))return new Ri(e,t);t||DJ(e)&&(t=e,e={}),this.__opts__=xD({},Qj,t),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=xD({},kJ,e),this.__compiled__={},this.__tlds__=CJ,this.__tlds_replaced__=!1,this.re={},Sm(this)}Ri.prototype.add=function(t,r){return this.__schemas__[t]=r,Sm(this),this};Ri.prototype.set=function(t){return this.__opts__=xD(this.__opts__,t),this};Ri.prototype.test=function(t){if(this.__text_cache__=t,this.__index__=-1,!t.length)return!1;var r,n,a,o,s,l,d,h,v;if(this.re.schema_test.test(t)){for(d=this.re.schema_search,d.lastIndex=0;(r=d.exec(t))!==null;)if(o=this.testSchemaAt(t,r[2],d.lastIndex),o){this.__schema__=r[2],this.__index__=r.index+r[1].length,this.__last_index__=r.index+r[0].length+o;break}}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(h=t.search(this.re.host_fuzzy_test),h>=0&&(this.__index__<0||h=0&&(a=t.match(this.re.email_fuzzy))!==null&&(s=a.index+a[1].length,l=a.index+a[0].length,(this.__index__<0||s this.__last_index__)&&(this.__schema__="mailto:",this.__index__=s,this.__last_index__=l))),this.__index__>=0};Ri.prototype.pretest=function(t){return this.re.pretest.test(t)};Ri.prototype.testSchemaAt=function(t,r,n){return this.__compiled__[r.toLowerCase()]?this.__compiled__[r.toLowerCase()].validate(t,n,this):0};Ri.prototype.match=function(t){var r=0,n=[];this.__index__>=0&&this.__text_cache__===t&&(n.push(Hj(this,r)),r=this.__last_index__);for(var a=r?t.slice(r):t;this.test(a);)n.push(Hj(this,r)),a=a.slice(this.__last_index__),r+=this.__last_index__;return n.length?n:null};Ri.prototype.tlds=function(t,r){return t=Array.isArray(t)?t:[t],r?(this.__tlds__=this.__tlds__.concat(t).sort().filter(function(n,a,o){return n!==o[a-1]}).reverse(),Sm(this),this):(this.__tlds__=t.slice(),this.__tlds_replaced__=!0,Sm(this),this)};Ri.prototype.normalize=function(t){t.schema||(t.url="http://"+t.url),t.schema==="mailto:"&&!/^mailto:/i.test(t.url)&&(t.url="mailto:"+t.url)};Ri.prototype.onCompile=function(){};zj.exports=Ri});var aP=U((Sae,iP)=>{"use strict";var hc=2147483647,Fa=36,ID=1,pp=26,LJ=38,xJ=700,Yj=72,Jj=128,Xj="-",IJ=/^xn--/,RJ=/[^\0-\x7E]/,FJ=/[\x2E\u3002\uFF0E\uFF61]/g,jJ={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},RD=Fa-ID,ja=Math.floor,FD=String.fromCharCode;function Ts(e){throw new RangeError(jJ[e])}function PJ(e,t){let r=[],n=e.length;for(;n--;)r[n]=t(e[n]);return r}function Zj(e,t){let r=e.split("@"),n="";r.length>1&&(n=r[0]+"@",e=r[1]),e=e.replace(FJ,".");let a=e.split("."),o=PJ(a,t).join(".");return n+o}function $j(e){let t=[],r=0,n=e.length;for(;r =55296&&a<=56319&&r String.fromCodePoint(...e),qJ=function(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:Fa},eP=function(e,t){return e+22+75*(e<26)-((t!=0)<<5)},tP=function(e,t,r){let n=0;for(e=r?ja(e/xJ):e>>1,e+=ja(e/t);e>RD*pp>>1;n+=Fa)e=ja(e/RD);return ja(n+(RD+1)*e/(e+LJ))},rP=function(e){let t=[],r=e.length,n=0,a=Jj,o=Yj,s=e.lastIndexOf(Xj);s<0&&(s=0);for(let l=0;l =128&&Ts("not-basic"),t.push(e.charCodeAt(l));for(let l=s>0?s+1:0;l=r&&Ts("invalid-input");let T=qJ(e.charCodeAt(l++));(T>=Fa||T>ja((hc-n)/v))&&Ts("overflow"),n+=T*v;let A=b<=o?ID:b>=o+pp?pp:b-o;if(Tja(hc/L)&&Ts("overflow"),v*=L}let h=t.length+1;o=tP(n-d,h,d==0),ja(n/h)>hc-a&&Ts("overflow"),a+=ja(n/h),n%=h,t.splice(n++,0,a)}return String.fromCodePoint(...t)},nP=function(e){let t=[];e=$j(e);let r=e.length,n=Jj,a=0,o=Yj;for(let d of e)d<128&&t.push(FD(d));let s=t.length,l=s;for(s&&t.push(Xj);l =n&&v ja((hc-a)/h)&&Ts("overflow"),a+=(d-n)*h,n=d;for(let v of e)if(v hc&&Ts("overflow"),v==n){let b=a;for(let T=Fa;;T+=Fa){let A=T<=o?ID:T>=o+pp?pp:T-o;if(b{"use strict";oP.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}}});var lP=U((kae,sP)=>{"use strict";sP.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline"]},block:{rules:["paragraph"]},inline:{rules:["text"],rules2:["balance_pairs","text_collapse"]}}}});var fP=U((Oae,cP)=>{"use strict";cP.exports={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline"]},block:{rules:["blockquote","code","fence","heading","hr","html_block","lheading","list","reference","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","html_inline","image","link","newline","text"],rules2:["balance_pairs","emphasis","text_collapse"]}}}});var vP=U((Cae,hP)=>{"use strict";var hp=Ct(),GJ=zR(),QJ=YR(),KJ=TF(),HJ=nj(),zJ=Bj(),WJ=Wj(),vc=dD(),dP=aP(),YJ={default:uP(),zero:lP(),commonmark:fP()},JJ=/^(vbscript|javascript|file|data):/,XJ=/^data:image\/(gif|png|jpeg|webp);/;function ZJ(e){var t=e.trim().toLowerCase();return JJ.test(t)?!!XJ.test(t):!0}var pP=["http:","https:","mailto:"];function $J(e){var t=vc.parse(e,!0);if(t.hostname&&(!t.protocol||pP.indexOf(t.protocol)>=0))try{t.hostname=dP.toASCII(t.hostname)}catch(r){}return vc.encode(vc.format(t))}function eX(e){var t=vc.parse(e,!0);if(t.hostname&&(!t.protocol||pP.indexOf(t.protocol)>=0))try{t.hostname=dP.toUnicode(t.hostname)}catch(r){}return vc.decode(vc.format(t))}function Fi(e,t){if(!(this instanceof Fi))return new Fi(e,t);t||hp.isString(e)||(t=e||{},e="default"),this.inline=new zJ,this.block=new HJ,this.core=new KJ,this.renderer=new QJ,this.linkify=new WJ,this.validateLink=ZJ,this.normalizeLink=$J,this.normalizeLinkText=eX,this.utils=hp,this.helpers=hp.assign({},GJ),this.options={},this.configure(e),t&&this.set(t)}Fi.prototype.set=function(e){return hp.assign(this.options,e),this};Fi.prototype.configure=function(e){var t=this,r;if(hp.isString(e)&&(r=e,e=YJ[r],!e))throw new Error('Wrong `markdown-it` preset "'+r+'", check name');if(!e)throw new Error("Wrong `markdown-it` preset, can't be empty");return e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(n){e.components[n].rules&&t[n].ruler.enableOnly(e.components[n].rules),e.components[n].rules2&&t[n].ruler2.enableOnly(e.components[n].rules2)}),this};Fi.prototype.enable=function(e,t){var r=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(a){r=r.concat(this[a].ruler.enable(e,!0))},this),r=r.concat(this.inline.ruler2.enable(e,!0));var n=e.filter(function(a){return r.indexOf(a)<0});if(n.length&&!t)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+n);return this};Fi.prototype.disable=function(e,t){var r=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(a){r=r.concat(this[a].ruler.disable(e,!0))},this),r=r.concat(this.inline.ruler2.disable(e,!0));var n=e.filter(function(a){return r.indexOf(a)<0});if(n.length&&!t)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+n);return this};Fi.prototype.use=function(e){var t=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,t),this};Fi.prototype.parse=function(e,t){if(typeof e!="string")throw new Error("Input data should be a String");var r=new this.core.State(e,this,t);return this.core.process(r),r.tokens};Fi.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)};Fi.prototype.parseInline=function(e,t){var r=new this.core.State(e,this,t);return r.inlineMode=!0,this.core.process(r),r.tokens};Fi.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)};hP.exports=Fi});var Dm=U((wae,gP)=>{"use strict";gP.exports=vP()});var ft=U((jD,PD)=>{(function(e,t){typeof jD=="object"&&typeof PD!="undefined"?PD.exports=t():typeof define=="function"&&define.amd?define(t):(e=e||self,e.CodeMirror=t())})(jD,function(){"use strict";var e=navigator.userAgent,t=navigator.platform,r=/gecko\/\d/i.test(e),n=/MSIE \d/.test(e),a=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(e),o=/Edge\/(\d+)/.exec(e),s=n||a||o,l=s&&(n?document.documentMode||6:+(o||a)[1]),d=!o&&/WebKit\//.test(e),h=d&&/Qt\/\d+\.\d+/.test(e),v=!o&&/Chrome\/(\d+)/.exec(e),b=v&&+v[1],T=/Opera\//.test(e),A=/Apple Computer/.test(navigator.vendor),L=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(e),S=/PhantomJS/.test(e),y=A&&(/Mobile\/\w+/.test(e)||navigator.maxTouchPoints>2),_=/Android/.test(e),m=y||_||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),k=y||/Mac/.test(t),w=/\bCrOS\b/.test(e),C=/win/i.test(t),D=T&&e.match(/Version\/(\d*\.\d*)/);D&&(D=Number(D[1])),D&&D>=15&&(T=!1,d=!0);var R=k&&(h||T&&(D==null||D<12.11)),M=r||s&&l>=9;function q(i){return new RegExp("(^|\\s)"+i+"(?:$|\\s)\\s*")}var z=function(i,u){var f=i.className,c=q(u).exec(f);if(c){var p=f.slice(c.index+c[0].length);i.className=f.slice(0,c.index)+(p?c[1]+p:"")}};function Q(i){for(var u=i.childNodes.length;u>0;--u)i.removeChild(i.firstChild);return i}function G(i,u){return Q(i).appendChild(u)}function j(i,u,f,c){var p=document.createElement(i);if(f&&(p.className=f),c&&(p.style.cssText=c),typeof u=="string")p.appendChild(document.createTextNode(u));else if(u)for(var g=0;g =u)return E+(u-g);E+=O-g,E+=f-E%f,g=O+1}}var Pe=function(){this.id=null,this.f=null,this.time=0,this.handler=Mt(this.onTimeout,this)};Pe.prototype.onTimeout=function(i){i.id=0,i.time<=+new Date?i.f():setTimeout(i.handler,i.time-+new Date)},Pe.prototype.set=function(i,u){this.f=u;var f=+new Date+i;(!this.id||f =u)return c+Math.min(E,u-p);if(p+=g-c,p+=f-p%f,c=g+1,p>=u)return c}}var Se=[""];function fe(i){for(;Se.length<=i;)Se.push(ue(Se)+" ");return Se[i]}function ue(i){return i[i.length-1]}function Ge(i,u){for(var f=[],c=0;c "\x80"&&(i.toUpperCase()!=i.toLowerCase()||Qi.test(i))}function mi(i,u){return u?u.source.indexOf("\\w")>-1&&la(i)?!0:u.test(i):la(i)}function Qa(i){for(var u in i)if(i.hasOwnProperty(u)&&i[u])return!1;return!0}var ca=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function Ka(i){return i.charCodeAt(0)>=768&&ca.test(i)}function kn(i,u,f){for(;(f<0?u>0:u f?-1:1;;){if(u==f)return u;var p=(u+f)/2,g=c<0?Math.ceil(p):Math.floor(p);if(g==u)return i(g)?u:f;i(g)?f=g:u=g+c}}function On(i,u,f,c){if(!i)return c(u,f,"ltr",0);for(var p=!1,g=0;g u||u==f&&E.to==u)&&(c(Math.max(E.from,u),Math.min(E.to,f),E.level==1?"rtl":"ltr",g),p=!0)}p||c(u,f,"ltr")}var yi=null;function qn(i,u,f){var c;yi=null;for(var p=0;p u)return p;g.to==u&&(g.from!=g.to&&f=="before"?c=p:yi=p),g.from==u&&(g.from!=g.to&&f!="before"?c=p:yi=p)}return c!=null?c:yi}var Pc=function(){var i="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",u="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";function f(x){return x<=247?i.charAt(x):1424<=x&&x<=1524?"R":1536<=x&&x<=1785?u.charAt(x-1536):1774<=x&&x<=2220?"r":8192<=x&&x<=8203?"w":x==8204?"b":"L"}var c=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,p=/[stwN]/,g=/[LRr]/,E=/[Lb1n]/,O=/[1n]/;function N(x,V,K){this.level=x,this.from=V,this.to=K}return function(x,V){var K=V=="ltr"?"L":"R";if(x.length==0||V=="ltr"&&!c.test(x))return!1;for(var $=x.length,X=[],ne=0;ne<$;++ne)X.push(f(x.charCodeAt(ne)));for(var ae=0,le=K;ae<$;++ae){var he=X[ae];he=="m"?X[ae]=le:le=he}for(var Ee=0,ve=K;Ee<$;++Ee){var Oe=X[Ee];Oe=="1"&&ve=="r"?X[Ee]="n":g.test(Oe)&&(ve=Oe,Oe=="r"&&(X[Ee]="R"))}for(var Fe=1,Re=X[0];Fe<$-1;++Fe){var Xe=X[Fe];Xe=="+"&&Re=="1"&&X[Fe+1]=="1"?X[Fe]="1":Xe==","&&Re==X[Fe+1]&&(Re=="1"||Re=="n")&&(X[Fe]=Re),Re=Xe}for(var Pt=0;Pt<$;++Pt){var Rr=X[Pt];if(Rr==",")X[Pt]="N";else if(Rr=="%"){var $t=void 0;for($t=Pt+1;$t<$&&X[$t]=="%";++$t);for(var Gn=Pt&&X[Pt-1]=="!"||$t<$&&X[$t]=="1"?"1":"N",An=Pt;An<$t;++An)X[An]=Gn;Pt=$t-1}}for(var hr=0,Nn=K;hr<$;++hr){var Wr=X[hr];Nn=="L"&&Wr=="1"?X[hr]="L":g.test(Wr)&&(Nn=Wr)}for(var Dr=0;Dr<$;++Dr)if(p.test(X[Dr])){var vr=void 0;for(vr=Dr+1;vr<$&&p.test(X[vr]);++vr);for(var ar=(Dr?X[Dr-1]:K)=="L",Ln=(vr<$?X[vr]:K)=="L",Xs=ar==Ln?ar?"L":"R":K,Lo=Dr;Lo -1&&(c[u]=p.slice(0,g).concat(p.slice(g+1)))}}}function At(i,u){var f=ku(i,u);if(!!f.length)for(var c=Array.prototype.slice.call(arguments,2),p=0;p 0}function zr(i){i.prototype.on=function(u,f){ge(this,u,f)},i.prototype.off=function(u,f){Tr(this,u,f)}}function ee(i){i.preventDefault?i.preventDefault():i.returnValue=!1}function P(i){i.stopPropagation?i.stopPropagation():i.cancelBubble=!0}function Y(i){return i.defaultPrevented!=null?i.defaultPrevented:i.returnValue==!1}function J(i){ee(i),P(i)}function B(i){return i.target||i.srcElement}function I(i){var u=i.which;return u==null&&(i.button&1?u=1:i.button&2?u=3:i.button&4&&(u=2)),k&&i.ctrlKey&&u==1&&(u=3),u}var te=function(){if(s&&l<9)return!1;var i=j("div");return"draggable"in i||"dragDrop"in i}(),ie;function Qe(i){if(ie==null){var u=j("span","\u200B");G(i,j("span",[u,document.createTextNode("x")])),i.firstChild.offsetHeight!=0&&(ie=u.offsetWidth<=1&&u.offsetHeight>2&&!(s&&l<8))}var f=ie?j("span","\u200B"):j("span","\xA0",null,"display: inline-block; width: 1px; margin-right: -1px");return f.setAttribute("cm-text",""),f}var It;function kt(i){if(It!=null)return It;var u=G(i,document.createTextNode("A\u062EA")),f=ke(u,0,1).getBoundingClientRect(),c=ke(u,1,2).getBoundingClientRect();return Q(i),!f||f.left==f.right?!1:It=c.right-f.right<3}var en=` + +b`.split(/\n/).length!=3?function(i){for(var u=0,f=[],c=i.length;u<=c;){var p=i.indexOf(` +`,u);p==-1&&(p=i.length);var g=i.slice(u,i.charAt(p-1)=="\r"?p-1:p),E=g.indexOf("\r");E!=-1?(f.push(g.slice(0,E)),u+=E+1):(f.push(g),u=p+1)}return f}:function(i){return i.split(/\r\n?|\n/)},Er=window.getSelection?function(i){try{return i.selectionStart!=i.selectionEnd}catch(u){return!1}}:function(i){var u;try{u=i.ownerDocument.selection.createRange()}catch(f){}return!u||u.parentElement()!=i?!1:u.compareEndPoints("StartToEnd",u)!=0},_r=function(){var i=j("div");return"oncopy"in i?!0:(i.setAttribute("oncopy","return;"),typeof i.oncopy=="function")}(),He=null;function Ki(i){if(He!=null)return He;var u=G(i,j("span","x")),f=u.getBoundingClientRect(),c=ke(u,0,1).getBoundingClientRect();return He=Math.abs(f.left-c.left)>1}var fn={},Hi={};function Kp(i,u){arguments.length>2&&(u.dependencies=Array.prototype.slice.call(arguments,2)),fn[i]=u}function xs(i,u){Hi[i]=u}function Vn(i){if(typeof i=="string"&&Hi.hasOwnProperty(i))i=Hi[i];else if(i&&typeof i.name=="string"&&Hi.hasOwnProperty(i.name)){var u=Hi[i.name];typeof u=="string"&&(u={name:u}),i=at(u,i),i.name=u.name}else{if(typeof i=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(i))return Vn("application/xml");if(typeof i=="string"&&/^[\w\-]+\/[\w\-]+\+json$/.test(i))return Vn("application/json")}return typeof i=="string"?{name:i}:i||{name:"null"}}function Ha(i,u){u=Vn(u);var f=fn[u.name];if(!f)return Ha(i,"text/plain");var c=f(i,u);if(Eo.hasOwnProperty(u.name)){var p=Eo[u.name];for(var g in p)!p.hasOwnProperty(g)||(c.hasOwnProperty(g)&&(c["_"+g]=c[g]),c[g]=p[g])}if(c.name=u.name,u.helperType&&(c.helperType=u.helperType),u.modeProps)for(var E in u.modeProps)c[E]=u.modeProps[E];return c}var Eo={};function Hp(i,u){var f=Eo.hasOwnProperty(i)?Eo[i]:Eo[i]={};Ie(u,f)}function za(i,u){if(u===!0)return u;if(i.copyState)return i.copyState(u);var f={};for(var c in u){var p=u[c];p instanceof Array&&(p=p.concat([])),f[c]=p}return f}function _o(i,u){for(var f;i.innerMode&&(f=i.innerMode(u),!(!f||f.mode==i));)u=f.state,i=f.mode;return f||{mode:i,state:u}}function Mc(i,u,f){return i.startState?i.startState(u,f):!0}var ir=function(i,u,f){this.pos=this.start=0,this.string=i,this.tabSize=u||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=f};ir.prototype.eol=function(){return this.pos>=this.string.length},ir.prototype.sol=function(){return this.pos==this.lineStart},ir.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},ir.prototype.next=function(){if(this.pos u},ir.prototype.eatSpace=function(){for(var i=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>i},ir.prototype.skipToEnd=function(){this.pos=this.string.length},ir.prototype.skipTo=function(i){var u=this.string.indexOf(i,this.pos);if(u>-1)return this.pos=u,!0},ir.prototype.backUp=function(i){this.pos-=i},ir.prototype.column=function(){return this.lastColumnPos 0?null:(g&&u!==!1&&(this.pos+=g[0].length),g)}},ir.prototype.current=function(){return this.string.slice(this.start,this.pos)},ir.prototype.hideFirstChars=function(i,u){this.lineStart+=i;try{return u()}finally{this.lineStart-=i}},ir.prototype.lookAhead=function(i){var u=this.lineOracle;return u&&u.lookAhead(i)},ir.prototype.baseToken=function(){var i=this.lineOracle;return i&&i.baseToken(this.pos)};function Ae(i,u){if(u-=i.first,u<0||u>=i.size)throw new Error("There is no line "+(u+i.first)+" in the document.");for(var f=i;!f.lines;)for(var c=0;;++c){var p=f.children[c],g=p.chunkSize();if(u =i.first&&u f?W(f,Ae(i,f).text.length):S3(u,Ae(i,u.line).text.length)}function S3(i,u){var f=i.ch;return f==null||f>u?W(i.line,u):f<0?W(i.line,0):i}function tk(i,u){for(var f=[],c=0;c this.maxLookAhead&&(this.maxLookAhead=i),u},da.prototype.baseToken=function(i){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=i;)this.baseTokenPos+=2;var u=this.baseTokens[this.baseTokenPos+1];return{type:u&&u.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-i}},da.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},da.fromSaved=function(i,u,f){return u instanceof zp?new da(i,za(i.mode,u.state),f,u.lookAhead):new da(i,za(i.mode,u),f)},da.prototype.save=function(i){var u=i!==!1?za(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new zp(u,this.maxLookAhead):u};function rk(i,u,f,c){var p=[i.state.modeGen],g={};sk(i,u.text,i.doc.mode,f,function(x,V){return p.push(x,V)},g,c);for(var E=f.state,O=function(x){f.baseTokens=p;var V=i.state.overlays[x],K=1,$=0;f.state=!0,sk(i,u.text,V.mode,f,function(X,ne){for(var ae=K;$ X&&p.splice(K,1,X,p[K+1],le),K+=2,$=Math.min(X,le)}if(!!ne)if(V.opaque)p.splice(ae,K-ae,X,"overlay "+ne),K=ae+2;else for(;ae i.options.maxHighlightLength&&za(i.doc.mode,c.state),g=rk(i,u,c);p&&(c.state=p),u.stateAfter=c.save(!p),u.styles=g.styles,g.classes?u.styleClasses=g.classes:u.styleClasses&&(u.styleClasses=null),f===i.doc.highlightFrontier&&(i.doc.modeFrontier=Math.max(i.doc.modeFrontier,++i.doc.highlightFrontier))}return u.styles}function qc(i,u,f){var c=i.doc,p=i.display;if(!c.mode.startState)return new da(c,!0,u);var g=D3(i,u,f),E=g>c.first&&Ae(c,g-1).stateAfter,O=E?da.fromSaved(c,E,g):new da(c,Mc(c.mode),g);return c.iter(g,u,function(N){py(i,N.text,O);var x=O.line;N.stateAfter=x==u-1||x%5==0||x>=p.viewFrom&&x u.start)return g}throw new Error("Mode "+i.name+" failed to advance stream.")}var ak=function(i,u,f){this.start=i.start,this.end=i.pos,this.string=i.current(),this.type=u||null,this.state=f};function ok(i,u,f,c){var p=i.doc,g=p.mode,E;u=qe(p,u);var O=Ae(p,u.line),N=qc(i,u.line,f),x=new ir(O.text,i.options.tabSize,N),V;for(c&&(V=[]);(c||x.pos i.options.maxHighlightLength?(O=!1,E&&py(i,u,c,V.pos),V.pos=u.length,K=null):K=uk(hy(f,V,c.state,$),g),$){var X=$[0].name;X&&(K="m-"+(K?X+" "+K:X))}if(!O||x!=K){for(;N E;--O){if(O<=g.first)return g.first;var N=Ae(g,O-1),x=N.stateAfter;if(x&&(!f||O+(x instanceof zp?x.lookAhead:0)<=g.modeFrontier))return O;var V=De(N.text,null,i.options.tabSize);(p==null||c>V)&&(p=O-1,c=V)}return p}function k3(i,u){if(i.modeFrontier=Math.min(i.modeFrontier,u),!(i.highlightFrontier f;c--){var p=Ae(i,c).stateAfter;if(p&&(!(p instanceof zp)||c+p.lookAhead=u:g.to>u);(c||(c=[])).push(new Wp(E,g.from,N?null:g.to))}}return c}function L3(i,u,f){var c;if(i)for(var p=0;p =u:g.to>u);if(O||g.from==u&&E.type=="bookmark"&&(!f||g.marker.insertLeft)){var N=g.from==null||(E.inclusiveLeft?g.from<=u:g.from0&&O)for(var Oe=0;Oe 0)){var V=[N,1],K=re(x.from,O.from),$=re(x.to,O.to);(K<0||!E.inclusiveLeft&&!K)&&V.push({from:x.from,to:O.from}),($>0||!E.inclusiveRight&&!$)&&V.push({from:O.to,to:x.to}),p.splice.apply(p,V),N+=V.length-3}}return p}function fk(i){var u=i.markedSpans;if(!!u){for(var f=0;f u)&&(!c||gy(c,g.marker)<0)&&(c=g.marker)}return c}function vk(i,u,f,c,p){var g=Ae(i,u),E=Ya&&g.markedSpans;if(E)for(var O=0;O =0&&K<=0||V<=0&&K>=0)&&(V<=0&&(N.marker.inclusiveRight&&p.inclusiveLeft?re(x.to,f)>=0:re(x.to,f)>0)||V>=0&&(N.marker.inclusiveRight&&p.inclusiveLeft?re(x.from,c)<=0:re(x.from,c)<0)))return!0}}}function zi(i){for(var u;u=hk(i);)i=u.find(-1,!0).line;return i}function R3(i){for(var u;u=Xp(i);)i=u.find(1,!0).line;return i}function F3(i){for(var u,f;u=Xp(i);)i=u.find(1,!0).line,(f||(f=[])).push(i);return f}function my(i,u){var f=Ae(i,u),c=zi(f);return f==c?u:yt(c)}function gk(i,u){if(u>i.lastLine())return u;var f=Ae(i,u),c;if(!So(i,f))return u;for(;c=Xp(f);)f=c.find(1,!0).line;return yt(f)+1}function So(i,u){var f=Ya&&u.markedSpans;if(f){for(var c=void 0,p=0;p u.maxLineLength&&(u.maxLineLength=p,u.maxLine=c)})}var Rs=function(i,u,f){this.text=i,dk(this,u),this.height=f?f(this):1};Rs.prototype.lineNo=function(){return yt(this)},zr(Rs);function j3(i,u,f,c){i.text=u,i.stateAfter&&(i.stateAfter=null),i.styles&&(i.styles=null),i.order!=null&&(i.order=null),fk(i),dk(i,f);var p=c?c(i):1;p!=i.height&&bi(i,p)}function P3(i){i.parent=null,fk(i)}var M3={},q3={};function mk(i,u){if(!i||/^\s*$/.test(i))return null;var f=u.addModeClass?q3:M3;return f[i]||(f[i]=i.replace(/\S+/g,"cm-$&"))}function yk(i,u){var f=ce("span",null,null,d?"padding-right: .1px":null),c={pre:ce("pre",[f],"CodeMirror-line"),content:f,col:0,pos:0,cm:i,trailingSpace:!1,splitSpaces:i.getOption("lineWrapping")};u.measure={};for(var p=0;p<=(u.rest?u.rest.length:0);p++){var g=p?u.rest[p-1]:u.line,E=void 0;c.pos=0,c.addToken=V3,kt(i.display.measure)&&(E=Bn(g,i.doc.direction))&&(c.addToken=G3(c.addToken,E)),c.map=[];var O=u!=i.display.externalMeasured&&yt(g);Q3(g,c,nk(i,g,O)),g.styleClasses&&(g.styleClasses.bgClass&&(c.bgClass=Ve(g.styleClasses.bgClass,c.bgClass||"")),g.styleClasses.textClass&&(c.textClass=Ve(g.styleClasses.textClass,c.textClass||""))),c.map.length==0&&c.map.push(0,0,c.content.appendChild(Qe(i.display.measure))),p==0?(u.measure.map=c.map,u.measure.cache={}):((u.measure.maps||(u.measure.maps=[])).push(c.map),(u.measure.caches||(u.measure.caches=[])).push({}))}if(d){var N=c.content.lastChild;(/\bcm-tab\b/.test(N.className)||N.querySelector&&N.querySelector(".cm-tab"))&&(c.content.className="cm-tab-wrap-hack")}return At(i,"renderLine",i,u.line,c.pre),c.pre.className&&(c.textClass=Ve(c.pre.className,c.textClass||"")),c}function B3(i){var u=j("span","\u2022","cm-invalidchar");return u.title="\\u"+i.charCodeAt(0).toString(16),u.setAttribute("aria-label",u.title),u}function V3(i,u,f,c,p,g,E){if(!!u){var O=i.splitSpaces?U3(u,i.trailingSpace):u,N=i.cm.state.specialChars,x=!1,V;if(!N.test(u))i.col+=u.length,V=document.createTextNode(O),i.map.push(i.pos,i.pos+u.length,V),s&&l<9&&(x=!0),i.pos+=u.length;else{V=document.createDocumentFragment();for(var K=0;;){N.lastIndex=K;var $=N.exec(u),X=$?$.index-K:u.length-K;if(X){var ne=document.createTextNode(O.slice(K,K+X));s&&l<9?V.appendChild(j("span",[ne])):V.appendChild(ne),i.map.push(i.pos,i.pos+X,ne),i.col+=X,i.pos+=X}if(!$)break;K+=X+1;var ae=void 0;if($[0]==" "){var le=i.cm.options.tabSize,he=le-i.col%le;ae=V.appendChild(j("span",fe(he),"cm-tab")),ae.setAttribute("role","presentation"),ae.setAttribute("cm-text"," "),i.col+=he}else $[0]=="\r"||$[0]==` +`?(ae=V.appendChild(j("span",$[0]=="\r"?"\u240D":"\u2424","cm-invalidchar")),ae.setAttribute("cm-text",$[0]),i.col+=1):(ae=i.cm.options.specialCharPlaceholder($[0]),ae.setAttribute("cm-text",$[0]),s&&l<9?V.appendChild(j("span",[ae])):V.appendChild(ae),i.col+=1);i.map.push(i.pos,i.pos+1,ae),i.pos++}}if(i.trailingSpace=O.charCodeAt(u.length-1)==32,f||c||p||x||g||E){var Ee=f||"";c&&(Ee+=c),p&&(Ee+=p);var ve=j("span",[V],Ee,g);if(E)for(var Oe in E)E.hasOwnProperty(Oe)&&Oe!="style"&&Oe!="class"&&ve.setAttribute(Oe,E[Oe]);return i.content.appendChild(ve)}i.content.appendChild(V)}}function U3(i,u){if(i.length>1&&!/ /.test(i))return i;for(var f=u,c="",p=0;p x&&K.from<=x));$++);if(K.to>=V)return i(f,c,p,g,E,O,N);i(f,c.slice(0,K.to-x),p,g,null,O,N),g=null,c=c.slice(K.to-x),x=K.to}}}function bk(i,u,f,c){var p=!c&&f.widgetNode;p&&i.map.push(i.pos,i.pos+u,p),!c&&i.cm.display.input.needsContentAttribute&&(p||(p=i.content.appendChild(document.createElement("span"))),p.setAttribute("cm-marker",f.id)),p&&(i.cm.display.input.setUneditable(p),i.content.appendChild(p)),i.pos+=u,i.trailingSpace=!1}function Q3(i,u,f){var c=i.markedSpans,p=i.text,g=0;if(!c){for(var E=1;E N||Xe.collapsed&&Re.to==N&&Re.from==N)){if(Re.to!=null&&Re.to!=N&&X>Re.to&&(X=Re.to,ae=""),Xe.className&&(ne+=" "+Xe.className),Xe.css&&($=($?$+";":"")+Xe.css),Xe.startStyle&&Re.from==N&&(le+=" "+Xe.startStyle),Xe.endStyle&&Re.to==X&&(Oe||(Oe=[])).push(Xe.endStyle,Re.to),Xe.title&&((Ee||(Ee={})).title=Xe.title),Xe.attributes)for(var Pt in Xe.attributes)(Ee||(Ee={}))[Pt]=Xe.attributes[Pt];Xe.collapsed&&(!he||gy(he.marker,Xe)<0)&&(he=Re)}else Re.from>N&&X>Re.from&&(X=Re.from)}if(Oe)for(var Rr=0;Rr =O)break;for(var Gn=Math.min(O,X);;){if(V){var An=N+V.length;if(!he){var hr=An>Gn?V.slice(0,Gn-N):V;u.addToken(u,hr,K?K+ne:ne,le,N+hr.length==X?ae:"",$,Ee)}if(An>=Gn){V=V.slice(Gn-N),N=Gn;break}N=An,le=""}V=p.slice(g,g=f[x++]),K=mk(f[x++],u.cm.options)}}}function Tk(i,u,f){this.line=u,this.rest=F3(u),this.size=this.rest?yt(ue(this.rest))-f+1:1,this.node=this.text=null,this.hidden=So(i,u)}function $p(i,u,f){for(var c=[],p,g=u;g 2&&g.push((N.bottom+x.top)/2-f.top)}}g.push(f.bottom-f.top)}}function Ck(i,u,f){if(i.line==u)return{map:i.measure.map,cache:i.measure.cache};if(i.rest){for(var c=0;c f)return{map:i.measure.maps[p],cache:i.measure.caches[p],before:!0}}}function tB(i,u){u=zi(u);var f=yt(u),c=i.display.externalMeasured=new Tk(i.doc,u,f);c.lineN=f;var p=c.built=yk(i,c);return c.text=p.pre,G(i.display.lineMeasure,p.pre),c}function wk(i,u,f,c){return ha(i,js(i,u),f,c)}function Sy(i,u){if(u>=i.display.viewFrom&&u =f.lineN&&u u)&&(g=N-O,p=g-1,u>=N&&(E="right")),p!=null){if(c=i[x+2],O==N&&f==(c.insertLeft?"left":"right")&&(E=f),f=="left"&&p==0)for(;x&&i[x-2]==i[x-3]&&i[x-1].insertLeft;)c=i[(x-=3)+2],E="left";if(f=="right"&&p==N-O)for(;x =0&&(f=i[p]).left==f.right;p--);return f}function nB(i,u,f,c){var p=Nk(u.map,f,c),g=p.node,E=p.start,O=p.end,N=p.collapse,x;if(g.nodeType==3){for(var V=0;V<4;V++){for(;E&&Ka(u.line.text.charAt(p.coverStart+E));)--E;for(;p.coverStart+O 0&&(N=c="right");var K;i.options.lineWrapping&&(K=g.getClientRects()).length>1?x=K[c=="right"?K.length-1:0]:x=g.getBoundingClientRect()}if(s&&l<9&&!E&&(!x||!x.left&&!x.right)){var $=g.parentNode.getClientRects()[0];$?x={left:$.left,right:$.left+Ms(i.display),top:$.top,bottom:$.bottom}:x=Ak}for(var X=x.top-u.rect.top,ne=x.bottom-u.rect.top,ae=(X+ne)/2,le=u.view.measure.heights,he=0;he =c.text.length?(N=c.text.length,x="before"):N<=0&&(N=0,x="after"),!O)return E(x=="before"?N-1:N,x=="before");function V(ne,ae,le){var he=O[ae],Ee=he.level==1;return E(le?ne-1:ne,Ee!=le)}var K=qn(O,N,x),$=yi,X=V(N,K,x=="before");return $!=null&&(X.other=V(N,$,x!="before")),X}function jk(i,u){var f=0;u=qe(i.doc,u),i.options.lineWrapping||(f=Ms(i.display)*u.ch);var c=Ae(i.doc,u.line),p=Ja(c)+eh(i.display);return{left:f,right:f,top:p,bottom:p+c.height}}function ky(i,u,f,c,p){var g=W(i,u,f);return g.xRel=p,c&&(g.outside=c),g}function Oy(i,u,f){var c=i.doc;if(f+=i.display.viewOffset,f<0)return ky(c.first,0,null,-1,-1);var p=fa(c,f),g=c.first+c.size-1;if(p>g)return ky(c.first+c.size-1,Ae(c,g).text.length,null,1,1);u<0&&(u=0);for(var E=Ae(c,p);;){var O=aB(i,E,p,u,f),N=I3(E,O.ch+(O.xRel>0||O.outside>0?1:0));if(!N)return O;var x=N.find(1);if(x.line==p)return x;E=Ae(c,p=x.line)}}function Pk(i,u,f,c){c-=Dy(u);var p=u.text.length,g=qt(function(E){return ha(i,f,E-1).bottom<=c},p,0);return p=qt(function(E){return ha(i,f,E).top>c},g,p),{begin:g,end:p}}function Mk(i,u,f,c){f||(f=js(i,u));var p=th(i,u,ha(i,f,c),"line").top;return Pk(i,u,f,p)}function Cy(i,u,f,c){return i.bottom<=f?!1:i.top>f?!0:(c?i.left:i.right)>u}function aB(i,u,f,c,p){p-=Ja(u);var g=js(i,u),E=Dy(u),O=0,N=u.text.length,x=!0,V=Bn(u,i.doc.direction);if(V){var K=(i.options.lineWrapping?uB:oB)(i,u,f,g,V,c,p);x=K.level!=1,O=x?K.from:K.to-1,N=x?K.to:K.from-1}var $=null,X=null,ne=qt(function(Fe){var Re=ha(i,g,Fe);return Re.top+=E,Re.bottom+=E,Cy(Re,c,p,!1)?(Re.top<=p&&Re.left<=c&&($=Fe,X=Re),!0):!1},O,N),ae,le,he=!1;if(X){var Ee=c-X.left =Oe.bottom?1:0}return ne=kn(u.text,ne,1),ky(f,ne,le,he,c-ae)}function oB(i,u,f,c,p,g,E){var O=qt(function(K){var $=p[K],X=$.level!=1;return Cy(Wi(i,W(f,X?$.to:$.from,X?"before":"after"),"line",u,c),g,E,!0)},0,p.length-1),N=p[O];if(O>0){var x=N.level!=1,V=Wi(i,W(f,x?N.from:N.to,x?"after":"before"),"line",u,c);Cy(V,g,E,!0)&&V.top>E&&(N=p[O-1])}return N}function uB(i,u,f,c,p,g,E){var O=Pk(i,u,c,E),N=O.begin,x=O.end;/\s/.test(u.text.charAt(x-1))&&x--;for(var V=null,K=null,$=0;$ =x||X.to<=N)){var ne=X.level!=1,ae=ha(i,c,ne?Math.min(x,X.to)-1:Math.max(N,X.from)).right,le=ae le)&&(V=X,K=le)}}return V||(V=p[p.length-1]),V.from x&&(V={from:V.from,to:x,level:V.level}),V}var Cu;function Ps(i){if(i.cachedTextHeight!=null)return i.cachedTextHeight;if(Cu==null){Cu=j("pre",null,"CodeMirror-line-like");for(var u=0;u<49;++u)Cu.appendChild(document.createTextNode("x")),Cu.appendChild(j("br"));Cu.appendChild(document.createTextNode("x"))}G(i.measure,Cu);var f=Cu.offsetHeight/50;return f>3&&(i.cachedTextHeight=f),Q(i.measure),f||1}function Ms(i){if(i.cachedCharWidth!=null)return i.cachedCharWidth;var u=j("span","xxxxxxxxxx"),f=j("pre",[u],"CodeMirror-line-like");G(i.measure,f);var c=u.getBoundingClientRect(),p=(c.right-c.left)/10;return p>2&&(i.cachedCharWidth=p),p||10}function wy(i){for(var u=i.display,f={},c={},p=u.gutters.clientLeft,g=u.gutters.firstChild,E=0;g;g=g.nextSibling,++E){var O=i.display.gutterSpecs[E].className;f[O]=g.offsetLeft+g.clientLeft+p,c[O]=g.clientWidth}return{fixedPos:Ay(u),gutterTotalWidth:u.gutters.offsetWidth,gutterLeft:f,gutterWidth:c,wrapperWidth:u.wrapper.clientWidth}}function Ay(i){return i.scroller.getBoundingClientRect().left-i.sizer.getBoundingClientRect().left}function qk(i){var u=Ps(i.display),f=i.options.lineWrapping,c=f&&Math.max(5,i.display.scroller.clientWidth/Ms(i.display)-3);return function(p){if(So(i.doc,p))return 0;var g=0;if(p.widgets)for(var E=0;E 0&&(x=Ae(i.doc,N.line).text).length==N.ch){var V=De(x,x.length,i.options.tabSize)-x.length;N=W(N.line,Math.max(0,Math.round((g-Ok(i.display).left)/Ms(i.display))-V))}return N}function Au(i,u){if(u>=i.display.viewTo||(u-=i.display.viewFrom,u<0))return null;for(var f=i.display.view,c=0;c u)&&(p.updateLineNumbers=u),i.curOp.viewChanged=!0,u>=p.viewTo)Ya&&my(i.doc,u) p.viewFrom?ko(i):(p.viewFrom+=c,p.viewTo+=c);else if(u<=p.viewFrom&&f>=p.viewTo)ko(i);else if(u<=p.viewFrom){var g=nh(i,f,f+c,1);g?(p.view=p.view.slice(g.index),p.viewFrom=g.lineN,p.viewTo+=c):ko(i)}else if(f>=p.viewTo){var E=nh(i,u,u,-1);E?(p.view=p.view.slice(0,E.index),p.viewTo=E.lineN):ko(i)}else{var O=nh(i,u,u,-1),N=nh(i,f,f+c,1);O&&N?(p.view=p.view.slice(0,O.index).concat($p(i,O.lineN,N.lineN)).concat(p.view.slice(N.index)),p.viewTo+=c):ko(i)}var x=p.externalMeasured;x&&(f =p.lineN&&u =c.viewTo)){var g=c.view[Au(i,u)];if(g.node!=null){var E=g.changes||(g.changes=[]);Ue(E,f)==-1&&E.push(f)}}}function ko(i){i.display.viewFrom=i.display.viewTo=i.doc.first,i.display.view=[],i.display.viewOffset=0}function nh(i,u,f,c){var p=Au(i,u),g,E=i.display.view;if(!Ya||f==i.doc.first+i.doc.size)return{index:p,lineN:f};for(var O=i.display.viewFrom,N=0;N 0){if(p==E.length-1)return null;g=O+E[p].size-u,p++}else g=O-u;u+=g,f+=g}for(;my(i.doc,f)!=f;){if(p==(c<0?0:E.length-1))return null;f+=c*E[p-(c<0?1:0)].size,p+=c}return{index:p,lineN:f}}function sB(i,u,f){var c=i.display,p=c.view;p.length==0||u>=c.viewTo||f<=c.viewFrom?(c.view=$p(i,u,f),c.viewFrom=u):(c.viewFrom>u?c.view=$p(i,u,c.viewFrom).concat(c.view):c.viewFromf&&(c.view=c.view.slice(0,Au(i,f)))),c.viewTo=f}function Bk(i){for(var u=i.display.view,f=0,c=0;c
=i.display.viewTo||N.to().line 0?E:i.defaultCharWidth())+"px"}if(c.other){var O=f.appendChild(j("div","\xA0","CodeMirror-cursor CodeMirror-secondarycursor"));O.style.display="",O.style.left=c.other.left+"px",O.style.top=c.other.top+"px",O.style.height=(c.other.bottom-c.other.top)*.85+"px"}}function ih(i,u){return i.top-u.top||i.left-u.left}function lB(i,u,f){var c=i.display,p=i.doc,g=document.createDocumentFragment(),E=Ok(i.display),O=E.left,N=Math.max(c.sizerWidth,Ou(i)-c.sizer.offsetLeft)-E.right,x=p.direction=="ltr";function V(ve,Oe,Fe,Re){Oe<0&&(Oe=0),Oe=Math.round(Oe),Re=Math.round(Re),g.appendChild(j("div",null,"CodeMirror-selected","position: absolute; left: "+ve+`px; + top: `+Oe+"px; width: "+(Fe==null?N-ve:Fe)+`px; + height: `+(Re-Oe)+"px"))}function K(ve,Oe,Fe){var Re=Ae(p,ve),Xe=Re.text.length,Pt,Rr;function $t(hr,Nn){return rh(i,W(ve,hr),"div",Re,Nn)}function Gn(hr,Nn,Wr){var Dr=Mk(i,Re,null,hr),vr=Nn=="ltr"==(Wr=="after")?"left":"right",ar=Wr=="after"?Dr.begin:Dr.end-(/\s/.test(Re.text.charAt(Dr.end-1))?2:1);return $t(ar,vr)[vr]}var An=Bn(Re,p.direction);return On(An,Oe||0,Fe==null?Xe:Fe,function(hr,Nn,Wr,Dr){var vr=Wr=="ltr",ar=$t(hr,vr?"left":"right"),Ln=$t(Nn-1,vr?"right":"left"),Xs=Oe==null&&hr==0,Lo=Fe==null&&Nn==Xe,rn=Dr==0,va=!An||Dr==An.length-1;if(Ln.top-ar.top<=3){var Fr=(x?Xs:Lo)&&rn,n0=(x?Lo:Xs)&&va,eo=Fr?O:(vr?ar:Ln).left,Ru=n0?N:(vr?Ln:ar).right;V(eo,ar.top,Ru-eo,ar.bottom)}else{var Fu,pn,Zs,i0;vr?(Fu=x&&Xs&&rn?O:ar.left,pn=x?N:Gn(hr,Wr,"before"),Zs=x?O:Gn(Nn,Wr,"after"),i0=x&&Lo&&va?N:Ln.right):(Fu=x?Gn(hr,Wr,"before"):O,pn=!x&&Xs&&rn?N:ar.right,Zs=!x&&Lo&&va?O:Ln.left,i0=x?Gn(Nn,Wr,"after"):N),V(Fu,ar.top,pn-Fu,ar.bottom),ar.bottom 0?u.blinker=setInterval(function(){i.hasFocus()||qs(i),u.cursorDiv.style.visibility=(f=!f)?"":"hidden"},i.options.cursorBlinkRate):i.options.cursorBlinkRate<0&&(u.cursorDiv.style.visibility="hidden")}}function Uk(i){i.hasFocus()||(i.display.input.focus(),i.state.focused||Ry(i))}function Iy(i){i.state.delayingBlurEvent=!0,setTimeout(function(){i.state.delayingBlurEvent&&(i.state.delayingBlurEvent=!1,i.state.focused&&qs(i))},100)}function Ry(i,u){i.state.delayingBlurEvent&&!i.state.draggingText&&(i.state.delayingBlurEvent=!1),i.options.readOnly!="nocursor"&&(i.state.focused||(At(i,"focus",i,u),i.state.focused=!0,we(i.display.wrapper,"CodeMirror-focused"),!i.curOp&&i.display.selForContextMenu!=i.doc.sel&&(i.display.input.reset(),d&&setTimeout(function(){return i.display.input.reset(!0)},20)),i.display.input.receivedFocus()),xy(i))}function qs(i,u){i.state.delayingBlurEvent||(i.state.focused&&(At(i,"blur",i,u),i.state.focused=!1,z(i.display.wrapper,"CodeMirror-focused")),clearInterval(i.display.blinker),setTimeout(function(){i.state.focused||(i.display.shift=!1)},150))}function ah(i){for(var u=i.display,f=u.lineDiv.offsetTop,c=Math.max(0,u.scroller.getBoundingClientRect().top),p=u.lineDiv.getBoundingClientRect().top,g=0,E=0;E .005||X<-.005)&&(p i.display.sizerWidth){var ae=Math.ceil(V/Ms(i.display));ae>i.display.maxLineLength&&(i.display.maxLineLength=ae,i.display.maxLine=O.line,i.display.maxLineChanged=!0)}}}Math.abs(g)>2&&(u.scroller.scrollTop+=g)}function Gk(i){if(i.widgets)for(var u=0;u =E&&(g=fa(u,Ja(Ae(u,N))-i.wrapper.clientHeight),E=N)}return{from:g,to:Math.max(E,g+1)}}function cB(i,u){if(!zt(i,"scrollCursorIntoView")){var f=i.display,c=f.sizer.getBoundingClientRect(),p=null,g=f.wrapper.ownerDocument;if(u.top+c.top<0?p=!0:u.bottom+c.top>(g.defaultView.innerHeight||g.documentElement.clientHeight)&&(p=!1),p!=null&&!S){var E=j("div","\u200B",null,`position: absolute; + top: `+(u.top-f.viewOffset-eh(i.display))+`px; + height: `+(u.bottom-u.top+pa(i)+f.barHeight)+`px; + left: `+u.left+"px; width: "+Math.max(2,u.right-u.left)+"px;");i.display.lineSpace.appendChild(E),E.scrollIntoView(p),i.display.lineSpace.removeChild(E)}}}function fB(i,u,f,c){c==null&&(c=0);var p;!i.options.lineWrapping&&u==f&&(f=u.sticky=="before"?W(u.line,u.ch+1,"before"):u,u=u.ch?W(u.line,u.sticky=="before"?u.ch-1:u.ch,"after"):u);for(var g=0;g<5;g++){var E=!1,O=Wi(i,u),N=!f||f==u?O:Wi(i,f);p={left:Math.min(O.left,N.left),top:Math.min(O.top,N.top)-c,right:Math.max(O.left,N.left),bottom:Math.max(O.bottom,N.bottom)+c};var x=Fy(i,p),V=i.doc.scrollTop,K=i.doc.scrollLeft;if(x.scrollTop!=null&&(zc(i,x.scrollTop),Math.abs(i.doc.scrollTop-V)>1&&(E=!0)),x.scrollLeft!=null&&(Nu(i,x.scrollLeft),Math.abs(i.doc.scrollLeft-K)>1&&(E=!0)),!E)break}return p}function dB(i,u){var f=Fy(i,u);f.scrollTop!=null&&zc(i,f.scrollTop),f.scrollLeft!=null&&Nu(i,f.scrollLeft)}function Fy(i,u){var f=i.display,c=Ps(i.display);u.top<0&&(u.top=0);var p=i.curOp&&i.curOp.scrollTop!=null?i.curOp.scrollTop:f.scroller.scrollTop,g=_y(i),E={};u.bottom-u.top>g&&(u.bottom=u.top+g);var O=i.doc.height+Ey(f),N=u.top O-c;if(u.top p+g){var V=Math.min(u.top,(x?O:u.bottom)-g);V!=p&&(E.scrollTop=V)}var K=i.options.fixedGutter?0:f.gutters.offsetWidth,$=i.curOp&&i.curOp.scrollLeft!=null?i.curOp.scrollLeft:f.scroller.scrollLeft-K,X=Ou(i)-f.gutters.offsetWidth,ne=u.right-u.left>X;return ne&&(u.right=u.left+X),u.left<10?E.scrollLeft=0:u.left<$?E.scrollLeft=Math.max(0,u.left+K-(ne?0:10)):u.right>X+$-3&&(E.scrollLeft=u.right+(ne?0:10)-X),E}function jy(i,u){u!=null&&(uh(i),i.curOp.scrollTop=(i.curOp.scrollTop==null?i.doc.scrollTop:i.curOp.scrollTop)+u)}function Bs(i){uh(i);var u=i.getCursor();i.curOp.scrollToPos={from:u,to:u,margin:i.options.cursorScrollMargin}}function Hc(i,u,f){(u!=null||f!=null)&&uh(i),u!=null&&(i.curOp.scrollLeft=u),f!=null&&(i.curOp.scrollTop=f)}function pB(i,u){uh(i),i.curOp.scrollToPos=u}function uh(i){var u=i.curOp.scrollToPos;if(u){i.curOp.scrollToPos=null;var f=jk(i,u.from),c=jk(i,u.to);Qk(i,f,c,u.margin)}}function Qk(i,u,f,c){var p=Fy(i,{left:Math.min(u.left,f.left),top:Math.min(u.top,f.top)-c,right:Math.max(u.right,f.right),bottom:Math.max(u.bottom,f.bottom)+c});Hc(i,p.scrollLeft,p.scrollTop)}function zc(i,u){Math.abs(i.doc.scrollTop-u)<2||(r||My(i,{top:u}),Kk(i,u,!0),r&&My(i),Jc(i,100))}function Kk(i,u,f){u=Math.max(0,Math.min(i.display.scroller.scrollHeight-i.display.scroller.clientHeight,u)),!(i.display.scroller.scrollTop==u&&!f)&&(i.doc.scrollTop=u,i.display.scrollbars.setScrollTop(u),i.display.scroller.scrollTop!=u&&(i.display.scroller.scrollTop=u))}function Nu(i,u,f,c){u=Math.max(0,Math.min(u,i.display.scroller.scrollWidth-i.display.scroller.clientWidth)),!((f?u==i.doc.scrollLeft:Math.abs(i.doc.scrollLeft-u)<2)&&!c)&&(i.doc.scrollLeft=u,Jk(i),i.display.scroller.scrollLeft!=u&&(i.display.scroller.scrollLeft=u),i.display.scrollbars.setScrollLeft(u))}function Wc(i){var u=i.display,f=u.gutters.offsetWidth,c=Math.round(i.doc.height+Ey(i.display));return{clientHeight:u.scroller.clientHeight,viewHeight:u.wrapper.clientHeight,scrollWidth:u.scroller.scrollWidth,clientWidth:u.scroller.clientWidth,viewWidth:u.wrapper.clientWidth,barLeft:i.options.fixedGutter?f:0,docHeight:c,scrollHeight:c+pa(i)+u.barHeight,nativeBarWidth:u.nativeBarWidth,gutterWidth:f}}var Lu=function(i,u,f){this.cm=f;var c=this.vert=j("div",[j("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),p=this.horiz=j("div",[j("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");c.tabIndex=p.tabIndex=-1,i(c),i(p),ge(c,"scroll",function(){c.clientHeight&&u(c.scrollTop,"vertical")}),ge(p,"scroll",function(){p.clientWidth&&u(p.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,s&&l<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Lu.prototype.update=function(i){var u=i.scrollWidth>i.clientWidth+1,f=i.scrollHeight>i.clientHeight+1,c=i.nativeBarWidth;if(f){this.vert.style.display="block",this.vert.style.bottom=u?c+"px":"0";var p=i.viewHeight-(u?c:0);this.vert.firstChild.style.height=Math.max(0,i.scrollHeight-i.clientHeight+p)+"px"}else this.vert.scrollTop=0,this.vert.style.display="",this.vert.firstChild.style.height="0";if(u){this.horiz.style.display="block",this.horiz.style.right=f?c+"px":"0",this.horiz.style.left=i.barLeft+"px";var g=i.viewWidth-i.barLeft-(f?c:0);this.horiz.firstChild.style.width=Math.max(0,i.scrollWidth-i.clientWidth+g)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&i.clientHeight>0&&(c==0&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:f?c:0,bottom:u?c:0}},Lu.prototype.setScrollLeft=function(i){this.horiz.scrollLeft!=i&&(this.horiz.scrollLeft=i),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Lu.prototype.setScrollTop=function(i){this.vert.scrollTop!=i&&(this.vert.scrollTop=i),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Lu.prototype.zeroWidthHack=function(){var i=k&&!L?"12px":"18px";this.horiz.style.height=this.vert.style.width=i,this.horiz.style.visibility=this.vert.style.visibility="hidden",this.disableHoriz=new Pe,this.disableVert=new Pe},Lu.prototype.enableZeroWidthBar=function(i,u,f){i.style.visibility="";function c(){var p=i.getBoundingClientRect(),g=f=="vert"?document.elementFromPoint(p.right-1,(p.top+p.bottom)/2):document.elementFromPoint((p.right+p.left)/2,p.bottom-1);g!=i?i.style.visibility="hidden":u.set(1e3,c)}u.set(1e3,c)},Lu.prototype.clear=function(){var i=this.horiz.parentNode;i.removeChild(this.horiz),i.removeChild(this.vert)};var Yc=function(){};Yc.prototype.update=function(){return{bottom:0,right:0}},Yc.prototype.setScrollLeft=function(){},Yc.prototype.setScrollTop=function(){},Yc.prototype.clear=function(){};function Vs(i,u){u||(u=Wc(i));var f=i.display.barWidth,c=i.display.barHeight;Hk(i,u);for(var p=0;p<4&&f!=i.display.barWidth||c!=i.display.barHeight;p++)f!=i.display.barWidth&&i.options.lineWrapping&&ah(i),Hk(i,Wc(i)),f=i.display.barWidth,c=i.display.barHeight}function Hk(i,u){var f=i.display,c=f.scrollbars.update(u);f.sizer.style.paddingRight=(f.barWidth=c.right)+"px",f.sizer.style.paddingBottom=(f.barHeight=c.bottom)+"px",f.heightForcer.style.borderBottom=c.bottom+"px solid transparent",c.right&&c.bottom?(f.scrollbarFiller.style.display="block",f.scrollbarFiller.style.height=c.bottom+"px",f.scrollbarFiller.style.width=c.right+"px"):f.scrollbarFiller.style.display="",c.bottom&&i.options.coverGutterNextToScrollbar&&i.options.fixedGutter?(f.gutterFiller.style.display="block",f.gutterFiller.style.height=c.bottom+"px",f.gutterFiller.style.width=u.gutterWidth+"px"):f.gutterFiller.style.display=""}var zk={native:Lu,null:Yc};function Wk(i){i.display.scrollbars&&(i.display.scrollbars.clear(),i.display.scrollbars.addClass&&z(i.display.wrapper,i.display.scrollbars.addClass)),i.display.scrollbars=new zk[i.options.scrollbarStyle](function(u){i.display.wrapper.insertBefore(u,i.display.scrollbarFiller),ge(u,"mousedown",function(){i.state.focused&&setTimeout(function(){return i.display.input.focus()},0)}),u.setAttribute("cm-not-content","true")},function(u,f){f=="horizontal"?Nu(i,u):zc(i,u)},i),i.display.scrollbars.addClass&&we(i.display.wrapper,i.display.scrollbars.addClass)}var hB=0;function xu(i){i.curOp={cm:i,viewChanged:!1,startHeight:i.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++hB,markArrays:null},K3(i.curOp)}function Iu(i){var u=i.curOp;u&&z3(u,function(f){for(var c=0;c
=f.viewTo)||f.maxLineChanged&&u.options.lineWrapping,i.update=i.mustUpdate&&new sh(u,i.mustUpdate&&{top:i.scrollTop,ensure:i.scrollToPos},i.forceUpdate)}function mB(i){i.updatedDisplay=i.mustUpdate&&Py(i.cm,i.update)}function yB(i){var u=i.cm,f=u.display;i.updatedDisplay&&ah(u),i.barMeasure=Wc(u),f.maxLineChanged&&!u.options.lineWrapping&&(i.adjustWidthTo=wk(u,f.maxLine,f.maxLine.text.length).left+3,u.display.sizerWidth=i.adjustWidthTo,i.barMeasure.scrollWidth=Math.max(f.scroller.clientWidth,f.sizer.offsetLeft+i.adjustWidthTo+pa(u)+u.display.barWidth),i.maxScrollLeft=Math.max(0,f.sizer.offsetLeft+i.adjustWidthTo-Ou(u))),(i.updatedDisplay||i.selectionChanged)&&(i.preparedSelection=f.input.prepareSelection())}function bB(i){var u=i.cm;i.adjustWidthTo!=null&&(u.display.sizer.style.minWidth=i.adjustWidthTo+"px",i.maxScrollLeft =i.display.viewTo)){var f=+new Date+i.options.workTime,c=qc(i,u.highlightFrontier),p=[];u.iter(c.line,Math.min(u.first+u.size,i.display.viewTo+500),function(g){if(c.line>=i.display.viewFrom){var E=g.styles,O=g.text.length>i.options.maxHighlightLength?za(u.mode,c.state):null,N=rk(i,g,c,!0);O&&(c.state=O),g.styles=N.styles;var x=g.styleClasses,V=N.classes;V?g.styleClasses=V:x&&(g.styleClasses=null);for(var K=!E||E.length!=g.styles.length||x!=V&&(!x||!V||x.bgClass!=V.bgClass||x.textClass!=V.textClass),$=0;!K&&$ f)return Jc(i,i.options.workDelay),!0}),u.highlightFrontier=c.line,u.modeFrontier=Math.max(u.modeFrontier,c.line),p.length&&Un(i,function(){for(var g=0;g =f.viewFrom&&u.visible.to<=f.viewTo&&(f.updateLineNumbers==null||f.updateLineNumbers>=f.viewTo)&&f.renderedView==f.view&&Bk(i)==0)return!1;Xk(i)&&(ko(i),u.dims=wy(i));var p=c.first+c.size,g=Math.max(u.visible.from-i.options.viewportMargin,c.first),E=Math.min(p,u.visible.to+i.options.viewportMargin);f.viewFrom E&&f.viewTo-E<20&&(E=Math.min(p,f.viewTo)),Ya&&(g=my(i.doc,g),E=gk(i.doc,E));var O=g!=f.viewFrom||E!=f.viewTo||f.lastWrapHeight!=u.wrapperHeight||f.lastWrapWidth!=u.wrapperWidth;sB(i,g,E),f.viewOffset=Ja(Ae(i.doc,f.viewFrom)),i.display.mover.style.top=f.viewOffset+"px";var N=Bk(i);if(!O&&N==0&&!u.force&&f.renderedView==f.view&&(f.updateLineNumbers==null||f.updateLineNumbers>=f.viewTo))return!1;var x=SB(i);return N>4&&(f.lineDiv.style.display="none"),kB(i,f.updateLineNumbers,u.dims),N>4&&(f.lineDiv.style.display=""),f.renderedView=f.view,DB(x),Q(f.cursorDiv),Q(f.selectionDiv),f.gutters.style.height=f.sizer.style.minHeight=0,O&&(f.lastWrapHeight=u.wrapperHeight,f.lastWrapWidth=u.wrapperWidth,Jc(i,400)),f.updateLineNumbers=null,!0}function Yk(i,u){for(var f=u.viewport,c=!0;;c=!1){if(!c||!i.options.lineWrapping||u.oldDisplayWidth==Ou(i)){if(f&&f.top!=null&&(f={top:Math.min(i.doc.height+Ey(i.display)-_y(i),f.top)}),u.visible=oh(i.display,i.doc,f),u.visible.from>=i.display.viewFrom&&u.visible.to<=i.display.viewTo)break}else c&&(u.visible=oh(i.display,i.doc,f));if(!Py(i,u))break;ah(i);var p=Wc(i);Kc(i),Vs(i,p),By(i,p),u.force=!1}u.signal(i,"update",i),(i.display.viewFrom!=i.display.reportedViewFrom||i.display.viewTo!=i.display.reportedViewTo)&&(u.signal(i,"viewportChange",i,i.display.viewFrom,i.display.viewTo),i.display.reportedViewFrom=i.display.viewFrom,i.display.reportedViewTo=i.display.viewTo)}function My(i,u){var f=new sh(i,u);if(Py(i,f)){ah(i),Yk(i,f);var c=Wc(i);Kc(i),Vs(i,c),By(i,c),f.finish()}}function kB(i,u,f){var c=i.display,p=i.options.lineNumbers,g=c.lineDiv,E=g.firstChild;function O(ne){var ae=ne.nextSibling;return d&&k&&i.display.currentWheelTarget==ne?ne.style.display="none":ne.parentNode.removeChild(ne),ae}for(var N=c.view,x=c.viewFrom,V=0;V -1&&(X=!1),Ek(i,K,x,f)),X&&(Q(K.lineNumber),K.lineNumber.appendChild(document.createTextNode(H(i.options,x)))),E=K.node.nextSibling}x+=K.size}for(;E;)E=O(E)}function qy(i){var u=i.gutters.offsetWidth;i.sizer.style.marginLeft=u+"px",Lr(i,"gutterChanged",i)}function By(i,u){i.display.sizer.style.minHeight=u.docHeight+"px",i.display.heightForcer.style.top=u.docHeight+"px",i.display.gutters.style.height=u.docHeight+i.display.barHeight+pa(i)+"px"}function Jk(i){var u=i.display,f=u.view;if(!(!u.alignWidgets&&(!u.gutters.firstChild||!i.options.fixedGutter))){for(var c=Ay(u)-u.scroller.scrollLeft+i.doc.scrollLeft,p=u.gutters.offsetWidth,g=c+"px",E=0;E =105&&(p.wrapper.style.clipPath="inset(0px)"),p.wrapper.setAttribute("translate","no"),s&&l<8&&(p.gutters.style.zIndex=-1,p.scroller.style.paddingRight=0),!d&&!(r&&m)&&(p.scroller.draggable=!0),i&&(i.appendChild?i.appendChild(p.wrapper):i(p.wrapper)),p.viewFrom=p.viewTo=u.first,p.reportedViewFrom=p.reportedViewTo=u.first,p.view=[],p.renderedView=null,p.externalMeasured=null,p.viewOffset=0,p.lastWrapHeight=p.lastWrapWidth=0,p.updateLineNumbers=null,p.nativeBarWidth=p.barHeight=p.barWidth=0,p.scrollbarsClipped=!1,p.lineNumWidth=p.lineNumInnerWidth=p.lineNumChars=null,p.alignWidgets=!1,p.cachedCharWidth=p.cachedTextHeight=p.cachedPaddingH=null,p.maxLine=null,p.maxLineLength=0,p.maxLineChanged=!1,p.wheelDX=p.wheelDY=p.wheelStartX=p.wheelStartY=null,p.shift=!1,p.selForContextMenu=null,p.activeTouch=null,p.gutterSpecs=Vy(c.gutters,c.lineNumbers),Zk(p),f.init(p)}var lh=0,Za=null;s?Za=-.53:r?Za=15:v?Za=-.7:A&&(Za=-1/3);function $k(i){var u=i.wheelDeltaX,f=i.wheelDeltaY;return u==null&&i.detail&&i.axis==i.HORIZONTAL_AXIS&&(u=i.detail),f==null&&i.detail&&i.axis==i.VERTICAL_AXIS?f=i.detail:f==null&&(f=i.wheelDelta),{x:u,y:f}}function CB(i){var u=$k(i);return u.x*=Za,u.y*=Za,u}function eO(i,u){v&&b==102&&(i.display.chromeScrollHack==null?i.display.sizer.style.pointerEvents="none":clearTimeout(i.display.chromeScrollHack),i.display.chromeScrollHack=setTimeout(function(){i.display.chromeScrollHack=null,i.display.sizer.style.pointerEvents=""},100));var f=$k(u),c=f.x,p=f.y,g=Za;u.deltaMode===0&&(c=u.deltaX,p=u.deltaY,g=1);var E=i.display,O=E.scroller,N=O.scrollWidth>O.clientWidth,x=O.scrollHeight>O.clientHeight;if(!!(c&&N||p&&x)){if(p&&k&&d){e:for(var V=u.target,K=E.view;V!=O;V=V.parentNode)for(var $=0;$ =0&&re(i,c.to())<=0)return f}return-1};var bt=function(i,u){this.anchor=i,this.head=u};bt.prototype.from=function(){return Sr(this.anchor,this.head)},bt.prototype.to=function(){return ht(this.anchor,this.head)},bt.prototype.empty=function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch};function Yi(i,u,f){var c=i&&i.options.selectionsMayTouch,p=u[f];u.sort(function($,X){return re($.from(),X.from())}),f=Ue(u,p);for(var g=1;g 0:N>=0){var x=Sr(O.from(),E.from()),V=ht(O.to(),E.to()),K=O.empty()?E.from()==E.head:O.from()==O.head;g<=f&&--f,u.splice(--g,2,new bt(K?V:x,K?x:V))}}return new ni(u,f)}function Oo(i,u){return new ni([new bt(i,u||i)],0)}function Co(i){return i.text?W(i.from.line+i.text.length-1,ue(i.text).length+(i.text.length==1?i.from.ch:0)):i.to}function tO(i,u){if(re(i,u.from)<0)return i;if(re(i,u.to)<=0)return Co(u);var f=i.line+u.text.length-(u.to.line-u.from.line)-1,c=i.ch;return i.line==u.to.line&&(c+=Co(u).ch-u.to.ch),W(f,c)}function Uy(i,u){for(var f=[],c=0;c 1&&i.remove(O.line+1,ne-1),i.insert(O.line+1,he)}Lr(i,"change",i,u)}function wo(i,u,f){function c(p,g,E){if(p.linked)for(var O=0;O 1&&!i.done[i.done.length-2].ranges)return i.done.pop(),ue(i.done)}function uO(i,u,f,c){var p=i.history;p.undone.length=0;var g=+new Date,E,O;if((p.lastOp==c||p.lastOrigin==u.origin&&u.origin&&(u.origin.charAt(0)=="+"&&p.lastModTime>g-(i.cm?i.cm.options.historyEventDelay:500)||u.origin.charAt(0)=="*"))&&(E=NB(p,p.lastOp==c)))O=ue(E.changes),re(u.from,u.to)==0&&re(u.from,O.to)==0?O.to=Co(u):E.changes.push(Ky(i,u));else{var N=ue(p.done);for((!N||!N.ranges)&&fh(i.sel,p.done),E={changes:[Ky(i,u)],generation:p.generation},p.done.push(E);p.done.length>p.undoDepth;)p.done.shift(),p.done[0].ranges||p.done.shift()}p.done.push(f),p.generation=++p.maxGeneration,p.lastModTime=p.lastSelTime=g,p.lastOp=p.lastSelOp=c,p.lastOrigin=p.lastSelOrigin=u.origin,O||At(i,"historyAdded")}function LB(i,u,f,c){var p=u.charAt(0);return p=="*"||p=="+"&&f.ranges.length==c.ranges.length&&f.somethingSelected()==c.somethingSelected()&&new Date-i.history.lastSelTime<=(i.cm?i.cm.options.historyEventDelay:500)}function xB(i,u,f,c){var p=i.history,g=c&&c.origin;f==p.lastSelOp||g&&p.lastSelOrigin==g&&(p.lastModTime==p.lastSelTime&&p.lastOrigin==g||LB(i,g,ue(p.done),u))?p.done[p.done.length-1]=u:fh(u,p.done),p.lastSelTime=+new Date,p.lastSelOrigin=g,p.lastSelOp=f,c&&c.clearRedo!==!1&&oO(p.undone)}function fh(i,u){var f=ue(u);f&&f.ranges&&f.equals(i)||u.push(i)}function sO(i,u,f,c){var p=u["spans_"+i.id],g=0;i.iter(Math.max(i.first,f),Math.min(i.first+i.size,c),function(E){E.markedSpans&&((p||(p=u["spans_"+i.id]={}))[g]=E.markedSpans),++g})}function IB(i){if(!i)return null;for(var u,f=0;f -1&&(ue(O)[K]=x[K],delete x[K])}}return c}function Hy(i,u,f,c){if(c){var p=i.anchor;if(f){var g=re(u,p)<0;g!=re(f,p)<0?(p=u,u=f):g!=re(u,f)<0&&(u=f)}return new bt(p,u)}else return new bt(f||u,u)}function dh(i,u,f,c,p){p==null&&(p=i.cm&&(i.cm.display.shift||i.extend)),tn(i,new ni([Hy(i.sel.primary(),u,f,p)],0),c)}function cO(i,u,f){for(var c=[],p=i.cm&&(i.cm.display.shift||i.extend),g=0;g =u.ch:O.to>u.ch))){if(p&&(At(N,"beforeCursorEnter"),N.explicitlyCleared))if(g.markedSpans){--E;continue}else break;if(!N.atomic)continue;if(f){var K=N.find(c<0?1:-1),$=void 0;if((c<0?V:x)&&(K=gO(i,K,-c,K&&K.line==u.line?g:null)),K&&K.line==u.line&&($=re(K,f))&&(c<0?$<0:$>0))return Gs(i,K,u,c,p)}var X=N.find(c<0?-1:1);return(c<0?x:V)&&(X=gO(i,X,c,X.line==u.line?g:null)),X?Gs(i,X,u,c,p):null}}return u}function hh(i,u,f,c,p){var g=c||1,E=Gs(i,u,f,g,p)||!p&&Gs(i,u,f,g,!0)||Gs(i,u,f,-g,p)||!p&&Gs(i,u,f,-g,!0);return E||(i.cantEdit=!0,W(i.first,0))}function gO(i,u,f,c){return f<0&&u.ch==0?u.line>i.first?qe(i,W(u.line-1)):null:f>0&&u.ch==(c||Ae(i,u.line)).text.length?u.line =0;--p)bO(i,{from:c[p].from,to:c[p].to,text:p?[""]:u.text,origin:u.origin});else bO(i,u)}}function bO(i,u){if(!(u.text.length==1&&u.text[0]==""&&re(u.from,u.to)==0)){var f=Uy(i,u);uO(i,u,f,i.cm?i.cm.curOp.id:NaN),$c(i,u,f,vy(i,u));var c=[];wo(i,function(p,g){!g&&Ue(c,p.history)==-1&&(SO(p.history,u),c.push(p.history)),$c(p,u,null,vy(p,u))})}}function vh(i,u,f){var c=i.cm&&i.cm.state.suppressEdits;if(!(c&&!f)){for(var p=i.history,g,E=i.sel,O=u=="undo"?p.done:p.undone,N=u=="undo"?p.undone:p.done,x=0;x =0;--X){var ne=$(X);if(ne)return ne.v}}}}function TO(i,u){if(u!=0&&(i.first+=u,i.sel=new ni(Ge(i.sel.ranges,function(p){return new bt(W(p.anchor.line+u,p.anchor.ch),W(p.head.line+u,p.head.ch))}),i.sel.primIndex),i.cm)){Cn(i.cm,i.first,i.first-u,u);for(var f=i.cm.display,c=f.viewFrom;c i.lastLine())){if(u.from.line g&&(u={from:u.from,to:W(g,Ae(i,g).text.length),text:[u.text[0]],origin:u.origin}),u.removed=Wa(i,u.from,u.to),f||(f=Uy(i,u)),i.cm?jB(i.cm,u,c):Qy(i,u,c),ph(i,f,ut),i.cantEdit&&hh(i,W(i.firstLine(),0))&&(i.cantEdit=!1)}}function jB(i,u,f){var c=i.doc,p=i.display,g=u.from,E=u.to,O=!1,N=g.line;i.options.lineWrapping||(N=yt(zi(Ae(c,g.line))),c.iter(N,E.line+1,function(X){if(X==p.maxLine)return O=!0,!0})),c.sel.contains(u.from,u.to)>-1&&Ls(i),Qy(c,u,f,qk(i)),i.options.lineWrapping||(c.iter(N,g.line+u.text.length,function(X){var ne=Zp(X);ne>p.maxLineLength&&(p.maxLine=X,p.maxLineLength=ne,p.maxLineChanged=!0,O=!1)}),O&&(i.curOp.updateMaxLine=!0)),k3(c,g.line),Jc(i,400);var x=u.text.length-(E.line-g.line)-1;u.full?Cn(i):g.line==E.line&&u.text.length==1&&!nO(i.doc,u)?Do(i,g.line,"text"):Cn(i,g.line,E.line+1,x);var V=Hr(i,"changes"),K=Hr(i,"change");if(K||V){var $={from:g,to:E,text:u.text,removed:u.removed,origin:u.origin};K&&Lr(i,"change",i,$),V&&(i.curOp.changeObjs||(i.curOp.changeObjs=[])).push($)}i.display.selForContextMenu=null}function Ks(i,u,f,c,p){var g;c||(c=f),re(c,f)<0&&(g=[c,f],f=g[0],c=g[1]),typeof u=="string"&&(u=i.splitLines(u)),Qs(i,{from:f,to:c,text:u,origin:p})}function EO(i,u,f,c){f