This commit is contained in:
Ben C 2023-07-01 11:50:46 -04:00
parent 02c518ede2
commit f676a05123
No known key found for this signature in database
GPG Key ID: 556064B755159BBC
119 changed files with 7029 additions and 3266 deletions

15
docs/.eslintrc.yml Normal file
View File

@ -0,0 +1,15 @@
env:
browser: true
es2021: true
extends:
- eslint:recommended
- plugin:@typescript-eslint/recommended
overrides: []
parser: "@typescript-eslint/parser"
parserOptions:
ecmaVersion: latest
sourceType: module
plugins:
- "@typescript-eslint"
rules:
"@typescript-eslint/no-non-null-assertion": off

21
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

7
docs/.prettierrc.yml Normal file
View File

@ -0,0 +1,7 @@
$schema: "https://json.schemastore.org/prettierrc"
tabWidth: 4
semi: true
singleQuote: false
trailingComma: none
printWidth: 100
endOfLine: lf

4
docs/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
docs/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View File

@ -1,12 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
menagerie-docs = "*"
[requires]
python_version = "3.11"

613
docs/Pipfile.lock generated
View File

@ -1,613 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "e93f7f7087f635da529dc8dbaa56be872c12a26be4d8cfcaa9393f12fe7f1bda"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.11"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {},
"develop": {
"attrs": {
"hashes": [
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836",
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"
],
"markers": "python_version >= '3.6'",
"version": "==22.2.0"
},
"beautifulsoup4": {
"hashes": [
"sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591",
"sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"
],
"markers": "python_full_version >= '3.6.0'",
"version": "==4.12.0"
},
"certifi": {
"hashes": [
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
],
"markers": "python_version >= '3.6'",
"version": "==2022.12.7"
},
"charset-normalizer": {
"hashes": [
"sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6",
"sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1",
"sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e",
"sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373",
"sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62",
"sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230",
"sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be",
"sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c",
"sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0",
"sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448",
"sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f",
"sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649",
"sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d",
"sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0",
"sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706",
"sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a",
"sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59",
"sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23",
"sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5",
"sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb",
"sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e",
"sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e",
"sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c",
"sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28",
"sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d",
"sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41",
"sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974",
"sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce",
"sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f",
"sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1",
"sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d",
"sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8",
"sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017",
"sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31",
"sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7",
"sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8",
"sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e",
"sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14",
"sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd",
"sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d",
"sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795",
"sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b",
"sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b",
"sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b",
"sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203",
"sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f",
"sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19",
"sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1",
"sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a",
"sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac",
"sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9",
"sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0",
"sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137",
"sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f",
"sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6",
"sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5",
"sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909",
"sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f",
"sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0",
"sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324",
"sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755",
"sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb",
"sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854",
"sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c",
"sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60",
"sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84",
"sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0",
"sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b",
"sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1",
"sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531",
"sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1",
"sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11",
"sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326",
"sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df",
"sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"
],
"markers": "python_full_version >= '3.7.0'",
"version": "==3.1.0"
},
"click": {
"hashes": [
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.3"
},
"dataclasses-json": {
"hashes": [
"sha256:bc285b5f892094c3a53d558858a88553dd6a61a11ab1a8128a0e554385dcc5dd",
"sha256:c2c11bc8214fbf709ffc369d11446ff6945254a7f09128154a7620613d8fda90"
],
"markers": "python_version >= '3.6'",
"version": "==0.5.7"
},
"elementpath": {
"hashes": [
"sha256:2b1b524223d70fd6dd63a36b9bc32e4919c96a272c2d1454094c4d85086bc6f8",
"sha256:dbd7eba3cf0b3b4934f627ba24851a3e0798ef2bc9104555a4cd831f2e6e8e14"
],
"markers": "python_version >= '3.7'",
"version": "==4.1.0"
},
"htmlmin": {
"hashes": [
"sha256:50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178"
],
"version": "==0.1.12"
},
"idna": {
"hashes": [
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
],
"markers": "python_version >= '3.5'",
"version": "==3.4"
},
"jinja2": {
"hashes": [
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
],
"markers": "python_version >= '3.7'",
"version": "==3.1.2"
},
"json-minify": {
"hashes": [
"sha256:268e6966c0f1dcb32ac54e1d047b83deba9ce711c0763ceba63f26d3aeedf656",
"sha256:499717626144a533d64ed4a1513976cf2212958b6806a66e07dd8e22207df559"
],
"version": "==0.3.0"
},
"json-schema-for-humans": {
"hashes": [
"sha256:1e34f1ae053c0884a52bcfc415f8de10a9dc918554523912f53015d202549f37",
"sha256:62a72dd2edb064fb6f2cb6939670185b80a79317b1e7cdb2132634287b142493"
],
"markers": "python_version >= '3.7' and python_version < '4.0'",
"version": "==0.44.4"
},
"jsonschema": {
"hashes": [
"sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d",
"sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"
],
"markers": "python_version >= '3.7'",
"version": "==4.17.3"
},
"libsass": {
"hashes": [
"sha256:081e256ab3c5f3f09c7b8dea3bf3bf5e64a97c6995fd9eea880639b3f93a9f9a",
"sha256:3ab5ad18e47db560f4f0c09e3d28cf3bb1a44711257488ac2adad69f4f7f8425",
"sha256:65455a2728b696b62100eb5932604aa13a29f4ac9a305d95773c14aaa7200aaf",
"sha256:89c5ce497fcf3aba1dd1b19aae93b99f68257e5f2026b731b00a872f13324c7f",
"sha256:f1efc1b612299c88aec9e39d6ca0c266d360daa5b19d9430bdeaffffa86993f9"
],
"markers": "python_version >= '3.6'",
"version": "==0.22.0"
},
"markdown": {
"hashes": [
"sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49",
"sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"
],
"markers": "python_version >= '3.6'",
"version": "==3.3.4"
},
"markdown2": {
"hashes": [
"sha256:7d49ca871d3e0e412c65d7d21fcbc13ae897f7876f3e5f14dd4db3b7fbf27f10",
"sha256:90475aca3d9c8e7df6d70c51de5bbbe9edf7fcf6a380bd1044d321500f5445da"
],
"markers": "python_version >= '3.5' and python_version < '4'",
"version": "==2.4.8"
},
"markupsafe": {
"hashes": [
"sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed",
"sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc",
"sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2",
"sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460",
"sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7",
"sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0",
"sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1",
"sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa",
"sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03",
"sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323",
"sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65",
"sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013",
"sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036",
"sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f",
"sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4",
"sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419",
"sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2",
"sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619",
"sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a",
"sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a",
"sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd",
"sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7",
"sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666",
"sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65",
"sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859",
"sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625",
"sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff",
"sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156",
"sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd",
"sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba",
"sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f",
"sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1",
"sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094",
"sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a",
"sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513",
"sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed",
"sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d",
"sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3",
"sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147",
"sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c",
"sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603",
"sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601",
"sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a",
"sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1",
"sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d",
"sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3",
"sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54",
"sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2",
"sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6",
"sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"
],
"markers": "python_version >= '3.7'",
"version": "==2.1.2"
},
"marshmallow": {
"hashes": [
"sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78",
"sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"
],
"markers": "python_version >= '3.7'",
"version": "==3.19.0"
},
"marshmallow-enum": {
"hashes": [
"sha256:38e697e11f45a8e64b4a1e664000897c659b60aa57bfa18d44e226a9920b6e58",
"sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"
],
"version": "==1.5.1"
},
"menagerie-docs": {
"hashes": [
"sha256:ad6ff178b3edc493b7e031d932616e4aaef788c2e796494e729fb2fb96c334eb",
"sha256:bfd5b78c8a2931983a1941ee2e96204b93e5ff90f5bbc0e0178c763de42b844f"
],
"index": "pypi",
"version": "==0.1.14"
},
"more-itertools": {
"hashes": [
"sha256:cabaa341ad0389ea83c17a94566a53ae4c9d07349861ecb14dc6d0345cf9ac5d",
"sha256:d2bc7f02446e86a68911e58ded76d6561eea00cddfb2a91e7019bbb586c799f3"
],
"markers": "python_version >= '3.7'",
"version": "==9.1.0"
},
"mypy-extensions": {
"hashes": [
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.0"
},
"ndicts": {
"hashes": [
"sha256:010b0c94180fe89e7e0d5fa89909c4bd7784c52d56908d4d776337c9358378e9",
"sha256:1a1f31cdb770c037c9cc9bc27a8493e43bfe035a606d3630c2e3d14eabe7bfbf"
],
"markers": "python_version >= '3.8' and python_version < '4.0'",
"version": "==0.3.0"
},
"packaging": {
"hashes": [
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2",
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"
],
"markers": "python_version >= '3.7'",
"version": "==23.0"
},
"pillow": {
"hashes": [
"sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33",
"sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b",
"sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e",
"sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35",
"sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153",
"sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9",
"sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569",
"sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57",
"sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8",
"sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1",
"sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264",
"sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157",
"sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9",
"sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133",
"sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9",
"sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab",
"sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6",
"sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5",
"sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df",
"sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503",
"sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b",
"sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa",
"sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327",
"sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493",
"sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d",
"sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4",
"sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4",
"sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35",
"sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2",
"sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c",
"sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011",
"sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a",
"sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e",
"sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f",
"sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848",
"sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57",
"sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f",
"sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c",
"sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9",
"sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5",
"sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9",
"sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d",
"sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0",
"sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1",
"sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e",
"sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815",
"sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0",
"sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b",
"sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd",
"sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c",
"sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3",
"sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab",
"sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858",
"sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5",
"sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee",
"sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343",
"sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb",
"sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47",
"sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed",
"sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837",
"sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286",
"sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28",
"sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628",
"sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df",
"sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d",
"sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d",
"sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a",
"sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6",
"sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336",
"sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132",
"sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070",
"sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe",
"sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a",
"sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd",
"sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391",
"sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a",
"sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"
],
"markers": "python_version >= '3.7'",
"version": "==9.4.0"
},
"pygments": {
"hashes": [
"sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297",
"sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"
],
"markers": "python_version >= '3.6'",
"version": "==2.14.0"
},
"pyrsistent": {
"hashes": [
"sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8",
"sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440",
"sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a",
"sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c",
"sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3",
"sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393",
"sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9",
"sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da",
"sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf",
"sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64",
"sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a",
"sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3",
"sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98",
"sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2",
"sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8",
"sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf",
"sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc",
"sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7",
"sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28",
"sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2",
"sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b",
"sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a",
"sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64",
"sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19",
"sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1",
"sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9",
"sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"
],
"markers": "python_version >= '3.7'",
"version": "==0.19.3"
},
"pytz": {
"hashes": [
"sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588",
"sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"
],
"version": "==2023.3"
},
"pyyaml": {
"hashes": [
"sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf",
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
"sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b",
"sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4",
"sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07",
"sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba",
"sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9",
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
"sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782",
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
"sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1",
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
"sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d",
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
"sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7",
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
"sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358",
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
"sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f",
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
],
"markers": "python_version >= '3.6'",
"version": "==6.0"
},
"rcssmin": {
"hashes": [
"sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72",
"sha256:35da6a6999e9e2c5b0e691b42ed56cc479373e0ecab33ef5277dfecce625e44a",
"sha256:42576d95dfad53d77df2e68dfdec95b89b10fad320f241f1af3ca1438578254a",
"sha256:4f9400b4366d29f5f5446f58e78549afa8338e6a59740c73115e9f6ac413dc64",
"sha256:705c9112d0ed54ea40aecf97e7fd29bdf0f1c46d278a32d8f957f31dde90778a",
"sha256:79421230dd67c37ec61ed9892813d2b839b68f2f48ef55c75f976e81701d60b4",
"sha256:868215e1fd0e92a6122e0ed5973dfc7bb8330fe1e92274d05b2585253b38c0ca",
"sha256:8a26fec3c1e6b7a3765ccbaccc20fbb5c0ed3422cc381e01a2607f08d7621c44",
"sha256:8fcfd10ae2a1c4ce231a33013f2539e07c3836bf17cc945cc25cc30bf8e68e45",
"sha256:908fe072efd2432fb0975a61124609a8e05021367f6a3463d45f5e3e74c4fdda",
"sha256:914e589f40573035006913861ed2adc28fbe70082a8b6bff5be7ee430b7b5c2e",
"sha256:a04d58a2a21e9a089306d3f99c4b12bf5b656a79c198ef2321e80f8fd9afab06",
"sha256:a417735d4023d47d048a6288c88dbceadd20abaaf65a11bb4fda1e8458057019",
"sha256:c30f8bc839747b6da59274e0c6e4361915d66532e26448d589cb2b1846d7bf11",
"sha256:c7278c1c25bb90d8e554df92cfb3b6a1195004ead50f764653d3093933ee0877",
"sha256:c7728e3b546b1b6ea08cab721e8e21409dbcc11b881d0b87d10b0be8930af2a2",
"sha256:cf74d7ea5e191f0f344b354eed8b7c83eeafbd9a97bec3a579c3d26edf11b005",
"sha256:d0afc6e7b64ef30d6dcde88830ec1a237b9f16a39f920a8fd159928684ccf8db",
"sha256:d4e263fa9428704fd94c2cb565c7519ca1d225217943f71caffe6741ab5b9df1",
"sha256:e923c105100ab70abde1c01d3196ddd6b07255e32073685542be4e3a60870c8e",
"sha256:ee386bec6d62f8c814d65c011d604a7c82d24aa3f718facd66e850eea8d6a5a1",
"sha256:f15673e97f0a68b4c378c4d15b088fe96d60bc106d278c88829923118833c20f",
"sha256:f7a1fcdbafaacac0530da04edca4a44303baab430ea42e7d59aece4b3f3e9a51"
],
"version": "==1.1.1"
},
"requests": {
"hashes": [
"sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa",
"sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"
],
"markers": "python_version >= '3.7' and python_version < '4'",
"version": "==2.28.2"
},
"rjsmin": {
"hashes": [
"sha256:113132a40ce7d03b2ced4fac215f0297338ed1c207394b739266efab7831988b",
"sha256:122aa52bcf7ad9f12728d309012d1308c6ecfe4d6b09ea867a110dcad7b7728c",
"sha256:145c6af8df42d8af102d0d39a6de2e5fa66aef9e38947cfb9d65377d1b9940b2",
"sha256:1f982be8e011438777a94307279b40134a3935fc0f079312ee299725b8af5411",
"sha256:3453ee6d5e7a2723ec45c2909e2382371783400e8d51952b692884c6d850a3d0",
"sha256:35827844d2085bd59d34214dfba6f1fc42a215c455887437b07dbf9c73019cc1",
"sha256:35f21046504544e2941e04190ce24161255479133751550e36ddb3f4af0ecdca",
"sha256:5d67ec09da46a492186e35cabca02a0d092eda5ef5b408a419b99ee4acf28d5c",
"sha256:747bc9d3bc8a220f40858e6aad50b2ae2eb7f69c924d4fa3803b81be1c1ddd02",
"sha256:7dd58b5ed88233bc61dc80b0ed87b93a1786031d9977c70d335221ef1ac5581a",
"sha256:812af25c08d6a5ae98019a2e1b47ebb47f7469abd351670c353d619eaeae4064",
"sha256:8a6710e358c661dcdcfd027e67de3afd72a6af4c88101dcf110de39e9bbded39",
"sha256:8c340e251619c97571a5ade20f147f1f7e8664f66a2d6d7319e05e3ef6a4423c",
"sha256:99c074cd6a8302ff47118a9c3d086f89328dc8e5c4b105aa1f348fb85c765a30",
"sha256:b8464629a18fe69f70677854c93a3707976024b226a0ce62707c618f923e1346",
"sha256:bbd7a0abaa394afd951f5d4e05249d306fec1c9674bfee179787674dddd0bdb7",
"sha256:bc5bc2f94e59bc81562c572b7f1bdd6bcec4f61168dc68a2993bad2d355b6e19",
"sha256:bd1faedc425006d9e86b23837d164f01d105b7a8b66b767a9766d0014773db2a",
"sha256:ca90630b84fe94bb07739c3e3793e87d30c6ee450dde08653121f0d9153c8d0d",
"sha256:d332e44a1b21ad63401cc7eebc81157e3d982d5fb503bb4faaea5028068d71e9",
"sha256:eb770aaf637919b0011c4eb87b9ac6317079fb9800eb17c90dda05fc9de4ebc3",
"sha256:f0895b360dccf7e2d6af8762a52985e3fbaa56778de1bf6b20dbc96134253807",
"sha256:f7cd33602ec0f393a0058e883284496bb4dbbdd34e0bbe23b594c8933ddf9b65"
],
"version": "==1.2.1"
},
"soupsieve": {
"hashes": [
"sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955",
"sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"
],
"markers": "python_version >= '3.7'",
"version": "==2.4"
},
"typing-extensions": {
"hashes": [
"sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb",
"sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"
],
"markers": "python_version >= '3.7'",
"version": "==4.5.0"
},
"typing-inspect": {
"hashes": [
"sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188",
"sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d"
],
"version": "==0.8.0"
},
"urllib3": {
"hashes": [
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
"sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.26.15"
},
"xmlschema": {
"hashes": [
"sha256:0caa96668807b4b51c42a0fe2b6610752bc59f069615df3e34dcfffb962973fd",
"sha256:557f3632b54b6ff10576736bba62e43db84eb60f6465a83818576cd9ffcc1799"
],
"markers": "python_version >= '3.7'",
"version": "==2.2.2"
}
}
}

179
docs/README.md Normal file
View File

@ -0,0 +1,179 @@
# Astro Starter Kit: Docs Site
```bash
npm create astro@latest -- --template docs
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/docs)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/docs)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/docs/devcontainer.json)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![docs](https://user-images.githubusercontent.com/4677417/186189283-0831b9ab-d6b9-485d-8955-3057e532ab31.png)
## Features
- ✅ **Full Markdown support**
- ✅ **Responsive mobile-friendly design**
- ✅ **Sidebar navigation**
- ✅ **Search (powered by Algolia)**
- ✅ **Multi-language i18n**
- ✅ **Automatic table of contents**
- ✅ **Automatic list of contributors**
- ✅ (and, best of all) **dark mode**
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide.
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
## Customize This Theme
### Site metadata
`src/consts.ts` contains several data objects that describe metadata about your site like title, description, default language, and Open Graph details. You can customize these to match your project.
### CSS styling
The theme's look and feel is controlled by a few key variables that you can customize yourself. You'll find them in the `src/styles/theme.css` CSS file.
If you've never worked with CSS variables before, give [MDN's guide on CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) a quick read.
This theme uses a "cool blue" accent color by default. To customize this for your project, change the `--theme-accent` variable to whatever color you'd like:
```diff
/* src/styles/theme.css */
:root {
color-scheme: light;
- --theme-accent: hsla(var(--color-blue), 1);
+ --theme-accent: hsla(var(--color-red), 1); /* or: hsla(#FF0000, 1); */
```
## Page metadata
Astro uses frontmatter in Markdown pages to choose layouts and pass properties to those layouts. If you are using the default layout, you can customize the page in many different ways to optimize SEO and other things. For example, you can use the `title` and `description` properties to set the document title, meta title, meta description, and Open Graph description.
```markdown
---
title: Example title
description: Really cool docs example that uses Astro
layout: ../../layouts/MainLayout.astro
---
# Page content...
```
For more SEO related properties, look at `src/components/HeadSEO.astro`
### Sidebar navigation
The sidebar navigation is controlled by the `SIDEBAR` variable in your `src/consts.ts` file. You can customize the sidebar by modifying this object. A default, starter navigation has already been created for you.
```ts
export const SIDEBAR = {
en: {
'Section Header': [
{ text: 'Introduction', link: 'en/introduction' },
{ text: 'Page 2', link: 'en/page-2' },
{ text: 'Page 3', link: 'en/page-3' },
],
'Another Section': [{ text: 'Page 4', link: 'en/page-4' }],
},
};
```
Note the top-level `en` key: This is needed for multi-language support. You can change it to whatever language you'd like, or add new languages as you go. More details on this below.
### Multiple Languages support
The Astro docs template supports multiple languages out of the box. The default theme only shows `en` documentation, but you can enable multi-language support features by adding a second language to your project.
To add a new language to your project, you'll want to extend the current `src/content/docs/[lang]/...` layout:
```diff
📂 src/content/docs
┣ 📂 en
┃ ┣ 📜 page-1.md
┃ ┣ 📜 page-2.md
┃ ┣ 📜 page-3.astro
+ ┣ 📂 es
+ ┃ ┣ 📜 page-1.md
+ ┃ ┣ 📜 page-2.md
+ ┃ ┣ 📜 page-3.astro
```
You'll also need to add the new language name to the `KNOWN_LANGUAGES` map in your `src/consts.ts` file. This will enable your new language switcher in the site header.
```diff
// src/consts.ts
export const KNOWN_LANGUAGES = {
English: 'en',
+ Spanish: 'es',
};
```
Last step: you'll need to add a new entry to your sidebar, to create the table of contents for that language. While duplicating every page might not sound ideal to everyone, this extra control allows you to create entirely custom content for every language.
> Make sure the sidebar `link` value points to the correct language!
```diff
// src/consts.ts
export const SIDEBAR = {
en: {
'Section Header': [
{ text: 'Introduction', link: 'en/introduction' },
// ...
],
// ...
},,
+ es: {
+ 'Encabezado de sección': [
+ { text: 'Introducción', link: 'en/introduction' },
+ // ...
+ ],
+ // ...
+ },
};
// ...
```
If you plan to use Spanish as the default language, you just need to modify the redirect path in `src/pages/index.astro`:
```diff
<script>
- window.location.pathname = `/en/introduction`;
+ window.location.pathname = `/es/introduction`;
</script>
```
You can also remove the above script and write a landing page in Spanish instead.
### What if I don't plan to support multiple languages?
That's totally fine! Not all projects need (or can support) multiple languages. You can continue to use this theme without ever adding a second language.
If that single language is not English, you can just replace `en` in directory layouts and configurations with the preferred language.
### Search (Powered by Algolia)
[Algolia](https://www.algolia.com/) offers a free service to qualified open source projects called [DocSearch](https://docsearch.algolia.com/). If you are accepted to the DocSearch program, provide your API Key & index name in `src/consts.ts` and a search box will automatically appear in your site header.
Note that Algolia and Astro are not affiliated. We have no say over acceptance to the DocSearch program.
If you'd prefer to remove Algolia's search and replace it with your own, check out the `src/components/Header.astro` component to see where the component is added.

View File

@ -1,41 +0,0 @@
# Setup to build docs
## Requirements
- Python 3.10
## Clone the repo
Clone the entire repo and navigate to the docs folder
```shell
git clone https://github.com/xen-42/outer-wilds-new-horizons
cd outer-wilds-new-horizons/docs
```
## Setup Pipenv
Install pipenv if you haven't already
```shell
pip install --user pipenv
```
Install dependencies
```shell
pipenv install --dev
```
## Environment Variables
- URL_PREFIX: Path to put before all links and static files, see below for recommended values
- Production and Local Builds: "/"
- PyCharm Development Server: "/outer-wilds-new-horizons/docs/out/"
## Copy Schemas
Create a folder called `schemas` in the `docs/content/pages/` folder and copy all schemas to generate into it, make sure not to add this folder to git.
Production build automatically copies over schemas.
## Generating
Run `generate` with pipenv
```shell
pipenv run menagerie generate
```
## Opening
- Production: Go to the site
- Local: Go into `docs/out` in a new terminal window and run `py -m http.server 8080` and then connect to http://localhost:8080/
- PyCharm Development Server: Right click `out/index.html` -> Open In -> Browser -> Default

14
docs/astro.config.mjs Normal file
View File

@ -0,0 +1,14 @@
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
// https://astro.build/config
export default defineConfig({
integrations: [
// Enable Preact to support Preact JSX components.
preact(),
// Enable React for the Algolia search component.
react(),
],
site: `https://astro.build`,
});

View File

@ -1,72 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/Bwc9876/menagerie/master/menagerie/schemas/config_schema.json",
"cache_enabled": false,
"base_url": "https://nh.outerwildsmods.com/",
"themes": {
"bootstrap": "https://bootswatch.com/5/darkly/bootstrap.min.css",
"highlight_js": "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/github-dark-dimmed.min.css",
"theme": "dark"
},
"styles": {
"base": "styles/nh_base.css"
},
"search": {
"enabled": false,
"site": "nh.outerwildsmods.com"
},
"brand": {
"app_name": "New Horizons",
"favicon_folder": "fav/",
"navbar_icon": "images/icon.webp",
"navbar_icon_size": [
29,
29
],
"socials": [
{
"name": "Discord",
"link": "https://discord.gg/wusTQYbYTc",
"icon": "discord"
},
{
"name": "GitHub",
"link": "https://github.com/xen-42/outer-wilds-new-horizons",
"icon": "github"
},
{
"name": "Patreon",
"link": "https://patreon.com/ownh",
"icon": "coin"
}
],
"meta": {
"search_console_code": "SafYg2zgXPfpW4MZbkBTpAtuNs5W7N-upr08Kv6tyMo",
"description": "Documentation on how to use the New Horizons planet creation tool for Outer Wilds.",
"keywords": [
"New Horizons",
"Outer Wilds",
"Modding",
"C#",
"Unity"
],
"categories": [
"games",
"utilities"
],
"image": "images/home/home_logo.webp",
"image_alt": "The New Horizons Logo",
"theme_color": "#ffab8a",
"bg_color": "#1a1a1a"
},
"footer": {
"show_made_with": false,
"links": [
{
"link": "https://github.com/xen-42/outer-wilds-new-horizons/issues/new/choose",
"text": "Report an issue",
"external": true
}
]
}
}
}

