[HN Gopher] Launch HN: Wasp (YC W21) - DSL for building full-sta...
___________________________________________________________________
Launch HN: Wasp (YC W21) - DSL for building full-stack web apps
Hi HN! We are Martin and Matija, twin brothers and creators of
Wasp (https://wasp-lang.dev). Wasp is a declarative language that
makes it really easy to build full-stack web apps while still using
the latest technologies such as React, Node.js and Prisma. Martin
and I both studied computer science where we mostly focused on
algorithms for bioinformatics. Afterwards we led engineering teams
in several SaaS companies, on the way gaining plenty of experience
in building web apps. Moving from one project to another, we used
various technologies: JQuery -> Backbone -> Angular -> React, own
scripts / makefile -> Grunt -> Gulp -> Webpack, PHP -> Java ->
Node.js, ... , and we always felt that things are harder than they
should be. We were spending a lot of time adopting the latest tech
stack and figuring out the best practices: how to make the web app
performant, scalable, economical and secure and also how to connect
all the pieces of the stack together. While the tech stack kept
advancing rapidly, the core requirements of the apps we were
building changed very little (auth, routing, data model CRUD, ACL,
...). That is why about 1.5 years ago we started thinking about
separating web app specification (what it should do) from its
implementation (how it should do it). This led us to the idea of
extracting common web app features and concepts into a special
specification language from which we could generate code in the
currently popular technologies. We don't think it is feasible to
replace everything with a single language so that is why we went
with a DSL which integrates with the modern stack (right now React,
NodeJS, Prisma). Wasp lets you define high-level aspects of your
web app (auth, routing, ACL, data models, CRUD) via a simple
specification language and then write your specific logic in React
and Node.js. The majority of the code is still being written in
React and Node.js, with Wasp serving as the backbone of your whole
application. To see some examples of what the language looks like
in practice, take a look here: https://github.com/wasp-
lang/wasp/blob/master/examples/tutor... The main difference
between Wasp and frameworks (e.g. Meteor, Blitz, Redwood) is that
Wasp is a language, not a library. One benefit of that is a simpler
and cleaner, declarative syntax, focused on the requirements and
detached from the implementation details. Another benefit of a DSL
is that it allows Wasp to understand the web app's requirements
during the build time and reason about it before generating the
final code. For example, when generating code to be deployed to
production, it could pick the most appropriate architecture based
on its understanding of the web app and deploy it to serverless or
another type of architecture (or even a combination). Another
example would be reusing your data model logic through all the
parts of the stack while defining it just once in Wasp. DSL opens
the potential for optimisations, static analysis and extensibility.
Wasp's compiler is built in Haskell and it compiles the source code
in Wasp + React/Node.js into the target code in just React and
Node.js (currently in Javascript, but we plan to move to Typescript
soon). The generated code is human readable and can easily be
inspected and even ejected if Wasp becomes too limiting. We are
currently in Alpha and many features are still rough or missing,
but you can try it out and build and deploy web apps! There are
things we haven't solved yet and others that will probably change
as we progress. You can check out our repo at
https://github.com/wasp-lang/wasp and give it a try at
https://wasp-lang.dev/docs/. Thank you for reading! We would love
to get your feedback and also hear about your experiences building
web apps - what has worked for you and where do you see the
opportunities for improvement?
Author : matijash
Score : 125 points
Date : 2021-02-10 17:15 UTC (5 hours ago)
| pella wrote:
| Question:
|
| Mobile App (iOS/Android) - generation is on the roadmap?
|
| ( using same metadata(DSL) )
| Martinsos wrote:
| Yes, that's the idea! We first want to get the web app part
| working really well, and then we will be looking into adding
| mobile. It will certainly require extending the DSL though, to
| capture both web and mobile specifics, but the idea would be to
| keep it as general as we can.
| nicoburns wrote:
| What's your story on extensibility? My experience with such tools
| if that they're great while you stay within the bounds of what
| they support, and quickly become a nightmare when you (usually
| quite quickly) hit into their limitations.
|
| As a junior dev I'd have loved this. Now, every instinct is
| telling me stay away.
| Martinsos wrote:
| You are right, with this kind of approach,
| extensibility/flexibility is the central question - we want to
| make Wasp really easy and simple to use, but on the other hand,
| complexity is needed to provide the flexibility to produce
| complex applications.
|
| Right now, Wasp is already leaving big gaps to be filled in by
| JS/TS (Node, React), but there is also a big part that is
| abstracted away and hidden by Wasp. For that part, our main
| idea is to offer abstractions of different levels that you can
| choose from. For example, you can choose Wasp's RPC to
| communicate between backend and frontend, but nothing is
| stopping you to directly access request and response in your
| expressJS middleware if you want and write your own REST API or
| use GraphQL. Or, you can use our authentication system
| completely, or use just part of it, or completely ditch it. So
| there should always be a "lid" that you can remove and access
| the system beneath.
|
| That said, we are still figuring this out - where to offer
| escape mechanisms, how to organize them, how much to abstract
| certain parts - there is certainly some limit to flexibility
| that we can offer. What is cool that having our own DSL gives
| us a lot of freedom here (although it is also a lot of work!).
|
| One thing we do have in the meantime is ability to eject the
| code and continue with it if you get stuck with Wasp at this
| alpha stage -> it is actually human readable! I am not sure if
| we will be able to maintain that property as Wasp grows though,
| but we are not giving up on it for now.
| bgdnpn wrote:
| I have been thinking of something similar for the last few weeks:
| most apps are 80% the same components (as you were saying "auth,
| routing, data model CRUD, ACL"), but these get re-written or at
| least re-engineered again and again.. wouldn't it be cool to
| define your apps' main components as a sort of DSL and then
| generate a starting poitn? And here you are. This is so
| interesting.
|
| Would love to have a short chat about this in the near future, if
| you have time!
| Martinsos wrote:
| Exactly!! Ah I love to hear this :D. Sure, we would love to ->
| consider joining us on Discord
| (https://discord.com/invite/rzdnErX) and you can ping us there
| whenever you want, or you can also shoot us an email at
| hi@wasp-lang.dev and we can continue from there :).
| matijash wrote:
| would be awesome to chat!
| sharemywin wrote:
| What is the benefit of a DSL versus a configuration file?
| matijash wrote:
| right now Wasp DSL is pretty much the config file, it isn't
| much more expressive. Short term benefit is that this way we
| can provide nicer & more intuitive syntax (config files like
| json/yaml can quickly become very nested and hard to read).
|
| Longer term, we plan to add support for inline-JS, so you could
| e.g. mix JS and Wasp code (instead of just referencing js
| imports as it works now). We will also add some basic language
| constructs (expressions, conditionals, multiple wasp files) so
| we might get more similar to e.g. Starlark or Terraform's DSL.
| cpursley wrote:
| Would be great to see this paired up with Hasura as the backend
| (also written is Haskell). I'm using Hasura with React Admin
| (configuration based admin framework) and it's a huge time saver.
| Martinsos wrote:
| We know about Hasura -> it sounds like a cool idea! First we
| will be focusing on conquering React/Node combo, but it will be
| interesting to explore if there is an opportunity to include
| solutions like Hasura. What part of logic do you imagine
| happening in Hasura, and what in Wasp? I guess in this case
| Wasp would mostly be handling frontend right?
|
| I will have to check out React Admin, I haven't heard about it
| yet.
| bradyo wrote:
| Yeah this feels a little bit like a declarative configuration
| file for Hasura/Firebase (which is already a good idea).
| Looking forward to seeing how far you can take the frontend
| stuff!
| matijash wrote:
| thanks for sharing, definitely sounds like an interesting
| combo! How is your experience with Hasura/Firebase, anything
| you found cumbersome?
| bnr wrote:
| That link does not work, Page not found: https://wasp-
| lang.dev/docs/tutorials/getting-started
| matijash wrote:
| thank you, fixed! The correct link is https://wasp-
| lang.dev/docs/
| [deleted]
| jonstaab wrote:
| Very cool project! I love stuff like this. I actually started a
| very similar fun project last week[0]. It's very much just a
| thought experiment, but the most interesting thing about it (I
| think) is the use of dynamic rather than lexical scope to control
| state. It's also designed to be extensible using python, js, and
| html.
|
| I did take a quick look at the Wasp real-world app and was sort
| of disappointed. It seemed like a single file with lots of weird
| syntax that pulls in a regular old React app. Is there something
| I'm missing?
|
| [0] https://github.com/staab/quack
| Martinsos wrote:
| Oho you are also building a DSL for full stack web apps, I
| didn't expect that :D! Consider joining our Discord
| (https://discord.com/invite/rzdnErX), I would love to learn
| more about your quack!
|
| True, right now it is just one file, and language is a simple
| "configuration", declarative language, just because we didn't
| need more so far. This is how we started, because we wanted to
| focus on capturing the basic abstractions of the web app at
| high level, and we want to keep the language as simple as
| possible -> so we decided to start really simple and then
| extend as we need more power.
|
| We will certainly add splitting into multiple files, and will
| probably go beyond that with actual modules, expressions,
| simple conditional logic, basic types and similar - kind of
| like meson (https://mesonbuild.com/Syntax.html) and Terraform.
| Right now we don't see it ever becoming a Turing complete
| language, since we don't intend to capture the low-level logic
| in Wasp - we feel existing solutions are better fit for that
| (JS/TS/HTML/CSS/...) and we would not be doing our best work
| there, nor would we be able to keep up with the innovation.
|
| Although, never say never -> my mind does wander off to Mint
| (https://www.mint-lang.com/) every so and so, thinking if we
| could do something similar at some point -> but even if we do,
| that is further down the road.
| jonstaab wrote:
| I'd love to join the discord and contribute my two cents,
| looks like the invite is expired though. Also, I hadn't seen
| Mint, that also looks like an awesome project.
| Martinsos wrote:
| That is weird, the one I provided above is set to unlimited
| expiration time and I see people coming -> maybe you used
| some other link, from the page/docs that might be old? If
| so let me know and I will fix it!
| pella wrote:
| Please add an extra AI layer generating WASP DSL !
|
| GPT-3 -> WASP -> Web APP
| matijash wrote:
| hah that would be cool! One reason we are excited about the DSL
| approach is that it allows us to 'capture' web app's
| requirements in a declarative structure separated from the
| implementation.
|
| As you mentioned, that means it could be possible to generate
| Wasp DSL via other means as well, not just by writing it down
| directly (e.g. via a visual editor), and some specific parts
| could be even assisted by AI.
| momothereal wrote:
| Looks cool!
|
| Do you have any examples or have experience with larger projects?
| For example, my React app has dozens of pages and some complex
| routing, and the backend has 50+ endpoints and talks to different
| databases, RabbitMQ, etc.
|
| When I see "shoe that fits all" solutions like this I'm honestly
| skeptical about the degree of freedom I get for more complex
| architecture needs. I've found frameworks like Next.js usually
| give you the freedom you need because it's basically pure JS.
|
| Also, this seems like it has a good opportunity to automatically
| integrate e2e/integration testing.
| Martinsos wrote:
| Hey yes, we have been working on a React/Node app for two years
| some time ago, that grew to that size and some more.
|
| I understand the skepticism, to be honest I was also pretty
| skeptical when we started (I am still a little bit, a healthy
| dose :D!), but we think now we can get to the level of
| flexibility of serious web frameworks - it all comes down to
| figuring out where the flexibility is needed.
|
| Right now it is already pretty flexible - you can write any
| nodeJS logic and use any JS library, same goes for React
| components. What is tricky is hitting this right trade-off
| between flexibility and power, and we are thinking a lot about
| that.
|
| So to summarize, I agree, but am hopeful!
|
| e2e testing -> yes, that would be very cool :)! We don't have
| any testing capabilities yet, but will be looking into it.
|
| Regarding bigger projects - one thing I am excited about is the
| possibility to model not just one web app via the DSL, but to
| capture multiple services - for example multiple (micro)servers
| - and orchestrate them. I haven't explored that direction
| enough yet though, since it is not the priority right now.
| sanmak wrote:
| To author, the app looks like an efficient way to build an app
| but would be better if you can add some more examples to showcase
| wasp-lang actual power. Examples with basic workflow will
| suffice.
|
| For someone who want to build something fast and prevent
| themselves from repetitive tasks, they need to be very sure
| before jumping into a new wasp-lang codebase.
| matijash wrote:
| thanks for the feedback, I agree having showcases is crucial
| for showing what can actually be built with Wasp.
|
| We ourselves built a copy of Medium with Wasp - feel free to
| see it deployed here (https://wasp-rwa.netlify.app/) and check
| the code here (https://github.com/wasp-
| lang/wasp/tree/master/examples/realw...)
|
| For the super simple example with less code check out TODO app
| built with Wasp: https://github.com/wasp-
| lang/wasp/tree/master/examples/tutor... (check out main.wasp
| and then the code in ext/ folder)
|
| Hope this helps!
| catchmeifyoucan wrote:
| This seems really awesome. I read the sample project, and was
| able to understand it really fast. It honestly would make our
| engineer onboarding really fast! Since it's all in one simple
| place. And the architecture is standardized.
|
| The authentication model is what I liked most.
|
| I think the biggest blocker is the use of Prisma however. I've
| never heard of Prisma before, and I'd have no problem using it.
| But I use DynamoDB for practically everything, not sure how that
| translates to that world.
|
| The second concern is that most of projects are written in
| Typescript. I'm not sure how this works with TS. I'd hate to
| write an entity twice - for example, a user entity, and a user
| interface in TS. Because they have to be typed anyways.
| Martinsos wrote:
| Great to hear that :)!!
|
| Thanks Nikolas for answering regarding Prisma! The reason why
| we chose Prisma is because it is declarative, which plays
| really well with Wasp, and because it supports multiple types
| of databases - for now only relational, but as Nikolas said, in
| the future also nosql.
|
| Regarding TS - you are right, TS is a better fit for this than
| JS! We started with JS, but plan is to switch to TS real soon,
| for the reasons you described. Here is the Github issue
| discussing this: https://github.com/wasp-lang/wasp/issues/143 .
|
| If you don't mind me asking, how big is your team / what are
| you using right now to build web apps?
| nikolasburk wrote:
| Hey, Nikolas from the Prisma team here!
|
| As of today, we indeed only support relational databases
| (Postgres, MySQL, SQL Server, SQLite) but we are already
| working on a connector for MongoDB[1] and plan to expand to
| more DBs in the future, here's the open issue to support
| DynamoDB[2].
|
| Hopefully Prisma becomes an option for you once we support your
| favorite DBs!
|
| [1]: https://www.notion.so/prismaio/Prisma-
| Roadmap-50766227b77946...
|
| [2]: https://github.com/prisma/prisma/issues/1676
| yaseer wrote:
| This is pretty neat. Programming languages are about working with
| the correct abstractions for your problem domain.
|
| It's about time we had a high level DSL for working with web
| abstractions.
| matijash wrote:
| thank you, that is what drove us too! But we also believe the
| key is in keeping integrations with the existing tech, e.g.
| React/Node.js so it is still possible to express more custom
| logic where it is needed.
| hopia wrote:
| I thought you were on to something really nice last year, and
| left you a long list of feedback on Indiehackers:
| https://www.indiehackers.com/post/launched-landing-page-for-...
|
| Nothing makes me happier than seeing you guys having come so far
| since then and having stayed so determined!
| Martinsos wrote:
| Hey, great to hear from you again :)!! Oh I remember that
| feedback very well, it was a big thing for us at the moment
| (and we left you even bigger response I believe ;)), really
| motivated us to see somebody is sharing so much of our vision!
|
| We would love to keep in touch, you shared a lot of great ideas
| with us - if you would consider joining us on Discord
| (https://discord.com/invite/rzdnErX) or shooting us an email at
| hi@wasp-lang.dev, it would be great :). Thanks again for the
| support!
| 0xferruccio wrote:
| I've tried to find something like this for a long time! You're
| bringing the ease of deploying and building a web app with Rails
| + Heroku to the JS ecosystem
| Martinsos wrote:
| Yes, that is what we are trying to do! And maybe even more - we
| are pretty excited about what using a DSL can unlock. Far in
| the future, we actually imagine being beyond JS ecosystem and
| offering a choice of languages to use, especially on the
| backend.
| alex-wallish wrote:
| Very cool project. How do you plan to monetize it? I don't see
| mention on the site
| matijash wrote:
| we are not totally sure yet (since we are now focusing on
| getting the project to the stable stage), but we think the most
| straightforward way would be to provide our own, "one-click"
| deployment/hosting service. On the other hand, since we are
| providing an e2e solution we think there could be multiple
| spots for providing extra value on top of the language, but we
| have yet to explore it.
| teryyy wrote:
| consulting/support might be another avenue for monetization
| zibbity-rw wrote:
| This is brilliant! Do you have any resources or thoughts to share
| on designing DSLs? Mad respect for people doing this.
| Martinsos wrote:
| Woah thanks :)! We had previous experience with writing a
| compiler for subset of C (during uni), and I also did some
| learning from the "Crafting Interpreters" book, but regarding
| the DSL design, I would say it is actually simpler -> we just
| went kind of ad-hoc and are expanding syntax as we figure out
| what we need. I am not sure if that is the best process, I
| would love to learn about the better one if there is one, but
| it worked so far. Wasp is still pretty simple, really not much
| more expressive than JSON at the moment, but we hope to add
| more stuff soon. While we are using parser combinators right
| now to parse the language, which is pretty manual process, once
| it becomes clearer what the language looks like, we will look
| into capturing it with formal grammar and then use some of the
| more advanced tools to parse it. The book I am going through
| right now is "Language Implementation Patterns" by creator of
| Antlr, it has chapters specific for designing DSLs!
| zibbity-rw wrote:
| Thank you!
| matijash wrote:
| we also have a DSL design channel in our Discord - feel
| free to join and start the discussion, we'd be happy to
| learn from you and also help if we can!
| https://discord.com/invite/rzdnErX
| fny wrote:
| Why did you decide to create a bespoke language rather that
| create a DSL that's still JavaScript?
| Martinsos wrote:
| If I got you right, you are talking about embedded DSL inside
| Javascript -> kind of like a library? Or about JS-like DSL,
| that is a superset of JS?
|
| Our main drivers for creating a bespoke language were: 1.
| potential to create a completely tailored developer experience
| - as simple and nice as possible. 2. detaching from specific
| language - we want to be able to potentially support multiple
| languages in the future, especially on the backend.
|
| How do you see it as a DSL that is still Javascript - I would
| love to hear more!
| cubano wrote:
| Great job guys and love hearing stories about brothers working
| together.
|
| So like the main problem with this is like the long standing one
| of time...while I would actually love to work with a better way
| to build webapps with modern stack elements, no matter what
| relearning to do everything in Wasp will take at least a month.
|
| What if after all the time you discover an issue with the
| framework that prevents you from being able to complete your
| project?
|
| Is it possible to extend the included base libs and work natively
| if need be?
|
| I guess as long as devs have the ability to push Wasp aside and
| work directly with the libs, there is nothing that you could not
| eventually do.
|
| Just some quick thoughts but Im gonna give this a whirl this
| week.
| Martinsos wrote:
| It is a tricky problem - on one hand, we want to capture as
| much as you can with DSL, since that gives us power to "do
| more", but on the other hand, we want to give you all the
| flexibility you need, which means doing stuff outside of DSL,
| stuff that Wasp does not understand and only sees as a black
| box. We think we can solve this by offering multiple levels of
| abstraction to choose from + escape mechanisms on the right
| places, and we are integrating with the JS ecosystem so you can
| write a lot of the natively already (NodeJS, React, more in the
| future).
|
| So while we still don't have this completely figured out (and I
| don't think we will until we get it done), we are hopeful! One
| cool thing is that doing our DSL also gives us a lot of freedom
| here, to find the best abstraction.
|
| Awesome, ping us on our Discord
| (https://discord.com/invite/rzdnErX) if you will have any
| questions - Wasp is still in early alpha and rough around the
| edges (including missing flexibility), so if you get stuck
| anywhere let us know! Actually ping us anyway if you wish, we
| would love to hear how you found the experience, how hard was
| it to get into it.
| ignoramous wrote:
| > _...understand the web app's requirements during the build time
| and reason about it before generating the final code. For
| example... it could pick the most appropriate architecture based
| on its understanding of the web app and deploy it to serverless
| or another type of architecture._
|
| Wowzer! For me, this is the main benefit. I'm a big believer in
| low-code platforms like darklang, because the fundamental truth
| that bugs are a function of both SLoC and underlying
| infrastructure is never going to change, and one solution to that
| is to _automate_ as much of it as possible.
|
| The only problem I see is that these automations that eliminate
| code and abstract away the infrastructure often result in a new
| class of harder-to-debug or worse never-seen-before bugs. And so,
| building a language that "solves software engineering" may
| require a _lot_ of patience and perseverance. With that in mind,
| how long do you plan to keep at it? How long term are you
| thinking you 'd be doing this? I mean, you could still be working
| on wasp-lang whilst working full-time elsewhere... but then, that
| requires a different level of commitment when the business around
| it has failed.
|
| > _Wasp's compiler is built in Haskell_
|
| Two questions, if I may: Why Haskell? Did you also consider OCaml
| (a la Rust) at some point?
|
| Edit: I see wasp-lang is MIT licensed. Why not Apache v2 (or even
| MPL v2)? Especially since MIT lacks patent-grants clause.
|
| Excited to see how wasp-lang evolves. Thanks!
| matijash wrote:
| thanks for your feedback and questions! yes, it (build-time
| reasoning) is also the most exciting thing for us, really
| excited to see what can be done.
|
| I also totally agree on being harder to debug, that is the
| challenge that comes with abstraction - at this stage we are
| not doing very much about it (mostly just propagating errors
| from server/client) but it is something we'll definitely need
| to focus on as Wasp matures.
|
| We chose Haskell because we had some previous experience with
| it and thought it would be a good fit for building a compiler
| (doesn't have a lot of realtime IO so we can keep the code
| simpler). Haven't yet tried OCaml or Rust (heard Rust is
| somewhat more low-lvl) but I believe they would be viable
| alternatives too.
|
| Re long-term doing Wasp - also agree, we believe this is a
| full-time job so that is why we joined YC and got the initial
| funding so we can focus on it longer term.
|
| Re Apache v2 vs MIT - thanks for letting us know! We haven't
| yet put much investigation into it but will definitely need to
| do it soon.
| ignoramous wrote:
| > _Re long-term doing Wasp - also agree, we believe this is a
| full-time job so that is why we joined YC..._
|
| All good, but what I really meant was, what happens when that
| funding money runs out and/or there's no business around
| wasp-lang to corner more investment?
|
| > _Re Apache v2 vs MIT..._
|
| Golang's BSD 3-Clause + patent-grant; and Rust's dual-
| licensed MIT (for compatibility with GPL v2, I believe) +
| Apache v2; whilst Clojure is EPL v1, though EPL v2 (+ the GPL
| compatibility clause) may also be a decent weak-copyleft
| choice for a programming language (ianal).
|
| See also:
|
| https://fossa.com/blog/open-source-licenses-101-apache-
| licen...
|
| https://opensource.com/article/17/9/facebook-patents-license
| matijash wrote:
| Get it now! The big part in our opinion is growing a
| community of people using Wasp for their projects - if we
| manage to do that, we'll definitely be motivated to
| continue, funding or no funding. We are of course motivated
| to build a business on top of Wasp, but for now still
| focusing on the product.
|
| Thanks for the info about licenses, awesome overview!
| mwcampbell wrote:
| Can we try a demo app somewhere, without having to build it
| ourselves? I'd like to see how you handle user-visible concerns
| such as accessibility.
| Martinsos wrote:
| Hey, we have a demo app deployed here: https://wasp-
| rwa.netlify.app/ , and you can see its source code here
| https://github.com/wasp-lang/wasp/tree/master/examples/realw...
| .
|
| Wasp is still in alpha so many things are rough or not there,
| including accessibility, but we do plan to handle it in the
| future! Here is relevant github issue: https://github.com/wasp-
| lang/wasp/issues/126 .
| mwcampbell wrote:
| I'm happy that you already had an issue open for
| accessibility. Thanks!
|
| This demo app isn't bad. The biggest problem I've found so
| far is that a screen reader user doesn't hear anything when a
| client-side page load happens. This is a common problem with
| SPAs, and there isn't a great solution for it. The best you
| can do right now is use an off-screen ARIA live region to
| announce something like "navigated to [page name]". Sometime
| though I'd like to work with the web standards community to
| standardize a better solution.
| borellvi wrote:
| Congratulations for the launch! How are you finding Haskell? Why
| did you pick it?
| Martinsos wrote:
| Thanks! We love Haskell, we have been playing with it for
| years, and when we realized we want to build a compiler, we
| thought Haskell is just the right fit for it, due to relatively
| small amount of IO and lot of complexity. That said, not
| everything is perfect in Haskell, and we are still learning a
| lot every day, but we are really enjoying it. How about you,
| are you considering Haskell or already using it?
___________________________________________________________________
(page generated 2021-02-10 23:00 UTC)