├── __pycache__ ├── db.cpython-38.pyc ├── models.cpython-38.pyc └── ratelimit.cpython-38.pyc ├── clone.sh ├── storage.py ├── README.md ├── pyproject.toml ├── templates ├── index.html ├── home.html └── base.html ├── static ├── auth.js ├── main.css └── feed.js ├── main.py └── poetry.lock /__pycache__/db.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/replit/example-repltweet/master/__pycache__/db.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/models.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/replit/example-repltweet/master/__pycache__/models.cpython-38.pyc -------------------------------------------------------------------------------- /clone.sh: -------------------------------------------------------------------------------- 1 | rm -rf replit-py 2 | git clone --single-branch https://github.com/replit/replit-py.git --branch make-audio-lint 3 | -------------------------------------------------------------------------------- /__pycache__/ratelimit.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/replit/example-repltweet/master/__pycache__/ratelimit.cpython-38.pyc -------------------------------------------------------------------------------- /storage.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | class UserData: 4 | def __init__(self, username): 5 | self.username = None 6 | self.data = {} 7 | 8 | def save(self): 9 | db[self.username] = json.dumps(self.data) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReplTweet: An Example Application 2 | 3 | **Using the `[replit.web](https://github.com/replit/replit-py)` Python module.** 4 | 5 | --------------------------------------- 6 | 7 | This repository exists as an example integration of some of the components provided by the `replit.web` Python library. 8 | 9 | Enjoy! -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "unlinedfunctionalsolidstatedrive" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Your Name "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.8" 9 | flask = "^1.1.2" 10 | werkzeug = "^1.0.1" 11 | marshmallow = "^3.7.1" 12 | aiohttp = "^3.6.2" 13 | typing-extensions = "^3.7.4" 14 | replitdev = "^2.5.22" 15 | 16 | [tool.poetry.dev-dependencies] 17 | 18 | [build-system] 19 | requires = ["poetry>=0.12"] 20 | build-backend = "poetry.masonry.api" 21 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block main %} 4 |

ReplTweet

5 | A twitter clone written with the Replit maqpy framework. 6 | View the source 7 |