View File

@ -1,10 +0,0 @@
---
Title: Page not Found
Hide_In_Nav: True
Render_TOC: False
---
# Page Not Found
The page you requested could not be found.

View File

@ -1,65 +0,0 @@
---
Title: Config Editor
Sort_Priority: 50
---
# Config Editor
Are you tired of manually editing JSON? Do you want richer validation than a JSON schema? Well then the config editor may be for you!
This page outlines how to install and use the config editor.
## Installation
To get started, head over to the [releases page for the editor](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor/releases/latest) and install the file for your OS:
- Windows: The .msi file (not the .msi.zip and .msi.zip.sig file)
- MacOS: The .AppImage file (not the .AppImage.tar.gz or the .AppImage.tar.gz.sig file)
Follow the installer instructions to complete setup
## Creating a New Project
Creating a new project is as simple as clicking the button.
Fill out the form with thr info for your mod and a new project will be made at the specified path.
## Editing Files
To edit a file, navigate to it in the left panel and click on it.
### JSON files
JSON files (planets, systems, etc) have a graphical interface for editing, **this will clear comments!**
If you don't want comments to be cleared, use the text editor
#### Using the Text Editor
Already familiar with JSON and prefer text-based editing? Simply open up settings (File -> Settings) and turn on the "Always use Text Editor" option.
### Image and Audio Files
You can view images and play audio files with this editor.
### XML Files
Right now, XML support is limited. You'll get syntax highlighting but no error checking or autofill.
## Running the Game
You can start the game from the editor by selecting Project -> Run Project this will open a new window where you can run the game
### Log Port
If you're using the mod manager and would like logs to appear there, you need to get the log port from the console, it's always the first entry in the logs. Keep in mind this port changes whenever you restart the manager.
![Get the log port]({{ "images/editor/log_port.webp"|static }})
## Building
The editor also provides a system for building your mod to a zip file, which can then be uploaded to GitHub in a release. To do this, press Project -> Build (Release)

