Compare commits

...

26 Commits
devel ... exp

Author SHA1 Message Date
Ethan Paul fcefe8a9ad
Update main config and content files 2022-01-31 23:45:28 -05:00
Ethan Paul 5ed61b06fa
Add web resource minification 2022-01-31 23:45:08 -05:00
Ethan Paul 5ab9ad02de
Reorganize http resources and build logic 2022-01-31 23:01:07 -05:00
Ethan Paul 691f92d90d
Cleanup project meta
Add makefile clean target
Update gitignore
Remove unused site static resources
2022-01-31 22:57:49 -05:00
Ethan Paul 0a285b0d7f
Update exploration page layout 2021-05-05 13:43:43 -04:00
Ethan Paul 0005836a95
!fixup date 2021-04-25 00:26:49 -04:00
Ethan Paul cb275ad95d
Add support for future post publication 2021-04-24 23:32:47 -04:00
Ethan Paul 1c371e8c1f
Add some demo posts to the config 2021-04-24 23:30:11 -04:00
Ethan Paul c06db053ab
Rename build dir to export 2021-04-24 22:49:27 -04:00
Ethan Paul 3c5e06dd0d
Remove publish option 2021-04-24 22:46:51 -04:00
Ethan Paul 379ef48078
Add 404 error page to nginx config 2021-04-24 22:45:02 -04:00
Ethan Paul 2396106339
Add basic makefile with clean target for removing temp data 2021-04-24 22:42:00 -04:00
Ethan Paul 1b4d88246a
Replace static sitemap with dynamic template 2021-04-24 22:42:00 -04:00
Ethan Paul 93d837c590
Update templates to use new data config data model 2021-04-24 22:42:00 -04:00
Ethan Paul 4541f80bcc
Update gitignore to exclude new build dirs and poetry venv 2021-04-24 22:36:56 -04:00
Ethan Paul cad63f39c5
Exclude error page dir from robots indexing 2021-04-24 22:36:56 -04:00
Ethan Paul 15cb22b955
Implement data model for build script 2021-04-24 22:36:53 -04:00
Ethan Paul c14ff1066c
Standardize static config parameters 2021-04-24 22:36:49 -04:00
Ethan Paul 7cf1bff1a2
Add some dummy data to the config for testing 2021-04-22 16:36:50 -04:00
Ethan Paul 6cfd6146e8
Update build script and templates for new org structure 2021-04-22 16:36:35 -04:00
Ethan Paul cedd73996f
Add precommit config and dependencies 2021-04-22 16:07:30 -04:00
Ethan Paul 3cca47da4c
Add gitignore to exclude builtup files 2021-04-22 12:28:38 -04:00
Ethan Paul 4713296e4e
Add ruamel and jinja dependencies 2021-04-22 12:14:18 -04:00
Ethan Paul f9b18637cf
Add initial build tooling skeleton 2021-04-22 12:12:18 -04:00
Ethan Paul d4b2a8441d
Finalize structure of exploration page 2021-04-14 01:25:01 -04:00
Ethan Paul 73e464f953
Initial exploration page 2021-04-03 21:59:28 -04:00
32 changed files with 2156 additions and 357 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
publish/
.venv/
*.conf
__pycache__

41
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,41 @@
---
repos:
- repo: local
hooks:
- id: end-of-file-fixer
name: end-of-file-fixer
entry: end-of-file-fixer
language: system
types: [text]
- id: fix-encoding-pragma
name: fix-encoding-pragma
entry: fix-encoding-pragma
args:
- "--remove"
language: system
types: [python]
- id: trailing-whitespace-fixer
name: trailing-whitespace-fixer
entry: trailing-whitespace-fixer
language: system
types: [text]
- id: check-merge-conflict
name: check-merge-conflict
entry: check-merge-conflict
language: system
types: [text]
- id: reorder-python-imports
name: reorder-python-imports
entry: reorder-python-imports
language: system
types: [python]
- id: black
name: black
entry: black
language: system
types: [python]

3
Makefile Normal file
View File

@ -0,0 +1,3 @@
clean:
rm --recursive --force publish
rm --force nginx.conf

449
build.py Normal file
View File

