diff --git a/.gitignore b/.gitignore index 68bc17f..48d8090 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,138 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + + + +# ! NODE JS = + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..22af2de --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,36 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + ".vscode": true, + "frontend/node_modules": true, + "lingosynth/app/static/css/main.css.map": true, + "lingosynth/app/static/css/main.css": true, + "lingosynth/app/static/css/input.css": true, + "lingosynth/app/static/css/input.css.map": true, + "lingosynth/app/__pycache__": true, + "lingosynth/__pycache__": true, + "lingosynth/app/static/css/utils.css.map": true, + "lingosynth/app/static/css/utils.css": true, + "lingosynth/app/static/css/landing.css.map": true, + "lingosynth/app/static/css/landing.css": true + }, + "hide-files.files": [ + ".vscode", + "frontend/node_modules", + "lingosynth/app/static/css/main.css.map", + "lingosynth/app/static/css/main.css", + "lingosynth/app/static/css/input.css", + "lingosynth/app/static/css/input.css.map", + "lingosynth/app/__pycache__", + "lingosynth/__pycache__", + "lingosynth/app/static/css/utils.css.map", + "lingosynth/app/static/css/utils.css", + "lingosynth/app/static/css/landing.css.map", + "lingosynth/app/static/css/landing.css" + ] +} \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..6241487 --- /dev/null +++ b/Pipfile @@ -0,0 +1,18 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +flask = "*" +flask-cors = "*" +python-dotenv = "*" +waitress = "*" +flask-limiter = "*" +authlib = "*" +requests = "*" + +[dev-packages] + +[requires] +python_version = "3.11" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..97f2e27 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,564 @@ +{ + "_meta": { + "hash": { + "sha256": "ae95db72f8d935c51fae1c8c400fb285a31973cc86ce2de1621babfb4a4257bd" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "authlib": { + "hashes": [ + "sha256:4ddf4fd6cfa75c9a460b361d4bd9dac71ffda0be879dbe4292a02e92349ad55a", + "sha256:4fa3e80883a5915ef9f5bc28630564bc4ed5b5af39812a3ff130ec76bd631e9d" + ], + "index": "pypi", + "version": "==1.2.0" + }, + "blinker": { + "hashes": [ + "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213", + "sha256:c3d739772abb7bc2860abf5f2ec284223d9ad5c76da018234f6f50d6f31ab1f0" + ], + "markers": "python_version >= '3.7'", + "version": "==1.6.2" + }, + "certifi": { + "hashes": [ + "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", + "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.5.7" + }, + "cffi": { + "hashes": [ + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" + }, + "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" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "platform_system == 'Windows'", + "version": "==0.4.6" + }, + "cryptography": { + "hashes": [ + "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440", + "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288", + "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b", + "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958", + "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b", + "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d", + "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a", + "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404", + "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b", + "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e", + "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2", + "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c", + "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b", + "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9", + "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b", + "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636", + "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99", + "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e", + "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9" + ], + "markers": "python_version >= '3.6'", + "version": "==40.0.2" + }, + "deprecated": { + "hashes": [ + "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d", + "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.2.13" + }, + "flask": { + "hashes": [ + "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0", + "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef" + ], + "index": "pypi", + "version": "==2.3.2" + }, + "flask-cors": { + "hashes": [ + "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438", + "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de" + ], + "index": "pypi", + "version": "==3.0.10" + }, + "flask-limiter": { + "hashes": [ + "sha256:2b99fec0cfc44f490bd729da52bb89c5c4158f38812d0f3854c01d0a83664923", + "sha256:3451fb8d84f50007753b799831c57c59c1eb3432cc9754cc4b7e41a88d8bdf51" + ], + "index": "pypi", + "version": "==3.3.1" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "importlib-resources": { + "hashes": [ + "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6", + "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a" + ], + "markers": "python_version >= '3.7'", + "version": "==5.12.0" + }, + "itsdangerous": { + "hashes": [ + "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", + "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.2" + }, + "jinja2": { + "hashes": [ + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.2" + }, + "limits": { + "hashes": [ + "sha256:919db5cdc00670b7a5bef992f0a00a5bdbe1bf5fc8ea840df8735ffde0e170b0", + "sha256:fc5e01a6a96b6f78b7e8a8f4610a93f3ebe3351a1bcd8cd93763a90fa52bc7fe" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.0" + }, + "markdown-it-py": { + "hashes": [ + "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30", + "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.2.0" + }, + "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" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "ordered-set": { + "hashes": [ + "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562", + "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8" + ], + "markers": "python_version >= '3.7'", + "version": "==4.1.0" + }, + "packaging": { + "hashes": [ + "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pygments": { + "hashes": [ + "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c", + "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.15.1" + }, + "python-dotenv": { + "hashes": [ + "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", + "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" + ], + "index": "pypi", + "version": "==1.0.0" + }, + "requests": { + "hashes": [ + "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294", + "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4" + ], + "index": "pypi", + "version": "==2.30.0" + }, + "rich": { + "hashes": [ + "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c", + "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==13.3.5" + }, + "setuptools": { + "hashes": [ + "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b", + "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990" + ], + "markers": "python_version >= '3.7'", + "version": "==67.7.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", + "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + ], + "markers": "python_version >= '3.7'", + "version": "==4.5.0" + }, + "urllib3": { + "hashes": [ + "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc", + "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.2" + }, + "waitress": { + "hashes": [ + "sha256:7500c9625927c8ec60f54377d590f67b30c8e70ef4b8894214ac6e4cad233d2a", + "sha256:780a4082c5fbc0fde6a2fcfe5e26e6efc1e8f425730863c04085769781f51eba" + ], + "index": "pypi", + "version": "==2.1.2" + }, + "werkzeug": { + "hashes": [ + "sha256:1d5a58e0377d1fe39d061a5de4469e414e78ccb1e1e59c0f5ad6fa1c36c52b76", + "sha256:48e5e61472fee0ddee27ebad085614ebedb7af41e88f687aaf881afb723a162f" + ], + "markers": "python_version >= '3.8'", + "version": "==2.3.4" + }, + "wrapt": { + "hashes": [ + "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0", + "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420", + "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a", + "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c", + "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079", + "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923", + "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f", + "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1", + "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8", + "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86", + "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0", + "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364", + "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e", + "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c", + "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e", + "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c", + "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727", + "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff", + "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e", + "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29", + "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7", + "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72", + "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475", + "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a", + "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317", + "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2", + "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd", + "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640", + "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98", + "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248", + "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e", + "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d", + "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec", + "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1", + "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e", + "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9", + "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92", + "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb", + "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094", + "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46", + "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29", + "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd", + "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705", + "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8", + "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975", + "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb", + "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e", + "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b", + "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418", + "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019", + "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1", + "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba", + "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6", + "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2", + "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3", + "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7", + "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752", + "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416", + "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f", + "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1", + "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc", + "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145", + "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee", + "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a", + "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7", + "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b", + "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653", + "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0", + "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90", + "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29", + "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6", + "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034", + "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09", + "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559", + "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.15.0" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index 6f28596..a22eb6d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # LingoSynth LingoSynth is a free AI rephrasing & facts checking tool. + +## Star History +[![Star History Chart](https://api.star-history.com/svg?repos=Luna-OSS/LingoSynth&type=Date)](https://star-history.com/#Luna-OSS/LingoSynth&Date) diff --git a/lingosynth/__main__.py b/lingosynth/__main__.py new file mode 100644 index 0000000..3856b3a --- /dev/null +++ b/lingosynth/__main__.py @@ -0,0 +1,9 @@ +import app + +app.app.run( + host='0.0.0.0', + port=5001, + debug=True, + use_evalex=False, + threaded=True, +) diff --git a/lingosynth/app/__init__.py b/lingosynth/app/__init__.py new file mode 100644 index 0000000..5e4ecdb --- /dev/null +++ b/lingosynth/app/__init__.py @@ -0,0 +1,29 @@ +"""Flask app for the backend of the project.""" + +import flask +import authlib +import flask_cors +import flask_limiter + +from . import api, views, other +from authlib.integrations.flask_client import OAuth + + +app = flask.Flask(__name__) +oauth = OAuth(app) + +limiter = flask_limiter.Limiter( + flask_limiter.util.get_remote_address, + app=app, + default_limits=['60 per minute', '2 per second'], + storage_uri='memory://', + strategy='fixed-window' +) + +flask_cors.CORS(app, resources={r'/api/*': {'origins': '*'}}) + +app.rate_limiter = limiter + +api.register(app) +views.register(app) +other.register(app) diff --git a/lingosynth/app/ai.py b/lingosynth/app/ai.py new file mode 100644 index 0000000..dc3dddb --- /dev/null +++ b/lingosynth/app/ai.py @@ -0,0 +1,27 @@ +import os +import openai + +from dotenv import load_dotenv + +import prompts + +load_dotenv() + +if os.getenv('OPENAI_API_BASE'): + openai.api_base = os.getenv('OPENAI_API_BASE') +openai.api_key = os.getenv('OPENAI_API_KEY') + +MODEL = os.getenv('OPENAI_CHAT_MODEL') or 'gpt-3.5-turbo' + +def generate(messages: str): + """Generates a new message based on the given messages.""" + + return openai.ChatCompletion.create( + model=MODEL, + messages=messages, + temperature=0.9 + ).choices[0].message.content + +if __name__ == '__main__': + print(prompts.MESSAGES) + # print(generate(prompts.MESSAGES)) diff --git a/lingosynth/app/api.py b/lingosynth/app/api.py new file mode 100644 index 0000000..07eeab8 --- /dev/null +++ b/lingosynth/app/api.py @@ -0,0 +1,17 @@ +import time +import flask + +def register(app: flask.Flask): + @app.route('/api/rephrase', methods=['GET', 'POST']) + @app.rate_limiter.limit('2 per second') + def api_rephrase(): + text = flask.request.args.get('text') or flask.request.json.get('text') + + time.sleep(3) + raise + + return flask.jsonify( + { + 'text': 'Done.' + } + ) diff --git a/lingosynth/app/other.py b/lingosynth/app/other.py new file mode 100644 index 0000000..f809d69 --- /dev/null +++ b/lingosynth/app/other.py @@ -0,0 +1,18 @@ +import os +import flask + +from dotenv import load_dotenv + +load_dotenv() + +def register(app: flask.Flask): + @app.errorhandler(400) + @app.errorhandler(403) + @app.errorhandler(404) + def error_handler(error): + return flask.render_template('error.html', error=error), error.code + + @app.context_processor + def inject_variables(): + return { + } diff --git a/lingosynth/app/prompts.py b/lingosynth/app/prompts.py new file mode 100644 index 0000000..7542e9d --- /dev/null +++ b/lingosynth/app/prompts.py @@ -0,0 +1,58 @@ +"""This file contains the prompts for the app. +The prompts are stored as a list of dictionaries, where each dictionary contains the role of the speaker and the content of the message. +The roles are "system", "user", and "assistant". The content is a string. +""" + +MESSAGES = [ + { + "role": "system", + "content": """Your task is to completely paraphrase text while still providing the same information and meaning. +Your main goal is to get a very high level of Perplexity and Burstiness (A document's perplexity is a measurement of the randomness of the text and A document's burstiness is a measurement of the variation in perplexity). + +You have to follow these rules: + +- The most important thing is to make your text sound like it was written by a human! +- You can and should switch some sentences around, and you can also add or remove paragraphs. +- Add or remove sentences as needed. +- Vary sentence length and structure, and try to not repeat words or phrases. +- Ensure that the text is not uniform. +- Use original, never-seen-before utterances that are improvised on the spot entirely themed on the talking point. +- Use strong choice words to express your raw and candid emotions. +- DO NOT talk in a monotonous manner, instead, sound more relaxed, casual, and a bit humorous. +- Don't use too many technical terms, instead, use more common words. +- Avoid the same structure, instead, write more freely. +- Talk naturally, just like a human would. +- Change the sentence structure and word choice to reflect the same meaning. +- The paraphrased text should be readable and make sense. +- Don't make it more complicated, instead focus on making it more unique. +- Moreover, it's also very important that you keep the style. If it's a poem, make sure it still sounds like one after paraphrasing it. +- Talk naturally. Don't use too many difficult terms, instead, use more common words. +- Write in a relaxed and casual manner. +- Make your text more random. Change words to more natural ones.""", + }, + { + "role": "user", + "content": """Gaining confidence and staying motivated can be challenging, especially when we face difficult situations or setbacks in our lives. However, with the right mindset and approach, you can build your confidence and motivation levels and achieve your goals. In this blog, I will share some tips and strategies that can help you boost your confidence and motivation. + + 1. Set Clear Goals: Setting clear and achievable goals is the first step towards building confidence and motivation. Write down your goals and make sure they are specific, measurable, and time-bound. Break them down into smaller milestones and track your progress regularly. Celebrate your accomplishments and learn from your mistakes. + + 2. Practice Self-Care: Taking care of yourself is essential for building confidence and motivation. Eat healthy foods, get enough sleep, exercise regularly, and make time for activities that you enjoy. Taking care of your physical and mental health will help you feel better about yourself and increase your motivation levels. + + 3. Build a Support System: Surround yourself with positive and supportive people who believe in you and your abilities. Seek out mentors, coaches, or friends who can provide guidance and encouragement when you need it. Join groups or communities that share your interests and values. + + 4. Learn New Skills: Learning new skills can help you gain confidence and motivation by expanding your knowledge and abilities. Take courses, read books, or attend workshops to improve your skills and knowledge. Look for opportunities to apply what you have learned in real-life situations. + + 5. Embrace Failure: Failure is a natural part of the learning process, and it can help you grow and become more resilient. Embrace failure as an opportunity to learn and grow, and don't let it define your worth or abilities. Remember that even the most successful people have failed many times before achieving their goals. + + 6. Challenge Negative Self-Talk: Negative self-talk can undermine your confidence and motivation. Challenge negative thoughts and replace them with positive ones. Practice self-affirmations, and remind yourself of your strengths and accomplishments. Focus on the progress you have made, rather than the setbacks you have faced. + + 7. Take Action: Finally, taking action is the key to building confidence and motivation. Set clear goals, develop a plan, and take small steps towards achieving them. Celebrate your progress along the way, and don't be afraid to ask for help when you need it. + + In conclusion, building confidence and staying motivated is a lifelong journey that requires consistent effort and practice. By setting clear goals, practicing self-care, building a support system, learning new skills, embracing failure, challenging negative self-talk, and taking action, you can increase your confidence and motivation levels and achieve your goals. Remember to be patient with yourself, and don't give up when faced with obstacles. With persistence and dedication, you can build the confidence and motivation you need to succeed.""", + }, + # { + # "role": "assistant", + # "content": """ + # """, + # }, +] \ No newline at end of file diff --git a/lingosynth/app/static/css/_vars.sass b/lingosynth/app/static/css/_vars.sass new file mode 100644 index 0000000..cc0d2cc --- /dev/null +++ b/lingosynth/app/static/css/_vars.sass @@ -0,0 +1,24 @@ +$red: #ed8796 +$maroon: #ee99a0 +$peach: #f5a97f +$yellow: #eed49f +$green: #a6da95 + +$accent: #268678 +$accent-bg: #1c6e63 +$accent-dead: #54867e + +$teal: #3f8a90 + +$text: #eaedf7 +$subtext1: #b8c0e0 +$subtext0: #a5adcb +$overlay2: #939ab7 +$overlay1: #8087a2 +$overlay0: #6e738d +$surface2: #5b6078 +$surface1: #494d64 +$surface0: #363a4f +$base: #24273a +$mantle: #1e2030 +$crust: #181926 \ No newline at end of file diff --git a/lingosynth/app/static/css/input.css b/lingosynth/app/static/css/input.css new file mode 100644 index 0000000..e8e11cb --- /dev/null +++ b/lingosynth/app/static/css/input.css @@ -0,0 +1,89 @@ +@keyframes rotate-gradient { + from { + transform: rotate(0deg) scale(2); + } + to { + transform: rotate(360deg) scale(2); + } +} +@keyframes pulsing { + 0% { + background: #54867e; + } + 100% { + background: #268678; + } +} +@keyframes rotate { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +div.input-wrapper { + position: relative; + overflow: hidden; + background: #363a4f; + padding: 2px 3px; + border-radius: 0.5rem; +} +div.input-wrapper.loading { + cursor: wait !important; + position: relative; + animation: pulsing 1s ease-in-out infinite alternate; +} +div.input-wrapper.loading * { + pointer-events: none; +} +div.input-wrapper.loading::before { + content: ""; + display: block; + z-index: -1; + position: absolute; + top: 1rem; + left: 1rem; + right: 1rem; + bottom: 1rem; + background-image: conic-gradient(from 0deg, #268678, #eed49f, #268678); + animation: rotate-gradient 1s linear infinite; +} + +textarea { + width: 100%; + height: 300px; + font-size: 1.5rem; + padding: 1rem; + border-radius: 0.5rem; + background: #363a4f; + color: #eaedf7; + resize: none; + outline: none; + transition: border 0.1s ease-in-out; + min-height: 300px; + box-shadow: 0 0 40px 0 #181926; +} + +button { + margin-top: 1rem; + padding: 0.8rem 1.5rem; + border-radius: 0.5rem; + background: #1c6e63; + font-size: 18px; + cursor: pointer; + transition: background 0.1s ease-in-out; + color: #eaedf7; +} +button:hover { + background: #268678; +} +button.loading { + cursor: wait; + animation: pulsing 1s ease-in-out infinite alternate; +} + +i.ti.ti-loader-2 { + display: inline-block; + animation: rotate 1s linear infinite; +}/*# sourceMappingURL=input.css.map */ \ No newline at end of file diff --git a/lingosynth/app/static/css/input.css.map b/lingosynth/app/static/css/input.css.map new file mode 100644 index 0000000..ec1486a --- /dev/null +++ b/lingosynth/app/static/css/input.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["input.sass","_vars.sass"],"names":[],"mappings":"AAEA;EACI;IACI;;EACJ;IACI;;;AAGR;EACI;IACI,YCHM;;EDKV;IACI,YCRC;;;ADUT;EACI;IACI;;EAEJ;IACI;;;AAER;EACI;EACA;EACA,YCNO;EDOP;EACA;;AAEA;EACI;EACA;EAKA;;AAHA;EACI;;AAIJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAEZ;EACI;EACA;EACA;EACA;EACA;EACA,YCtCO;EDuCP,OC/CG;EDgDH;EACA;EACA;EAEA;EAEA;;;AAEJ;EACI;EACA;EACA;EACA,YCjEQ;EDkER;EACA;EACA;EAEA,OCjEG;;ADmEH;EACI,YC1EC;;AD4EL;EACI;EACA;;;AAGR;EACI;EACA","sourcesContent":["@import '_vars'\r\n\r\n@keyframes rotate-gradient\r\n from\r\n transform: rotate(0deg) scale(2)\r\n to\r\n transform: rotate(360deg) scale(2)\r\n\r\n\r\n@keyframes pulsing\r\n 0%\r\n background: $accent-dead\r\n \r\n 100%\r\n background: $accent\r\n\r\n@keyframes rotate\r\n 0%\r\n transform: rotate(0deg)\r\n \r\n 100%\r\n transform: rotate(360deg)\r\n\r\ndiv.input-wrapper\r\n position: relative\r\n overflow: hidden\r\n background: $surface0\r\n padding: 2px 3px\r\n border-radius: 0.5rem\r\n\r\n &.loading\r\n cursor: wait !important\r\n position: relative\r\n\r\n *\r\n pointer-events: none\r\n\r\n animation: pulsing 1s ease-in-out infinite alternate\r\n\r\n &::before\r\n content: ''\r\n display: block\r\n z-index: -1\r\n position: absolute\r\n top: 1rem\r\n left: 1rem\r\n right: 1rem\r\n bottom: 1rem\r\n\r\n background-image: conic-gradient(from 0deg, $accent, $yellow, $accent)\r\n animation: rotate-gradient 1s linear infinite\r\n\r\ntextarea\r\n width: 100%\r\n height: 300px\r\n font-size: 1.5rem\r\n padding: 1rem\r\n border-radius: 0.5rem\r\n background: $surface0\r\n color: $text\r\n resize: none\r\n outline: none\r\n transition: border 0.1s ease-in-out\r\n\r\n min-height: 300px\r\n\r\n box-shadow: 0 0 40px 0 $crust\r\n\r\nbutton\r\n margin-top: 1rem\r\n padding: 0.8rem 1.5rem\r\n border-radius: 0.5rem\r\n background: $accent-bg\r\n font-size: 18px\r\n cursor: pointer\r\n transition: background 0.1s ease-in-out\r\n\r\n color: $text\r\n\r\n &:hover\r\n background: $accent\r\n\r\n &.loading\r\n cursor: wait\r\n animation: pulsing 1s ease-in-out infinite alternate\r\n // pointer-events: none\r\n\r\ni.ti.ti-loader-2\r\n display: inline-block\r\n animation: rotate 1s linear infinite\r\n","$red: #ed8796\r\n$maroon: #ee99a0\r\n$peach: #f5a97f\r\n$yellow: #eed49f\r\n$green: #a6da95\r\n\r\n$accent: #268678\r\n$accent-bg: #1c6e63\r\n$accent-dead: #54867e\r\n\r\n$teal: #3f8a90\r\n\r\n$text: #eaedf7\r\n$subtext1: #b8c0e0\r\n$subtext0: #a5adcb\r\n$overlay2: #939ab7\r\n$overlay1: #8087a2\r\n$overlay0: #6e738d\r\n$surface2: #5b6078\r\n$surface1: #494d64\r\n$surface0: #363a4f\r\n$base: #24273a\r\n$mantle: #1e2030\r\n$crust: #181926"]} \ No newline at end of file diff --git a/lingosynth/app/static/css/input.sass b/lingosynth/app/static/css/input.sass new file mode 100644 index 0000000..b9e6ab3 --- /dev/null +++ b/lingosynth/app/static/css/input.sass @@ -0,0 +1,90 @@ +@import '_vars' + +@keyframes rotate-gradient + from + transform: rotate(0deg) scale(2) + to + transform: rotate(360deg) scale(2) + + +@keyframes pulsing + 0% + background: $accent-dead + + 100% + background: $accent + +@keyframes rotate + 0% + transform: rotate(0deg) + + 100% + transform: rotate(360deg) + +div.input-wrapper + position: relative + overflow: hidden + background: $surface0 + padding: 2px 3px + border-radius: 0.5rem + + &.loading + cursor: wait !important + position: relative + + * + pointer-events: none + + animation: pulsing 1s ease-in-out infinite alternate + + &::before + content: '' + display: block + z-index: -1 + position: absolute + top: 1rem + left: 1rem + right: 1rem + bottom: 1rem + + background-image: conic-gradient(from 0deg, $accent, $yellow, $accent) + animation: rotate-gradient 1s linear infinite + +textarea + width: 100% + height: 300px + font-size: 1.5rem + padding: 1rem + border-radius: 0.5rem + background: $surface0 + color: $text + resize: none + outline: none + transition: border 0.1s ease-in-out + + min-height: 300px + + box-shadow: 0 0 40px 0 $crust + +button + margin-top: 1rem + padding: 0.8rem 1.5rem + border-radius: 0.5rem + background: $accent-bg + font-size: 18px + cursor: pointer + transition: background 0.1s ease-in-out + + color: $text + + &:hover + background: $accent + + &.loading + cursor: wait + animation: pulsing 1s ease-in-out infinite alternate + // pointer-events: none + +i.ti.ti-loader-2 + display: inline-block + animation: rotate 1s linear infinite diff --git a/lingosynth/app/static/css/landing.css b/lingosynth/app/static/css/landing.css new file mode 100644 index 0000000..7685d27 --- /dev/null +++ b/lingosynth/app/static/css/landing.css @@ -0,0 +1,17 @@ +header { + margin-block: 3rem 6rem; + text-align: center; +} +header h1 { + font-size: 46px; +} +header p { + max-width: 600px; + margin: 0 auto; +} + +.gradient-text { + background: -webkit-linear-gradient(45deg, #a6da95, #3f8a90); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +}/*# sourceMappingURL=landing.css.map */ \ No newline at end of file diff --git a/lingosynth/app/static/css/landing.css.map b/lingosynth/app/static/css/landing.css.map new file mode 100644 index 0000000..6d4c256 --- /dev/null +++ b/lingosynth/app/static/css/landing.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["landing.sass"],"names":[],"mappings":"AAEA;EACI;EACA;;AAEA;EACI;;AAEJ;EACI;EACA;;;AAER;EACI;EACA;EACA","sourcesContent":["@import '_vars'\r\n\r\nheader\r\n margin-block: 3rem 6rem\r\n text-align: center\r\n\r\n h1\r\n font-size: 46px\r\n\r\n p\r\n max-width: 600px\r\n margin: 0 auto\r\n\r\n.gradient-text\r\n background: -webkit-linear-gradient(45deg, $green, $teal)\r\n -webkit-background-clip: text\r\n -webkit-text-fill-color: transparent\r\n"]} \ No newline at end of file diff --git a/lingosynth/app/static/css/landing.sass b/lingosynth/app/static/css/landing.sass new file mode 100644 index 0000000..e1b371a --- /dev/null +++ b/lingosynth/app/static/css/landing.sass @@ -0,0 +1,17 @@ +@import '_vars' + +header + margin-block: 3rem 6rem + text-align: center + + h1 + font-size: 46px + + p + max-width: 600px + margin: 0 auto + +.gradient-text + background: -webkit-linear-gradient(45deg, $green, $teal) + -webkit-background-clip: text + -webkit-text-fill-color: transparent diff --git a/lingosynth/app/static/css/main.css b/lingosynth/app/static/css/main.css new file mode 100644 index 0000000..013a08e --- /dev/null +++ b/lingosynth/app/static/css/main.css @@ -0,0 +1,35 @@ +html { + scroll-behavior: smooth; +} + +body { + margin: 1rem; + background-color: #24273a; +} + +* { + color: #eaedf7; + border: none; + outline: none; + box-sizing: border-box; + font-family: "Inter", sans-serif; +} + +nav, header, main, footer { + max-width: 800px; + margin: 0 auto; +} + +nav a { + opacity: 0.8; + text-decoration: none; + margin-right: 1rem; +} +nav a:hover { + opacity: 1; +} + +footer { + margin-top: 2rem; + opacity: 0.5; +}/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/lingosynth/app/static/css/main.css.map b/lingosynth/app/static/css/main.css.map new file mode 100644 index 0000000..fff3cf2 --- /dev/null +++ b/lingosynth/app/static/css/main.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["main.sass","_vars.sass"],"names":[],"mappings":"AAEA;EACI;;;AAEJ;EACI;EACA,kBCcG;;;ADZP;EACI,OCEG;EDDH;EACA;EACA;EACA;;;AAEJ;EACI;EACA;;;AAGA;EACI;EACA;EACA;;AAEA;EACI;;;AAEZ;EACI;EACA","sourcesContent":["@import '_vars'\r\n\r\nhtml\r\n scroll-behavior: smooth\r\n\r\nbody\r\n margin: 1rem\r\n background-color: $base\r\n\r\n*\r\n color: $text\r\n border: none\r\n outline: none\r\n box-sizing: border-box\r\n font-family: 'Inter', sans-serif\r\n\r\nnav, header, main, footer\r\n max-width: 800px\r\n margin: 0 auto\r\n\r\nnav\r\n a\r\n opacity: 0.8\r\n text-decoration: none\r\n margin-right: 1rem\r\n\r\n &:hover\r\n opacity: 1\r\n\r\nfooter\r\n margin-top: 2rem\r\n opacity: 0.5\r\n","$red: #ed8796\r\n$maroon: #ee99a0\r\n$peach: #f5a97f\r\n$yellow: #eed49f\r\n$green: #a6da95\r\n\r\n$accent: #268678\r\n$accent-bg: #1c6e63\r\n$accent-dead: #54867e\r\n\r\n$teal: #3f8a90\r\n\r\n$text: #eaedf7\r\n$subtext1: #b8c0e0\r\n$subtext0: #a5adcb\r\n$overlay2: #939ab7\r\n$overlay1: #8087a2\r\n$overlay0: #6e738d\r\n$surface2: #5b6078\r\n$surface1: #494d64\r\n$surface0: #363a4f\r\n$base: #24273a\r\n$mantle: #1e2030\r\n$crust: #181926"]} \ No newline at end of file diff --git a/lingosynth/app/static/css/main.sass b/lingosynth/app/static/css/main.sass new file mode 100644 index 0000000..f5c2f99 --- /dev/null +++ b/lingosynth/app/static/css/main.sass @@ -0,0 +1,32 @@ +@import '_vars' + +html + scroll-behavior: smooth + +body + margin: 1rem + background-color: $base + +* + color: $text + border: none + outline: none + box-sizing: border-box + font-family: 'Inter', sans-serif + +nav, header, main, footer + max-width: 800px + margin: 0 auto + +nav + a + opacity: 0.8 + text-decoration: none + margin-right: 1rem + + &:hover + opacity: 1 + +footer + margin-top: 2rem + opacity: 0.5 diff --git a/lingosynth/app/static/css/utils.css b/lingosynth/app/static/css/utils.css new file mode 100644 index 0000000..63f3864 --- /dev/null +++ b/lingosynth/app/static/css/utils.css @@ -0,0 +1,14 @@ +div.alert { + margin-block: 1rem; + padding: 1rem; + border-radius: 0.5rem; + border-left: 0.5rem solid #268678; + background: #494d64; + transition: opacity 0.5s ease-in-out; +} +div.alert.effect { + opacity: 0; +} +div.alert.error { + border-left-color: #ed8796; +}/*# sourceMappingURL=utils.css.map */ \ No newline at end of file diff --git a/lingosynth/app/static/css/utils.css.map b/lingosynth/app/static/css/utils.css.map new file mode 100644 index 0000000..9da14a6 --- /dev/null +++ b/lingosynth/app/static/css/utils.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["utils.sass","_vars.sass"],"names":[],"mappings":"AAEA;EACI;EACA;EACA;EACA;EACA,YCYO;EDXP;;AAEA;EACI;;AAEJ;EACI,mBCdF","sourcesContent":["@import '_vars'\r\n\r\ndiv.alert\r\n margin-block: 1rem\r\n padding: 1rem\r\n border-radius: 0.5rem\r\n border-left: 0.5rem solid $accent\r\n background: $surface1\r\n transition: opacity 0.5s ease-in-out\r\n\r\n &.effect\r\n opacity: 0\r\n\r\n &.error\r\n border-left-color: $red\r\n","$red: #ed8796\r\n$maroon: #ee99a0\r\n$peach: #f5a97f\r\n$yellow: #eed49f\r\n$green: #a6da95\r\n\r\n$accent: #268678\r\n$accent-bg: #1c6e63\r\n$accent-dead: #54867e\r\n\r\n$teal: #3f8a90\r\n\r\n$text: #eaedf7\r\n$subtext1: #b8c0e0\r\n$subtext0: #a5adcb\r\n$overlay2: #939ab7\r\n$overlay1: #8087a2\r\n$overlay0: #6e738d\r\n$surface2: #5b6078\r\n$surface1: #494d64\r\n$surface0: #363a4f\r\n$base: #24273a\r\n$mantle: #1e2030\r\n$crust: #181926"]} \ No newline at end of file diff --git a/lingosynth/app/static/css/utils.sass b/lingosynth/app/static/css/utils.sass new file mode 100644 index 0000000..10abd8c --- /dev/null +++ b/lingosynth/app/static/css/utils.sass @@ -0,0 +1,15 @@ +@import '_vars' + +div.alert + margin-block: 1rem + padding: 1rem + border-radius: 0.5rem + border-left: 0.5rem solid $accent + background: $surface1 + transition: opacity 0.5s ease-in-out + + &.effect + opacity: 0 + + &.error + border-left-color: $red diff --git a/lingosynth/app/static/js/index.js b/lingosynth/app/static/js/index.js new file mode 100644 index 0000000..f5c5765 --- /dev/null +++ b/lingosynth/app/static/js/index.js @@ -0,0 +1,49 @@ +function stopRephrasing() { + rephraseButton.classList.remove('loading'); + textWrapper.classList.remove('loading'); + rephraseIcon.className = 'ti ti-language'; +} + +function rephrase() { + if (textBox.classList.contains('loading')) { + return; + } + + rephraseButton.classList.add('loading'); + textWrapper.classList.add('loading'); + rephraseIcon.className = 'ti ti-loader-2'; + + const data = { + text: textBox.value + }; + + fetch('/api/rephrase', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'User-Agent': navigator.userAgent + }, + body: JSON.stringify(data), + }) + .then(response => response.json()) + .then(data => { + textBox.value = data.text; + stopRephrasing(); + }) + .catch((error) => { + stopRephrasing(); + console.error('Error:', error); + + const errorDiv = document.createElement('div'); + errorDiv.className = 'error alert'; + errorDiv.innerText = 'An error occurred. Please try again later.'; + popups.appendChild(errorDiv); + + }); +}; + +document.addEventListener('keydown', function(event) { + if (event.ctrlKey && event.keyCode === 13) { + rephrase(); + } +}); diff --git a/lingosynth/app/templates/components/base.html b/lingosynth/app/templates/components/base.html new file mode 100644 index 0000000..cd8c6d9 --- /dev/null +++ b/lingosynth/app/templates/components/base.html @@ -0,0 +1,38 @@ + + +
+ + + + + {%- for sheet in 'main input utils landing'.split() %} + + {%- endfor %} + + + +{{ error }}
+{% endblock %} diff --git a/lingosynth/app/templates/index.html b/lingosynth/app/templates/index.html new file mode 100644 index 0000000..c041819 --- /dev/null +++ b/lingosynth/app/templates/index.html @@ -0,0 +1,50 @@ +{% extends "components/base.html" %} + +{% block header %} ++ Stop worrying about plagiarism and start focusing on your productivity now with LingoSynth. + It's free and works without an account! +
+ + + +No account required.
+ + + + +