View File

@ -1,88 +0,0 @@
{#~ Title:FAQ ~#}
{#~ Sort_Priority:95 ~#}
{#~ Render_TOC:False ~#}
{% macro faq(id, q, a) %}
<div class="accordion-item">
<h2 class="accordion-header">
<button id="{{ id }}-heading" class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ id }}" aria-expanded="false" aria-controls="{{ id }}">
Q: {{ q }}
</button>
</h2>
<div id="{{ id }}" class="accordion-collapse collapse" aria-labelledby="{{ id }}-heading" data-bs-parent="#accordionFAQ">
<div class="accordion-body">
{{ ("A: " + a)|simple_md|replace('<p>', '<p class="my-0 ms-2">')|safe }}
</div>
</div>
</div>
{% endmacro %}
<h1 class="text-center pb-2">FAQ</h1>
<div class="accordion" id="accordionFAQ">
{{
faq(
"is-easy",
"How easy is it to make a planet mod?",
"Easy, you don't even need to know how to code! Just start off slowly and make a single planet with a few surface details. Don't try to make a full DLC-scale story mod on your first try."
)
}}
{{
faq(
"model-whole-planet",
"Can I model my entire planet in Blender and put it into the game?",
"Yes! Follow the instructions on the Detailing page. All you have to do is add that model as a single detail prop at the center of the planet."
)
}}
{{
faq(
"why-no-planet",
"Why doesn't my planet show up in game?",
"Have you checked the logs for errors? Are you using a program like [VSCode](https://code.visualstudio.com/){ target='_blank' } to write your configs that validates them against our schema to catch your errors? Do you incrementally test each new planet that you add, or did you write 10 json files and then try them all at once? If you're still not sure, come by our [Discord channel](https://discord.gg/wusTQYbYTc){ target='_blank' } (`#nh-addon-discussion`) and we'll try to help out!"
)
}}
{{
faq(
"ui-program",
"Will you make a UI program to generate json files in the future?",
"Yes! It's available [on GitHub](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor){ target='_blank' }."
)
}}
{{
faq(
"when-version-1",
"When will New Horizons get to version 1.0.0.",
"It already did **BOZO**!!!!!"
)
}}
{{
faq(
"feature-request",
"When will (*insert feature request here*) be implemented into New Horizons?",
"If it's on the road-map, eventually. If it's not on the road-map let us know and we'll see if it's something we can consider adding."
)
}}
{{
faq(
"i-dont-use-reload-configs",
"It takes so long to test my mod because I keep having to restart my game whenever I change something in a config.",
"That's not a question. But go into your mod settings in game and enable Debug mode on New Horizons. Now there will be a “Reload Configs” button in your options screen that will reload all your planets without restarting your game!"
)
}}
{{
faq(
"rails",
"Will you ditch the physics simulation and instead track planet positions on their orbits as a function of time, effectively putting the planets on rails and thereby making the game more efficient and accurate at the expense of the game's original vision as being an actual simulation of orbital mechanics?",
"**No.**"
)
}}
{{
faq(
"jammer",
"Will Jammer Be Added?",
"Yes! Check **your front door**"
)
}}
</div>

View File

@ -1,4 +0,0 @@
{
"$schema": "https://github.com/Bwc9876/menagerie/raw/master/menagerie/schemas/folder_schema.json",
"sort_priority": 15
}

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
---
Title: Bramble Colors
Render_TOC: False
---
| Dimension | Fog color | Node fog color |
|-------------|------------------------------------------|------------------------------------------|
| Cluster | {"r": 126, "g": 119, "b": 101, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
| Vessel | {"r": 206, "g": 187, "b": 137, "a": 255} | {"r": 191, "g": 171, "b": 133, "a": 255} |
| Small Nest | {"r": 131, "g": 128, "b": 121, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
| Pioneer | {"r": 106, "g": 116, "b": 99, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
| Hub | {"r": 84, "g": 83, "b": 73, "a": 255} | {"r": 84, "g": 83, "b": 73, "a": 255} |
| Exit Only | {"r": 113, "g": 107, "b": 81, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
| Escape Pod | {"r": 83, "g": 99, "b": 87, "a": 255} | {"r": 255, "g": 245, "b": 217, "a": 255} |
| Angler Nest | {"r": 113, "g": 107, "b": 81, "a": 255} | {"r": 255, "g": 129, "b": 83, "a": 255} |

View File

@ -1,25 +0,0 @@
---
Title: Hidden Page
Description: Hehe funny secret
Hide_In_Nav: True
---
# Hello!!
Uh idk what to put here thought it would be funny haha
![Cow](https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia1.tenor.com%2Fimages%2F964831e7eccb34007e82c065a50679ef%2Ftenor.gif%3Fitemid%3D18924714&f=1&nofb=1)
## It's Morbin' Time
![image](https://user-images.githubusercontent.com/25644444/178856213-44cb0a38-6d3d-4af6-b7f8-0ae6cda8d44a.png)
## Test
aaaaaaaaaaaaaaaaaaaaaaaaa
## 9/2/22
Where were you when new horizons docs died, im going gorbo mode

View File

@ -1,84 +0,0 @@
---
Title: Reading Schemas
Sort_Priority: 90
---
# Reading Schema Pages
Reading and understanding the schema pages are key to knowing how to create planets. While these tutorials may be helpful, they won't cover everything, and new features may be added before the tutorial on them can be written.
## Celestial Body Schema
The [celestial body schema]({{ "Celestial Body Schema"|route }}) is the schema for making planets, there are other schemas which will be explained later but for now let's focus on this one.
![The Celestial Body Schema Page]({{ "images/reading_schemas/body_schema_1.webp"|static }})
As you can see the type of this is `object`, which we talked about in the previous section.
We can also observe a blue badge that says "No Additional Properties", this signifies that you can't add keys to the object that aren't in the schema, for example:
```json
{
"name": "Wetrock",
"coolKey": "Look at my cool key!"
}
```
Will result in a warning in VSCode. Now, this will *not* prevent the planet from being loaded, however you should still avoid doing it.
## Simple Properties
![The name property on the celestial body schema]({{ "images/reading_schemas/body_schema_2.webp"|static }})
Next up let's look at `name`, this field is required, meaning you *have* to have it for a planet to load.
When we click on name we first see a breadcrumb, this is essentially a guide of where you are in the schema, right now we're in the name property of the root (topmost) object.
We can also see it's description, its type is `string`, and that it requires at least one character (so you can't just put `""`).
Badges can also show stuff such as the default value, the minimum and maximum values, and more.
## Object Properties
![The Base object on the celestial body schema]({{ "images/reading_schemas/body_schema_3.webp"|static }})
Next let's look at an `object` within our root `object`, let's use `Base` as the example.
Here we can see it's similar to our root object, in that it doesn't allow additional properties.
We can also see all of its properties listed out.
## Array Properties
Now let's take a look over at [removeChildren]({{ "Celestial Body Schema"|route }}#removeChildren) to see how arrays work (if you're wondering how you can get the page to scroll to a specific property, simply click on the property and copy the URL in your URL bar)
![The curve property on a star in the celestial body schema]({{ "images/reading_schemas/body_schema_4.webp"|static }})
Here we can see that the type is an `array`, and each item in this array must be a `string`
## Enum Properties
Enum properties simply mean that they must be of one of the values shown, for example [Ring fluid type]({{ "Celestial Body Schema"|route }}#Ring_fluidType) has to be one of these values.
![The enum values of fluidType]({{ "images/reading_schemas/body_schema_5.webp"|static }})
## Some Vocabulary
- GameObject: Essentially just any object in, well, the game. You can view these object in a tree-like structure with the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod. Every GameObject has a path, which is sort of like a file path in that it's a list of parent GameObjects seperated by forward slashes followed by the GameObject's name.
- Component: By themselves, a GameObject doesn't actually *do* anything, components provide stuff like collision, rendering, and logistics to GameObjects
- Config: Just another name for a JSON file "planet config" simply means a json file that describes a planet
- Module: A specific section of the config (e.g. Base, Atmosphere, etc), these usually start with capital letters
## Note About File Paths
Whenever a description refers to the "relative path" of a file, it means relative to the mod's directory, this means you **must** include the `planets` folder in the path:
```json
"planets/assets/images/MyCoolImage.png"
```
## Other Schemas
There are other schemas available, some are for JSON, and some are for XML.
## Moving Forward
Now that you know how to read the schema pages, you can understand the rest of this site. A lot of the other tutorials here will often tell you to take a look at schemas to explain what certain properties do.
**Next Up: [Creating An Addon]({{ "Creating An Addon"|route }})**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,54 +0,0 @@
pre > code {
background-color: #1a1a1a !important;
border-radius: .25rem !important;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: var(--bs-dark);
border-radius: 5px;
}
::-webkit-scrollbar-thumb {
background: var(--bs-secondary);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
.accordion-button {
background-color: #2b2b2b !important;
}
.accordion-button:not(.collapsed)::after {
color: #effff7 !important;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}
.accordion-item {
border: 1px solid rgba(0, 0, 0, 0.4) !important;
}
.accordion-button:not(.collapsed) {
color: #effff7;
background-color: #2b2b2b;
}
.accordion-button:not(.collapsed)::after {
color: #effff7;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}
.accordion-item {
border: 1px solid rgba(0, 0, 0, 0.4);
}
.accordion-body {
background-color: #353535 !important;
}

36
docs/package.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "docs",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@algolia/client-search": "^4.17.0",
"@apidevtools/json-schema-ref-parser": "^10.1.0",
"@astrojs/preact": "^2.2.1",
"@astrojs/react": "^2.2.1",
"@docsearch/css": "^3.3.4",
"@docsearch/react": "^3.3.4",
"@types/node": "^18.16.3",
"@types/react": "^18.2.5",
"@types/react-dom": "^18.2.3",
"astro": "^2.5.6",
"eslint": "^8.42.0",
"eslint-plugin-prettier": "^4.2.1",
"fast-xml-parser": "^4.2.3",
"preact": "^10.13.2",
"prettier": "^2.8.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"xml-js": "^1.6.11"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.59.8",
"html-escaper": "^3.0.3"
}
}

4178
docs/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 660 B

View File

@ -0,0 +1,3 @@
Array.from(document.getElementsByTagName('pre')).forEach((element) => {
element.setAttribute('tabindex', '0');
});

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -0,0 +1,175 @@
---
// fetch all commits for just this page's path
type Props = {
path: string;
};
const { path } = Astro.props;
const resolvedPath = `docs/${path}`;
const url = `https://api.github.com/repos/Outer-Wilds-New-Horizons/new-horizons/commits?path=${resolvedPath}`;
const commitsURL = `https://github.com/Outer-Wilds-New-Horizons/new-horizons/commits/main/${resolvedPath}`;
type Commit = {
author: {
id: string;
login: string;
};
};
async function getCommits(url: string) {
try {
const token = import.meta.env.GITHUB_TOKEN ?? "hello";
if (!token) {
throw new Error('Cannot find "GITHUB_TOKEN" used for escaping rate-limiting.');
}
const auth = `Basic ${Buffer.from(token, "binary").toString("base64")}`;
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: auth,
"User-Agent": "astro-docs/1.0"
}
});
const data = await res.json();
if (!res.ok) {
throw new Error(
`Request to fetch commits failed. Reason: ${res.statusText}
Message: ${data.message}`
);
}
return data as Commit[];
} catch (e) {
console.warn(`[error] /src/components/AvatarList.astro
${(e as any)?.message ?? e}`);
return [] as Commit[];
}
}
function removeDups(arr: Commit[]) {
const map = new Map<string, Commit["author"]>();
for (let item of arr) {
const author = item.author;
// Deduplicate based on author.id
map.set(author.id, { login: author.login, id: author.id });
}
return [...map.values()];
}
const data = await getCommits(url);
const unique = removeDups(data);
const recentContributors = unique.slice(0, 3); // only show avatars for the 3 most recent contributors
const additionalContributors = unique.length - recentContributors.length; // list the rest of them as # of extra contributors
---
<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
<div class="contributors">
<ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}>
{
recentContributors.map((item) => (
<li>
<a href={`https://github.com/${item.login}`}>
<img
alt={`Contributor ${item.login}`}
title={`Contributor ${item.login}`}
width="64"
height="64"
src={`https://avatars.githubusercontent.com/u/${item.id}`}
/>
</a>
</li>
))
}
</ul>
{
additionalContributors > 0 && (
<span>
<a href={commitsURL}>{`and ${additionalContributors} additional contributor${
additionalContributors > 1 ? "s" : ""
}.`}</a>
</span>
)
}
{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
</div>
<style>
.avatar-list {
--avatar-size: 2.5rem;
--avatar-count: 3;
display: grid;
list-style: none;
/* Default to displaying most of the avatar to
enable easier access on touch devices, ensuring
the WCAG touch target size is met or exceeded */
grid-template-columns: repeat(
var(--avatar-count),
max(44px, calc(var(--avatar-size) / 1.15))
);
/* `padding` matches added visual dimensions of
the `box-shadow` to help create a more accurate
computed component size */
padding: 0.08em;
font-size: var(--avatar-size);
}
@media (any-hover: hover) and (any-pointer: fine) {
.avatar-list {
/* We create 1 extra cell to enable the computed
width to match the final visual width */
grid-template-columns: repeat(
calc(var(--avatar-count) + 1),
calc(var(--avatar-size) / 1.75)
);
}
}
.avatar-list li {
width: var(--avatar-size);
height: var(--avatar-size);
}
.avatar-list li:hover ~ li a,
.avatar-list li:focus-within ~ li a {
transform: translateX(33%);
}
.avatar-list img,
.avatar-list a {
display: block;
border-radius: 50%;
}
.avatar-list a {
transition: transform 180ms ease-in-out;
}
.avatar-list img {
width: 100%;
height: 100%;
object-fit: cover;
background-color: #fff;
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
}
.avatar-list a:focus {
outline: 2px solid transparent;
/* Double-layer trick to work for dark and light backgrounds */
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
}
.contributors {
display: flex;
align-items: center;
}
.contributors > * + * {
margin-left: 0.75rem;
}
</style>

View File

@ -0,0 +1,19 @@
---
import AvatarList from './AvatarList.astro';
type Props = {
path: string;
};
const { path } = Astro.props;
---
<footer>
<AvatarList path={path} />
</footer>
<style>
footer {
margin-top: auto;
padding: 2rem;
border-top: 3px solid var(--theme-divider);
}
</style>

View File

@ -0,0 +1,44 @@
---
import "../styles/theme.css";
import "../styles/index.css";
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<link rel="icon" href="/favicon.ico" />
<link rel="sitemap" href="/sitemap.xml" />
<!-- Preload Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap"
rel="stylesheet"
/>
<!-- Scrollable a11y code helper -->
<script src="/make-scrollable-code-focusable.js" is:inline></script>
<!-- This is intentionally inlined to avoid FOUC -->
<script is:inline>
const root = document.documentElement;
const theme = localStorage.getItem("theme");
if (theme === "dark" || (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
root.classList.add("theme-dark");
} else {
root.classList.remove("theme-dark");
}
</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<!-- <script async src="https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9" is:inline></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-TEL60V1WM9');
</script> -->

View File

@ -0,0 +1,39 @@
---
import type { CollectionEntry } from "astro:content";
import { SITE, OPEN_GRAPH } from "../consts";
type Props = { canonicalUrl: URL } & CollectionEntry<"docs">["data"];
const { ogLocale, image, title, description, canonicalUrl } = Astro.props;
const formattedContentTitle = `${title} 🚀 ${SITE.title}`;
const imageSrc = image?.src ?? OPEN_GRAPH.image.src;
const canonicalImageSrc = new URL(imageSrc, Astro.site);
const imageAlt = image?.alt ?? OPEN_GRAPH.image.alt;
---
<!-- Page Metadata -->
<link rel="canonical" href={canonicalUrl} />
<!-- OpenGraph Tags -->
<meta property="og:title" content={formattedContentTitle} />
<meta property="og:type" content="article" />
<meta property="og:url" content={canonicalUrl} />
<meta property="og:locale" content={ogLocale ?? SITE.defaultLanguage} />
<meta property="og:image" content={canonicalImageSrc} />
<meta property="og:image:alt" content={imageAlt} />
<meta name="description" property="og:description" content={description ?? SITE.description} />
<meta property="og:site_name" content={SITE.title} />
<!-- Twitter Tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={formattedContentTitle} />
<meta name="twitter:description" content={description ?? SITE.description} />
<meta name="twitter:image" content={canonicalImageSrc} />
<meta name="twitter:image:alt" content={imageAlt} />
<!--
TODO: Add json+ld data, maybe https://schema.org/APIReference makes sense?
Docs: https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data
https://www.npmjs.com/package/schema-dts seems like a great resource for implementing this.
Even better, there's a React component that integrates with `schema-dts`: https://github.com/google/react-schemaorg
-->

View File

@ -0,0 +1,8 @@
---
type Props = {
size: number;
};
const { size } = Astro.props;
---
<img src="/icon.webp" width="40" height="40" />

View File

@ -0,0 +1,149 @@
---
import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from '../../languages';
import { SITE } from '../../consts';
import AstroLogo from './AstroLogo.astro';
import SkipToContent from './SkipToContent.astro';
import SidebarToggle from './SidebarToggle';
import LanguageSelect from './LanguageSelect';
import Search from './Search';
type Props = {
currentPage: string;
};
const { currentPage } = Astro.props;
const lang = getLanguageFromURL(currentPage);
---
<header>
<SkipToContent />
<nav class="nav-wrapper" title="Top Navigation">
<div class="menu-toggle">
<SidebarToggle client:idle />
</div>
<div class="logo flex">
<a href="/">
<AstroLogo size={40} />
<h1>{SITE.title ?? 'Documentation'}</h1>
</a>
</div>
<div style="flex-grow: 1;"></div>
{KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
<div class="search-item">
<Search client:idle />
</div>
</nav>
</header>
<style>
header {
z-index: 11;
height: var(--theme-navbar-height);
width: 100%;
background-color: var(--theme-navbar-bg);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: sticky;
top: 0;
}
.logo {
flex: 1;
display: flex;
overflow: hidden;
width: 30px;
font-size: 2rem;
flex-shrink: 0;
font-weight: 600;
line-height: 1;
color: hsla(var(--color-base-white), 100%, 1);
gap: 0.25em;
z-index: -1;
}
.logo a {
display: flex;
padding: 0.5em 0.25em;
margin: -0.5em -0.25em;
text-decoration: none;
font-weight: bold;
}
.logo a {
transition: color 100ms ease-out;
color: var(--theme-text);
}
.logo a:hover,
.logo a:focus {
color: var(--theme-text-accent);
}
.logo h1 {
display: none;
font: inherit;
color: inherit;
margin: 0;
}
.nav-wrapper {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 1em;
width: 100%;
max-width: 82em;
padding: 0 1rem;
}
@media (min-width: 50em) {
header {
position: static;
padding: 2rem 0rem;
}
.logo {
width: auto;
margin: 0;
z-index: 0;
}
.logo h1 {
display: initial;
}
.menu-toggle {
display: none;
}
}
/** Style Algolia */
:root {
--docsearch-primary-color: var(--theme-accent);
--docsearch-logo-color: var(--theme-text);
}
.search-item {
display: none;
position: relative;
z-index: 10;
flex-grow: 1;
padding-right: 0.7rem;
display: flex;
max-width: 200px;
}
@media (min-width: 50em) {
.search-item {
max-width: 400px;
}
}
</style>
<style is:global>
.search-item > * {
flex-grow: 1;
}
</style>

View File

@ -0,0 +1,47 @@
.language-select {
flex-grow: 1;
width: 48px;
box-sizing: border-box;
margin: 0;
padding: 0.33em 0.5em;
overflow: visible;
font-weight: 500;
font-size: 1rem;
font-family: inherit;
line-height: inherit;
background-color: var(--theme-bg);
border-color: var(--theme-text-lighter);
color: var(--theme-text-light);
border-style: solid;
border-width: 1px;
border-radius: 0.25rem;
outline: 0;
cursor: pointer;
transition-timing-function: ease-out;
transition-duration: 0.2s;
transition-property: border-color, color;
-webkit-font-smoothing: antialiased;
padding-left: 30px;
padding-right: 1rem;
}
.language-select-wrapper .language-select:hover,
.language-select-wrapper .language-select:focus {
color: var(--theme-text);
border-color: var(--theme-text-light);
}
.language-select-wrapper {
color: var(--theme-text-light);
position: relative;
}
.language-select-wrapper > svg {
position: absolute;
top: 7px;
left: 10px;
pointer-events: none;
}
@media (min-width: 50em) {
.language-select {
width: 100%;
}
}

View File

@ -0,0 +1,49 @@
/** @jsxImportSource react */
import type { FunctionComponent } from 'react';
import './LanguageSelect.css';
import { KNOWN_LANGUAGES, langPathRegex } from '../../languages';
const LanguageSelect: FunctionComponent<{ lang: string }> = ({ lang }) => {
return (
<div className="language-select-wrapper">
<svg
aria-hidden="true"
focusable="false"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 88.6 77.3"
height="1.2em"
width="1.2em"
>
<path
fill="currentColor"
d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z"
/>
<path
fill="currentColor"
d="M53.6,60.6c-10-4-16-9-22-14c0,0,1.3,1.3,0,0c-6,5-20,13-20,13l-4-6c8-5,10-6,19-13c-2.1-1.9-12-13-13-19h8 c4,9,10,14,10,14c10-8,10-19,10-19h8c0,0-1,13-12,24l0,0c5,5,10,9,19,13L53.6,60.6z M1.6,16.6h56v-8h-23v-7h-9v7h-24V16.6z"
/>
</svg>
<select
className="language-select"
value={lang}
onChange={(e) => {
const newLang = e.target.value;
let actualDest = window.location.pathname.replace(langPathRegex, '/');
if (actualDest == '/') actualDest = `/introduction`;
window.location.pathname = '/' + newLang + actualDest;
}}
>
{Object.entries(KNOWN_LANGUAGES).map(([key, value]) => {
return (
<option value={value} key={value}>
{key}
</option>
);
})}
</select>
</div>
);
};
export default LanguageSelect;

View File

@ -0,0 +1,75 @@
/** Style Algolia */
:root {
--docsearch-primary-color: var(--theme-accent);
--docsearch-logo-color: var(--theme-text);
}
.search-input {
flex-grow: 1;
box-sizing: border-box;
width: 100%;
margin: 0;
padding: 0.33em 0.5em;
overflow: visible;
font-weight: 500;
font-size: 1rem;
font-family: inherit;
line-height: inherit;
background-color: var(--theme-divider);
border-color: var(--theme-divider);
color: var(--theme-text-light);
border-style: solid;
border-width: 1px;
border-radius: 0.25rem;
outline: 0;
cursor: pointer;
transition-timing-function: ease-out;
transition-duration: 0.2s;
transition-property: border-color, color;
-webkit-font-smoothing: antialiased;
}
.search-input:hover,
.search-input:focus {
color: var(--theme-text);
border-color: var(--theme-text-light);
}
.search-input:hover::placeholder,
.search-input:focus::placeholder {
color: var(--theme-text-light);
}
.search-input::placeholder {
color: var(--theme-text-light);
}
.search-hint {
position: absolute;
top: 7px;
right: 19px;
padding: 3px 5px;
display: none;
align-items: center;
justify-content: center;
letter-spacing: 0.125em;
font-size: 13px;
font-family: var(--font-mono);
pointer-events: none;
border-color: var(--theme-text-lighter);
color: var(--theme-text-light);
border-style: solid;
border-width: 1px;
border-radius: 0.25rem;
line-height: 14px;
}
@media (min-width: 50em) {
.search-hint {
display: flex;
}
}
/* ------------------------------------------------------------ *\
DocSearch (Algolia)
\* ------------------------------------------------------------ */
.DocSearch-Modal .DocSearch-Hit a {
box-shadow: none;
border: 1px solid var(--theme-accent);
}

View File

@ -0,0 +1,97 @@
/** @jsxImportSource react */
import { useState, useCallback, useRef } from 'react';
import { ALGOLIA } from '../../consts';
import '@docsearch/css';
import './Search.css';
import { createPortal } from 'react-dom';
import * as docSearchReact from '@docsearch/react';
/** FIXME: This is still kinda nasty, but DocSearch is not ESM ready. */
const DocSearchModal =
docSearchReact.DocSearchModal || (docSearchReact as any).default.DocSearchModal;
const useDocSearchKeyboardEvents =
docSearchReact.useDocSearchKeyboardEvents ||
(docSearchReact as any).default.useDocSearchKeyboardEvents;
export default function Search() {
const [isOpen, setIsOpen] = useState(false);
const searchButtonRef = useRef<HTMLButtonElement>(null);
const [initialQuery, setInitialQuery] = useState('');
const onOpen = useCallback(() => {
setIsOpen(true);
}, [setIsOpen]);
const onClose = useCallback(() => {
setIsOpen(false);
}, [setIsOpen]);
const onInput = useCallback(
(e) => {
setIsOpen(true);
setInitialQuery(e.key);
},
[setIsOpen, setInitialQuery]
);
useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
onInput,
searchButtonRef,
});
return (
<>
<button type="button" ref={searchButtonRef} onClick={onOpen} className="search-input">
<svg width="24" height="24" fill="none">
<path
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<span>Search</span>
<span className="search-hint">
<span className="sr-only">Press </span>
<kbd>/</kbd>
<span className="sr-only"> to search</span>
</span>
</button>
{isOpen &&
createPortal(
<DocSearchModal
initialQuery={initialQuery}
initialScrollY={window.scrollY}
onClose={onClose}
indexName={ALGOLIA.indexName}
appId={ALGOLIA.appId}
apiKey={ALGOLIA.apiKey}
transformItems={(items) => {
return items.map((item) => {
// We transform the absolute URL into a relative URL to
// work better on localhost, preview URLS.
const a = document.createElement('a');
a.href = item.url;
const hash = a.hash === '#overview' ? '' : a.hash;
return {
...item,
url: `${a.pathname}${hash}`,
};
});
}}
/>,
document.body
)}
</>
);
}

View File

@ -0,0 +1,44 @@
/** @jsxImportSource preact */
import type { FunctionalComponent } from 'preact';
import { useState, useEffect } from 'preact/hooks';
const MenuToggle: FunctionalComponent = () => {
const [sidebarShown, setSidebarShown] = useState(false);
useEffect(() => {
const body = document.querySelector('body')!;
if (sidebarShown) {
body.classList.add('mobile-sidebar-toggle');
} else {
body.classList.remove('mobile-sidebar-toggle');
}
}, [sidebarShown]);
return (
<button
type="button"
aria-pressed={sidebarShown ? 'true' : 'false'}
id="menu-toggle"
onClick={() => setSidebarShown(!sidebarShown)}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
<span className="sr-only">Toggle sidebar</span>
</button>
);
};
export default MenuToggle;

View File

@ -0,0 +1,26 @@
---
type Props = {};
---
<a href="#article" class="sr-only focus:not-sr-only skiplink"><span>Skip to Content</span></a>
<style>
.skiplink,
.skiplink:focus,
.skiplink:focus-visible {
position: absolute;
padding: 0.25em;
font-size: larger;
top: 0;
left: 0;
right: 0;
z-index: 9;
display: block;
text-align: center;
background-color: var(--theme-text-accent);
color: var(--theme-bg);
border-radius: 0.25em;
outline: var(--theme-bg) solid 1px;
outline-offset: 0;
}
</style>

View File

@ -0,0 +1,119 @@
---
import { getLanguageFromURL } from '../../languages';
import { SIDEBAR } from '../../consts';
type Props = {
currentPage: string;
};
const { currentPage } = Astro.props;
const currentPageMatch = currentPage.endsWith('/')
? currentPage.slice(1, -1)
: currentPage.slice(1);
const langCode = getLanguageFromURL(currentPage);
const sidebar = SIDEBAR[langCode];
---
<nav aria-labelledby="grid-left">
<ul class="nav-groups">
{
Object.entries(sidebar).map(([header, children]) => (
<li>
<div class="nav-group">
<h2 class="nav-group-title">{header}</h2>
<ul>
{children.map((child) => {
const url = Astro.site?.pathname + child.link;
return (
<li class="nav-link">
<a href={url} aria-current={currentPageMatch === child.link ? 'page' : false}>
{child.text}
</a>
</li>
);
})}
</ul>
</div>
</li>
))
}
</ul>
</nav>
<script is:inline>
window.addEventListener('DOMContentLoaded', () => {
var target = document.querySelector('[aria-current="page"]');
if (target && target.offsetTop > window.innerHeight - 100) {
document.querySelector('.nav-groups').scrollTop = target.offsetTop;
}
});
</script>
<style>
nav {
width: 100%;
margin-right: 1rem;
}
.nav-groups {
height: 100%;
padding: 2rem 0;
overflow-x: visible;
overflow-y: auto;
max-height: 100vh;
}
.nav-groups > li + li {
margin-top: 2rem;
}
.nav-groups > :first-child {
padding-top: var(--doc-padding);
}
.nav-groups > :last-child {
padding-bottom: 2rem;
margin-bottom: var(--theme-navbar-height);
}
.nav-group-title {
font-size: 1rem;
font-weight: 700;
padding: 0.1rem 1rem;
text-transform: uppercase;
margin-bottom: 0.5rem;
}
.nav-link a {
font-size: 1rem;
margin: 1px;
padding: 0.3rem 1rem;
font: inherit;
color: inherit;
text-decoration: none;
display: block;
}
.nav-link a:hover,
.nav-link a:focus {
background-color: var(--theme-bg-hover);
}
.nav-link a[aria-current='page'] {
color: var(--theme-text-accent);
background-color: var(--theme-bg-accent);
font-weight: 600;
}
@media (min-width: 50em) {
.nav-groups {
padding: 0;
}
}
</style>
<style is:global>
:root.theme-dark .nav-link a[aria-current='page'] {
color: hsla(var(--color-base-white), 100%, 1);
}
</style>

View File

@ -0,0 +1,51 @@
---
import type { MarkdownHeading } from 'astro';
import MoreMenu from '../RightSidebar/MoreMenu.astro';
import TableOfContents from '../RightSidebar/TableOfContents';
type Props = {
title: string;
headings: MarkdownHeading[];
githubEditUrl: string;
};
const { title, headings, githubEditUrl } = Astro.props;
---
<article id="article" class="content">
<section class="main-section">
<h1 class="content-title" id="overview">{title}</h1>
<nav class="block sm:hidden">
<TableOfContents client:media="(max-width: 50em)" headings={headings} />
</nav>
<slot />
</section>
<nav class="block sm:hidden">
<MoreMenu editHref={githubEditUrl} />
</nav>
</article>
<style>
.content {
padding: 0;
max-width: 75ch;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.content > section {
margin-bottom: 4rem;
}
.block {
display: block;
}
@media (min-width: 50em) {
.sm\:hidden {
display: none;
}
}
</style>

View File

@ -0,0 +1,79 @@
---
import ThemeToggleButton from './ThemeToggleButton';
import { COMMUNITY_INVITE_URL } from '../../consts';
type Props = {
editHref: string;
};
const { editHref } = Astro.props;
const showMoreSection = Boolean(COMMUNITY_INVITE_URL);
---
{showMoreSection && <h2 class="heading">More</h2>}
<ul>
{
editHref && (
<li class={`header-link depth-2`}>
<a class="edit-on-github" href={editHref} target="_blank">
<svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="pen"
class="svg-inline--fa fa-pen fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
height="1em"
width="1em"
>
<path
fill="currentColor"
d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z"
/>
</svg>
<span>Edit this page</span>
</a>
</li>
)
}
{
COMMUNITY_INVITE_URL && (
<li class={`header-link depth-2`}>
<a href={COMMUNITY_INVITE_URL} target="_blank">
<svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="comment-alt"
class="svg-inline--fa fa-comment-alt fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
height="1em"
width="1em"
>
<path
fill="currentColor"
d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z"
/>
</svg>
<span>Join our community</span>
</a>
</li>
)
}
</ul>
<div style="margin: 2rem 0; text-align: center;">
<ThemeToggleButton client:visible />
</div>
<style>
.edit-on-github {
text-decoration: none;
font: inherit;
color: inherit;
font-size: 1rem;
}
</style>

View File

@ -0,0 +1,34 @@
---
import type { MarkdownHeading } from 'astro';
import TableOfContents from './TableOfContents';
import MoreMenu from './MoreMenu.astro';
type Props = {
headings: MarkdownHeading[];
githubEditUrl: string;
};
const { headings, githubEditUrl } = Astro.props;
---
<nav class="sidebar-nav" aria-labelledby="grid-right">
<div class="sidebar-nav-inner">
<TableOfContents client:media="(min-width: 50em)" headings={headings} />
<MoreMenu editHref={githubEditUrl} />
</div>
</nav>
<style>
.sidebar-nav {
width: 100%;
position: sticky;
top: 0;
}
.sidebar-nav-inner {
height: 100%;
padding: 0;
padding-top: var(--doc-padding);
overflow: auto;
}
</style>

View File

@ -0,0 +1,93 @@
import type { MarkdownHeading } from 'astro';
import type { FunctionalComponent } from 'preact';
import { unescape } from 'html-escaper';
import { useState, useEffect, useRef } from 'preact/hooks';
type ItemOffsets = {
id: string;
topOffset: number;
};
const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({
headings = [],
}) => {
const toc = useRef<HTMLUListElement>();
const onThisPageID = 'on-this-page-heading';
const itemOffsets = useRef<ItemOffsets[]>([]);
const [currentID, setCurrentID] = useState('overview');
useEffect(() => {
const getItemOffsets = () => {
const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)');
itemOffsets.current = Array.from(titles).map((title) => ({
id: title.id,
topOffset: title.getBoundingClientRect().top + window.scrollY,
}));
};
getItemOffsets();
window.addEventListener('resize', getItemOffsets);
return () => {
window.removeEventListener('resize', getItemOffsets);
};
}, []);
useEffect(() => {
if (!toc.current) return;
const setCurrent: IntersectionObserverCallback = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
const { id } = entry.target;
if (id === onThisPageID) continue;
setCurrentID(entry.target.id);
break;
}
}
};
const observerOptions: IntersectionObserverInit = {
// Negative top margin accounts for `scroll-margin`.
// Negative bottom margin means heading needs to be towards top of viewport to trigger intersection.
rootMargin: '-100px 0% -66%',
threshold: 1,
};
const headingsObserver = new IntersectionObserver(setCurrent, observerOptions);
// Observe all the headings in the main page content.
document.querySelectorAll('article :is(h1,h2,h3)').forEach((h) => headingsObserver.observe(h));
// Stop observing when the component is unmounted.
return () => headingsObserver.disconnect();
}, [toc.current]);
const onLinkClick = (e) => {
setCurrentID(e.target.getAttribute('href').replace('#', ''));
};
return (
<>
<h2 id={onThisPageID} className="heading">
On this page
</h2>
<ul ref={toc}>
{headings
.filter(({ depth }) => depth > 1 && depth < 4)
.map((heading) => (
<li
className={`header-link depth-${heading.depth} ${
currentID === heading.slug ? 'current-header-link' : ''
}`.trim()}
>
<a href={`#${heading.slug}`} onClick={onLinkClick}>
{unescape(heading.text)}
</a>
</li>
))}
</ul>
</>
);
};
export default TableOfContents;