@ -0,0 +1,449 @@
import argparse
import datetime
import hashlib
import shutil
import sys
import uuid
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from typing import Dict
from typing import List
from typing import NamedTuple
from typing import Optional
from typing import Sequence
from typing import Tuple
from typing import Union
import jinja2
import jsmin
import marshmallow as msh
import minify_html
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ="safe")
def multi_replace(source: str, replacements: Sequence[Tuple[str, str]]) -> str:
for old, new in replacements:
replaced = source.replace(old, new)
return replaced
class PathField(msh.fields.String):
def _deserialize(self, value, *args, **kwargs):
return Path(value).expanduser().resolve()
class BaseSchema(msh.Schema):
@msh.post_load
def _make_dataclass(self, data: Dict[str, Any], *args, **kwargs):
return self.Container(**data)
class MediaSerializer(BaseSchema):
@dataclass
class Container:
title: str
link: str
anchor: str
content: Optional[str]
def preload_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/{config.build.kodak.preload}.jpeg"
return self.link
def asset_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/{config.build.kodak.asset}.jpeg"
return self.link
def source_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.link}/original"
return self.link
title = msh.fields.String()
link = msh.fields.String()
anchor = msh.fields.String(allow_none=True, missing=None)
content = msh.fields.String(allow_none=True, missing=None)
@msh.post_load
def _make_default_anchor(self, data, **kwargs):
if not data.anchor:
data.anchor = multi_replace(
data.title, [(" ", "-"), ("?", ""), ("!", ""), (".", ""), (":", "")]
)
return data
class LinkSerializer(BaseSchema):
@dataclass
class Container:
title: Optional[str]
url: str
icon: str
url = msh.fields.URL()
title = msh.fields.String(allow_none=True, missing=None)
icon = msh.fields.String(missing="fas fa-external-link-square-alt")
class LocationSeralizer(BaseSchema):
class Container(NamedTuple):
title: str
link: str
title = msh.fields.String()
link = msh.fields.URL()
class PostSerializer(BaseSchema):
@dataclass
class Container:
title: str
description: Optional[str]
location: LocationSeralizer.Container
date: datetime.date
banner: Optional[str]
slug: str
links: Sequence[LinkSerializer.Container]
media: Sequence[MediaSerializer.Container]
def banner_url(self, config) -> str:
if config.build.kodak:
return f"{config.build.kodak.baseurl}image/{self.banner}/{config.build.kodak.banner}.jpeg"
return self.banner
title = msh.fields.String()
description = msh.fields.String(missing=None, allow_none=True)
location = msh.fields.Nested(LocationSeralizer)
date = msh.fields.Raw()
banner = msh.fields.String(missing=None, allow_none=True)
slug = msh.fields.String(
validate=msh.validate.Regexp(r"^[a-z0-9][a-z0-9\-]+[a-z0-9]$")
)
links = msh.fields.List(msh.fields.Nested(LinkSerializer), missing=list())
media = msh.fields.List(msh.fields.Nested(MediaSerializer), missing=list())
@msh.validates_schema
def _unique_anchors(self, data: Dict[str, Any], **kwargs):
anchors = [item.anchor for item in data["media"] if item.anchor is not None]
if len(anchors) != len(set(anchors)):
raise msh.ValidationError(
f"Media anchors used multiple times: {set([item for item in anchors if anchors.count(item) > 1])}"
)
class ConfigBuildKodakSerializer(BaseSchema):
@dataclass
class Container:
baseurl: str
link_original: bool
asset: str
banner: str
preload: str
baseurl = msh.fields.URL()
link_original = msh.fields.Boolean(missing=False)
asset = msh.fields.String()
banner = msh.fields.String()
preload = msh.fields.String()
class ConfigBuildSerializer(BaseSchema):
@dataclass
class Container:
generated: Path
posts: Path
static: Path
bundle: Path
templates: Path
post_base: str
kodak: ConfigBuildKodakSerializer.Container
generated = PathField(missing=Path("publish"))
posts = PathField(missing=Path("posts"))
static = PathField(missing=Path("static"))
bundle = PathField(missing=Path("bundle"))
templates = PathField(missing=Path("templates"))
post_base = msh.fields.String(
missing="explore", validate=msh.validate.Regexp(r"[a-z0-9\-]+")
)
kodak = msh.fields.Nested(ConfigBuildKodakSerializer, missing=None)
class ConfigSerializer(BaseSchema):
@dataclass
class Container:
domain: str
https: bool
baseurl: str
title: str
email: str
description: str
keywords: Sequence[str]
social: Dict[str, str]
build: ConfigBuildSerializer.Container
@property
def url(self) -> str:
return f"http{'s' if self.https else ''}://{self.domain}{self.baseurl}"
domain = msh.fields.String()
https = msh.fields.Boolean(missing=True)
baseurl = msh.fields.String()
title = msh.fields.String()
email = msh.fields.Email()
description = msh.fields.String()
keywords = msh.fields.List(
msh.fields.String(validate=msh.validate.Regexp(r"^[a-z0-9]+$"))
)
social = msh.fields.Dict(
keys=msh.fields.String(
validate=msh.validate.OneOf(
["instagram", "facebook", "twitter", "mastodon", "patreon"]
)
),
values=msh.fields.Url(),
missing=dict(),
)
build = msh.fields.Nested(ConfigBuildSerializer)
def get_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"-c",
"--config",
help="Path to the config file",
default=(Path.cwd() / "config.yaml"),
)
parser.add_argument(
"--check", action="store_true", help="Check the config without building"
)
parser.add_argument(
"--dev",
action="store_true",
help="Run local development server",
)
return parser.parse_args()
def _hash_from_file(path: Union[str, Path]):
"""Construct from a file path, generating the hash of the file
.. note:: This method attempts to _efficiently_ compute a hash of large image files. The
hashing code was adapted from here:
https://stackoverflow.com/a/44873382/5361209
"""
hasher = hashlib.sha256()
view = memoryview(bytearray(1024 * 1024))
with Path(path).open("rb", buffering=0) as infile:
for chunk in iter(lambda: infile.readinto(view), 0): # type: ignore
hasher.update(view[:chunk])
return hasher
def _copy_resource(path: Path, dest_dir: Path):
if path.is_file():
dest_dir.mkdir(parents=True, exist_ok=True)
shutil.copyfile(path, dest_dir / path.name, follow_symlinks=True)
elif path.is_dir():
for item in path.iterdir():
_copy_resource(item, dest_dir / path.name)
def _write_template(env: jinja2.Environment, name: str, dest: Path, **kwargs):
dest.parent.mkdir(exist_ok=True)
template = env.get_template(name).render(**kwargs)
minified = minify_html.minify(template, keep_comments=False)
with dest.open("w") as outfile:
outfile.write(minified)
def _build_bundle(
config: ConfigSerializer.Container, ftype: str, dest: str, sources: List[str]
) -> str:
(config.build.generated / ftype.lower()).mkdir(exist_ok=True, parents=True)
working_path = (
config.build.generated / ftype.lower() / f"{uuid.uuid4().hex}.{ftype.lower()}"
)
content: List[str] = []
for source in sources:
try:
with (
config.build.bundle / ftype.lower() / f"{source}.{ftype.lower()}"
).open("r") as infile:
content.append(infile.read())
except FileNotFoundError as err:
raise ValueError(
f"No {ftype.upper()} source file to bundle named '{source}'"
) from err
if ftype.lower() == "js":
minified = jsmin.jsmin("\n\n".join(content))
else:
minified = minify_html.minify("\n\n".join(content), keep_comments=False)
hasher = hashlib.sha256()
hasher.update(minified.encode("utf-8"))
slug = f"{dest}-{hasher.hexdigest()[:8]}"
final_path = config.build.generated / ftype.lower() / f"{slug}.{ftype.lower()}"
with final_path.open("w") as outfile:
outfile.write(minified)
return slug
def _dev(
cwd: Path,
config: ConfigSerializer.Container,
posts: Sequence[PostSerializer.Container],
):
config.https = False
config.domain = "localhost:5000"
config.base_url = "/"
# server = http.server.HTTPServer(
# ("127.0.0.1", 5000),
# functools.partial(
# http.server.SimpleHTTPRequestHandler, directory=str(cwd / config.build.generated)
# ),
# )
_build(cwd, config, posts)
# print(f"Serving dev site at {config.url}, press Ctrl+C to exit", file=sys.stderr)
# try:
# server.serve_forever()
# except KeyboardInterrupt:
# print("Stopping...", file=sys.stderr)
# server.shutdown()
def _build(
cwd: Path,
config: ConfigSerializer.Container,
posts: Sequence[PostSerializer.Container],
):
print(
f"Rebuilding static assets into {cwd / config.build.generated}", file=sys.stderr
)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(cwd / config.build.templates)),
autoescape=jinja2.select_autoescape(["html", "xml"]),
)
output = cwd / config.build.generated
static = cwd / config.build.static
today = datetime.datetime.utcnow()
bundle_slug = uuid.uuid4().hex[:8]
index_css_bundle = _build_bundle(config, "css", "index", ["common", "home"])
index_js_bundle = _build_bundle(
config, "js", "index", ["random-background", "preloader"]
)
_write_template(
env,
"index.html.j2",
output / "index.html",
config=config,
today=today,
css_bundle=index_css_bundle,
js_bundle=index_js_bundle,
)
_write_template(
env, "sitemap.xml.j2", output / "sitemap.xml", config=config, today=today
)
_write_template(
env,
"robots.txt.j2",
output / "robots.txt",
config=config,
today=today,
disallowed=[item.name for item in static.iterdir() if item.is_dir()],
)
static = cwd / config.build.static
if static.exists():
for item in static.iterdir():
_copy_resource(item, output)
explore_css_bundle = _build_bundle(config, "css", "explore", ["common", "explore"])
explore_js_bundle = _build_bundle(
config,
"js",
"explore",
["random-background", "preloader", "toggle-article-text-button"],
)
_write_template(
env,
"explore.html.j2",
output / config.build.post_base / "index.html",
config=config,
today=today,
posts=posts,
css_bundle=explore_css_bundle,
js_bundle=explore_js_bundle,
)
post_css_bundle = _build_bundle(config, "css", "post", ["common"])
post_js_bundle = _build_bundle(config, "js", "post", ["preloader"])
for post in posts:
_write_template(
env,
"post.html.j2",
output / config.build.post_base / post.slug / "index.html",
config=config,
today=today,
post=post,
css_bundle=post_css_bundle,
js_bundle=post_js_bundle,
)
def main():
args = get_args()
cwd = Path.cwd().resolve()
with Path(args.config).resolve().open(encoding="utf-8") as infile:
config = ConfigSerializer().load(yaml.load(infile))
posts = []
post_serializer = PostSerializer()
for item in (cwd / config.build.posts).iterdir():
if item.suffix.lower() == ".yaml":
with item.open() as infile:
raw = yaml.load(infile)
raw["slug"] = raw.get("slug", item.stem)
posts.append(post_serializer.load(raw))
slugs = [post.slug for post in posts]
if len(set(slugs)) != len(slugs):
raise msh.ValidationError("Duplicate post slugs found in config")
if args.check:
print("Config check successful!", file=sys.stderr)
return 0
posts = sorted(posts, key=lambda item: item.date, reverse=True)
if args.dev:
_dev(cwd, config, posts)
else:
_build(cwd, config, posts)
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@ -5,19 +5,13 @@ html {
font-family: Verdana, Helvetica, sans-serif;
}
a {
color: inherit;
text-decoration: none;
transition: all 0.1s ease-in-out;
}
a:hover {
text-decoration: none;
text-shadow: 5px 5px 10px #fff, -5px -5px 10px #fff;
body {
color: white;
font-family: sans-serif;
}
#background-image {
background-image: url("https://cdn.enp.one/img/backgrounds/cl-photo-allis.jpg");
background-image: url("https://cdn.enp.one/img/backgrounds/cl-photo-rt112.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
@ -38,136 +32,13 @@ a:hover {
z-index: 0;
}
#content {
text-align: center;
text-shadow: 3px 3px 5px #000, -3px -3px 5px #000;
font-weight: bold;
color: white;
padding: 1em;
width: 40em;
max-width: 90%;
background-color: rgba(0, 0, 0, 0.4);
border-style: solid;
border-width: 2px;
border-color: rgba(0, 0, 0, 0);
border-radius: 128px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 0);
z-index: 10;
}
#logo {
margin: auto;
margin-top: -5em;
max-width: 60%;
width: 50%;
display: block;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
border-width: 5px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4), 0 6px 20px 0 rgba(0, 0, 0, 0.4);
}
h1 {
font-variant: small-caps;
font-size: 2.5em;
}
#content p {
margin: 2em;
line-height: 1.5;
}
ul.buttons {
list-style: none;
padding-left: 0;
margin-top: 1em;
margin-bottom: 1em;
font-size: 1.75em;
}
ul.buttons li {
line-height: 1;
padding: 0.5em;
margin-left: 0.5em;
margin-right: 0.5em;
text-transform: uppercase;
}
.button.nav {
padding-top: 0.75em;
padding-bottom: 0.55em;
padding-left: 1.5em;
padding-right: 1.5em;
border-radius: 30px;
transition: all 0.25s ease-in-out;
}
.button:hover {
text-shadow:
-3px -3px 5px #fff,
-3px 3px 5px #fff,
3px -3px 5px #fff,
3px 3px 5px #fff,
0px 0px 7px #ff0000;
}
.button.nav:hover {
text-shadow:
0px 0px 7px #000,
-5px -5px 10px #fff,
-5px 5px 10px #fff,
5px -5px 10px #fff,
5px 5px 10px #fff;
-webkit-animation-name: pulse;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: none;
animation-name: pulse;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: none;
}
.explore:hover { color: #5588e0; }
.youtube:hover { color: #ff0000; }
.instagram:hover { color: #c13584; }
.twitter:hover { color: #1da1f2; }
#background-info {
text-align: right;
font-size: 0.85em;
padding: 0.75em;
#background-image .overlay {
background-color: rgba(0, 0, 0, 0.8);
width: 100%;
height: 100%;
position: fixed;
bottom: 0;
right: 0;
z-index: 5;
}
footer { font-size: 0.9em; }
footer div { margin-bottom: 0.5em; }
footer a.button i {
padding: 0.5em;
font-size: 1.25em;
top: 0;
left: 0;
}
.fadeout {
@ -227,49 +98,6 @@ footer a.button i {
100% {opacity: 0;}
}
@keyframes pulse {
0% {
box-shadow:
0px 0px 15px 3px #fff,
0px 0px 15px 3px #88a9fc;
}
10% {
box-shadow:
-10px -10px 15px 3px #fff,
10px 10px 15px 3px #88a9fc;
}
30% {
box-shadow:
-10px 10px 15px 3px #b5f7fc,
10px -10px 15px 3px #fcaa99;
}
45% {
box-shadow:
10px 10px 15px 3px #ecf9a7,
-10px -10px 15px 3px #fcaa99;
}
60% {
box-shadow:
10px -10px 15px 3px #ecf9a7,
-10px 10px 15px 3px #abfcad;
}
75% {
box-shadow:
-10px -10px 15px 3px #b5f7fc,
10px 10px 15px 3px #abfcad;
}
90% {
box-shadow:
-10px 10px 15px 3px #fff,
10px -10px 15px 3px #88a9fc;
}
100% {
box-shadow:
0px 0px 15px 3px #b5f7fc,
0px 0px 15px 3px #88a9fc;
}
}
@-webkit-keyframes spinner {
0% { transform: translate(-50%,-50%) rotate(0deg); }
100% { transform: translate(-50%,-50%) rotate(360deg); }
@ -280,25 +108,67 @@ footer a.button i {
100% { transform: translate(-50%,-50%) rotate(360deg); }
}
@media only screen and (max-width: 600px) {
#content {
padding: 0;
padding-bottom: 1em;
border-radius: 32px;
top: 6em;
}
#content p {
margin: 1em;
}
ul.buttons {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
ul.buttons li {
display: block;
margin-top: 1em;
}
a {
color: inherit;
text-decoration: none;
transition: all 0.1s ease-in-out;
}
a:hover {
text-decoration: none;
text-shadow: 5px 5px 10px #fff, -5px -5px 10px #fff;
}
ul.buttons {
list-style: none;
padding-left: 0;
margin-top: 1em;
margin-bottom: 1em;
font-size: 1.75em;
}
ul.buttons li {
line-height: 1;
padding: 0.5em;
margin-left: 0.5em;
margin-right: 0.5em;
text-transform: uppercase;
}
.button:hover {
text-shadow:
-3px -3px 5px #fff,
-3px 3px 5px #fff,
3px -3px 5px #fff,
3px 3px 5px #fff,
0px 0px 7px #ff0000;
}
.button.nav:hover {
text-shadow:
0px 0px 7px #000,
-5px -5px 10px #fff,
-5px 5px 10px #fff,
5px -5px 10px #fff,
5px 5px 10px #fff;
-webkit-animation-name: pulse;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: none;
animation-name: pulse;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: none;
}
.explore:hover { color: #5588e0; }
.youtube:hover { color: #ff0000; }
.instagram:hover { color: #c13584; }
.twitter:hover { color: #1da1f2; }

160
bundle/css/explore.css Normal file
View File

@ -0,0 +1,160 @@
ul {
list-style: none;
padding: 0;
}
#toggle-description {
position: fixed;
right: 0;
top: 0;
margin: 0.75em;
font-size: 1.5em;
width: 1em;
height: 1em;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.6);
padding: 0.5em;
transition: all 0.25s ease-in-out;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
z-index: 10;
}
#toggle-description:hover {
cursor: pointer;
box-shadow: 4px 4px 8px 0 rgba(255, 255, 255, 0.3), -4px -4px 8px 0 rgba(255, 255, 255, 0.3);
}
#toggle-description:hover, #toggle-description.active {
background-color: rgba(255, 255, 255, 0.8);
color: black;
}
#header {
font-variant: small-caps;
text-shadow: 3px 3px 5px #000;
text-align: left;
margin-bottom: 2em;
margin-top: 1em;
}
#header h1 {
border-bottom-style: solid;
padding-bottom: 1em;
margin-left: auto;
margin-right: auto;
width: 75%;
}
#header p {
margin-left: auto;
margin-right: auto;
width: 75%;
}
#header span {
float: right;
text-align: right;
font-size: 0.75em;
}
#header span a {
margin-left: 1em;
}
#content {
text-align: center;
max-width: 90%;
left: 50%;
width: 65em;
transform: translate(-50%, 0);
position: absolute;
}
.article {
height: 14em;
margin-bottom: 2em;
border-radius: 7em;
border-style: none;
border-color: rgba(0, 0, 0, 0);
border-width: 5px;
transition: all 0.25s ease-in-out;
color: rgba(0, 0, 0, 0);
text-align: center;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
}
.article:hover, .primary-text {
color: rgba(255, 255, 255, 1);
}
.article:hover {
box-shadow: 4px 4px 8px 0 rgba(255, 255, 255, 0.3), -4px -4px 8px 0 rgba(255, 255, 255, 0.3);
}
.article-banner {
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
width: 100%;
border-radius: 7em;
outline-style: none;
}
.article-content {
height: 14em;
overflow: hidden;
transition: all 0.25s ease-in-out;
display: block;
padding-left: 4em;
padding-right: 4em;
}
.article-content:hover, .primary-text .article-content {
background-color: rgba(0, 0, 0, 0.7);
text-shadow: 5px 5px 8px #000;
}
.article-content h2 {
text-transform: capitalize;
margin-top: 3em;
margin-bottom: 1.25em;
}
.article-content p {
font-weight: bold;
}
.article-content i {
margin-left: 1em;
margin-right: 0.7em;
}
@media only screen and (max-width: 600px) {
h1 { font-size: 1.5rem; }
h2 { font-size: 1.25rem; }
p { font-size: 0.9rem; }
#toggle-description { font-size: 1.25rem; }
.article {
border-radius: 3em;
margin-bottom: 1em;
}
.article-banner {
border-radius: 3em;
}
.article-content {
padding-left: 2em;
padding-right: 2em;
}
}