8 |
9 |
13 | 14 | {% endblock %} 15 | {% block js %} 16 | 17 | {% endblock %} -------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}ReplTweet - Feed{% endblock %} 3 | {% block css %} 4 | 5 | {% endblock %} 6 | {% block main %} 7 |
Signed in as {{ name }}
8 |
9 | 10 | 11 |
12 |
13 | Feed 14 | 17 |
18 |
19 | {% endblock %} 20 | {% block js %} 21 | 24 | 25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /static/auth.js: -------------------------------------------------------------------------------- 1 | /* Repl auth js, adapted from https://auth.turbio.repl.co/script.js */ 2 | // the server should force https, but check just in case 3 | if (location.protocol !== 'https:') { 4 | //alert("Repl auth requires HTTPS, please check the url") 5 | location.protocol = 'https:' 6 | } 7 | 8 | var button = document.getElementById('login') 9 | if (button) { 10 | button.onclick = function() { 11 | window.addEventListener('message', authComplete); 12 | 13 | var h = 500; 14 | var w = 350; 15 | var left = (screen.width / 2) - ( w / 2); 16 | var top = (screen.height / 2) - (h / 2); 17 | 18 | var authWindow = window.open( 19 | 'https://repl.it/auth_with_repl_site?domain='+location.host, 20 | '_blank', 21 | 'modal =yes, toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left) 22 | 23 | function authComplete(e) { 24 | if (e.data !== 'auth_complete') return; 25 | window.removeEventListener('message', authComplete); 26 | authWindow.close(); 27 | location.href = '/home'; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block head %} 5 | {% block title %}ReplTweet{% endblock %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% endblock %} 18 | {% block css %}{% endblock %} 19 | 20 | 21 | {% block body %} 22 | {% if back_location %} 23 | 30 | {% endif %} 31 |
32 |
33 | {% block main %}There's nothing here yet.{% endblock %} 34 |
35 |
36 | {% block js %}{% endblock %} 37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /static/main.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://repl.it/@mat1/webconnect#static/main.css */ 2 | .verticalAlign { 3 | display: grid; 4 | height: 100%; 5 | align-items: center 6 | } 7 | .bigButton { 8 | display: block; 9 | border-radius: .2em; 10 | border: .1em solid #ccc; 11 | max-width: max-content; 12 | padding: .5em; 13 | margin: .5em; 14 | font-size: 1.5em; 15 | color: #ccc; 16 | cursor: pointer; 17 | transition-duration: 200ms; 18 | text-decoration: none!important 19 | } 20 | .horizontalCenterList { 21 | display: flex; 22 | justify-content: center 23 | } 24 | .centerText { 25 | text-align: center; 26 | width: 100%; 27 | display: inline-block; 28 | } 29 | 30 | /* Loading symbol */ 31 | .spinner { 32 | display: inline-block; 33 | } 34 | .spinner-med { 35 | width: 80px; 36 | height: 80px; 37 | } 38 | .spinner-sm { 39 | width: 25px; 40 | height: 25px; 41 | } 42 | .spinner:after { 43 | content: " "; 44 | display: block; 45 | /*margin: 8px;*/ 46 | border-radius: 50%; 47 | border-style: solid; 48 | border-color: #fff transparent #fff transparent; 49 | animation: spinner 1.2s linear infinite; 50 | } 51 | .spinner-med:after { 52 | width: 64px; 53 | height: 64px; 54 | border-width: 6px; 55 | } 56 | .spinner-sm:after { 57 | width: 20px; 58 | height: 20px; 59 | border-width: 3px; 60 | } 61 | @keyframes spinner { 62 | 0% { 63 | transform: rotate(0deg); 64 | } 65 | 100% { 66 | transform: rotate(360deg); 67 | } 68 | } 69 | .tweet-name { 70 | margin-right: 5px; 71 | } 72 | .like .trash { 73 | padding-left: 10px; 74 | padding-right: 10px; 75 | font-size: 20px; 76 | } 77 | .like { 78 | color: red; 79 | } 80 | .trash { 81 | color: grey; 82 | } 83 | .feed-header { 84 | font-weight: 600; 85 | margin-bottom: 12px; 86 | font-size: 1.17em; 87 | padding: 10px; 88 | } 89 | #refresh-btn { 90 | padding-left: 10px; 91 | padding-right: 10px; 92 | } 93 | #refresh-icon { 94 | font-size: 15px; 95 | } 96 | .likes-label { 97 | margin: 5px; 98 | } 99 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # , __ ___ , __ _ ______ 2 | # /|/ \ / (_)/|/ \\_|_) (_) | 3 | # |___/ \__ |___/ | | _ _ _|_ 4 | # | \ / | _| _ || | |_|/ |/ | 5 | # | \_/\___/ | (/\___/(_/ \/ \/ |__/|__/|_/ 6 | 7 | import json 8 | import time 9 | 10 | from replitdev import db, web 11 | from flask import request 12 | 13 | # -- Static Variables. 14 | ZERO_WIDTH_SPACE = chr(0x200B) # for detecting blank tweets. 15 | REPLTWEET_MODS = ["Scoder12", "amasad", "AllAwesome497", "kennethreitz42"] 16 | 17 | # -- Create & configure Flask application. 18 | app = web.App(__name__) 19 | app.static_url_path = "/static" 20 | # auth = web.auth # shorthand 21 | 22 | 23 | def is_mod(): 24 | return web.whoami() in REPLTWEET_MODS 25 | 26 | # Use a single ratelimit bucket for all API endpoints 27 | ratelimit = web.authed_ratelimit( 28 | max_requests=1, 29 | period=1, 30 | login_res=json.dumps({"error": "Not signed in"}), 31 | get_ratelimited_res=( 32 | lambda time_left: json.dumps( 33 | {"error": f"Wait {time_left:.2f} sec before trying again."} 34 | ) 35 | ), 36 | ) 37 | 38 | 39 | # Landing page, only for signed out users 40 | @app.route("/") 41 | def index(): 42 | if request.user_info.is_authenticated: 43 | return web.local_redirect("/home") 44 | return web.render_template("index.html") 45 | 46 | 47 | # Home page, only for signed in users 48 | @app.route("/home") 49 | @web.needs_sign_in(login_res=web.local_redirect("/")) 50 | def home(): 51 | return web.render_template("home.html", name=web.whoami(), mod=is_mod()) 52 | 53 | 54 | @app.route("/api/tweet", methods=["POST"]) 55 | @ratelimit 56 | @web.needs_params("body") 57 | def api_tweet(body): 58 | # Don't allow blank tweets using zero width spaces 59 | body = body.replace(ZERO_WIDTH_SPACE, str()).strip() 60 | if not len(body): 61 | return {"error": "Cannot submit a blank tweet"}, 400 62 | 63 | current = db.get(web.whoami(), {}) 64 | newtweet = dict(body=body, ts=int(time.time()), likes=[]) 65 | new = {**current, "tweets": current.get("tweets", []) + [newtweet]} 66 | db[web.whoami()] = new 67 | 68 | print(new) 69 | return {"success": True} 70 | 71 | 72 | @app.route("/api/feed") 73 | @ratelimit 74 | def feed(): 75 | # The username is only stored as the key name, but the client doesn't know the key name so add an author field to each tweet 76 | tweets = [ 77 | {**tweet, "author": username} 78 | for username in db.keys() 79 | for tweet in db.get(username, {}).get("tweets", []) 80 | ] 81 | # Sort by time, newest first 82 | tweets = sorted(tweets, key=(lambda t: t.get("ts", 0)), reverse=True) 83 | return {"tweets": tweets} 84 | 85 | 86 | def find_matching(a, ts): 87 | ind, t = web.find(enumerate(a.get("tweets", [])), lambda t: t[1]["ts"] == ts) 88 | return ind 89 | 90 | 91 | @app.route("/api/like", methods=["POST"]) 92 | @web.needs_params("author", "ts", "action") 93 | @ratelimit 94 | def like(author, ts, action): 95 | 96 | current_user = web.whoami() 97 | 98 | # validate arguments 99 | if not ts.isdigit(): 100 | return {"error": "Bad ts"}, 400 101 | ts = int(ts) 102 | if action not in ["like", "unlike"]: 103 | return {"error": "Invalid action"}, 400 104 | 105 | # find matching tweet. 106 | author_data = db.get(author, {}) 107 | tweet_ind = find_matching(author_data, ts) 108 | if tweet_ind is None: 109 | return {"error": "Tweet not found"}, 404 110 | tweets = author_data.get("tweets", []) 111 | 112 | # Convert to a unique set so we can add and remove and prevent double liking 113 | likes = set(tweets[tweet_ind].get("likes", [])) 114 | if action == "like": 115 | likes.add(current_user) 116 | else: 117 | likes.discard(current_user) 118 | tweets[tweet_ind]["likes"] = list(likes) 119 | 120 | db[author] = {**author_data, "tweets": tweets} 121 | return {"success": True} 122 | 123 | 124 | @app.route("/api/delete", methods=["POST"]) 125 | @web.needs_params("author", "ts") 126 | @ratelimit 127 | def delete(author, ts): 128 | if not ts.isdigit(): 129 | return {"error": "Bad ts"}, 400 130 | ts = int(ts) 131 | author_data = db.get(author, {}) 132 | 133 | match_ind= find_matching(author_data, ts) 134 | if match_ind is None: 135 | return {"error": "Tweet not found"}, 404 136 | 137 | print(f"{web.whoami()!r} trying to delete tweet by {author!r}") 138 | # Moderators bypass this check, they can delete anything 139 | if not is_mod() and author != web.whoami(): 140 | return {"error": "Permission denied"}, 401 141 | 142 | db[author] = {**author_data, "tweets": [ 143 | t for i, t in enumerate(author_data.get("tweets", [])) if i != match_ind 144 | ]} 145 | return {"success": True} 146 | 147 | 148 | if __name__ == "__main__": 149 | app.debug(watch_dirs=["templates"]) 150 | # Reload on code changes and template changes 151 | -------------------------------------------------------------------------------- /static/feed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const ele = (tagname, content, c) => { 3 | const e = document.createElement(tagname) 4 | if (content) e.innerText = content 5 | if (c) e.classList.add(c) 6 | return e 7 | } 8 | 9 | function msg(msg, isError) { 10 | const d = ele('div', msg) 11 | const goodColors = { 12 | color: '#155724', 13 | backgroundColor: '#d4edda', 14 | borderColor: '#c3e6cb' 15 | } 16 | const errorColors = { 17 | backgroundColor: '#f8d7da', 18 | color: '#721c24', 19 | borderColor: '#f5c6cb', 20 | } 21 | 22 | Object.assign(d.style, { 23 | padding: '5px', 24 | 25 | maxWidth: '50vw', 26 | minWidth: '100px', 27 | minHeight: '30px', 28 | 29 | display: 'flex', 30 | alignItems: 'center', 31 | 32 | position: 'fixed', 33 | bottom: '1rem', 34 | right: '1rem', 35 | }, isError? errorColors : goodColors) 36 | 37 | document.body.appendChild(d) 38 | setTimeout(() => document.body.removeChild(d), 4000) 39 | } 40 | 41 | 42 | async function apiRequest(route, obj) { 43 | let parts = []; 44 | for (var p in obj) { 45 | if (obj.hasOwnProperty(p)) { 46 | parts.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 47 | } 48 | } 49 | const data = parts.join("&"); 50 | 51 | let res 52 | try { 53 | res = await fetch(route, { 54 | method: "POST", 55 | headers: { 56 | 'Content-Type': 'application/x-www-form-urlencoded', 57 | }, 58 | body: data 59 | }).then(async res => { 60 | // even if the status code is bad, try to show the error sent in JSON 61 | 62 | let err = `Unexpected status code ${res.status}` 63 | let json = {} 64 | try { 65 | json = await res.json() 66 | }catch(e) { 67 | console.error(e) 68 | throw new Error(res.ok ? err : "Couldn't parse response") 69 | } 70 | if (!res.ok) { 71 | console.log(json) 72 | throw new Error(json.error || err) 73 | } 74 | return json 75 | }) 76 | } catch(e) { 77 | console.error(`Error in request to ${route}:`, e) 78 | res = {error: e} 79 | } 80 | return res 81 | } 82 | 83 | 84 | class LikeButton { 85 | constructor(tweet) { 86 | // save this for the like request 87 | this.tweet = tweet 88 | // create elements 89 | this.btn = ele('button', '', 'like') 90 | this.i = ele('i', '', 'fa') 91 | this.btn.appendChild(this.i) 92 | this.btn.onclick = (() => this.click()) 93 | this.liked = tweet.likes.includes(USERNAME) 94 | this.update() 95 | } 96 | 97 | update() { 98 | // toggle whether heart is filled in 99 | this.i.classList.remove('fa-heart') 100 | this.i.classList.remove('fa-heart-o') 101 | this.i.classList.add(this.liked ? 'fa-heart' : 'fa-heart-o') 102 | } 103 | 104 | toggle() { 105 | this.liked = !this.liked 106 | this.update() 107 | } 108 | 109 | async click() { 110 | this.toggle() 111 | const { author, ts } = this.tweet 112 | const action = this.liked ? 'like' : 'unlike' 113 | try { 114 | const res = await apiRequest("/api/like", { author, ts, action }) 115 | if (res.error) { 116 | throw new Error(res.error) 117 | } 118 | } catch(e) { 119 | msg(e.message ? e.message : e, true) 120 | // If the action didn't complete successfully, 121 | // toggle back to the state the server thinks 122 | this.toggle() 123 | } 124 | } 125 | } 126 | 127 | 128 | class TrashButton { 129 | constructor(tweet) { 130 | this.tweet = tweet 131 | // make element 132 | this.btn = ele('button') 133 | this.btn.classList.add('trash') 134 | this.btn.innerHTML = '' 135 | this.btn.onclick = (() => this.click()) 136 | } 137 | 138 | async click() { 139 | if (!confirm("Are you sure you want to delete this tweet?")) return 140 | const { author, ts } = this.tweet 141 | const res = await apiRequest("/api/delete", { author, ts }) 142 | if (res.error) { 143 | msg(res.error, true) 144 | } else { 145 | refreshFeed() 146 | } 147 | } 148 | } 149 | 150 | 151 | async function refreshFeed() { 152 | const tweetsDiv = document.getElementById('tweets') 153 | tweetsDiv.innerHTML = '
' 154 | 155 | // fetch feed 156 | const data = await fetch("/api/feed").then(r => r.json()) 157 | // check for errors 158 | if (data.error) { 159 | tweetsDiv.innerHTML = "" // clear loading indicator 160 | return msg("Error: " + data.error, true) 161 | } 162 | // clear tweets 163 | tweetsDiv.innerHTML = ""; 164 | if (!data.tweets) { 165 | tweetsDiv.innerHTML = "No tweets..." 166 | return 167 | } 168 | // render each tweet 169 | data.tweets.forEach(tweet => { 170 | console.log(tweet) 171 | const tDiv = document.createElement('div') 172 | // tweet header 173 | const tHead = ele('div') 174 | tHead.appendChild(ele('b', tweet.author || "User", 'tweet-name')) 175 | tHead.appendChild(ele('i', moment.unix(tweet.ts).fromNow(), 'tweet-ts')) 176 | tDiv.appendChild(tHead) 177 | // body 178 | tDiv.appendChild(ele('p', tweet.body || "")) 179 | // buttons 180 | const tButtons = ele('div') 181 | tButtons.appendChild(ele('b', `${tweet.likes.length} like${tweet.likes.length == 1?' ':'s'}`, 'likes-label')) 182 | const likeButton = new LikeButton(tweet) 183 | tButtons.appendChild(likeButton.btn) 184 | if (tweet.author == USERNAME || MOD) { 185 | const trashButton = new TrashButton(tweet) 186 | tButtons.appendChild(trashButton.btn) 187 | } 188 | tDiv.appendChild(tButtons) 189 | // render the tweet 190 | tweetsDiv.appendChild(tDiv) 191 | }) 192 | } 193 | 194 | const postBtn = document.getElementById('tweet-btn') 195 | 196 | async function submitTweet() { 197 | const tweetArea = document.getElementById('tweet-area') 198 | const body = tweetArea.value 199 | 200 | if (!body) { 201 | return msg("Error: Tweet cannot be empty", true) 202 | } 203 | 204 | // show loading indicator 205 | postBtn.innerHTML = '
' 206 | // perform API request 207 | const res = await apiRequest("/api/tweet", { body }) 208 | // remove loading indicator 209 | postBtn.innerHTML = "Post" 210 | 211 | if (res.error) { 212 | return msg(res.error, true) 213 | } 214 | // clear tweet area 215 | tweetArea.value = "" 216 | msg("Tweet posted") 217 | } 218 | 219 | postBtn.onclick = submitTweet 220 | document.getElementById('refresh-btn').onclick = refreshFeed 221 | refreshFeed() 222 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | category = "main" 3 | description = "Async http client/server framework (asyncio)" 4 | name = "aiohttp" 5 | optional = false 6 | python-versions = ">=3.6" 7 | version = "3.7.3" 8 | 9 | [package.dependencies] 10 | async-timeout = ">=3.0,<4.0" 11 | attrs = ">=17.3.0" 12 | chardet = ">=2.0,<4.0" 13 | multidict = ">=4.5,<7.0" 14 | typing-extensions = ">=3.6.5" 15 | yarl = ">=1.0,<2.0" 16 | 17 | [package.extras] 18 | speedups = ["aiodns", "brotlipy", "cchardet"] 19 | 20 | [[package]] 21 | category = "main" 22 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 23 | name = "appdirs" 24 | optional = false 25 | python-versions = "*" 26 | version = "1.4.4" 27 | 28 | [[package]] 29 | category = "main" 30 | description = "Timeout context manager for asyncio programs" 31 | name = "async-timeout" 32 | optional = false 33 | python-versions = ">=3.5.3" 34 | version = "3.0.1" 35 | 36 | [[package]] 37 | category = "main" 38 | description = "Classes Without Boilerplate" 39 | name = "attrs" 40 | optional = false 41 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 42 | version = "20.3.0" 43 | 44 | [package.extras] 45 | dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] 46 | docs = ["furo", "sphinx", "zope.interface"] 47 | tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] 48 | tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] 49 | 50 | [[package]] 51 | category = "main" 52 | description = "Screen-scraping library" 53 | name = "beautifulsoup4" 54 | optional = false 55 | python-versions = "*" 56 | version = "4.9.3" 57 | 58 | [package.dependencies] 59 | [package.dependencies.soupsieve] 60 | python = ">=3.0" 61 | version = ">1.2" 62 | 63 | [package.extras] 64 | html5lib = ["html5lib"] 65 | lxml = ["lxml"] 66 | 67 | [[package]] 68 | category = "main" 69 | description = "Dummy package for Beautiful Soup" 70 | name = "bs4" 71 | optional = false 72 | python-versions = "*" 73 | version = "0.0.1" 74 | 75 | [package.dependencies] 76 | beautifulsoup4 = "*" 77 | 78 | [[package]] 79 | category = "main" 80 | description = "Universal encoding detector for Python 2 and 3" 81 | name = "chardet" 82 | optional = false 83 | python-versions = "*" 84 | version = "3.0.4" 85 | 86 | [[package]] 87 | category = "main" 88 | description = "Composable command line interface toolkit" 89 | name = "click" 90 | optional = false 91 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 92 | version = "7.1.2" 93 | 94 | [[package]] 95 | category = "main" 96 | description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" 97 | name = "cssselect" 98 | optional = false 99 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 100 | version = "1.1.0" 101 | 102 | [[package]] 103 | category = "main" 104 | description = "Up to date simple useragent faker with real world database" 105 | name = "fake-useragent" 106 | optional = false 107 | python-versions = "*" 108 | version = "0.1.11" 109 | 110 | [[package]] 111 | category = "main" 112 | description = "A simple framework for building complex web applications." 113 | name = "flask" 114 | optional = false 115 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 116 | version = "1.1.2" 117 | 118 | [package.dependencies] 119 | Jinja2 = ">=2.10.1" 120 | Werkzeug = ">=0.15" 121 | click = ">=5.1" 122 | itsdangerous = ">=0.24" 123 | 124 | [package.extras] 125 | dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] 126 | docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] 127 | dotenv = ["python-dotenv"] 128 | 129 | [[package]] 130 | category = "main" 131 | description = "Internationalized Domain Names in Applications (IDNA)" 132 | name = "idna" 133 | optional = false 134 | python-versions = ">=3.4" 135 | version = "3.1" 136 | 137 | [[package]] 138 | category = "main" 139 | description = "Various helpers to pass data to untrusted environments and back." 140 | name = "itsdangerous" 141 | optional = false 142 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 143 | version = "1.1.0" 144 | 145 | [[package]] 146 | category = "main" 147 | description = "A very fast and expressive template engine." 148 | name = "jinja2" 149 | optional = false 150 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 151 | version = "2.11.2" 152 | 153 | [package.dependencies] 154 | MarkupSafe = ">=0.23" 155 | 156 | [package.extras] 157 | i18n = ["Babel (>=0.8)"] 158 | 159 | [[package]] 160 | category = "main" 161 | description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." 162 | name = "lxml" 163 | optional = false 164 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" 165 | version = "4.6.2" 166 | 167 | [package.extras] 168 | cssselect = ["cssselect (>=0.7)"] 169 | html5 = ["html5lib"] 170 | htmlsoup = ["beautifulsoup4"] 171 | source = ["Cython (>=0.29.7)"] 172 | 173 | [[package]] 174 | category = "main" 175 | description = "Safely add untrusted strings to HTML/XML markup." 176 | name = "markupsafe" 177 | optional = false 178 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" 179 | version = "1.1.1" 180 | 181 | [[package]] 182 | category = "main" 183 | description = "A lightweight library for converting complex datatypes to and from native Python datatypes." 184 | name = "marshmallow" 185 | optional = false 186 | python-versions = ">=3.5" 187 | version = "3.10.0" 188 | 189 | [package.extras] 190 | dev = ["pytest", "pytz", "simplejson", "mypy (0.790)", "flake8 (3.8.4)", "flake8-bugbear (20.11.1)", "pre-commit (>=2.4,<3.0)", "tox"] 191 | docs = ["sphinx (3.3.1)", "sphinx-issues (1.2.0)", "alabaster (0.7.12)", "sphinx-version-warning (1.1.2)", "autodocsumm (0.2.2)"] 192 | lint = ["mypy (0.790)", "flake8 (3.8.4)", "flake8-bugbear (20.11.1)", "pre-commit (>=2.4,<3.0)"] 193 | tests = ["pytest", "pytz", "simplejson"] 194 | 195 | [[package]] 196 | category = "main" 197 | description = "multidict implementation" 198 | name = "multidict" 199 | optional = false 200 | python-versions = ">=3.6" 201 | version = "5.1.0" 202 | 203 | [[package]] 204 | category = "main" 205 | description = "parse() is the opposite of format()" 206 | name = "parse" 207 | optional = false 208 | python-versions = "*" 209 | version = "1.19.0" 210 | 211 | [[package]] 212 | category = "main" 213 | description = "A port of node.js's EventEmitter to python." 214 | name = "pyee" 215 | optional = false 216 | python-versions = "*" 217 | version = "8.1.0" 218 | 219 | [[package]] 220 | category = "main" 221 | description = "Headless chrome/chromium automation library (unofficial port of puppeteer)" 222 | name = "pyppeteer" 223 | optional = false 224 | python-versions = ">=3.6.1,<4.0.0" 225 | version = "0.2.5" 226 | 227 | [package.dependencies] 228 | appdirs = ">=1.4.3,<2.0.0" 229 | pyee = ">=8.1.0,<9.0.0" 230 | tqdm = ">=4.42.1,<5.0.0" 231 | urllib3 = ">=1.25.8,<2.0.0" 232 | websockets = ">=8.1,<9.0" 233 | 234 | [[package]] 235 | category = "main" 236 | description = "A jquery-like library for python" 237 | name = "pyquery" 238 | optional = false 239 | python-versions = "*" 240 | version = "1.4.3" 241 | 242 | [package.dependencies] 243 | cssselect = ">0.7.9" 244 | lxml = ">=2.1" 245 | 246 | [[package]] 247 | category = "main" 248 | description = "A library for interacting with features of repl.it" 249 | name = "replitdev" 250 | optional = false 251 | python-versions = ">=3.8,<4.0" 252 | version = "2.5.22" 253 | 254 | [package.dependencies] 255 | aiohttp = ">=3.6.2,<4.0.0" 256 | flask = ">=1.1.2,<2.0.0" 257 | requests-html = ">=0.10.0,<0.11.0" 258 | typing_extensions = ">=3.7.4,<4.0.0" 259 | werkzeug = ">=1.0.1,<2.0.0" 260 | 261 | [[package]] 262 | category = "main" 263 | description = "Python HTTP for Humans." 264 | name = "requests" 265 | optional = false 266 | python-versions = "*" 267 | version = "2.15.1" 268 | 269 | [package.extras] 270 | security = ["cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)"] 271 | socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] 272 | 273 | [[package]] 274 | category = "main" 275 | description = "HTML Parsing for Humans." 276 | name = "requests-html" 277 | optional = false 278 | python-versions = ">=3.6.0" 279 | version = "0.10.0" 280 | 281 | [package.dependencies] 282 | bs4 = "*" 283 | fake-useragent = "*" 284 | parse = "*" 285 | pyppeteer = ">=0.0.14" 286 | pyquery = "*" 287 | requests = "*" 288 | w3lib = "*" 289 | 290 | [[package]] 291 | category = "main" 292 | description = "Python 2 and 3 compatibility utilities" 293 | name = "six" 294 | optional = false 295 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 296 | version = "1.15.0" 297 | 298 | [[package]] 299 | category = "main" 300 | description = "A modern CSS selector implementation for Beautiful Soup." 301 | marker = "python_version >= \"3.0\"" 302 | name = "soupsieve" 303 | optional = false 304 | python-versions = ">=3.5" 305 | version = "2.1" 306 | 307 | [[package]] 308 | category = "main" 309 | description = "Fast, Extensible Progress Meter" 310 | name = "tqdm" 311 | optional = false 312 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 313 | version = "4.56.0" 314 | 315 | [package.extras] 316 | dev = ["py-make (>=0.1.0)", "twine", "wheel"] 317 | telegram = ["requests"] 318 | 319 | [[package]] 320 | category = "main" 321 | description = "Backported and Experimental Type Hints for Python 3.5+" 322 | name = "typing-extensions" 323 | optional = false 324 | python-versions = "*" 325 | version = "3.7.4.3" 326 | 327 | [[package]] 328 | category = "main" 329 | description = "HTTP library with thread-safe connection pooling, file post, and more." 330 | name = "urllib3" 331 | optional = false 332 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" 333 | version = "1.26.2" 334 | 335 | [package.extras] 336 | brotli = ["brotlipy (>=0.6.0)"] 337 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] 338 | socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] 339 | 340 | [[package]] 341 | category = "main" 342 | description = "Library of web-related functions" 343 | name = "w3lib" 344 | optional = false 345 | python-versions = "*" 346 | version = "1.22.0" 347 | 348 | [package.dependencies] 349 | six = ">=1.4.1" 350 | 351 | [[package]] 352 | category = "main" 353 | description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" 354 | name = "websockets" 355 | optional = false 356 | python-versions = ">=3.6.1" 357 | version = "8.1" 358 | 359 | [[package]] 360 | category = "main" 361 | description = "The comprehensive WSGI web application library." 362 | name = "werkzeug" 363 | optional = false 364 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 365 | version = "1.0.1" 366 | 367 | [package.extras] 368 | dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] 369 | watchdog = ["watchdog"] 370 | 371 | [[package]] 372 | category = "main" 373 | description = "Yet another URL library" 374 | name = "yarl" 375 | optional = false 376 | python-versions = ">=3.6" 377 | version = "1.6.3" 378 | 379 | [package.dependencies] 380 | idna = ">=2.0" 381 | multidict = ">=4.0" 382 | 383 | [metadata] 384 | content-hash = "549f20d47c498ee9fdbeb5638ebd2b10fc0dfbd08e29c42477c7edc31dee4195" 385 | python-versions = "^3.8" 386 | 387 | [metadata.files] 388 | aiohttp = [ 389 | {file = "aiohttp-3.7.3-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:328b552513d4f95b0a2eea4c8573e112866107227661834652a8984766aa7656"}, 390 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c733ef3bdcfe52a1a75564389bad4064352274036e7e234730526d155f04d914"}, 391 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2858b2504c8697beb9357be01dc47ef86438cc1cb36ecb6991796d19475faa3e"}, 392 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:d2cfac21e31e841d60dc28c0ec7d4ec47a35c608cb8906435d47ef83ffb22150"}, 393 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:3228b7a51e3ed533f5472f54f70fd0b0a64c48dc1649a0f0e809bec312934d7a"}, 394 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:dcc119db14757b0c7bce64042158307b9b1c76471e655751a61b57f5a0e4d78e"}, 395 | {file = "aiohttp-3.7.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:7d9b42127a6c0bdcc25c3dcf252bb3ddc70454fac593b1b6933ae091396deb13"}, 396 | {file = "aiohttp-3.7.3-cp36-cp36m-win32.whl", hash = "sha256:df48a623c58180874d7407b4d9ec06a19b84ed47f60a3884345b1a5099c1818b"}, 397 | {file = "aiohttp-3.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:0b795072bb1bf87b8620120a6373a3c61bfcb8da7e5c2377f4bb23ff4f0b62c9"}, 398 | {file = "aiohttp-3.7.3-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:0d438c8ca703b1b714e82ed5b7a4412c82577040dadff479c08405e2a715564f"}, 399 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8389d6044ee4e2037dca83e3f6994738550f6ee8cfb746762283fad9b932868f"}, 400 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3ea8c252d8df5e9166bcf3d9edced2af132f4ead8ac422eac723c5781063709a"}, 401 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:78e2f18a82b88cbc37d22365cf8d2b879a492faedb3f2975adb4ed8dfe994d3a"}, 402 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:df3a7b258cc230a65245167a202dd07320a5af05f3d41da1488ba0fa05bc9347"}, 403 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:f326b3c1bbfda5b9308252ee0dcb30b612ee92b0e105d4abec70335fab5b1245"}, 404 | {file = "aiohttp-3.7.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5e479df4b2d0f8f02133b7e4430098699450e1b2a826438af6bec9a400530957"}, 405 | {file = "aiohttp-3.7.3-cp37-cp37m-win32.whl", hash = "sha256:6d42debaf55450643146fabe4b6817bb2a55b23698b0434107e892a43117285e"}, 406 | {file = "aiohttp-3.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9c58b0b84055d8bc27b7df5a9d141df4ee6ff59821f922dd73155861282f6a3"}, 407 | {file = "aiohttp-3.7.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:f411cb22115cb15452d099fec0ee636b06cf81bfb40ed9c02d30c8dc2bc2e3d1"}, 408 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1e0920909d916d3375c7a1fdb0b1c78e46170e8bb42792312b6eb6676b2f87f"}, 409 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:59d11674964b74a81b149d4ceaff2b674b3b0e4d0f10f0be1533e49c4a28408b"}, 410 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:41608c0acbe0899c852281978492f9ce2c6fbfaf60aff0cefc54a7c4516b822c"}, 411 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:16a3cb5df5c56f696234ea9e65e227d1ebe9c18aa774d36ff42f532139066a5f"}, 412 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:6ccc43d68b81c424e46192a778f97da94ee0630337c9bbe5b2ecc9b0c1c59001"}, 413 | {file = "aiohttp-3.7.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:d03abec50df423b026a5aa09656bd9d37f1e6a49271f123f31f9b8aed5dc3ea3"}, 414 | {file = "aiohttp-3.7.3-cp38-cp38-win32.whl", hash = "sha256:39f4b0a6ae22a1c567cb0630c30dd082481f95c13ca528dc501a7766b9c718c0"}, 415 | {file = "aiohttp-3.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:c68fdf21c6f3573ae19c7ee65f9ff185649a060c9a06535e9c3a0ee0bbac9235"}, 416 | {file = "aiohttp-3.7.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:710376bf67d8ff4500a31d0c207b8941ff4fba5de6890a701d71680474fe2a60"}, 417 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2406dc1dda01c7f6060ab586e4601f18affb7a6b965c50a8c90ff07569cf782a"}, 418 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:2a7b7640167ab536c3cb90cfc3977c7094f1c5890d7eeede8b273c175c3910fd"}, 419 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:684850fb1e3e55c9220aad007f8386d8e3e477c4ec9211ae54d968ecdca8c6f9"}, 420 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:1edfd82a98c5161497bbb111b2b70c0813102ad7e0aa81cbeb34e64c93863005"}, 421 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:77149002d9386fae303a4a162e6bce75cc2161347ad2ba06c2f0182561875d45"}, 422 | {file = "aiohttp-3.7.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:756ae7efddd68d4ea7d89c636b703e14a0c686688d42f588b90778a3c2fc0564"}, 423 | {file = "aiohttp-3.7.3-cp39-cp39-win32.whl", hash = "sha256:3b0036c978cbcc4a4512278e98e3e6d9e6b834dc973206162eddf98b586ef1c6"}, 424 | {file = "aiohttp-3.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:e1b95972a0ae3f248a899cdbac92ba2e01d731225f566569311043ce2226f5e7"}, 425 | {file = "aiohttp-3.7.3.tar.gz", hash = "sha256:9c1a81af067e72261c9cbe33ea792893e83bc6aa987bfbd6fdc1e5e7b22777c4"}, 426 | ] 427 | appdirs = [ 428 | {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, 429 | {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, 430 | ] 431 | async-timeout = [ 432 | {file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"}, 433 | {file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"}, 434 | ] 435 | attrs = [ 436 | {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, 437 | {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, 438 | ] 439 | beautifulsoup4 = [ 440 | {file = "beautifulsoup4-4.9.3-py2-none-any.whl", hash = "sha256:4c98143716ef1cb40bf7f39a8e3eec8f8b009509e74904ba3a7b315431577e35"}, 441 | {file = "beautifulsoup4-4.9.3-py3-none-any.whl", hash = "sha256:fff47e031e34ec82bf17e00da8f592fe7de69aeea38be00523c04623c04fb666"}, 442 | {file = "beautifulsoup4-4.9.3.tar.gz", hash = "sha256:84729e322ad1d5b4d25f805bfa05b902dd96450f43842c4e99067d5e1369eb25"}, 443 | ] 444 | bs4 = [ 445 | {file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"}, 446 | ] 447 | chardet = [ 448 | {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, 449 | {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, 450 | ] 451 | click = [ 452 | {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, 453 | {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, 454 | ] 455 | cssselect = [ 456 | {file = "cssselect-1.1.0-py2.py3-none-any.whl", hash = "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf"}, 457 | {file = "cssselect-1.1.0.tar.gz", hash = "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc"}, 458 | ] 459 | fake-useragent = [ 460 | {file = "fake-useragent-0.1.11.tar.gz", hash = "sha256:c104998b750eb097eefc28ae28e92d66397598d2cf41a31aa45d5559ef1adf35"}, 461 | ] 462 | flask = [ 463 | {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, 464 | {file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, 465 | ] 466 | idna = [ 467 | {file = "idna-3.1-py3-none-any.whl", hash = "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16"}, 468 | {file = "idna-3.1.tar.gz", hash = "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1"}, 469 | ] 470 | itsdangerous = [ 471 | {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, 472 | {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, 473 | ] 474 | jinja2 = [ 475 | {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, 476 | {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, 477 | ] 478 | lxml = [ 479 | {file = "lxml-4.6.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a9d6bc8642e2c67db33f1247a77c53476f3a166e09067c0474facb045756087f"}, 480 | {file = "lxml-4.6.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:791394449e98243839fa822a637177dd42a95f4883ad3dec2a0ce6ac99fb0a9d"}, 481 | {file = "lxml-4.6.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:68a5d77e440df94011214b7db907ec8f19e439507a70c958f750c18d88f995d2"}, 482 | {file = "lxml-4.6.2-cp27-cp27m-win32.whl", hash = "sha256:fc37870d6716b137e80d19241d0e2cff7a7643b925dfa49b4c8ebd1295eb506e"}, 483 | {file = "lxml-4.6.2-cp27-cp27m-win_amd64.whl", hash = "sha256:69a63f83e88138ab7642d8f61418cf3180a4d8cd13995df87725cb8b893e950e"}, 484 | {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:42ebca24ba2a21065fb546f3e6bd0c58c3fe9ac298f3a320147029a4850f51a2"}, 485 | {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f83d281bb2a6217cd806f4cf0ddded436790e66f393e124dfe9731f6b3fb9afe"}, 486 | {file = "lxml-4.6.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:535f067002b0fd1a4e5296a8f1bf88193080ff992a195e66964ef2a6cfec5388"}, 487 | {file = "lxml-4.6.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:366cb750140f221523fa062d641393092813b81e15d0e25d9f7c6025f910ee80"}, 488 | {file = "lxml-4.6.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:97db258793d193c7b62d4e2586c6ed98d51086e93f9a3af2b2034af01450a74b"}, 489 | {file = "lxml-4.6.2-cp35-cp35m-win32.whl", hash = "sha256:648914abafe67f11be7d93c1a546068f8eff3c5fa938e1f94509e4a5d682b2d8"}, 490 | {file = "lxml-4.6.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4e751e77006da34643ab782e4a5cc21ea7b755551db202bc4d3a423b307db780"}, 491 | {file = "lxml-4.6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:681d75e1a38a69f1e64ab82fe4b1ed3fd758717bed735fb9aeaa124143f051af"}, 492 | {file = "lxml-4.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:127f76864468d6630e1b453d3ffbbd04b024c674f55cf0a30dc2595137892d37"}, 493 | {file = "lxml-4.6.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4fb85c447e288df535b17ebdebf0ec1cf3a3f1a8eba7e79169f4f37af43c6b98"}, 494 | {file = "lxml-4.6.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:5be4a2e212bb6aa045e37f7d48e3e1e4b6fd259882ed5a00786f82e8c37ce77d"}, 495 | {file = "lxml-4.6.2-cp36-cp36m-win32.whl", hash = "sha256:8c88b599e226994ad4db29d93bc149aa1aff3dc3a4355dd5757569ba78632bdf"}, 496 | {file = "lxml-4.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:6e4183800f16f3679076dfa8abf2db3083919d7e30764a069fb66b2b9eff9939"}, 497 | {file = "lxml-4.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d8d3d4713f0c28bdc6c806a278d998546e8efc3498949e3ace6e117462ac0a5e"}, 498 | {file = "lxml-4.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8246f30ca34dc712ab07e51dc34fea883c00b7ccb0e614651e49da2c49a30711"}, 499 | {file = "lxml-4.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:923963e989ffbceaa210ac37afc9b906acebe945d2723e9679b643513837b089"}, 500 | {file = "lxml-4.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:1471cee35eba321827d7d53d104e7b8c593ea3ad376aa2df89533ce8e1b24a01"}, 501 | {file = "lxml-4.6.2-cp37-cp37m-win32.whl", hash = "sha256:2363c35637d2d9d6f26f60a208819e7eafc4305ce39dc1d5005eccc4593331c2"}, 502 | {file = "lxml-4.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f4822c0660c3754f1a41a655e37cb4dbbc9be3d35b125a37fab6f82d47674ebc"}, 503 | {file = "lxml-4.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0448576c148c129594d890265b1a83b9cd76fd1f0a6a04620753d9a6bcfd0a4d"}, 504 | {file = "lxml-4.6.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:60a20bfc3bd234d54d49c388950195d23a5583d4108e1a1d47c9eef8d8c042b3"}, 505 | {file = "lxml-4.6.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2e5cc908fe43fe1aa299e58046ad66981131a66aea3129aac7770c37f590a644"}, 506 | {file = "lxml-4.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:50c348995b47b5a4e330362cf39fc503b4a43b14a91c34c83b955e1805c8e308"}, 507 | {file = "lxml-4.6.2-cp38-cp38-win32.whl", hash = "sha256:94d55bd03d8671686e3f012577d9caa5421a07286dd351dfef64791cf7c6c505"}, 508 | {file = "lxml-4.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:7a7669ff50f41225ca5d6ee0a1ec8413f3a0d8aa2b109f86d540887b7ec0d72a"}, 509 | {file = "lxml-4.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e0bfe9bb028974a481410432dbe1b182e8191d5d40382e5b8ff39cdd2e5c5931"}, 510 | {file = "lxml-4.6.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6fd8d5903c2e53f49e99359b063df27fdf7acb89a52b6a12494208bf61345a03"}, 511 | {file = "lxml-4.6.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7e9eac1e526386df7c70ef253b792a0a12dd86d833b1d329e038c7a235dfceb5"}, 512 | {file = "lxml-4.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7ee8af0b9f7de635c61cdd5b8534b76c52cd03536f29f51151b377f76e214a1a"}, 513 | {file = "lxml-4.6.2-cp39-cp39-win32.whl", hash = "sha256:2e6fd1b8acd005bd71e6c94f30c055594bbd0aa02ef51a22bbfa961ab63b2d75"}, 514 | {file = "lxml-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf"}, 515 | {file = "lxml-4.6.2.tar.gz", hash = "sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc"}, 516 | ] 517 | markupsafe = [ 518 | {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, 519 | {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, 520 | {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, 521 | {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, 522 | {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, 523 | {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, 524 | {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, 525 | {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, 526 | {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, 527 | {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, 528 | {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, 529 | {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, 530 | {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, 531 | {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, 532 | {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, 533 | {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, 534 | {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, 535 | {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, 536 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, 537 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, 538 | {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, 539 | {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, 540 | {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, 541 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, 542 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, 543 | {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, 544 | {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, 545 | {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, 546 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, 547 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, 548 | {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, 549 | {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, 550 | {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, 551 | ] 552 | marshmallow = [ 553 | {file = "marshmallow-3.10.0-py2.py3-none-any.whl", hash = "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177"}, 554 | {file = "marshmallow-3.10.0.tar.gz", hash = "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7"}, 555 | ] 556 | multidict = [ 557 | {file = "multidict-5.1.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f"}, 558 | {file = "multidict-5.1.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf"}, 559 | {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281"}, 560 | {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d"}, 561 | {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d"}, 562 | {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da"}, 563 | {file = "multidict-5.1.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224"}, 564 | {file = "multidict-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26"}, 565 | {file = "multidict-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6"}, 566 | {file = "multidict-5.1.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76"}, 567 | {file = "multidict-5.1.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a"}, 568 | {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f"}, 569 | {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348"}, 570 | {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93"}, 571 | {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9"}, 572 | {file = "multidict-5.1.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37"}, 573 | {file = "multidict-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5"}, 574 | {file = "multidict-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632"}, 575 | {file = "multidict-5.1.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952"}, 576 | {file = "multidict-5.1.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79"}, 577 | {file = "multidict-5.1.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456"}, 578 | {file = "multidict-5.1.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7"}, 579 | {file = "multidict-5.1.0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635"}, 580 | {file = "multidict-5.1.0-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a"}, 581 | {file = "multidict-5.1.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea"}, 582 | {file = "multidict-5.1.0-cp38-cp38-win32.whl", hash = "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656"}, 583 | {file = "multidict-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3"}, 584 | {file = "multidict-5.1.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93"}, 585 | {file = "multidict-5.1.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647"}, 586 | {file = "multidict-5.1.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d"}, 587 | {file = "multidict-5.1.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8"}, 588 | {file = "multidict-5.1.0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1"}, 589 | {file = "multidict-5.1.0-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841"}, 590 | {file = "multidict-5.1.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda"}, 591 | {file = "multidict-5.1.0-cp39-cp39-win32.whl", hash = "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80"}, 592 | {file = "multidict-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359"}, 593 | {file = "multidict-5.1.0.tar.gz", hash = "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5"}, 594 | ] 595 | parse = [ 596 | {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, 597 | ] 598 | pyee = [ 599 | {file = "pyee-8.1.0-py2.py3-none-any.whl", hash = "sha256:383973b63ad7ed5e3c0311f8b179c52981f9e7b3eaea0e9a830d13ec34dde65f"}, 600 | {file = "pyee-8.1.0.tar.gz", hash = "sha256:92dacc5bd2bdb8f95aa8dd2585d47ca1c4840e2adb95ccf90034d64f725bfd31"}, 601 | ] 602 | pyppeteer = [ 603 | {file = "pyppeteer-0.2.5-py3-none-any.whl", hash = "sha256:d4cb4a5ef94b00c1073aed888b39646ce26cff3339cff7a3f1f1cc307bf50408"}, 604 | {file = "pyppeteer-0.2.5.tar.gz", hash = "sha256:c2974be1afa13b17f7ecd120d265d8b8cd324d536a231c3953ca872b68aba4af"}, 605 | ] 606 | pyquery = [ 607 | {file = "pyquery-1.4.3-py3-none-any.whl", hash = "sha256:1fc33b7699455ed25c75282bc8f80ace1ac078b0dda5a933dacbd8b1c1f83963"}, 608 | {file = "pyquery-1.4.3.tar.gz", hash = "sha256:a388eefb6bc4a55350de0316fbd97cda999ae669b6743ae5b99102ba54f5aa72"}, 609 | ] 610 | replitdev = [ 611 | {file = "replitdev-2.5.22-py3-none-any.whl", hash = "sha256:41d479454b46305e8e77f8d22a6f7fc62d1731102340ac0ed78b9d19046d980c"}, 612 | {file = "replitdev-2.5.22.tar.gz", hash = "sha256:9617eade1c9feb2f61bb93f87f506870f9b48061f434ac4c9d96efc78f62df58"}, 613 | ] 614 | requests = [ 615 | {file = "requests-2.15.1-py2.py3-none-any.whl", hash = "sha256:ff753b2196cd18b1bbeddc9dcd5c864056599f7a7d9a4fb5677e723efa2b7fb9"}, 616 | {file = "requests-2.15.1.tar.gz", hash = "sha256:e5659b9315a0610505e050bb7190bf6fa2ccee1ac295f2b760ef9d8a03ebbb2e"}, 617 | ] 618 | requests-html = [ 619 | {file = "requests-html-0.10.0.tar.gz", hash = "sha256:7e929ecfed95fb1d0994bb368295d6d7c4d06b03fcb900c33d7d0b17e6003947"}, 620 | {file = "requests_html-0.10.0-py3-none-any.whl", hash = "sha256:cb8a78cf829c4eca9d6233f28524f65dd2bfaafb4bdbbc407f0a0b8f487df6e2"}, 621 | ] 622 | six = [ 623 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, 624 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, 625 | ] 626 | soupsieve = [ 627 | {file = "soupsieve-2.1-py3-none-any.whl", hash = "sha256:4bb21a6ee4707bf43b61230e80740e71bfe56e55d1f1f50924b087bb2975c851"}, 628 | {file = "soupsieve-2.1.tar.gz", hash = "sha256:6dc52924dc0bc710a5d16794e6b3480b2c7c08b07729505feab2b2c16661ff6e"}, 629 | ] 630 | tqdm = [ 631 | {file = "tqdm-4.56.0-py2.py3-none-any.whl", hash = "sha256:4621f6823bab46a9cc33d48105753ccbea671b68bab2c50a9f0be23d4065cb5a"}, 632 | {file = "tqdm-4.56.0.tar.gz", hash = "sha256:fe3d08dd00a526850568d542ff9de9bbc2a09a791da3c334f3213d8d0bbbca65"}, 633 | ] 634 | typing-extensions = [ 635 | {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, 636 | {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, 637 | {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, 638 | ] 639 | urllib3 = [ 640 | {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, 641 | {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, 642 | ] 643 | w3lib = [ 644 | {file = "w3lib-1.22.0-py2.py3-none-any.whl", hash = "sha256:0161d55537063e00d95a241663ede3395c4c6d7b777972ba2fd58bbab2001e53"}, 645 | {file = "w3lib-1.22.0.tar.gz", hash = "sha256:0ad6d0203157d61149fd45aaed2e24f53902989c32fc1dccc2e2bfba371560df"}, 646 | ] 647 | websockets = [ 648 | {file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"}, 649 | {file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"}, 650 | {file = "websockets-8.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8"}, 651 | {file = "websockets-8.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb"}, 652 | {file = "websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5"}, 653 | {file = "websockets-8.1-cp36-cp36m-win32.whl", hash = "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a"}, 654 | {file = "websockets-8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5"}, 655 | {file = "websockets-8.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989"}, 656 | {file = "websockets-8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d"}, 657 | {file = "websockets-8.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779"}, 658 | {file = "websockets-8.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8"}, 659 | {file = "websockets-8.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422"}, 660 | {file = "websockets-8.1-cp37-cp37m-win32.whl", hash = "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc"}, 661 | {file = "websockets-8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308"}, 662 | {file = "websockets-8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092"}, 663 | {file = "websockets-8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485"}, 664 | {file = "websockets-8.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1"}, 665 | {file = "websockets-8.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55"}, 666 | {file = "websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824"}, 667 | {file = "websockets-8.1-cp38-cp38-win32.whl", hash = "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36"}, 668 | {file = "websockets-8.1-cp38-cp38-win_amd64.whl", hash = "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"}, 669 | {file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"}, 670 | ] 671 | werkzeug = [ 672 | {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, 673 | {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, 674 | ] 675 | yarl = [ 676 | {file = "yarl-1.6.3-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434"}, 677 | {file = "yarl-1.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478"}, 678 | {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6"}, 679 | {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e"}, 680 | {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406"}, 681 | {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76"}, 682 | {file = "yarl-1.6.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366"}, 683 | {file = "yarl-1.6.3-cp36-cp36m-win32.whl", hash = "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721"}, 684 | {file = "yarl-1.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643"}, 685 | {file = "yarl-1.6.3-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e"}, 686 | {file = "yarl-1.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3"}, 687 | {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8"}, 688 | {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a"}, 689 | {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c"}, 690 | {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f"}, 691 | {file = "yarl-1.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970"}, 692 | {file = "yarl-1.6.3-cp37-cp37m-win32.whl", hash = "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e"}, 693 | {file = "yarl-1.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50"}, 694 | {file = "yarl-1.6.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2"}, 695 | {file = "yarl-1.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec"}, 696 | {file = "yarl-1.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71"}, 697 | {file = "yarl-1.6.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc"}, 698 | {file = "yarl-1.6.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959"}, 699 | {file = "yarl-1.6.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2"}, 700 | {file = "yarl-1.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2"}, 701 | {file = "yarl-1.6.3-cp38-cp38-win32.whl", hash = "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896"}, 702 | {file = "yarl-1.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a"}, 703 | {file = "yarl-1.6.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e"}, 704 | {file = "yarl-1.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724"}, 705 | {file = "yarl-1.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c"}, 706 | {file = "yarl-1.6.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25"}, 707 | {file = "yarl-1.6.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96"}, 708 | {file = "yarl-1.6.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0"}, 709 | {file = "yarl-1.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4"}, 710 | {file = "yarl-1.6.3-cp39-cp39-win32.whl", hash = "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424"}, 711 | {file = "yarl-1.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6"}, 712 | {file = "yarl-1.6.3.tar.gz", hash = "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10"}, 713 | ] 714 | --------------------------------------------------------------------------------