View File

@ -0,0 +1,37 @@
.theme-toggle {
display: inline-flex;
align-items: center;
gap: 0.25em;
padding: 0.33em 0.67em;
border-radius: 99em;
background-color: var(--theme-code-inline-bg);
}
.theme-toggle > label:focus-within {
outline: 2px solid transparent;
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
}
.theme-toggle > label {
color: var(--theme-code-inline-text);
position: relative;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.5;
}
.theme-toggle .checked {
color: var(--theme-accent);
opacity: 1;
}
input[name='theme-toggle'] {
position: absolute;
opacity: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
}

View File

@ -0,0 +1,82 @@
import type { FunctionalComponent } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import './ThemeToggleButton.css';
const themes = ['light', 'dark'];
const icons = [
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
clipRule="evenodd"
/>
</svg>,
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="currentColor"
>
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
</svg>,
];
const ThemeToggle: FunctionalComponent = () => {
const [theme, setTheme] = useState(() => {
if (import.meta.env.SSR) {
return undefined;
}
if (typeof localStorage !== undefined && localStorage.getItem('theme')) {
return localStorage.getItem('theme');
}
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
});
useEffect(() => {
const root = document.documentElement;
if (theme === 'light') {
root.classList.remove('theme-dark');
} else {
root.classList.add('theme-dark');
}
}, [theme]);
return (
<div className="theme-toggle">
{themes.map((t, i) => {
const icon = icons[i];
const checked = t === theme;
return (
<label className={checked ? ' checked' : ''}>
{icon}
<input
type="radio"
name="theme-toggle"
checked={checked}
value={t}
title={`Use ${t} theme`}
aria-label={`Use ${t} theme`}
onChange={() => {
localStorage.setItem('theme', t);
setTheme(t);
}}
/>
</label>
);
})}
</div>
);
};
export default ThemeToggle;