143
bundle/css/home.css Normal file
View File

@ -0,0 +1,143 @@
#content {
text-align: center;
text-shadow: 3px 3px 5px #000, -3px -3px 5px #000;
font-weight: bold;
color: white;
padding: 1em;
width: 40em;
max-width: 90%;
background-color: rgba(0, 0, 0, 0.4);
border-style: solid;
border-width: 2px;
border-color: rgba(0, 0, 0, 0);
border-radius: 128px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.6), 0 6px 20px 0 rgba(0, 0, 0, 0.6);
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 0);
z-index: 10;
}
#logo {
margin: auto;
margin-top: -5em;
max-width: 60%;
width: 50%;
display: block;
border-style: solid;
border-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
border-width: 5px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4), 0 6px 20px 0 rgba(0, 0, 0, 0.4);
}
h1 {
font-variant: small-caps;
font-size: 2.5em;
}
#content p {
margin: 2em;
line-height: 1.5;
}
.button.nav {
padding-top: 0.75em;
padding-bottom: 0.55em;
padding-left: 1.5em;
padding-right: 1.5em;
border-radius: 30px;
transition: all 0.25s ease-in-out;
}
#background-info {
text-align: right;
font-size: 0.85em;
padding: 0.75em;
position: fixed;
bottom: 0;
right: 0;
z-index: 5;
}
footer { font-size: 0.9em; }
footer div { margin-bottom: 0.5em; }
footer a.button i {
padding: 0.5em;
font-size: 1.25em;
}
@keyframes pulse {
0% {
box-shadow:
0px 0px 15px 3px #fff,
0px 0px 15px 3px #88a9fc;
}
10% {
box-shadow:
-10px -10px 15px 3px #fff,
10px 10px 15px 3px #88a9fc;
}
30% {
box-shadow:
-10px 10px 15px 3px #b5f7fc,
10px -10px 15px 3px #fcaa99;
}
45% {
box-shadow:
10px 10px 15px 3px #ecf9a7,
-10px -10px 15px 3px #fcaa99;
}
60% {
box-shadow:
10px -10px 15px 3px #ecf9a7,
-10px 10px 15px 3px #abfcad;
}
75% {
box-shadow:
-10px -10px 15px 3px #b5f7fc,
10px 10px 15px 3px #abfcad;
}
90% {
box-shadow:
-10px 10px 15px 3px #fff,
10px -10px 15px 3px #88a9fc;
}
100% {
box-shadow:
0px 0px 15px 3px #b5f7fc,
0px 0px 15px 3px #88a9fc;
}
}
@media only screen and (max-width: 600px) {
#content {
padding: 0;
padding-bottom: 1em;
border-radius: 32px;
top: 6em;
}
#content p {
margin: 1em;
}
ul.buttons {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
ul.buttons li {
display: block;
margin-top: 1em;
}
}