View File

@ -0,0 +1,73 @@
---
import type { JSONSchema } from "@apidevtools/json-schema-ref-parser/dist/lib/types";
export interface Props {
name: string;
slug: string;
schema: JSONSchema;
parentSchema: JSONSchema;
}
const { name, slug, schema, parentSchema } = Astro.props;
const getTag = () => {
switch (schema.type) {
default:
return Fragment;
}
};
const Tag = getTag();
const displayType = schema.$ref?.split("/").at(-1) ?? schema.type;
const required =
parentSchema.required &&
Array.isArray(parentSchema.required) &&
parentSchema.required.includes(name);
---
<div class="wrapper">
<div class="header">
<h2 id={slug}>{name}</h2>
<div class="badges">
{required && <span class="required">Required</span>}
<span>Type: {displayType}</span>
</div>
</div>
<p>
{schema.description}
</p>
<Tag schema={schema} />
</div>
<style>
h2 {
margin-top: 0.5rem !important;
}
div.header {
display: flex;
flex-direction: column;
margin-bottom: 0.5rem;
}
div.wrapper {
margin: 2rem 0;
}
span {
background-color: var(--theme-bg-accent);
font-size: small;
padding: 0.3rem;
margin-right: 0.3rem;
border: solid 2px var(--theme-accent);
border-radius: 5rem;
}
span.required {
background-color: hsla(var(--color-yellow), var(--theme-accent-opacity));
border-color: hsla(var(--color-yellow), 1);
}
</style>

View File

@ -0,0 +1,12 @@
---
import type { JSONSchema } from "@apidevtools/json-schema-ref-parser/dist/lib/types";
export interface Props {
name: string;
parentSlug: string;
}
const { name, parentSlug } = Astro.props;
---
<a href={`/schemas/defs/${parentSlug}/${name}`}>View {name}</a>

59
docs/src/consts.ts Normal file
View File

@ -0,0 +1,59 @@
export const SITE = {
title: 'New Horizons',
description: 'Documentation on how to use the New Horizons planet creation tool for Outer Wilds.',
defaultLanguage: 'en-us',
} as const;
export const OPEN_GRAPH = {
image: {
src: 'https://nh.outerwildsmods.com/public/home_logo.webp',
alt:
'The New Horizons Logo'
}
};
export const KNOWN_LANGUAGES = {
English: 'en',
} as const;
export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES);
export const GITHUB_EDIT_URL = `https://github.com/Outer-Wilds-New-Horizons/new-horizons/tree/main/docs`;
export const COMMUNITY_INVITE_URL = `https://discord.gg/wusTQYbYTc`;
// See "Algolia" section of the README for more information.
export const ALGOLIA = {
indexName: 'XXXXXXXXXX',
appId: 'XXXXXXXXXX',
apiKey: 'XXXXXXXXXX',
};
export type Sidebar = Record<
(typeof KNOWN_LANGUAGE_CODES)[number],
Record<string, { text: string; link: string }[]>
>;
export const SIDEBAR: Sidebar = {
en: {
'Intro': [
{ text: 'Introduction', link: 'en/introduction' },
],
'Guides': [
{ text: 'Getting Started', link: 'en/getting-started' },
{ text: 'Creating An Addon', link: 'en/creating-addons' },
{ text: 'Updating Existing Planets', link: 'en/updating-planets' },
{ text: 'Creating New Planets', link: 'en/planet-generation' },
{ text: 'Detailing Planets', link: 'en/details' },
{ text: 'Custom Star Systems', link: 'en/star-systems' },
{ text: 'Adding Translations', link: 'en/translation' },
{ text: 'Understanding XML', link: 'en/xml' },
{ text: 'Ship Log', link: 'en/ship-log' },
{ text: 'Dialogue', link: 'en/dialogue' },
{ text: 'API', link: 'en/api' },
{ text: 'Extending Configs', link: 'en/extending-configs' },
{ text: 'Publishing Your Addon', link: 'en/publishing' },
],
"Schemas": [
{ text: "Celestial Body Schema", link: "schemas/body-schema" }
]
},
};