8
bundle/js/preloader.js Normal file
View File

@ -0,0 +1,8 @@
window.addEventListener("load", async function() {
document.getElementById("preloader").classList.add("fadeout");
// I don't actually know how promises or async works
// ¯\_(ツ)_/¯
// https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
await new Promise(r => setTimeout(r, 250))
document.getElementById("preloader").style.display = "none";
});

View File

@ -1,5 +1,3 @@
// Some quick scripting to select a random background on page load
const BACKGROUND_IMAGES = [
{
url: "https://cdn.enp.one/img/backgrounds/cl-photo-allis.jpg",
@ -68,7 +66,6 @@ const BACKGROUND_IMAGES = [
}
];
function selectBackground() {
let max = BACKGROUND_IMAGES.length - 1
let min = 0;
@ -77,21 +74,10 @@ function selectBackground() {
return BACKGROUND_IMAGES[index];
}
window.addEventListener("DOMContentLoaded", function () {
window.addEventListener("DOMContentLoaded", function() {
let selected = selectBackground()
document.getElementById(
"background-image"
).style.backgroundImage = "url(" + selected.url + ")";
});
window.addEventListener("load", async function () {
document.getElementById("preloader").classList.add("fadeout");
// I don't actually know how promises or async works
// ¯\_(ツ)_/¯
// https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
await new Promise(r => setTimeout(r, 250))
document.getElementById("preloader").style.display = "none";
});

View File

@ -0,0 +1,23 @@
function togglePrimaryText() {
let items = document.getElementsByClassName("article");
for (index = 0; index < items.length; index++) {
if (items[index].classList.contains("primary-text")) {
items[index].classList.remove("primary-text");
} else {
items[index].classList.add("primary-text");
}
}
let button = document.getElementById("toggle-description");
if (button.classList.contains("active")) {
button.classList.remove("active");
} else {
button.classList.add("active");
}
};
window.addEventListener("load", async function() {
document.getElementById("toggle-description").addEventListener("click", togglePrimaryText);
});

20
config.yaml Normal file
View File

@ -0,0 +1,20 @@
---
domain: allaroundhere.org
baseurl: /
title: All Around Here
email: me@allaroundhere.org
description: Some of the best places are all around here
keywords: [travel, photography, explore, exploration, urbex, urban, nature, all, around, here, local, museum, history, historical, society]
social:
instagram: https://www.instagram.com/allaroundhere/
twitter: https://www.twitter.com/enpaul_/
build:
generated: publish/
post_base: explore/
kodak:
baseurl: http://localhost:8000/
link_original: true
asset: web
banner: banner
preload: lowres

View File

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- Web crawler and search indexing meta -->
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="author" content="admin@allaroundhere.org"/>
<meta name="description" content="Some of the best places are all around here"/>
<meta name="robots" content="index follow"/>
<meta
name="keywords"
content="travel photography explore exploration urbex urban nature all around here local museum history historical society"
/>
<!-- Facebook integration meta -->
<meta property="og:title" content="All Around Here"/>
<meta property="og:url" content="https://allaroundhere.org/explore/"/>
<meta property='og:site_name' content="All Around Here"/>
<meta property="og:type" content="website"/>
<meta property='og:locale' content="en_US"/>
<meta property="og:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg"/>
<meta property='og:description' content="Some of the best places are all around here"/>
<!-- Twitter integration meta -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="https://allaroundhere.org/explore/">
<meta name="twitter:title" content="All Around Here">
<meta name="twitter:description" content="Some of the best places are all around here">
<meta name="twitter:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg">
<meta name="twitter:image:alt" content="All Around Here">
<title>All Around Here</title>
<link rel="shortcut icon" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.enp.one/img/logos/aah-b-sm.png" >
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="stylesheet" href="css/style.css"/>
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous"
/>
<script type="text/javascript" src="js/custom.js"></script>
<noscript><style>.nojs { display: none; }</style></noscript>
</head>
<body>
<div id="background-image"></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="content">
<img
id="logo"
alt="Road to the great wide nowhere"
src="https://cdn.enp.one/img/logos/aah-md.jpg"
/>
<h1>All Around Here</h1>
<p>
This is a project of mine where I turn my random travels, undirected wanderings, and
unexpected discoveries into something other people can enjoy along with me. There are a
lot of cool things in the world and I like to find them, wherever I happen to be. If you're
interested in seeing some of these arbitrary oddities then check out the links below.
</p>
<ul class="buttons">
<li>
<a class="button nav" title="Explore All Around Here" href="explore/">
<i class="fas fa-binoculars"></i>&nbsp;Explore
</a>
</li>
</ul>
<footer>
<div>
<!-- <a
class="button youtube"
title="Subscribe to All Around Here on YouTube"
href="https://www.instagram.com/allaroundhere/"
>
<i class="fab fa-youtube"></i>
</a> -->
<a
class="button instagram"
title="Follow All Around Here on instagram @allaroundhere"
href="https://www.instagram.com/allaroundhere/"
>
<i class="fab fa-instagram"></i>
</a>
<a
class="button twitter"
title="Follow me on twitter @enpaul_"
href="https://www.twitter.com/enpaul_/"
>
<i class="fab fa-twitter"></i>
</a>
</div>
<div>
<a title="Personal website" href="https://enpaul.net/">&copy;2021 enpaul</a>
</div>
</footer>
</div>
</body>
</html>

885
poetry.lock generated Normal file
View File

@ -0,0 +1,885 @@
[[package]]
name = "appdirs"
version = "1.4.4"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "appnope"
version = "0.1.2"
description = "Disable App Nap on macOS >= 10.9"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "aspy.refactor-imports"
version = "2.2.0"
description = "Utilities for refactoring imports in python-like syntax."
category = "dev"
optional = false
python-versions = ">=3.6.1"
[package.dependencies]
cached-property = "*"
[[package]]
name = "attrs"
version = "21.2.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
[[package]]
name = "backcall"
version = "0.2.0"
description = "Specifications for callback functions passed in to an API"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "black"
version = "22.1.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = ">=1.1.0"
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "cached-property"
version = "1.5.2"
description = "A decorator for caching properties in classes."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "cfgv"
version = "3.2.0"
description = "Validate configuration and produce human readable error messages."
category = "dev"
optional = false
python-versions = ">=3.6.1"
[[package]]
name = "click"
version = "8.0.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.4"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "decorator"
version = "5.1.0"
description = "Decorators for Humans"
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]]
name = "distlib"
version = "0.3.1"
description = "Distribution utilities"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "filelock"
version = "3.0.12"
description = "A platform independent file lock."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "identify"
version = "2.2.4"
description = "File identification library for Python"
category = "dev"
optional = false
python-versions = ">=3.6.1"
[package.extras]
license = ["editdistance-s"]
[[package]]
name = "importlib-metadata"
version = "4.8.1"
description = "Read metadata from Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
perf = ["ipython"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
[[package]]
name = "ipython"
version = "7.28.0"
description = "IPython: Productive Interactive Computing"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
appnope = {version = "*", markers = "sys_platform == \"darwin\""}
backcall = "*"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
decorator = "*"
jedi = ">=0.16"
matplotlib-inline = "*"
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
pickleshare = "*"
prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
pygments = "*"
traitlets = ">=4.2"
[package.extras]
all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"]
doc = ["Sphinx (>=1.3)"]
kernel = ["ipykernel"]
nbconvert = ["nbconvert"]
nbformat = ["nbformat"]
notebook = ["notebook", "ipywidgets"]
parallel = ["ipyparallel"]
qtconsole = ["qtconsole"]
test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"]
[[package]]
name = "jedi"
version = "0.18.0"
description = "An autocompletion tool for Python that can be used for text editors."
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
parso = ">=0.8.0,<0.9.0"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"]
[[package]]
name = "jinja2"
version = "2.11.3"
description = "A very fast and expressive template engine."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.dependencies]
MarkupSafe = ">=0.23"
[package.extras]
i18n = ["Babel (>=0.8)"]
[[package]]
name = "jsmin"
version = "3.0.0"
description = "JavaScript minifier."
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "markdown-it-py"
version = "1.1.0"
description = "Python port of markdown-it. Markdown parsing, done right!"
category = "dev"
optional = false
python-versions = "~=3.6"
[package.dependencies]
attrs = ">=19,<22"
[package.extras]
code_style = ["pre-commit (==2.6)"]
compare = ["commonmark (>=0.9.1,<0.10.0)", "markdown (>=3.2.2,<3.3.0)", "mistletoe-ebp (>=0.10.0,<0.11.0)", "mistune (>=0.8.4,<0.9.0)", "panflute (>=1.12,<2.0)"]
linkify = ["linkify-it-py (>=1.0,<2.0)"]
plugins = ["mdit-py-plugins"]
rtd = ["myst-nb (==0.13.0a1)", "pyyaml", "sphinx (>=2,<4)", "sphinx-copybutton", "sphinx-panels (>=0.4.0,<0.5.0)", "sphinx-book-theme"]
testing = ["coverage", "psutil", "pytest (>=3.6,<4)", "pytest-benchmark (>=3.2,<4.0)", "pytest-cov", "pytest-regressions"]
[[package]]
name = "markupsafe"
version = "1.1.1"
description = "Safely add untrusted strings to HTML/XML markup."
category = "main"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
[[package]]
name = "marshmallow"
version = "3.11.1"
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
category = "main"
optional = false
python-versions = ">=3.5"
[package.extras]
dev = ["pytest", "pytz", "simplejson", "mypy (==0.812)", "flake8 (==3.9.0)", "flake8-bugbear (==21.3.2)", "pre-commit (>=2.4,<3.0)", "tox"]
docs = ["sphinx (==3.4.3)", "sphinx-issues (==1.2.0)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.2)"]
lint = ["mypy (==0.812)", "flake8 (==3.9.0)", "flake8-bugbear (==21.3.2)", "pre-commit (>=2.4,<3.0)"]
tests = ["pytest", "pytz", "simplejson"]
[[package]]
name = "matplotlib-inline"
version = "0.1.3"
description = "Inline Matplotlib backend for Jupyter"
category = "dev"
optional = false
python-versions = ">=3.5"
[package.dependencies]
traitlets = "*"
[[package]]
name = "mdformat"
version = "0.7.10"
description = "CommonMark compliant Markdown formatter"
category = "dev"
optional = false
python-versions = ">=3.7,<4.0"
[package.dependencies]
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
markdown-it-py = ">=1.0.0b2,<2.0.0"
tomli = ">=1.1.0"
[[package]]
name = "minify-html"
version = "0.8.0"
description = "Extremely fast and smart HTML + JS + CSS minifier"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "nodeenv"
version = "1.6.0"
description = "Node.js virtual environment builder"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "parso"
version = "0.8.2"
description = "A Python Parser"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.9.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "pexpect"
version = "4.8.0"
description = "Pexpect allows easy control of interactive console applications."
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
ptyprocess = ">=0.5"
[[package]]
name = "pickleshare"
version = "0.7.5"
description = "Tiny 'shelve'-like database with concurrency support"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "platformdirs"
version = "2.4.1"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
[[package]]
name = "pre-commit"
version = "2.12.1"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
category = "dev"
optional = false
python-versions = ">=3.6.1"
[package.dependencies]
cfgv = ">=2.0.0"
identify = ">=1.0.0"
nodeenv = ">=0.11.1"
pyyaml = ">=5.1"
toml = "*"
virtualenv = ">=20.0.8"
[[package]]
name = "pre-commit-hooks"
version = "3.4.0"
description = "Some out-of-the-box hooks for pre-commit."
category = "dev"
optional = false
python-versions = ">=3.6.1"
[package.dependencies]
"ruamel.yaml" = ">=0.15"
toml = "*"
[[package]]
name = "prompt-toolkit"
version = "3.0.20"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
wcwidth = "*"
[[package]]
name = "ptyprocess"
version = "0.7.0"
description = "Run a subprocess in a pseudo terminal"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "pygments"
version = "2.10.0"
description = "Pygments is a syntax highlighting package written in Python."
category = "dev"
optional = false
python-versions = ">=3.5"
[[package]]
name = "pyyaml"
version = "5.4.1"
description = "YAML parser and emitter for Python"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[[package]]
name = "reorder-python-imports"
version = "2.4.0"
description = "Tool for reordering python imports"
category = "dev"
optional = false
python-versions = ">=3.6.1"
[package.dependencies]
"aspy.refactor-imports" = ">=2.1.0"
[[package]]
name = "ruamel.yaml"
version = "0.17.4"
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
category = "main"
optional = false
python-versions = ">=3"
[package.dependencies]
"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.10\""}
[package.extras]
docs = ["ryd"]
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
[[package]]
name = "ruamel.yaml.clib"
version = "0.2.2"
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "six"
version = "1.15.0"
description = "Python 2 and 3 compatibility utilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "tomli"
version = "1.2.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.6"
[[package]]
name = "traitlets"
version = "5.1.0"
description = "Traitlets Python configuration system"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
test = ["pytest"]
[[package]]
name = "typing-extensions"
version = "4.0.1"
description = "Backported and Experimental Type Hints for Python 3.6+"
category = "dev"
optional = false
python-versions = ">=3.6"
[[package]]
name = "virtualenv"
version = "20.4.4"
description = "Virtual Python Environment builder"
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
[package.dependencies]
appdirs = ">=1.4.3,<2"
distlib = ">=0.3.1,<1"
filelock = ">=3.0.0,<4"
six = ">=1.9.0,<2"
[package.extras]
docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"]
testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
[[package]]
name = "wcwidth"
version = "0.2.5"
description = "Measures the displayed width of unicode strings in a terminal"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "zipp"
version = "3.6.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "a1028b5917bdf0e31b39431da10311b8a331bbfa12909ab889c6321698c62694"
[metadata.files]
appdirs = [
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
]
appnope = [
{file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
{file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"},
]
"aspy.refactor-imports" = [
{file = "aspy.refactor_imports-2.2.0-py2.py3-none-any.whl", hash = "sha256:7a18039d2e8be6b02b4791ce98891deb46b459b575c52ed35ab818c4eaa0c098"},
{file = "aspy.refactor_imports-2.2.0.tar.gz", hash = "sha256:78ca24122963fd258ebfc4a8dc708d23a18040ee39dca8767675821e84e9ea0a"},
]
attrs = [
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
]
backcall = [
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
{file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
]
black = [
{file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"},
{file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"},
{file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"},
{file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"},
{file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"},
{file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"},
{file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"},
{file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"},
{file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"},
{file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"},
{file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"},
{file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"},
{file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"},
{file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"},
{file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"},
{file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"},
{file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"},
{file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"},
{file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"},
{file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"},
{file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"},
{file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"},
{file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"},
]
cached-property = [
{file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
{file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"},
]
cfgv = [
{file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"},
{file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"},
]
click = [
{file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
{file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"},
]
colorama = [
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
decorator = [
{file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"},
{file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"},
]
distlib = [
{file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"},
{file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"},
]
filelock = [
{file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
{file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
]
identify = [
{file = "identify-2.2.4-py2.py3-none-any.whl", hash = "sha256:ad9f3fa0c2316618dc4d840f627d474ab6de106392a4f00221820200f490f5a8"},
{file = "identify-2.2.4.tar.gz", hash = "sha256:9bcc312d4e2fa96c7abebcdfb1119563b511b5e3985ac52f60d9116277865b2e"},
]
importlib-metadata = [
{file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"},
{file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"},
]
ipython = [
{file = "ipython-7.28.0-py3-none-any.whl", hash = "sha256:f16148f9163e1e526f1008d7c8d966d9c15600ca20d1a754287cf96d00ba6f1d"},
{file = "ipython-7.28.0.tar.gz", hash = "sha256:2097be5c814d1b974aea57673176a924c4c8c9583890e7a5f082f547b9975b11"},
]
jedi = [
{file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"},
{file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"},
]
jinja2 = [
{file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
{file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
]
jsmin = [
{file = "jsmin-3.0.0.tar.gz", hash = "sha256:88fc1bd6033a47c5911dbcada7d279c7a8b7ad0841909590f6a742c20c4d2e08"},
]
markdown-it-py = [
{file = "markdown-it-py-1.1.0.tar.gz", hash = "sha256:36be6bb3ad987bfdb839f5ba78ddf094552ca38ccbd784ae4f74a4e1419fc6e3"},
{file = "markdown_it_py-1.1.0-py3-none-any.whl", hash = "sha256:98080fc0bc34c4f2bcf0846a096a9429acbd9d5d8e67ed34026c03c61c464389"},
]
markupsafe = [
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
{file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
{file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"},
{file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"},
{file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"},
{file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"},
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
]
marshmallow = [
{file = "marshmallow-3.11.1-py2.py3-none-any.whl", hash = "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd"},
{file = "marshmallow-3.11.1.tar.gz", hash = "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b"},
]
matplotlib-inline = [
{file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
{file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
]
mdformat = [
{file = "mdformat-0.7.10-py3-none-any.whl", hash = "sha256:27bd8ebecb3c02ac90ccef93702b16587e8dc6f302a90b8d7381cad6b72c69e1"},
{file = "mdformat-0.7.10.tar.gz", hash = "sha256:bb086c56445a56d2d256e3b47504ccb96d03628f091f4d687cd456944ca91158"},
]
minify-html = [
{file = "minify_html-0.8.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:18ad08813517757a3130532b221355ca0859b41b2fafac59db74782db67b92a8"},
{file = "minify_html-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ccaaefd5b81b99fe1a9c16158c5d79a5396959d03e017934f765b511c5e876c"},
{file = "minify_html-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7be4458bb1b0b58bb1bc95563c1b65d75ba5096683281fb280dfd6ec865d2ea"},
{file = "minify_html-0.8.0-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:156c7387caa3196d3762f5dbf5c61d894889f04d49750a00fb9fb1259394ce89"},
{file = "minify_html-0.8.0-cp310-none-win_amd64.whl", hash = "sha256:1cfeb9802aacf68b9e888b6589c5b6b48bd56cc26a5e10c84058f9b42e52ec4e"},
{file = "minify_html-0.8.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:44c0cc36e1d3858cf8b21ba6b24fbd8a6e9baddc5d60f5cbef22f603c63b234b"},
{file = "minify_html-0.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a13c30375e3942c785bbff14b1d46cb9ae83433f29cf27fe176863b9dd90f06"},
{file = "minify_html-0.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1656962670273ba4e0c3edf369afd07c3443e2684bed459f0c0927d62ab3064b"},
{file = "minify_html-0.8.0-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:528372bfca7d1fbd11edeb5c76c415da50638480b2191682824f3de2a7a295ff"},
{file = "minify_html-0.8.0-cp38-none-win_amd64.whl", hash = "sha256:9f7697139ca7aa150e3706a1fa21094991c36503525bfa6482e9af973a8a7c13"},
{file = "minify_html-0.8.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:68fa4c1982f2058a9ff3db6adc4c0582ba2e4166e99e6b6e8fed5ac21416954e"},
{file = "minify_html-0.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:930dc7c8f26b96eb5685b9f8bd498d2bfe3c835437b1b41ff99e13ccb91ed06e"},
{file = "minify_html-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c312d700f52a69af18dbc95b95669f5dc298f433b3c3b0911fa7441c3c7cfeeb"},
{file = "minify_html-0.8.0-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:5f75e7484ba09a8c313428bdce7e6aca1340231e5e6983d3246be7d7c964587e"},
{file = "minify_html-0.8.0-cp39-none-win_amd64.whl", hash = "sha256:bac93bb286751af2ad2db5d6e63f54e30fc1632a1fb3b6622cad180d67aa4cb5"},
]
mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
nodeenv = [
{file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"},
{file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"},
]
parso = [
{file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"},
{file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"},
]
pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
pexpect = [
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
]
pickleshare = [
{file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
]
platformdirs = [
{file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"},
{file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"},
]
pre-commit = [
{file = "pre_commit-2.12.1-py2.py3-none-any.whl", hash = "sha256:70c5ec1f30406250b706eda35e868b87e3e4ba099af8787e3e8b4b01e84f4712"},
{file = "pre_commit-2.12.1.tar.gz", hash = "sha256:900d3c7e1bf4cf0374bb2893c24c23304952181405b4d88c9c40b72bda1bb8a9"},
]
pre-commit-hooks = [
{file = "pre_commit_hooks-3.4.0-py2.py3-none-any.whl", hash = "sha256:b1d329fc712f53f56af7c4a0ac08c414a7fcfd634dbd829c3a03f39cfb9c3574"},
{file = "pre_commit_hooks-3.4.0.tar.gz", hash = "sha256:57e377b931aceead550e4a7bdbe8065e79e371e80f593b5b6d1129e63a77154f"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.20-py3-none-any.whl", hash = "sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c"},
{file = "prompt_toolkit-3.0.20.tar.gz", hash = "sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"},
]
ptyprocess = [
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
]
pygments = [
{file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"},
{file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"},
]
pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
{file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"},
{file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"},
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
]
reorder-python-imports = [
{file = "reorder_python_imports-2.4.0-py2.py3-none-any.whl", hash = "sha256:995a2a93684af31837f30cf2bcddce2e7eb17f0d2d69c9905da103baf8cec42b"},
{file = "reorder_python_imports-2.4.0.tar.gz", hash = "sha256:9a9e7774d66e9b410b619f934e8206a63dce5be26bd894f5006eb764bba6a26d"},
]
"ruamel.yaml" = [
{file = "ruamel.yaml-0.17.4-py3-none-any.whl", hash = "sha256:ac79fb25f5476e8e9ed1c53b8a2286d2c3f5dde49eb37dbcee5c7eb6a8415a22"},
{file = "ruamel.yaml-0.17.4.tar.gz", hash = "sha256:44bc6b54fddd45e4bc0619059196679f9e8b79c027f4131bb072e6a22f4d5e28"},
]
"ruamel.yaml.clib" = [
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:28116f204103cb3a108dfd37668f20abe6e3cafd0d3fd40dba126c732457b3cc"},
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:daf21aa33ee9b351f66deed30a3d450ab55c14242cfdfcd377798e2c0d25c9f1"},
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-win32.whl", hash = "sha256:30dca9bbcbb1cc858717438218d11eafb78666759e5094dd767468c0d577a7e7"},
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f6061a31880c1ed6b6ce341215336e2f3d0c1deccd84957b6fa8ca474b41e89f"},
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:73b3d43e04cc4b228fa6fa5d796409ece6fcb53a6c270eb2048109cbcbc3b9c2"},
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:53b9dd1abd70e257a6e32f934ebc482dac5edb8c93e23deb663eac724c30b026"},
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:839dd72545ef7ba78fd2aa1a5dd07b33696adf3e68fae7f31327161c1093001b"},
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1236df55e0f73cd138c0eca074ee086136c3f16a97c2ac719032c050f7e0622f"},
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-win32.whl", hash = "sha256:b1e981fe1aff1fd11627f531524826a4dcc1f26c726235a52fcb62ded27d150f"},
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4e52c96ca66de04be42ea2278012a2342d89f5e82b4512fb6fb7134e377e2e62"},
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a873e4d4954f865dcb60bdc4914af7eaae48fb56b60ed6daa1d6251c72f5337c"},
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ab845f1f51f7eb750a78937be9f79baea4a42c7960f5a94dde34e69f3cce1988"},
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2fd336a5c6415c82e2deb40d08c222087febe0aebe520f4d21910629018ab0f3"},
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-win32.whl", hash = "sha256:e9f7d1d8c26a6a12c23421061f9022bb62704e38211fe375c645485f38df34a2"},
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2602e91bd5c1b874d6f93d3086f9830f3e907c543c7672cf293a97c3fabdcd91"},
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:44c7b0498c39f27795224438f1a6be6c5352f82cb887bc33d962c3a3acc00df6"},
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8e8fd0a22c9d92af3a34f91e8a2594eeb35cba90ab643c5e0e643567dc8be43e"},
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:75f0ee6839532e52a3a53f80ce64925ed4aed697dd3fa890c4c918f3304bd4f4"},
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-win32.whl", hash = "sha256:464e66a04e740d754170be5e740657a3b3b6d2bcc567f0c3437879a6e6087ff6"},
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:52ae5739e4b5d6317b52f5b040b1b6639e8af68a5b8fd606a8b08658fbd0cab5"},
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df5019e7783d14b79217ad9c56edf1ba7485d614ad5a385d1b3c768635c81c0"},
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5254af7d8bdf4d5484c089f929cb7f5bafa59b4f01d4f48adda4be41e6d29f99"},
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8be05be57dc5c7b4a0b24edcaa2f7275866d9c907725226cdde46da09367d923"},
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win32.whl", hash = "sha256:74161d827407f4db9072011adcfb825b5258a5ccb3d2cd518dd6c9edea9e30f1"},
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:058a1cc3df2a8aecc12f983a48bda99315cebf55a3b3a5463e37bb599b05727b"},
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6ac7e45367b1317e56f1461719c853fd6825226f45b835df7436bb04031fd8a"},
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b4b0d31f2052b3f9f9b5327024dc629a253a83d8649d4734ca7f35b60ec3e9e5"},
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1f8c0a4577c0e6c99d208de5c4d3fd8aceed9574bb154d7a2b21c16bb924154c"},
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-win32.whl", hash = "sha256:46d6d20815064e8bb023ea8628cfb7402c0f0e83de2c2227a88097e239a7dffd"},
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6c0a5dc52fc74eb87c67374a4e554d4761fd42a4d01390b7e868b30d21f4b8bb"},
{file = "ruamel.yaml.clib-0.2.2.tar.gz", hash = "sha256:2d24bd98af676f4990c4d715bcdc2a60b19c56a3fb3a763164d2d8ca0e806ba7"},
]
six = [
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
{file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
tomli = [
{file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"},
{file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"},
]
traitlets = [
{file = "traitlets-5.1.0-py3-none-any.whl", hash = "sha256:03f172516916220b58c9f19d7f854734136dd9528103d04e9bf139a92c9f54c4"},
{file = "traitlets-5.1.0.tar.gz", hash = "sha256:bd382d7ea181fbbcce157c133db9a829ce06edffe097bcf3ab945b435452b46d"},
]
typing-extensions = [
{file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
{file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
]
virtualenv = [
{file = "virtualenv-20.4.4-py2.py3-none-any.whl", hash = "sha256:a935126db63128861987a7d5d30e23e8ec045a73840eeccb467c148514e29535"},
{file = "virtualenv-20.4.4.tar.gz", hash = "sha256:09c61377ef072f43568207dc8e46ddeac6bcdcaf288d49011bda0e7f4d38c4a2"},
]
wcwidth = [
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
]
zipp = [
{file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
{file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"},
]

View File

@ -0,0 +1,42 @@
---
title: Behemouth Waterworks from the Age of Steam
description: >-
The Metropolitan Waterworks Museum in Boston Massachusetts was once the centerpoint of the most
advanced municipal water system in America. Today, it educates visitors on the evolution of
Boston's incredible water system and perserves the amazing steam engines that made it possible.
location:
title: Boston, MA
link: https://maps.google.com
date: 2019-05-18
banner: allis
links:
- title: Instagram
icon: fab fa-instagram
url: https://www.instagram.com/p/B1j4w3cgPBq/
- title: Metropolitan Waterworks Museum
url: https://waterworksmuseum.org/
media:
- title: Chestnut Hill Reservoir
link: chestnut-hill
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- title: The Cathedral of Steam
link: high-service-pumping-station
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- title: "Mechanical Art: The Leavitt Engine"
link: leavitt-internals
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View File

@ -0,0 +1,8 @@
---
title: The three hundred year old fort with delusions of grandeur
location:
title: Hull, MA
link: https://maps.google.com
date: 2021-04-12
banner: hull-overlook
media: []

View File

@ -0,0 +1,8 @@
---
title: Talcott's "Castle on the Mountain" does not dissapoint
location:
title: Simsbury, CT
link: https://maps.google.com
date: 2021-04-01
banner: heubline-tower
media: []

View File

@ -0,0 +1,8 @@
---
title: Supervillian lair or air traffic control station?
location:
title: North Truro, MA
link: https://maps.google.com
date: 2021-02-28
banner: north-turo-air-station
media: []

View File

@ -0,0 +1,8 @@
---
title: The Most Essential Lighthouse
location:
title: York, ME
link: https://maps.google.com
date: 2020-11-29
banner: nubble-lighthouse
media: []

26
pyproject.toml Normal file
View File

@ -0,0 +1,26 @@
[tool.poetry]
name = "allaroundhere.org"
version = "0.0.0"
description = ""
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = "^3.8"
"ruamel.yaml" = "^0.17.4"
Jinja2 = "^2.11.3"
marshmallow = "^3.11.1"
minify-html = "^0.8.0"
jsmin = "^3.0.0"
[tool.poetry.dev-dependencies]
ipython = "^7.28.0"
mdformat = "^0.7.10"
pre-commit = "^2.12.1"
pre-commit-hooks = "^3.4.0"
reorder-python-imports = "^2.4.0"
black = "^22.1.0"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

View File

@ -1,8 +0,0 @@
# Allow all bots
User-agent: *
# Disallow access to non-content directories
Disallow: /css
Disallow: /js
Sitemap: https://allaroundhere.org/sitemap.xml

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
<url>
<loc>https://allaroundhere.org/</loc>
<lastmod>2021-02-01T00:30:55+00:00</lastmod>
<priority>1.00</priority>
</url>
</urlset>

0
static/error/400.html Normal file
View File

0
static/error/404.html Normal file
View File

0
static/error/500.html Normal file
View File

0
static/error/502.html Normal file
View File

40
templates/explore.html.j2 Normal file
View File

@ -0,0 +1,40 @@
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
{{ make_header(config, alttitle="Explore " + config.title, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="background-image"><div class="overlay"></div></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="toggle-description" class="nojs active"><i class="fas fa-paragraph"></i></div>
<div id="content">
<div id="header">
<h1>
Explore {{ config.title }}
<span class="float-right">
{{ make_social_links(config) }}
</span>
</h1>
</div>
<ul>
{% for post in posts %}
<li class="article primary-text{{ ' hidden' if loop.index > 10 else '' }}">
<div class="article-banner" style="background-image: url('{{ post.banner_url(config) }}');">
<a href="{{ post.slug }}/" class="article-content">
<h2>{{ post.title }}</h2>
<p>
<i class="fas fa-map-marker-alt"></i>{{ post.location.title }}
<i class="far fa-calendar-alt"></i>{{ post.date }}
</p>
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>

44
templates/index.html.j2 Normal file
View File

@ -0,0 +1,44 @@
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
{{ make_header(config, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="background-image"></div>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
<div id="content">
<img
id="logo"
alt="Road to the great wide nowhere"
src="https://cdn.enp.one/img/logos/aah-md.jpg"
/>
<h1>{{ config.title }}</h1>
<p>
This is a project of mine where I turn my random travels, undirected wanderings, and
unexpected discoveries into something other people can enjoy along with me. There are a
lot of cool things in the world and I like to find them, wherever I happen to be. If you're
interested in seeing some of these arbitrary oddities then check out the links below.
</p>
<ul class="buttons">
<li>
<a class="button nav" title="Explore All Around Here" href="{{ config.baseurl }}{{ config.build.post_base }}">
<i class="fas fa-binoculars"></i>&nbsp;Explore
</a>
</li>
</ul>
<footer>
<div>
{{ make_social_links(config) }}
</div>
<div>
<a title="Personal website" href="https://enpaul.net/">&copy;2022-{{ today.year }} enpaul</a>
</div>
</footer>
</div>
</body>
</html>

62
templates/macros.html.j2 Normal file
View File

@ -0,0 +1,62 @@
{% macro make_header(config, alttitle=none, css_bundle=none, js_bundle=none) %}
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<!-- Web crawler and search indexing meta -->
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="author" content="{{ config.email }}"/>
<meta name="description" content="{{ config.description }}"/>
<meta name="robots" content="index follow"/>
<meta name="keywords" content="{{ config.keywords | join(' ') }}"/>
<!-- Facebook integration meta -->
<meta property="og:title" content="{{ alttitle or config.title }}"/>
<meta property="og:url" content="{{ config.url }}{{ config.build.post_base }}"/>
<meta property='og:site_name' content="{{ config.title }}"/>
<meta property="og:type" content="website"/>
<meta property='og:locale' content="en_US"/>
<meta property="og:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg"/>
<meta property='og:description' content="{{ config.description }}"/>
<!-- Twitter integration meta -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="{{ config.url }}{{ config.build.post_base }}">
<meta name="twitter:title" content="{{ alttitle or config.title }}">
<meta name="twitter:description" content="{{ config.description }}">
<meta name="twitter:image" content="https://cdn.enp.one/img/backgrounds/cl-photo-boston.jpg">
<meta name="twitter:image:alt" content="{{ config.title }}">
<title>{{ alttitle or config.title }}</title>
<link rel="shortcut icon" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://cdn.enp.one/img/logos/aah-b-sm.png" >
<link rel="icon" type="image/png" sizes="16x16" href="https://cdn.enp.one/img/logos/aah-b-sm.png">
{% if css_bundle %}<link rel="stylesheet" href="{{ config.baseurl }}css/{{ css_bundle }}.css"/>{% endif %}
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous"
/>
{% if js_bundle %}<script type="text/javascript" src="{{ config.baseurl }}js/{{ js_bundle }}.js"></script>{% endif %}
<noscript><style>.nojs { display: none; }</style></noscript>
</head>
{% endmacro %}
{% macro make_social_links(config) %}
{% for social, link in config.social.items() %}
<a
class="button {{ social }}"
title="Follow me on {{ social }} @{{ link.rstrip('/').rpartition('/')[-1] }}"
href="{{ link }}"
>
<i class="fab fa-{{ social }}"></i>
</a>
{% endfor %}
{% endmacro %}

22
templates/nginx.conf.d.j2 Normal file
View File

@ -0,0 +1,22 @@
error_page 404 error/404.html;
location = error/404.html {
internal;
}
location = robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = explore/ {
index index.html
}
location ~* explore/(.*)/ {
if ($request_uri ~ ^/(.*)\.html) {
return 302 explore/$1/;
}
try_files $uri $uri.html $uri/ =404;
}
}

43
templates/post.html.j2 Normal file
View File

@ -0,0 +1,43 @@
{% from "macros.html.j2" import make_header %}{% from "macros.html.j2" import make_social_links %}<!DOCTYPE html>
<html lang="en">
{{ make_header(config, alttitle=post.title, css_bundle=css_bundle, js_bundle=js_bundle) }}
<body>
<div id="preloader" class="nojs"><div class="spinner"><div></div></div></div>
{% for media in post.media %}
<div class="post-media" style="background-image: url('{{ media.preload_url(config) }}')"><div class="overlay"></div></div>
{% endfor %}
<div id="download-source" class="nojs"><i class="fas fa-cloud-download-alt"></i></div>
<div id="link" class="nojs"><i class="fas fa-link"></i></div>
<div id="media-previous" class="nojs"><i class="fas fa-chevron-left"></i></div>
<div id="media-next" class="nojs"><i class="fas fa-chevron-right"></i></div>
<div id="content">
<div id="header">
<h1>
Explore {{ config.title }}
<span class="float-right">
{{ make_social_links(config) }}
</span>
</h1>
</div>
<ul>
{% for post in posts %}
<li class="article primary-text">
<div class="article-banner" style="background-image: url('{{ post.banner_url(config) }}');">
<a href="{{ post.slug }}/" class="article-content">
<h2>{{ post.title }}</h2>
<p>
<i class="fas fa-map-marker-alt"></i>{{ post.location.title }}
<i class="far fa-calendar-alt"></i>{{ post.date }}
</p>
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</body>
</html>

7
templates/robots.txt.j2 Normal file
View File

@ -0,0 +1,7 @@
# Allow all bots
User-agent: *
# Disallow access to non-content directories{% for path in disallowed %}
Disallow: {{ path }}{% endfor %}
Sitemap: {{ config.url }}sitemap.xml

28
templates/sitemap.xml.j2 Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>{{ config.url }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>0.90</priority>
</url>
<url>
<loc>{{ config.url }}{{ config.build.post_base }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>1.00</priority>
</url>
{% for post in config.posts %}
<url>
<loc>{{ config.url }}{{ config.build.post_base }}{{ post.slug }}</loc>
<lastmod>{{ today.strftime('%Y-%m-%dT%H:%M:%S') }}+00:00</lastmod>
<priority>0.80</priority>
</url>
{% endfor %}
</urlset>