View File

@ -0,0 +1,20 @@
import { defineCollection, z } from 'astro:content';
import { SITE } from '../consts';
const docs = defineCollection({
schema: z.object({
title: z.string().default(SITE.title),
description: z.string().default(SITE.description),
lang: z.literal('en-us').default(SITE.defaultLanguage),
dir: z.union([z.literal('ltr'), z.literal('rtl')]).default('ltr'),
image: z
.object({
src: z.string(),
alt: z.string(),
})
.optional(),
ogLocale: z.string().optional(),
}),
});
export const collections = { docs };

View File

@ -1,6 +1,6 @@
---
Title: API
Sort_Priority: 20
title: API
description: A guide on using New Horizons' API
---
## How to use the API

View File

@ -1,10 +1,8 @@
---
Title: Creating An Addon
Sort_Priority: 85
title: Creating An Addon
description: A guide to creating addons for New Horizons
---
# Creating An Addon
Up until now, you've been using the sandbox feature of New Horizons (simply placing your files in the `xen.NewHorizons` folder).
While this is the easiest way to get started, you won't be able to publish your work like this. In this tutorial we will:
@ -15,7 +13,7 @@ While this is the easiest way to get started, you won't be able to publish your
## Making a GitHub Repository
To get started, we need a place to store our code. GitHub is one of the most popular websites to store source code, and it's also what the mod database uses to let people access our mod.
First you're going to want to [create a GitHub account](https://github.com/signup){ target="_blank" }, and then head to [this repository](https://github.com/xen-42/ow-new-horizons-config-template){ target="_blank" }.
First you're going to want to [create a GitHub account](https://github.com/signup), and then head to [this repository](https://github.com/xen-42/ow-new-horizons-config-template).
Now, click the green "Use This Template" button.
- Set the Name to your username followed by a dot (`.`), followed by your mod's name in PascalCase (no spaces, new words have capital letters). So for example if my username was "Test" and my mod's name was "Really Cool Addon", I would name the repo `Test.ReallyCoolAddon`.
@ -25,7 +23,7 @@ Now, click the green "Use This Template" button.
## Cloning the Repository
Now that we've created our GitHub repository (or "repo"), we need to clone (or download) it onto our computer.
To do this we recommend using the [GitHub Desktop App](https://desktop.github.com/){ target="_blank" }, as it's much easier to use than having to fight with the command line.
To do this we recommend using the [GitHub Desktop App](https://desktop.github.com/), as it's much easier to use than having to fight with the command line.
Once we open GitHub desktop we're going to log in, select File -> Options -> Accounts and sign in to your newly created GitHub account.
Now we're ready to clone the repo, select File -> Clone Repository. Your repository should appear in the list.
@ -52,12 +50,12 @@ To get started editing the files, simply click "Open in Visual Studio Code" in G
- You can leave `version`, `owmlVersion`, and `dependencies` alone
- NewHorizonsConfig.dll: This is the heart of your addon, make sure to never move or rename it.
- README.md: This file is displayed on the mod website when you go to a specific mod's page, you can delete the current contents.
- This file is a [markdown](https://www.markdowntutorial.com/){ target="_blank" } file, if you're not comfortable writing an entire README right now, just write a small description of your mod.
- This file is a [markdown](https://www.markdowntutorial.com/) file, if you're not comfortable writing an entire README right now, just write a small description of your mod.
### Committing The Changes
Now that we have our files set up, switch back to GitHub desktop, you'll notice that the files you've changed have appeared in a list on the left.
What GitHub Desktop does is keep track of changes you make to your files over time.
What GitHub Desktop does is keep track of changes you make to your files over time.
Then, once you're ready, you commit these changes to your repo by filling out the "Summary" field with a small description of your changes, and then pressing the blue button that says "commit to main".
Think of committing like taking a snapshot of your project at this moment in time. If you ever mess up your project, you can always revert to another commit to get back to a working version. It is highly recommended to commit often, there is no downside to committing too much.
@ -76,8 +74,14 @@ You should see your mod there with the downloads counter set as a dash and the v
Now when you click "Start Game" and load into the solar system, you should be able to notice that the quantum moon is gone entirely, this means that your addon and its configs were successfully loaded.
## Note About File Paths
Whenever something refers to the "relative path" of a file, it means relative to your mod's directory, this means you **must** include the `planets` folder in the path:
```json
"planets/assets/images/MyCoolImage.png"
```
## Going Forward
Now instead of using the New Horizons mod folder, you can use your own mod's folder instead.
**Next Up: [Planet Generation]({{ "Planet Generation"|route }})**

View File

@ -1,11 +1,9 @@
---
Title: Detailing
Sort_Priority: 80
title: Detailing
description: A guide to adding details to planets in New Horizons
---
# Details/Scatterer
For physical objects there are currently two ways of setting them up: specify an asset bundle and path to load a custom asset you created, or specify the path to the item you want to copy from the game in the scene hierarchy. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer){ target="_blank" } mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck. Some pointers:
For physical objects there are currently two ways of setting them up: specify an asset bundle and path to load a custom asset you created, or specify the path to the item you want to copy from the game in the scene hierarchy. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck. Some pointers:
- Use "Object Explorer" to search
- Generally you can find planets by writing their name with no spaces/punctuation followed by "_Body".
@ -22,20 +20,6 @@ The Prop Placer is a convenience tool that lets you manually place details from
1. This menu scrolls. If you do not see your mod, it may be further down the list.
3. The Prop Placer is now active! Unpause the game, and you can now place Nomai vases using "G"
### How to Save
1. In the Prop Placer Menu, you will see a greyed out button titled "Update your mod's configs".
2. Click the small button to the left of it.
3. Click "Update your mod's configs" to save!
!!! alert-danger "IMPORTANT"
Your updated configs will save *only* to your mod's build folder, eg "AppData\Roaming\OuterWildsModManager\OWML\Mods\you.yourModName"
!!! alert-warning "WARNING"
Dying in-game will cause you to lose all work since you last saved. Make sure to save often.
What's that? You want to place something other than just vases? Well I can't say I agree with your choices, but here's how you would do that.
### How to Select Props
1. Pause the game again. The prop placer menu should still be visible.
@ -56,13 +40,13 @@ What's that? You want to place something other than just vases? Well I can't say
## Asset Bundles
Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template){ target="_blank" }
Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template)
The template project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game.
If for whatever reason you want to set up a Unity project manually instead of using the template, follow these instructions:
1. Start up a Unity 2017 project (I use Unity 2017.4.40f1 (64-bit), so if you use something else I can't guarantee it will work). The DLC updated Outer Wilds to 2019.4.27 so that probably works, but I personally haven't tried it.
1. Start up a Unity 2019.4.39f1 project
2. In the "Assets" folder in Unity, create a new folder called "Editor". In it create a file called "CreateAssetBundle.cs" with the following code in it:
```cs
@ -87,10 +71,11 @@ public class CreateAssetBundles
3. Create your object in the Unity scene and save it as a prefab.
4. Add all files used (models, prefabs, textures, materials, etc.) to an asset bundle by selecting them and using the dropdown in the bottom right. Here I am adding a rover model to my "rss" asset bundle for the Real Solar System add-on.
![setting asset bundle]({{ 'images/detailing/asset_bundle.webp'|static }})
5. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets".
6. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double-check everything is included, open the .manifest file in a text editor to see the files included and their paths.
![setting asset bundle](/details/asset_bundle.webp)
1. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets".
2. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double-check everything is included, open the .manifest file in a text editor to see the files included and their paths.
## Importing a planet's surface from Unity

View File

@ -1,14 +1,11 @@
---
Title: Dialogue
Description: Guide to making dialogue in New Horizons
Sort_Priority: 30
title: Dialogue
description: Guide to making dialogue in New Horizons
---
# Dialogue
This page goes over how to use dialogue in New Horizons.
You may want to view [Understanding XML]({{ "Understanding XML"|route }}) if you haven't already.
You may want to view [Understanding XML](/en/xml) if you haven't already.
## Understanding Dialogue
@ -134,7 +131,7 @@ To use the dialogue XML you have created, you simply need to reference it in the
## Dialogue Config
To view the options for the dialogue prop, check [the schema]({{ "Celestial Body Schema"|route }}#Props_dialogue)
To view the options for the dialogue prop, check [the schema](/schemas/body-schema#Props_dialogue)
## Controlling Conditions
@ -151,7 +148,7 @@ You can set condition in dialogue with the `<SetCondition>` and `<SetPersistentC
## Dialogue Options
There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema]({{ "Dialogue Schema"|route }}#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info.
There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema](/schemas/dialogue-schema#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info.
## Controlling Flow
@ -163,4 +160,4 @@ Defining `<DialogueTarget>` in the `<DialogueNode>` tag instead of a `<DialogueO
### DialogueTargetShipLogCondition
Used in tandem with `DialogueTarget`, makes it so you must have a [ship log fact]({{ "Ship Log"|route }}#explore-facts) to go to the next node.
Used in tandem with `DialogueTarget`, makes it so you must have a [ship log fact](/en/ship-log#explore-facts) to go to the next node.

View File

@ -1,11 +1,8 @@
---
Title: Extending Configs
Description: A guide on extending config files with the New Horizons API
Sort_Priority: 5
title: Extending Configs
description: A guide on extending config files with the New Horizons API
---
# Extending Configs
This guide will explain how to use the API to add new features to New Horizons.
## How Extending Works

View File

@ -1,23 +1,21 @@
---
Title: Getting Started
Sort_Priority: 100
title: Getting Started
description: A guide for getting started with New Horizons
---
# Getting Started
Congrats on taking the first step to becoming an addon developer!
This tutorial will outline how to begin learning to use new horizons.
## Recommended Tools
It's strongly recommended you get [VSCode](https://code.visualstudio.com/){ target="_blank" } to edit your files, as it can provide syntax and error highlighting.
It's strongly recommended you get [VSCode](https://code.visualstudio.com/) to edit your files, as it can provide syntax and error highlighting.
## Using The Sandbox
Making an entirely separate addon can get a little complicated, so New Horizons provides a way to play around without the need to set up a full addon.
To get started, navigate to your mod manager and click the ⋮ symbol, then select "Show In Explorer".
![Select "Show in explorer"]({{ "images/getting_started/mod_manager_show_in_explorer.webp"|static }})
![Select "Show in explorer"](/getting_started/mod_manager_show_in_explorer.webp)
Now, create a new folder named "planets". As the name suggests, New Horizons will search the files in this folder for planets to generate.
@ -84,7 +82,7 @@ Objects can have multiple keys as well, as long as you separate them by commas:
}
```
But wait! why is `Jim` in quotation marks while `23` isn't? that's because of something called data types.
But wait! why is `Jim` in quotation marks while `23` isn't? that's because of something called data types.
Each value has a datatype, in this case `"Jim"` is a `string`, because it represents a *string* of characters.
Age is a `number`, it represents a numerical value. If we put 23 in quotation marks, its data type switches from a number to a string.
And if we remove the quotation marks from `"Jim"` we get a syntax error (a red underline). Datatypes are a common source of errors, which is why we recommend using an editor like VSCode.
@ -207,22 +205,22 @@ Alright so now that we understand how the file is structures, let's look into wh
- `name` simply sets the name of the planet
- `$schema` we'll get to in a second
- `starSystem` specifies what star system this planet is located in, in this case we're using the base game star system, so we put "SolarSystem"
- Then it has an object called `Base`
- Base has a `groundSize` of 100, this generates a perfect sphere that is 100 units in radius as the ground of our planet
- It also has a `surfaceSize` of 101, surface size is used in many calculations, it's generally good to set it to a bit bigger than ground size.
- `surfaceGravity` describes the strength of gravity on this planet, in this case it's 12 which is the same as Timber Hearth
- `hasMapMarker` tells new horizons that we want this planet to have a marker on the map screen
- Next it has another object called `Orbit`
- `semiMajorAxis` specifies the radius of the orbit (how far away the body is from its parent)
- `primaryBody` is set to TIMBER_HEARTH, this makes our planet orbit timber hearth
- `isMoon` simply tells the game how close you have to be to the planet in map mode before its name appears
- `isTidallyLocked` makes sure that one side of our planet is always facing timber hearth (the primary body)
- Finally, we have `Atmosphere`
- Its `size` is 150, this simply sets how far away from the planet our atmosphere stretches
- Its `fogTint` is set to a color which is an object with r, g, b, and a properties (properties is another word for keys)
- `fogSize` determines how far away the fog stretches from the planet
- `fogDensity` is simply how dense the fog is
- `hasRain` makes rainfall on the planet
- Then it has an object called `Base`
- Base has a `groundSize` of 100, this generates a perfect sphere that is 100 units in radius as the ground of our planet
- It also has a `surfaceSize` of 101, surface size is used in many calculations, it's generally good to set it to a bit bigger than ground size.
- `surfaceGravity` describes the strength of gravity on this planet, in this case it's 12 which is the same as Timber Hearth
- `hasMapMarker` tells new horizons that we want this planet to have a marker on the map screen
- Next it has another object called `Orbit`
- `semiMajorAxis` specifies the radius of the orbit (how far away the body is from its parent)
- `primaryBody` is set to TIMBER_HEARTH, this makes our planet orbit timber hearth
- `isMoon` simply tells the game how close you have to be to the planet in map mode before its name appears
- `isTidallyLocked` makes sure that one side of our planet is always facing timber hearth (the primary body)
- Finally, we have `Atmosphere`
- Its `size` is 150, this simply sets how far away from the planet our atmosphere stretches
- Its `fogTint` is set to a color which is an object with r, g, b, and a properties (properties is another word for keys)
- `fogSize` determines how far away the fog stretches from the planet
- `fogDensity` is simply how dense the fog is
- `hasRain` makes rainfall on the planet
### What's a Schema?
@ -242,7 +240,7 @@ If you run into issues please make sure:
- You placed the JSON file in a folder called `planets` in the New Horizons mod folder
- There are no red or yellow squiggly lines in your file
## Experiment!
## Experiment
With that, try tweaking some value like groundSize and semiMajorAxis, get a feel for how editing JSON works.
@ -255,5 +253,3 @@ You may also notice blue and yellow logs start appearing in your console, this i
## Modules
Base, Atmosphere, and Orbit are all modules, which define the different aspects of your planet, modules are represented by JSON objects
**Next Up: [Reading Schemas]({{ "Reading Schemas"|route }})**

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