From ba4ebe17937c2d14cb185b44b252185bf483ae50 Mon Sep 17 00:00:00 2001 From: Damillora Date: Sun, 9 May 2021 22:07:23 +0700 Subject: [PATCH] feat: initial commit --- .gitignore | 18 + Dockerfile | 14 + go.mod | 15 + go.sum | 559 ++++ main.go | 18 + pkg/app/app.go | 50 + pkg/app/auth_routes.go | 52 + pkg/app/blob_routes.go | 54 + pkg/app/frontend_routes.go | 20 + pkg/app/post_routes.go | 201 ++ pkg/app/routes.go | 16 + pkg/app/tag_routes.go | 29 + pkg/app/tag_type_routes.go | 99 + pkg/app/user_routes.go | 124 + pkg/config/config.go | 23 + pkg/database/blob.go | 12 + pkg/database/main.go | 37 + pkg/database/post.go | 15 + pkg/database/tag.go | 15 + pkg/database/tag_type.go | 6 + pkg/database/user.go | 14 + pkg/database/user_token.go | 12 + pkg/middleware/auth_middleware.go | 50 + pkg/models/create_update.go | 38 + pkg/models/form.go | 6 + pkg/models/item.go | 18 + pkg/models/read.go | 8 + pkg/models/responses.go | 25 + pkg/services/auth.go | 56 + pkg/services/post.go | 99 + pkg/services/tag.go | 86 + pkg/services/tag_type.go | 36 + pkg/services/user.go | 65 + web/app/.gitignore | 4 + web/app/README.md | 105 + web/app/package.json | 24 + web/app/rollup.config.js | 76 + web/app/src/App.svelte | 75 + web/app/src/api.js | 41 + web/app/src/main.js | 8 + web/app/src/routes/Home.svelte | 14 + web/app/src/routes/Login.svelte | 33 + web/app/src/routes/Logout.svelte | 11 + web/app/src/routes/Post.svelte | 48 + web/app/src/routes/Posts.svelte | 48 + web/app/src/routes/Tag.svelte | 53 + web/app/src/stores.js | 8 + web/app/yarn.lock | 689 +++++ web/static/bundle.js | 4707 +++++++++++++++++++++++++++++ web/static/bundle.js.map | 1 + web/template/layout/footer.html | 4 + web/template/layout/header.html | 15 + web/template/pages/index.html | 3 + 53 files changed, 7857 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 pkg/app/app.go create mode 100644 pkg/app/auth_routes.go create mode 100644 pkg/app/blob_routes.go create mode 100644 pkg/app/frontend_routes.go create mode 100644 pkg/app/post_routes.go create mode 100644 pkg/app/routes.go create mode 100644 pkg/app/tag_routes.go create mode 100644 pkg/app/tag_type_routes.go create mode 100644 pkg/app/user_routes.go create mode 100644 pkg/config/config.go create mode 100644 pkg/database/blob.go create mode 100644 pkg/database/main.go create mode 100644 pkg/database/post.go create mode 100644 pkg/database/tag.go create mode 100644 pkg/database/tag_type.go create mode 100644 pkg/database/user.go create mode 100644 pkg/database/user_token.go create mode 100644 pkg/middleware/auth_middleware.go create mode 100644 pkg/models/create_update.go create mode 100644 pkg/models/form.go create mode 100644 pkg/models/item.go create mode 100644 pkg/models/read.go create mode 100644 pkg/models/responses.go create mode 100644 pkg/services/auth.go create mode 100644 pkg/services/post.go create mode 100644 pkg/services/tag.go create mode 100644 pkg/services/tag_type.go create mode 100644 pkg/services/user.go create mode 100644 web/app/.gitignore create mode 100644 web/app/README.md create mode 100644 web/app/package.json create mode 100644 web/app/rollup.config.js create mode 100644 web/app/src/App.svelte create mode 100644 web/app/src/api.js create mode 100644 web/app/src/main.js create mode 100644 web/app/src/routes/Home.svelte create mode 100644 web/app/src/routes/Login.svelte create mode 100644 web/app/src/routes/Logout.svelte create mode 100644 web/app/src/routes/Post.svelte create mode 100644 web/app/src/routes/Posts.svelte create mode 100644 web/app/src/routes/Tag.svelte create mode 100644 web/app/src/stores.js create mode 100644 web/app/yarn.lock create mode 100644 web/static/bundle.js create mode 100644 web/static/bundle.js.map create mode 100644 web/template/layout/footer.html create mode 100644 web/template/layout/header.html create mode 100644 web/template/pages/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..210a729 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +web/static + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8ca5030 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM golang:1.16-alpine AS build + +WORKDIR /go/src/shioriko +COPY . . + +RUN go get -d -v ./... +RUN CGO_ENABLED=0 GOOS=linux go build -o /shioriko +RUN mkdir -p /web && cp -r web/static web/template /web + +FROM scratch AS runtime +COPY --from=build /shioriko / +COPY --from=build /web / + +ENTRYPOINT ["/shioriko"] diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..08a9ede --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module github.com/Damillora/Shioriko + +go 1.16 + +require ( + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/gin-contrib/cors v1.3.1 + github.com/gin-contrib/static v0.0.1 + github.com/gin-gonic/gin v1.7.1 + github.com/go-playground/validator/v10 v10.6.0 // indirect + github.com/google/uuid v1.2.0 + golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf // indirect + gorm.io/driver/postgres v1.1.0 + gorm.io/gorm v1.21.9 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d0fc7e2 --- /dev/null +++ b/go.sum @@ -0,0 +1,559 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= +github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U= +github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= +github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.6.0 h1:UGIt4xR++fD9QrBOoo/ascJfGe3AGHEB9s6COnss4Rk= +github.com/go-playground/validator/v10 v10.6.0/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.1 h1:ySBX7Q87vOMqKU2bbmKbUvtYhauDFclYbNDYIE1/h6s= +github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.7.0 h1:6f4kVsW01QftE38ufBYxKciO6gyioXSC0ABIRLcZrGs= +github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.11.0 h1:J86tSWd3Y7nKjwT/43xZBvpi04keQWx8gNC2YkdJhZI= +github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shaj13/go-guardian v1.5.11 h1:GRoMBgh5stRh86iAkEOj7UqcodIs6E7pZ+LtOnxTUGk= +github.com/shaj13/go-guardian v1.5.11/go.mod h1:Y4LLKzIAVAZlpr4tZCRvk+pkyZUwgsjZL86PZIzAH8g= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ldap.v3 v3.1.0/go.mod h1:dQjCc0R0kfyFjIlWNMH1DORwUASZyDxo2Ry1B51dXaQ= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gorm.io/driver/postgres v1.1.0 h1:afBljg7PtJ5lA6YUWluV2+xovIPhS+YiInuL3kUjrbk= +gorm.io/driver/postgres v1.1.0/go.mod h1:hXQIwafeRjJvUm+OMxcFWyswJ/vevcpPLlGocwAwuqw= +gorm.io/gorm v1.21.9 h1:INieZtn4P2Pw6xPJ8MzT0G4WUOsHq3RhfuDF1M6GW0E= +gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/main.go b/main.go new file mode 100644 index 0000000..7934048 --- /dev/null +++ b/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "embed" + + "github.com/Damillora/Shioriko/pkg/app" +) + +//go:embed web/static +var staticFiles embed.FS + +//go:embed web/template +var templateFiles embed.FS + +func main() { + app.Initialize() + app.Start() +} diff --git a/pkg/app/app.go b/pkg/app/app.go new file mode 100644 index 0000000..ba4dcc0 --- /dev/null +++ b/pkg/app/app.go @@ -0,0 +1,50 @@ +package app + +import ( + "embed" + "net/http" + + "github.com/Damillora/Shioriko/pkg/config" + "github.com/Damillora/Shioriko/pkg/database" + "github.com/gin-contrib/cors" + "github.com/gin-contrib/static" + "github.com/gin-gonic/gin" +) + +type embedFileSystem struct { + http.FileSystem +} + +func (e embedFileSystem) Exists(prefix string, path string) bool { + _, err := e.Open(path) + if err != nil { + return false + } + return true +} + +func EmbedFolder(fsEmbed embed.FS) static.ServeFileSystem { + return embedFileSystem{ + FileSystem: http.FS(fsEmbed), + } +} + +func Initialize() { + config.InitializeConfig() + database.Initialize() +} + +func Start() { + g := gin.Default() + + g.Static("/static", "./web/static") + g.Static("/data", config.CurrentConfig.DataDirectory) + + g.LoadHTMLGlob("web/template/**/*") + + g.Use(cors.Default()) + + InitializeRoutes(g) + + g.Run() +} diff --git a/pkg/app/auth_routes.go b/pkg/app/auth_routes.go new file mode 100644 index 0000000..e02a018 --- /dev/null +++ b/pkg/app/auth_routes.go @@ -0,0 +1,52 @@ +package app + +import ( + "net/http" + + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" +) + +func InitializeAuthRoutes(g *gin.Engine) { + g.POST("/api/auth/login", createToken) +} +func createToken(c *gin.Context) { + var model models.LoginFormModel + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + user := services.Login(model.Username, model.Password) + + if user != nil { + token := services.CreateToken(user) + c.JSON(http.StatusOK, models.TokenResponse{ + Token: token, + }) + + } else { + c.JSON(http.StatusUnauthorized, models.ErrorResponse{ + Code: http.StatusUnauthorized, + Message: "Wrong username or password", + }) + } +} diff --git a/pkg/app/blob_routes.go b/pkg/app/blob_routes.go new file mode 100644 index 0000000..dad7a8f --- /dev/null +++ b/pkg/app/blob_routes.go @@ -0,0 +1,54 @@ +package app + +import ( + "net/http" + "path/filepath" + + "github.com/Damillora/Shioriko/pkg/config" + "github.com/Damillora/Shioriko/pkg/database" + "github.com/Damillora/Shioriko/pkg/middleware" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/gin-gonic/gin" + "github.com/google/uuid" +) + +func InitializeBlobRoutes(g *gin.Engine) { + protected := g.Group("/api/blob").Use(middleware.AuthMiddleware()) + { + protected.POST("/upload", uploadBlob) + } + +} + +func uploadBlob(c *gin.Context) { + dataDir := config.CurrentConfig.DataDirectory + // Source + file, err := c.FormFile("file") + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + id := uuid.NewString() + filename := id + filepath.Ext(file.Filename) + + err = c.SaveUploadedFile(file, filepath.Join(dataDir, filename)) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + + blob := database.Blob{ + ID: id, + FilePath: filename, + } + database.DB.Create(&blob) + + c.JSON(http.StatusOK, models.BlobResponse{ + ID: id, + }) +} diff --git a/pkg/app/frontend_routes.go b/pkg/app/frontend_routes.go new file mode 100644 index 0000000..e591174 --- /dev/null +++ b/pkg/app/frontend_routes.go @@ -0,0 +1,20 @@ +package app + +import ( + "net/http" + + "github.com/Damillora/Shioriko/pkg/config" + "github.com/gin-gonic/gin" +) + +func InitializeFrontendRoutes(g *gin.Engine) { + g.NoRoute(frontendHome) +} + +func frontendHome(c *gin.Context) { + baseURL := config.CurrentConfig.BaseURL + c.HTML(http.StatusOK, "index.html", gin.H{ + "title": "Home", + "base_url": baseURL, + }) +} diff --git a/pkg/app/post_routes.go b/pkg/app/post_routes.go new file mode 100644 index 0000000..4d83796 --- /dev/null +++ b/pkg/app/post_routes.go @@ -0,0 +1,201 @@ +package app + +import ( + "net/http" + "strconv" + + "github.com/Damillora/Shioriko/pkg/middleware" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" +) + +func InitializePostRoutes(g *gin.Engine) { + unprotected := g.Group("/api/post") + { + unprotected.GET("/", postGet) + unprotected.GET("/:id", postGetOne) + unprotected.GET("/tag/:id", postGetTag) + } + protected := g.Group("/api/post").Use(middleware.AuthMiddleware()) + { + protected.POST("/create", postCreate) + protected.POST("/:id", postUpdate) + protected.DELETE("/:id", postDelete) + } + +} + +func postGet(c *gin.Context) { + pageParam := c.Query("page") + page, _ := strconv.Atoi(pageParam) + posts := services.GetPostAll(page) + var postResult []models.PostListItem + for _, post := range posts { + var tagStrings []string + for _, tag := range post.Tags { + tagStrings = append(tagStrings, tag.TagType.Name+":"+tag.Name) + } + + postResult = append(postResult, models.PostListItem{ + ID: post.ID, + ImagePath: "/data/" + post.Blob.FilePath, + Tags: tagStrings, + }) + } + postPages := services.CountPostPages() + c.JSON(http.StatusOK, models.PostPaginationResponse{ + CurrentPage: page, + TotalPage: postPages, + Posts: postResult, + }) +} + +func postGetTag(c *gin.Context) { + pageParam := c.Query("page") + page, _ := strconv.Atoi(pageParam) + + tag := c.Param("id") + + posts := services.GetPostTag(page, tag) + var postResult []models.PostListItem + for _, post := range posts { + var tagStrings []string + for _, tag := range post.Tags { + tagStrings = append(tagStrings, tag.TagType.Name+":"+tag.Name) + } + + postResult = append(postResult, models.PostListItem{ + ID: post.ID, + ImagePath: "/data/" + post.Blob.FilePath, + Tags: tagStrings, + }) + } + postPages := services.CountPostPages() + c.JSON(http.StatusOK, models.PostPaginationResponse{ + CurrentPage: page, + TotalPage: postPages, + Posts: postResult, + }) +} + +func postGetOne(c *gin.Context) { + id := c.Param("id") + post, err := services.GetPost(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + var tagStrings []string + for _, tag := range post.Tags { + tagStrings = append(tagStrings, tag.TagType.Name+":"+tag.Name) + } + + c.JSON(http.StatusOK, models.PostReadModel{ + ID: post.ID, + ImagePath: "/data/" + post.Blob.FilePath, + SourceURL: post.SourceURL, + Tags: tagStrings, + }) +} + +func postCreate(c *gin.Context) { + var model models.PostCreateModel + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + post, err := services.CreatePost(model) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + c.JSON(http.StatusOK, models.PostReadModel{ + ID: post.ID, + ImagePath: "/data/" + post.Blob.FilePath, + }) +} + +func postUpdate(c *gin.Context) { + id := c.Param("id") + + var model models.PostUpdateModel + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + post, err := services.UpdatePost(id, model) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + + c.JSON(http.StatusOK, models.PostListItem{ + ID: post.ID, + ImagePath: "/data/" + post.Blob.FilePath, + }) + +} + +func postDelete(c *gin.Context) { + id := c.Param("id") + + err := services.DeletePost(id) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + return + } + + c.JSON(http.StatusOK, models.ErrorResponse{ + Code: http.StatusOK, + Message: "Success", + }) + +} diff --git a/pkg/app/routes.go b/pkg/app/routes.go new file mode 100644 index 0000000..1440abb --- /dev/null +++ b/pkg/app/routes.go @@ -0,0 +1,16 @@ +package app + +import ( + "github.com/gin-gonic/gin" +) + +func InitializeRoutes(g *gin.Engine) { + InitializeUserRoutes(g) + InitializeAuthRoutes(g) + InitializeTagTypeRoutes(g) + InitializeTagRoutes(g) + InitializeBlobRoutes(g) + InitializePostRoutes(g) + + InitializeFrontendRoutes(g) +} diff --git a/pkg/app/tag_routes.go b/pkg/app/tag_routes.go new file mode 100644 index 0000000..4c10029 --- /dev/null +++ b/pkg/app/tag_routes.go @@ -0,0 +1,29 @@ +package app + +import ( + "net/http" + + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" +) + +func InitializeTagRoutes(g *gin.Engine) { + unprotected := g.Group("/api/tag") + { + unprotected.GET("/", tagGet) + } +} + +func tagGet(c *gin.Context) { + tags := services.GetTagAll() + var tagResult []models.TagListItem + for _, tag := range tags { + tagResult = append(tagResult, models.TagListItem{ + ID: tag.ID, + Name: tag.Name, + TagType: tag.TagType.Name, + }) + } + c.JSON(http.StatusOK, tagResult) +} diff --git a/pkg/app/tag_type_routes.go b/pkg/app/tag_type_routes.go new file mode 100644 index 0000000..94c3c72 --- /dev/null +++ b/pkg/app/tag_type_routes.go @@ -0,0 +1,99 @@ +package app + +import ( + "net/http" + "strconv" + + "github.com/Damillora/Shioriko/pkg/middleware" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" +) + +func InitializeTagTypeRoutes(g *gin.Engine) { + + protected := g.Group("/api/tagtype").Use(middleware.AuthMiddleware()) + { + protected.GET("/", tagTypeGet) + protected.POST("/create", tagTypeCreate) + protected.DELETE("/:id", tagTypeDelete) + } +} + +func tagTypeGet(c *gin.Context) { + tagTypes := services.GetTagTypeAll() + + var tagResult []models.TagTypeListItem + + for _, tagType := range tagTypes { + tagResult = append(tagResult, models.TagTypeListItem{ + ID: tagType.ID, + Name: tagType.Name, + }) + } + c.JSON(http.StatusOK, tagResult) +} + +func tagTypeCreate(c *gin.Context) { + var model models.TagTypeCreateModel + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + tagType, err := services.CreateOrUpdateTagType(model) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + c.JSON(http.StatusOK, models.TagTypeListItem{ + ID: tagType.ID, + Name: tagType.Name, + }) + +} + +func tagTypeDelete(c *gin.Context) { + idParam := c.Param("id") + id, err := strconv.Atoi(idParam) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + + err = services.DeleteTagType(uint(id)) + + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + } + c.JSON(http.StatusOK, models.ErrorResponse{ + Code: http.StatusOK, + Message: "Success", + }) +} diff --git a/pkg/app/user_routes.go b/pkg/app/user_routes.go new file mode 100644 index 0000000..793d727 --- /dev/null +++ b/pkg/app/user_routes.go @@ -0,0 +1,124 @@ +package app + +import ( + "net/http" + + "github.com/Damillora/Shioriko/pkg/config" + "github.com/Damillora/Shioriko/pkg/database" + "github.com/Damillora/Shioriko/pkg/middleware" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" +) + +func InitializeUserRoutes(g *gin.Engine) { + g.POST("/api/user/register", registerUser) + + protected := g.Group("/api/user").Use(middleware.AuthMiddleware()) + { + protected.GET("/profile", userProfile) + protected.POST("/update", userUpdate) + } +} + +func registerUser(c *gin.Context) { + var disableRegistration = config.CurrentConfig.DisableRegistration + if disableRegistration == "true" { + c.JSON(http.StatusForbidden, models.ErrorResponse{ + Code: http.StatusForbidden, + Message: "Registration is disabled", + }) + c.Abort() + return + } + + var model models.UserCreateModel + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + user, err := services.CreateUser(model) + if err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse{ + Code: http.StatusInternalServerError, + Message: "Cannot create user", + }) + c.Abort() + return + } + + c.JSON(http.StatusOK, models.UserProfileResponse{ + Email: user.Email, + Username: user.Username, + }) +} + +func userProfile(c *gin.Context) { + result, ok := c.Get("user") + if ok { + user := result.(*database.User) + c.JSON(http.StatusOK, models.UserProfileResponse{ + Email: user.Email, + Username: user.Username, + }) + } else { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: "User does not exist", + }) + } +} + +func userUpdate(c *gin.Context) { + var model models.UserUpdateModel + + err := c.ShouldBindJSON(&model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + validate := validator.New() + err = validate.Struct(model) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + c.Abort() + return + } + + result, ok := c.Get("user") + if ok { + user := result.(*database.User) + services.UpdateUser(user.ID, model) + } else { + c.JSON(http.StatusBadRequest, models.ErrorResponse{ + Code: http.StatusBadRequest, + Message: "User does not exist", + }) + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 0000000..f044b70 --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,23 @@ +package config + +import "os" + +type Config struct { + PostgresDatabase string + AuthSecret string + DisableRegistration string + DataDirectory string + BaseURL string +} + +var CurrentConfig Config + +func InitializeConfig() { + CurrentConfig = Config{ + PostgresDatabase: os.Getenv("POSTGRES_DATABASE"), + AuthSecret: os.Getenv("AUTH_SECRET"), + DisableRegistration: os.Getenv("DISABLE_REGISTRATION"), + DataDirectory: os.Getenv("DATA_DIR"), + BaseURL: os.Getenv("BASE_URL"), + } +} diff --git a/pkg/database/blob.go b/pkg/database/blob.go new file mode 100644 index 0000000..3dbd3bb --- /dev/null +++ b/pkg/database/blob.go @@ -0,0 +1,12 @@ +package database + +import ( + "time" +) + +type Blob struct { + ID string `gorm:"size:36"` + FilePath string + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/pkg/database/main.go b/pkg/database/main.go new file mode 100644 index 0000000..624ebe3 --- /dev/null +++ b/pkg/database/main.go @@ -0,0 +1,37 @@ +package database + +import ( + "log" + + "github.com/Damillora/Shioriko/pkg/config" + "gorm.io/gorm" + + "gorm.io/driver/postgres" +) + +var DB *gorm.DB + +func Initialize() { + dsn := config.CurrentConfig.PostgresDatabase + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + + db.AutoMigrate(&User{}) + db.AutoMigrate(&TagType{}) + db.AutoMigrate(&Tag{}) + db.AutoMigrate(&Blob{}) + db.AutoMigrate(&Post{}) + + var general TagType + result := db.Where("name = ?", "general").First(&general) + if result.Error != nil { + db.Create(&TagType{ + Name: "general", + }) + } + + if err != nil { + log.Fatal("Unable to connect to database" + err.Error()) + } + + DB = db +} diff --git a/pkg/database/post.go b/pkg/database/post.go new file mode 100644 index 0000000..b6eb51b --- /dev/null +++ b/pkg/database/post.go @@ -0,0 +1,15 @@ +package database + +import ( + "time" +) + +type Post struct { + ID string `gorm:"size:36"` + BlobID string + Blob Blob `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + SourceURL string + Tags []Tag `gorm:"many2many:post_tags;constraint:OnDelete:CASCADE"` + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/pkg/database/tag.go b/pkg/database/tag.go new file mode 100644 index 0000000..dd77d55 --- /dev/null +++ b/pkg/database/tag.go @@ -0,0 +1,15 @@ +package database + +import ( + "time" +) + +type Tag struct { + ID string `gorm:"size:36"` + Name string + CreatedAt time.Time + UpdatedAt time.Time + TagTypeID uint + TagType TagType + Posts []Post `gorm:"many2many:post_tags"` +} diff --git a/pkg/database/tag_type.go b/pkg/database/tag_type.go new file mode 100644 index 0000000..b617e6b --- /dev/null +++ b/pkg/database/tag_type.go @@ -0,0 +1,6 @@ +package database + +type TagType struct { + ID uint + Name string +} diff --git a/pkg/database/user.go b/pkg/database/user.go new file mode 100644 index 0000000..c0a7aad --- /dev/null +++ b/pkg/database/user.go @@ -0,0 +1,14 @@ +package database + +import ( + "time" +) + +type User struct { + ID string `gorm:"size:36"` + Email string + Username string + Password string + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/pkg/database/user_token.go b/pkg/database/user_token.go new file mode 100644 index 0000000..1ec780e --- /dev/null +++ b/pkg/database/user_token.go @@ -0,0 +1,12 @@ +package database + +import "time" + +type UserToken struct { + ID uint + UserID string + User User + Token string + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/pkg/middleware/auth_middleware.go b/pkg/middleware/auth_middleware.go new file mode 100644 index 0000000..ada0993 --- /dev/null +++ b/pkg/middleware/auth_middleware.go @@ -0,0 +1,50 @@ +package middleware + +import ( + "strings" + + "github.com/Damillora/Shioriko/pkg/models" + "github.com/Damillora/Shioriko/pkg/services" + "github.com/gin-gonic/gin" +) + +func AuthMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + clientToken := c.Request.Header.Get("Authorization") + if clientToken == "" { + c.JSON(403, models.ErrorResponse{ + Code: 403, + Message: "Authorization required", + }) + c.Abort() + return + } + + extractedToken := strings.Split(clientToken, "Bearer ") + + if len(extractedToken) == 2 { + clientToken = strings.TrimSpace(extractedToken[1]) + } else { + c.JSON(400, models.ErrorResponse{ + Code: 400, + Message: "Incorrect Format of Authorization Token", + }) + c.Abort() + return + } + + claims, err := services.ValidateToken(clientToken) + if err != nil { + c.JSON(401, models.ErrorResponse{ + Code: 401, + Message: err.Error(), + }) + c.Abort() + return + } + user := services.GetUser(claims["sub"].(string)) + c.Set("user", user) + + c.Next() + } +} diff --git a/pkg/models/create_update.go b/pkg/models/create_update.go new file mode 100644 index 0000000..177bdc5 --- /dev/null +++ b/pkg/models/create_update.go @@ -0,0 +1,38 @@ +package models + +type UserCreateModel struct { + Email string `json:"email" validate:"required,email"` + Username string `json:"username" validate:"required"` + Password string `json:"password" validate:"required"` +} + +type UserUpdateModel struct { + Email string `json:"email" validate:"required,email"` + Username string `json:"username" validate:"required"` + Password string `json:"password"` +} + +type TagTypeCreateModel struct { + Name string `json:"name" validate:"required,ascii"` +} + +type TagCreateModel struct { + Name string `json:"name" validate:"required,ascii"` + TagTypeID uint `json:"tagTypeId" validate:"required"` +} + +type TagUpdateModel struct { + Name string `json:"name" validate:"required,ascii"` + TagTypeID uint `json:"tagTypeId" validate:"required"` +} + +type PostCreateModel struct { + BlobID string `json:"blob_id" validate:"required"` + SourceURL string `json:"source_url"` + Tags []string `json:"tags" validate:"required"` +} + +type PostUpdateModel struct { + SourceURL string `json:"source_url"` + Tags []string `json:"tags" validate:"required"` +} diff --git a/pkg/models/form.go b/pkg/models/form.go new file mode 100644 index 0000000..300bc9d --- /dev/null +++ b/pkg/models/form.go @@ -0,0 +1,6 @@ +package models + +type LoginFormModel struct { + Username string `json:"username" validate:"required"` + Password string `json:"password" validate:"required"` +} diff --git a/pkg/models/item.go b/pkg/models/item.go new file mode 100644 index 0000000..042f8ed --- /dev/null +++ b/pkg/models/item.go @@ -0,0 +1,18 @@ +package models + +type TagTypeListItem struct { + ID uint `json:"id"` + Name string `json:"name"` +} + +type TagListItem struct { + ID string `json:"id"` + Name string `json:"name"` + TagType string `json:"tagType"` +} + +type PostListItem struct { + ID string `json:"id"` + ImagePath string `json:"image_path"` + Tags []string `json:"tags"` +} diff --git a/pkg/models/read.go b/pkg/models/read.go new file mode 100644 index 0000000..6a48d19 --- /dev/null +++ b/pkg/models/read.go @@ -0,0 +1,8 @@ +package models + +type PostReadModel struct { + ID string `json:"id"` + ImagePath string `json:"image_path"` + SourceURL string `json:"source_url"` + Tags []string `json:"tags"` +} diff --git a/pkg/models/responses.go b/pkg/models/responses.go new file mode 100644 index 0000000..f0c2956 --- /dev/null +++ b/pkg/models/responses.go @@ -0,0 +1,25 @@ +package models + +type TokenResponse struct { + Token string `json:"token"` +} + +type ErrorResponse struct { + Code int `json:"code"` + Message string `json:"message"` +} + +type UserProfileResponse struct { + Email string `json:"email"` + Username string `json:"password"` +} + +type BlobResponse struct { + ID string `json:"id"` +} + +type PostPaginationResponse struct { + CurrentPage int `json:"currentPage"` + TotalPage int `json:"totalPage"` + Posts []PostListItem `json:"posts"` +} diff --git a/pkg/services/auth.go b/pkg/services/auth.go new file mode 100644 index 0000000..1ee22de --- /dev/null +++ b/pkg/services/auth.go @@ -0,0 +1,56 @@ +package services + +import ( + "errors" + "log" + "time" + + "github.com/Damillora/Shioriko/pkg/config" + "github.com/Damillora/Shioriko/pkg/database" + "github.com/dgrijalva/jwt-go" + "golang.org/x/crypto/bcrypt" +) + +func Login(username string, password string) *database.User { + user := GetUserFromUsername(username) + log.Println(user.Username) + err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) + if err != nil { + return nil + } + return user +} + +func CreateToken(user *database.User) string { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "email": user.Email, + "name": user.Username, + "iss": "shioriko-api", + "sub": user.ID, + "aud": "shioriko", + "exp": time.Now().Add(time.Hour * 24).Unix(), + }) + jwtToken, _ := token.SignedString([]byte(config.CurrentConfig.AuthSecret)) + return jwtToken +} + +func ValidateToken(signedToken string) (jwt.MapClaims, error) { + claims := jwt.MapClaims{} + + _, err := jwt.ParseWithClaims( + signedToken, + claims, + func(token *jwt.Token) (interface{}, error) { + return []byte(config.CurrentConfig.AuthSecret), nil + }, + ) + if err != nil { + return nil, err + } + + if !claims.VerifyExpiresAt(time.Now().Local().Unix(), true) { + return nil, errors.New("Token is expired") + } + + return claims, nil +} diff --git a/pkg/services/post.go b/pkg/services/post.go new file mode 100644 index 0000000..7fbc966 --- /dev/null +++ b/pkg/services/post.go @@ -0,0 +1,99 @@ +package services + +import ( + "github.com/Damillora/Shioriko/pkg/database" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/google/uuid" +) + +const perPage = 20 + +func GetPostAll(page int) []database.Post { + var posts []database.Post + database.DB.Joins("Blob").Preload("Tags").Preload("Tags.TagType").Offset((page - 1) * perPage).Limit(20).Find(&posts) + return posts +} + +func GetPostTag(page int, tagSyntax string) []database.Post { + tag, err := GetTag(tagSyntax) + if err != nil { + return []database.Post{} + } + var posts []database.Post + database.DB.Model(&tag).Joins("Blob").Preload("Tags").Preload("Tags.TagType").Offset((page - 1) * perPage).Limit(20).Association("Posts").Find(&posts) + return posts +} + +func GetPost(id string) (*database.Post, error) { + var post database.Post + result := database.DB.Joins("Blob").Preload("Tags").Preload("Tags.TagType").Where("posts.id = ?", id).First(&post) + if result.Error != nil { + return nil, result.Error + } + + return &post, nil +} +func CreatePost(model models.PostCreateModel) (*database.Post, error) { + tags, err := ParseTags(model.Tags) + if err != nil { + return nil, err + } + + post := database.Post{ + ID: uuid.NewString(), + BlobID: model.BlobID, + SourceURL: model.SourceURL, + Tags: tags, + } + + result := database.DB.Create(&post) + if result.Error != nil { + return nil, result.Error + } + return &post, nil +} +func UpdatePost(id string, model models.PostUpdateModel) (*database.Post, error) { + tags, err := ParseTags(model.Tags) + if err != nil { + return nil, err + } + + var post database.Post + result := database.DB.Where("id = ?", id).First(&post) + if result.Error != nil { + return nil, result.Error + } + post.SourceURL = model.SourceURL + post.Tags = tags + + result = database.DB.Save(&post) + if result.Error != nil { + return nil, result.Error + } + return &post, nil + +} +func CountPostPages() int { + var count int64 + database.DB.Model(&database.Post{}).Count(&count) + return int(count/perPage) + 1 +} + +func DeletePost(id string) error { + + var post database.Post + result := database.DB.Where("id = ?", id).First(&post) + if result.Error != nil { + return result.Error + } + result = database.DB.Where("id = ?", post.BlobID).Delete(&database.Blob{}) + if result.Error != nil { + return result.Error + } + result = database.DB.Delete(&post) + if result.Error != nil { + return result.Error + } + return nil + +} diff --git a/pkg/services/tag.go b/pkg/services/tag.go new file mode 100644 index 0000000..4bff6d7 --- /dev/null +++ b/pkg/services/tag.go @@ -0,0 +1,86 @@ +package services + +import ( + "errors" + "strings" + + "github.com/Damillora/Shioriko/pkg/database" + "github.com/google/uuid" +) + +func GetTagAll() []database.Tag { + var tags []database.Tag + database.DB.Joins("TagType").Find(&tags) + return tags +} + +func CreateOrUpdateTag(tagSyntax string) (*database.Tag, error) { + tagFields := strings.Split(tagSyntax, ":") + var tagName string + var tagType database.TagType + if len(tagFields) == 1 { + tagName = tagFields[0] + database.DB.Where("name = ?", "general").First(&tagType) + } else if len(tagFields) == 2 { + tagName = tagFields[1] + result := database.DB.Where("name = ?", tagFields[0]).First(&tagType) + if result.Error != nil { + return nil, result.Error + } + } else { + return nil, errors.New("Malformed tag syntax") + } + var tag database.Tag + result := database.DB.Where("name = ? AND tag_type_id = ? ", tagName, tagType.ID).First(&tag) + + if result.Error != nil { + tag = database.Tag{ + ID: uuid.NewString(), + Name: tagName, + TagTypeID: tagType.ID, + } + result = database.DB.Create(&tag) + if result.Error != nil { + return nil, result.Error + } + + } + return &tag, nil +} + +func GetTag(tagSyntax string) (*database.Tag, error) { + tagFields := strings.Split(tagSyntax, ":") + var tagName string + var tagType database.TagType + if len(tagFields) == 1 { + tagName = tagFields[0] + database.DB.Where("name = ?", "general").First(&tagType) + } else if len(tagFields) == 2 { + tagName = tagFields[1] + result := database.DB.Where("name = ?", tagFields[0]).First(&tagType) + if result.Error != nil { + return nil, result.Error + } + } else { + return nil, errors.New("Malformed tag syntax") + } + var tag database.Tag + result := database.DB.Preload("Posts").Where("name = ? AND tag_type_id = ? ", tagName, tagType.ID).First(&tag) + + if result.Error != nil { + return nil, result.Error + } + return &tag, nil +} + +func ParseTags(tags []string) ([]database.Tag, error) { + var result []database.Tag + for _, tagSyntax := range tags { + tag, err := CreateOrUpdateTag(tagSyntax) + if err != nil { + return nil, err + } + result = append(result, *tag) + } + return result, nil +} diff --git a/pkg/services/tag_type.go b/pkg/services/tag_type.go new file mode 100644 index 0000000..0ea4a61 --- /dev/null +++ b/pkg/services/tag_type.go @@ -0,0 +1,36 @@ +package services + +import ( + "github.com/Damillora/Shioriko/pkg/database" + "github.com/Damillora/Shioriko/pkg/models" +) + +func GetTagTypeAll() []database.TagType { + var tagTypes []database.TagType + database.DB.Find(&tagTypes) + return tagTypes +} + +func CreateOrUpdateTagType(model models.TagTypeCreateModel) (*database.TagType, error) { + var tagType database.TagType + result := database.DB.Where("name = ?", model.Name).First(&tagType) + + if result.Error != nil { + tagType = database.TagType{ + Name: model.Name, + } + result = database.DB.Create(&tagType) + if result.Error != nil { + return nil, result.Error + } + + } + return &tagType, nil +} + +func DeleteTagType(id uint) error { + var tagType database.TagType + database.DB.Where("id = ?", id).First(&tagType) + result := database.DB.Delete(tagType) + return result.Error +} diff --git a/pkg/services/user.go b/pkg/services/user.go new file mode 100644 index 0000000..f09e3fe --- /dev/null +++ b/pkg/services/user.go @@ -0,0 +1,65 @@ +package services + +import ( + "github.com/Damillora/Shioriko/pkg/database" + "github.com/Damillora/Shioriko/pkg/models" + "github.com/google/uuid" + "golang.org/x/crypto/bcrypt" +) + +func CreateUser(model models.UserCreateModel) (*database.User, error) { + passwd, err := bcrypt.GenerateFromPassword([]byte(model.Password), bcrypt.DefaultCost) + if err != nil { + return nil, err + } + + user := database.User{ + ID: uuid.NewString(), + Email: model.Email, + Username: model.Username, + Password: string(passwd), + } + result := database.DB.Create(&user) + if result.Error != nil { + return nil, result.Error + } + return &user, nil +} + +func GetUser(id string) *database.User { + var user database.User + database.DB.Where("id = ?", id).First(&user) + + return &user +} +func GetUserFromUsername(username string) *database.User { + var user database.User + database.DB.Where("username = ?", username).First(&user) + + return &user +} + +func UpdateUser(id string, model models.UserUpdateModel) (*database.User, error) { + var user database.User + result := database.DB.Where("id = ?", id).First(&user) + + if result.Error != nil { + return nil, result.Error + } + user.Email = model.Email + user.Username = model.Username + + if user.Password != "" { + passwd, err := bcrypt.GenerateFromPassword([]byte(model.Password), bcrypt.DefaultCost) + if err != nil { + return nil, err + } + user.Password = string(passwd) + } + + result = database.DB.Save(&user) + if result.Error != nil { + return nil, result.Error + } + return &user, nil +} diff --git a/web/app/.gitignore b/web/app/.gitignore new file mode 100644 index 0000000..da93220 --- /dev/null +++ b/web/app/.gitignore @@ -0,0 +1,4 @@ +/node_modules/ +/public/build/ + +.DS_Store diff --git a/web/app/README.md b/web/app/README.md new file mode 100644 index 0000000..7b1ba83 --- /dev/null +++ b/web/app/README.md @@ -0,0 +1,105 @@ +*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)* + +--- + +# svelte app + +This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. + +To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): + +```bash +npx degit sveltejs/template svelte-app +cd svelte-app +``` + +*Note that you will need to have [Node.js](https://nodejs.org) installed.* + + +## Get started + +Install the dependencies... + +```bash +cd svelte-app +npm install +``` + +...then start [Rollup](https://rollupjs.org): + +```bash +npm run dev +``` + +Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. + +By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. + +If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense. + +## Building and running in production mode + +To create an optimised version of the app: + +```bash +npm run build +``` + +You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). + + +## Single-page app mode + +By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. + +If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: + +```js +"start": "sirv public --single" +``` + +## Using TypeScript + +This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with: + +```bash +node scripts/setupTypeScript.js +``` + +Or remove the script via: + +```bash +rm scripts/setupTypeScript.js +``` + +## Deploying to the web + +### With [Vercel](https://vercel.com) + +Install `vercel` if you haven't already: + +```bash +npm install -g vercel +``` + +Then, from within your project folder: + +```bash +cd public +vercel deploy --name my-project +``` + +### With [surge](https://surge.sh/) + +Install `surge` if you haven't already: + +```bash +npm install -g surge +``` + +Then, from within your project folder: + +```bash +npm run build +surge public my-project.surge.sh +``` diff --git a/web/app/package.json b/web/app/package.json new file mode 100644 index 0000000..3e8dde6 --- /dev/null +++ b/web/app/package.json @@ -0,0 +1,24 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "start": "sirv public --no-clear" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "svelte": "^3.0.0" + }, + "dependencies": { + "sirv-cli": "^1.0.0", + "svelte-routing": "^1.6.0" + } +} diff --git a/web/app/rollup.config.js b/web/app/rollup.config.js new file mode 100644 index 0000000..4915710 --- /dev/null +++ b/web/app/rollup.config.js @@ -0,0 +1,76 @@ +import svelte from 'rollup-plugin-svelte'; +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import livereload from 'rollup-plugin-livereload'; +import { terser } from 'rollup-plugin-terser'; +import css from 'rollup-plugin-css-only'; + +const production = !process.env.ROLLUP_WATCH; + +function serve() { + let server; + + function toExit() { + if (server) server.kill(0); + } + + return { + writeBundle() { + if (server) return; + server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { + stdio: ['ignore', 'inherit', 'inherit'], + shell: true + }); + + process.on('SIGTERM', toExit); + process.on('exit', toExit); + } + }; +} + +export default { + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: '../static/bundle.js' + }, + plugins: [ + svelte({ + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: '../static/bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + + // In dev mode, call `npm run start` once + // the bundle has been generated + !production && serve(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + } +}; diff --git a/web/app/src/App.svelte b/web/app/src/App.svelte new file mode 100644 index 0000000..bcd2f99 --- /dev/null +++ b/web/app/src/App.svelte @@ -0,0 +1,75 @@ + + + + +
+ + + + + + +
+
\ No newline at end of file diff --git a/web/app/src/api.js b/web/app/src/api.js new file mode 100644 index 0000000..9f71286 --- /dev/null +++ b/web/app/src/api.js @@ -0,0 +1,41 @@ +import { token } from "./stores.js" + +let url = window.BASE_URL; +let current_token; +const unsub_token = token.subscribe(value => { + current_token = token; +}) +export async function login({ username, password }) { + const endpoint = url + "/api/auth/login"; + const response = await fetch(endpoint, { + method: "POST", + body: JSON.stringify({ + username, + password, + }), + }) + const data = await response.json(); + token.set(data.token); + return data; +} + +export async function getPosts({ page }) { + const endpoint = url + "/api/post?page=" + page; + const response = await fetch(endpoint); + const data = await response.json(); + return data; +} + +export async function getPostsTag({ page, tag }) { + const endpoint = url + "/api/post/tag/" + tag + "?page=" + page; + const response = await fetch(endpoint); + const data = await response.json(); + return data; +} + +export async function getPost({ id }) { + const endpoint = url + "/api/post/" + id; + const response = await fetch(endpoint); + const data = await response.json(); + return data; +} \ No newline at end of file diff --git a/web/app/src/main.js b/web/app/src/main.js new file mode 100644 index 0000000..dbbc233 --- /dev/null +++ b/web/app/src/main.js @@ -0,0 +1,8 @@ +import App from './App.svelte'; + +const app = new App({ + target: document.body, + hydrate: false, +}); + +export default app; \ No newline at end of file diff --git a/web/app/src/routes/Home.svelte b/web/app/src/routes/Home.svelte new file mode 100644 index 0000000..fab0961 --- /dev/null +++ b/web/app/src/routes/Home.svelte @@ -0,0 +1,14 @@ + + +
+
+

+ Shioriko +

+

+ Booru-style gallery written in Go and Svelte +

+
+
diff --git a/web/app/src/routes/Login.svelte b/web/app/src/routes/Login.svelte new file mode 100644 index 0000000..d5cecd6 --- /dev/null +++ b/web/app/src/routes/Login.svelte @@ -0,0 +1,33 @@ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
diff --git a/web/app/src/routes/Logout.svelte b/web/app/src/routes/Logout.svelte new file mode 100644 index 0000000..d5db507 --- /dev/null +++ b/web/app/src/routes/Logout.svelte @@ -0,0 +1,11 @@ + diff --git a/web/app/src/routes/Post.svelte b/web/app/src/routes/Post.svelte new file mode 100644 index 0000000..bdf8979 --- /dev/null +++ b/web/app/src/routes/Post.svelte @@ -0,0 +1,48 @@ + + + +
+
+ {#if post} +

+ Post ID: {post.id} +

+ {/if} +
+
+{#if post} +
+
+
+
+

+ Source URL: {post.source_url} +

+

+ Tags: + {#each post.tags as tag (tag)} + {tag} + {/each} +

+
+
+
+ +
+
+
+
+
+{/if} \ No newline at end of file diff --git a/web/app/src/routes/Posts.svelte b/web/app/src/routes/Posts.svelte new file mode 100644 index 0000000..063d74c --- /dev/null +++ b/web/app/src/routes/Posts.svelte @@ -0,0 +1,48 @@ + + +
+
+

+ Posts +

+
+
+ +
+
+
+ {#each posts as post (post.id)} +
+
+
+ + + +
+
+
+
+ {#each post.tags as tag (tag)} + {tag} + {/each} +
+
+
+ {/each} +
+
+
diff --git a/web/app/src/routes/Tag.svelte b/web/app/src/routes/Tag.svelte new file mode 100644 index 0000000..afcfa16 --- /dev/null +++ b/web/app/src/routes/Tag.svelte @@ -0,0 +1,53 @@ + + +
+
+

+ {id} +

+

+ Tag +

+
+
+ +
+
+
+ {#each posts as post (post.id)} +
+
+
+ + + +
+
+
+
+ {#each post.tags as tag (tag)} + {tag} + {/each} +
+
+
+ {/each} +
+
+
diff --git a/web/app/src/stores.js b/web/app/src/stores.js new file mode 100644 index 0000000..318c9fd --- /dev/null +++ b/web/app/src/stores.js @@ -0,0 +1,8 @@ +import { writable } from "svelte/store"; + +const storedToken = localStorage.getItem("apiToken"); + +export const token = writable(storedToken); +token.subscribe(value => { + localStorage.setItem("apiToken", value); +}); \ No newline at end of file diff --git a/web/app/yarn.lock b/web/app/yarn.lock new file mode 100644 index 0000000..7263c4e --- /dev/null +++ b/web/app/yarn.lock @@ -0,0 +1,689 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.10.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@polka/url@^1.0.0-next.9": + version "1.0.0-next.12" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.12.tgz#431ec342a7195622f86688bbda82e3166ce8cb28" + integrity sha512-6RglhutqrGFMO1MNUXp95RBuYIuc8wTnMAV5MUhLmjTOy78ncwOw7RgeQ/HeymkKXRhZd0s2DNrM1rL7unk3MQ== + +"@rollup/plugin-commonjs@^17.0.0": + version "17.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz#757ec88737dffa8aa913eb392fade2e45aef2a2d" + integrity sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + +"@rollup/plugin-node-resolve@^11.0.0": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/pluginutils@4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838" + integrity sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@types/estree@*": + version "0.0.47" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" + integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@*": + version "15.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" + integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chokidar@^3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +console-clear@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/console-clear/-/console-clear-1.1.1.tgz#995e20cbfbf14dd792b672cde387bd128d674bf7" + integrity sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ== + +dedent-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dedent-js/-/dedent-js-1.0.1.tgz#bee5fb7c9e727d85dffa24590d10ec1ab1255305" + integrity sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU= + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + +glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.6: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" + integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-reference@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +kleur@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +livereload-js@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-3.3.2.tgz#c88b009c6e466b15b91faa26fd7c99d620e12651" + integrity sha512-w677WnINxFkuixAoUEXOStewzLYGI76XVag+0JWMMEyjJQKs0ibWZMxkTlB96Lm3EjZ7IeOxVziBEbtxVQqQZA== + +livereload@^0.9.1: + version "0.9.3" + resolved "https://registry.yarnpkg.com/livereload/-/livereload-0.9.3.tgz#a714816375ed52471408bede8b49b2ee6a0c55b1" + integrity sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw== + dependencies: + chokidar "^3.5.0" + livereload-js "^3.3.1" + opts ">= 1.2.0" + ws "^7.4.3" + +local-access@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/local-access/-/local-access-1.1.0.tgz#e007c76ba2ca83d5877ba1a125fc8dfe23ba4798" + integrity sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw== + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime@^2.3.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +mri@^1.1.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6" + integrity sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +"opts@>= 1.2.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1" + integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg== + +pascal-case@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +require-relative@^0.8.7: + version "0.8.7" + resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" + integrity sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4= + +resolve@^1.17.0, resolve@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +rollup-plugin-css-only@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz#6a701cc5b051c6b3f0961e69b108a9a118e1b1df" + integrity sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA== + dependencies: + "@rollup/pluginutils" "4" + +rollup-plugin-livereload@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.0.tgz#d3928d74e8cf2ae4286c5dd46b770fd3f3b82313" + integrity sha512-oC/8NqumGYuphkqrfszOHUUIwzKsaHBICw6QRwT5uD07gvePTS+HW+GFwu6f9K8W02CUuTvtIM9AWJrbj4wE1A== + dependencies: + livereload "^0.9.1" + +rollup-plugin-svelte@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz#d45f2b92b1014be4eb46b55aa033fb9a9c65f04d" + integrity sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg== + dependencies: + require-relative "^0.8.7" + rollup-pluginutils "^2.8.2" + +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup-pluginutils@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + +rollup@^2.3.4: + version "2.47.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.47.0.tgz#9d958aeb2c0f6a383cacc0401dff02b6e252664d" + integrity sha512-rqBjgq9hQfW0vRmz+0S062ORRNJXvwRpzxhFXORvar/maZqY6za3rgQ/p1Glg+j1hnc1GtYyQCPiAei95uTElg== + optionalDependencies: + fsevents "~2.3.1" + +sade@^1.6.0: + version "1.7.4" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691" + integrity sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA== + dependencies: + mri "^1.1.0" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semiver@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semiver/-/semiver-1.1.0.tgz#9c97fb02c21c7ce4fcf1b73e2c7a24324bdddd5f" + integrity sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg== + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +sirv-cli@^1.0.0: + version "1.0.11" + resolved "https://registry.yarnpkg.com/sirv-cli/-/sirv-cli-1.0.11.tgz#a3f4bed53b7c09306ed7f16ebea6e1e7be676c74" + integrity sha512-L8NILoRSBd38VcfFcERYCaVCnWPBLo9G6u/a37UJ8Ysv4DfjizMbFBcM+SswNnndJienhR6qy8KFuAEaeL4g8Q== + dependencies: + console-clear "^1.1.0" + get-port "^3.2.0" + kleur "^3.0.0" + local-access "^1.0.1" + sade "^1.6.0" + semiver "^1.0.0" + sirv "^1.0.11" + tinydate "^1.0.0" + +sirv@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.11.tgz#81c19a29202048507d6ec0d8ba8910fda52eb5a4" + integrity sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg== + dependencies: + "@polka/url" "^1.0.0-next.9" + mime "^2.3.1" + totalist "^1.0.0" + +source-map-support@~0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +svelte-routing@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/svelte-routing/-/svelte-routing-1.6.0.tgz#cdfed6b665d4a851f3d7e532e16bfbb318ce5294" + integrity sha512-+DbrSGttLA6lan7oWFz1MjyGabdn3tPRqn8Osyc471ut2UgCrzM5x1qViNMc2gahOP6fKbKK1aNtZMJEQP2vHQ== + dependencies: + svelte2tsx "^0.1.157" + +svelte2tsx@^0.1.157: + version "0.1.189" + resolved "https://registry.yarnpkg.com/svelte2tsx/-/svelte2tsx-0.1.189.tgz#3eacbeec8cef8a120da05373bb59be0eb46f4880" + integrity sha512-Mo4Sei1tNYthzSZx6biGSK7pI6/vj7nGvvmSevmLIiws/o1hyj1UIHn+AwqogeA9L46fcvy6WU3t7HxDg+LbLg== + dependencies: + dedent-js "^1.0.1" + pascal-case "^3.1.1" + +svelte@^3.0.0: + version "3.38.2" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5" + integrity sha512-q5Dq0/QHh4BLJyEVWGe7Cej5NWs040LWjMbicBGZ+3qpFWJ1YObRmUDZKbbovddLC9WW7THTj3kYbTOFmU9fbg== + +terser@^5.0.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" + integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +tinydate@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/tinydate/-/tinydate-1.3.0.tgz#e6ca8e5a22b51bb4ea1c3a2a4fd1352dbd4c57fb" + integrity sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + +tslib@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^7.4.3: + version "7.4.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" + integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== diff --git a/web/static/bundle.js b/web/static/bundle.js new file mode 100644 index 0000000..9a4e863 --- /dev/null +++ b/web/static/bundle.js @@ -0,0 +1,4707 @@ + +(function(l, r) { if (l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (window.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(window.document); +var app = (function () { + 'use strict'; + + function noop() { } + function assign(tar, src) { + // @ts-ignore + for (const k in src) + tar[k] = src[k]; + return tar; + } + function add_location(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char } + }; + } + function run(fn) { + return fn(); + } + function blank_object() { + return Object.create(null); + } + function run_all(fns) { + fns.forEach(run); + } + function is_function(thing) { + return typeof thing === 'function'; + } + function safe_not_equal(a, b) { + return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); + } + function is_empty(obj) { + return Object.keys(obj).length === 0; + } + function validate_store(store, name) { + if (store != null && typeof store.subscribe !== 'function') { + throw new Error(`'${name}' is not a store with a 'subscribe' method`); + } + } + function subscribe(store, ...callbacks) { + if (store == null) { + return noop; + } + const unsub = store.subscribe(...callbacks); + return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; + } + function component_subscribe(component, store, callback) { + component.$$.on_destroy.push(subscribe(store, callback)); + } + function create_slot(definition, ctx, $$scope, fn) { + if (definition) { + const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); + return definition[0](slot_ctx); + } + } + function get_slot_context(definition, ctx, $$scope, fn) { + return definition[1] && fn + ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) + : $$scope.ctx; + } + function get_slot_changes(definition, $$scope, dirty, fn) { + if (definition[2] && fn) { + const lets = definition[2](fn(dirty)); + if ($$scope.dirty === undefined) { + return lets; + } + if (typeof lets === 'object') { + const merged = []; + const len = Math.max($$scope.dirty.length, lets.length); + for (let i = 0; i < len; i += 1) { + merged[i] = $$scope.dirty[i] | lets[i]; + } + return merged; + } + return $$scope.dirty | lets; + } + return $$scope.dirty; + } + function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) { + const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn); + if (slot_changes) { + const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); + slot.p(slot_context, slot_changes); + } + } + function exclude_internal_props(props) { + const result = {}; + for (const k in props) + if (k[0] !== '$') + result[k] = props[k]; + return result; + } + function compute_rest_props(props, keys) { + const rest = {}; + keys = new Set(keys); + for (const k in props) + if (!keys.has(k) && k[0] !== '$') + rest[k] = props[k]; + return rest; + } + + function append(target, node) { + target.appendChild(node); + } + function insert(target, node, anchor) { + target.insertBefore(node, anchor || null); + } + function detach(node) { + node.parentNode.removeChild(node); + } + function element(name) { + return document.createElement(name); + } + function text(data) { + return document.createTextNode(data); + } + function space() { + return text(' '); + } + function empty() { + return text(''); + } + function listen(node, event, handler, options) { + node.addEventListener(event, handler, options); + return () => node.removeEventListener(event, handler, options); + } + function prevent_default(fn) { + return function (event) { + event.preventDefault(); + // @ts-ignore + return fn.call(this, event); + }; + } + function attr(node, attribute, value) { + if (value == null) + node.removeAttribute(attribute); + else if (node.getAttribute(attribute) !== value) + node.setAttribute(attribute, value); + } + function set_attributes(node, attributes) { + // @ts-ignore + const descriptors = Object.getOwnPropertyDescriptors(node.__proto__); + for (const key in attributes) { + if (attributes[key] == null) { + node.removeAttribute(key); + } + else if (key === 'style') { + node.style.cssText = attributes[key]; + } + else if (key === '__value') { + node.value = node[key] = attributes[key]; + } + else if (descriptors[key] && descriptors[key].set) { + node[key] = attributes[key]; + } + else { + attr(node, key, attributes[key]); + } + } + } + function children(element) { + return Array.from(element.childNodes); + } + function set_input_value(input, value) { + input.value = value == null ? '' : value; + } + function custom_event(type, detail) { + const e = document.createEvent('CustomEvent'); + e.initCustomEvent(type, false, false, detail); + return e; + } + + let current_component; + function set_current_component(component) { + current_component = component; + } + function get_current_component() { + if (!current_component) + throw new Error('Function called outside component initialization'); + return current_component; + } + function onMount(fn) { + get_current_component().$$.on_mount.push(fn); + } + function onDestroy(fn) { + get_current_component().$$.on_destroy.push(fn); + } + function createEventDispatcher() { + const component = get_current_component(); + return (type, detail) => { + const callbacks = component.$$.callbacks[type]; + if (callbacks) { + // TODO are there situations where events could be dispatched + // in a server (non-DOM) environment? + const event = custom_event(type, detail); + callbacks.slice().forEach(fn => { + fn.call(component, event); + }); + } + }; + } + function setContext(key, context) { + get_current_component().$$.context.set(key, context); + } + function getContext(key) { + return get_current_component().$$.context.get(key); + } + + const dirty_components = []; + const binding_callbacks = []; + const render_callbacks = []; + const flush_callbacks = []; + const resolved_promise = Promise.resolve(); + let update_scheduled = false; + function schedule_update() { + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } + } + function add_render_callback(fn) { + render_callbacks.push(fn); + } + let flushing = false; + const seen_callbacks = new Set(); + function flush() { + if (flushing) + return; + flushing = true; + do { + // first, call beforeUpdate functions + // and update components + for (let i = 0; i < dirty_components.length; i += 1) { + const component = dirty_components[i]; + set_current_component(component); + update(component.$$); + } + set_current_component(null); + dirty_components.length = 0; + while (binding_callbacks.length) + binding_callbacks.pop()(); + // then, once components are updated, call + // afterUpdate functions. This may cause + // subsequent updates... + for (let i = 0; i < render_callbacks.length; i += 1) { + const callback = render_callbacks[i]; + if (!seen_callbacks.has(callback)) { + // ...so guard against infinite loops + seen_callbacks.add(callback); + callback(); + } + } + render_callbacks.length = 0; + } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_scheduled = false; + flushing = false; + seen_callbacks.clear(); + } + function update($$) { + if ($$.fragment !== null) { + $$.update(); + run_all($$.before_update); + const dirty = $$.dirty; + $$.dirty = [-1]; + $$.fragment && $$.fragment.p($$.ctx, dirty); + $$.after_update.forEach(add_render_callback); + } + } + const outroing = new Set(); + let outros; + function group_outros() { + outros = { + r: 0, + c: [], + p: outros // parent group + }; + } + function check_outros() { + if (!outros.r) { + run_all(outros.c); + } + outros = outros.p; + } + function transition_in(block, local) { + if (block && block.i) { + outroing.delete(block); + block.i(local); + } + } + function transition_out(block, local, detach, callback) { + if (block && block.o) { + if (outroing.has(block)) + return; + outroing.add(block); + outros.c.push(() => { + outroing.delete(block); + if (callback) { + if (detach) + block.d(1); + callback(); + } + }); + block.o(local); + } + } + function outro_and_destroy_block(block, lookup) { + transition_out(block, 1, 1, () => { + lookup.delete(block.key); + }); + } + function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { + let o = old_blocks.length; + let n = list.length; + let i = o; + const old_indexes = {}; + while (i--) + old_indexes[old_blocks[i].key] = i; + const new_blocks = []; + const new_lookup = new Map(); + const deltas = new Map(); + i = n; + while (i--) { + const child_ctx = get_context(ctx, list, i); + const key = get_key(child_ctx); + let block = lookup.get(key); + if (!block) { + block = create_each_block(key, child_ctx); + block.c(); + } + else if (dynamic) { + block.p(child_ctx, dirty); + } + new_lookup.set(key, new_blocks[i] = block); + if (key in old_indexes) + deltas.set(key, Math.abs(i - old_indexes[key])); + } + const will_move = new Set(); + const did_move = new Set(); + function insert(block) { + transition_in(block, 1); + block.m(node, next); + lookup.set(block.key, block); + next = block.first; + n--; + } + while (o && n) { + const new_block = new_blocks[n - 1]; + const old_block = old_blocks[o - 1]; + const new_key = new_block.key; + const old_key = old_block.key; + if (new_block === old_block) { + // do nothing + next = new_block.first; + o--; + n--; + } + else if (!new_lookup.has(old_key)) { + // remove old block + destroy(old_block, lookup); + o--; + } + else if (!lookup.has(new_key) || will_move.has(new_key)) { + insert(new_block); + } + else if (did_move.has(old_key)) { + o--; + } + else if (deltas.get(new_key) > deltas.get(old_key)) { + did_move.add(new_key); + insert(new_block); + } + else { + will_move.add(old_key); + o--; + } + } + while (o--) { + const old_block = old_blocks[o]; + if (!new_lookup.has(old_block.key)) + destroy(old_block, lookup); + } + while (n) + insert(new_blocks[n - 1]); + return new_blocks; + } + function validate_each_keys(ctx, list, get_context, get_key) { + const keys = new Set(); + for (let i = 0; i < list.length; i++) { + const key = get_key(get_context(ctx, list, i)); + if (keys.has(key)) { + throw new Error('Cannot have duplicate keys in a keyed each'); + } + keys.add(key); + } + } + + function get_spread_update(levels, updates) { + const update = {}; + const to_null_out = {}; + const accounted_for = { $$scope: 1 }; + let i = levels.length; + while (i--) { + const o = levels[i]; + const n = updates[i]; + if (n) { + for (const key in o) { + if (!(key in n)) + to_null_out[key] = 1; + } + for (const key in n) { + if (!accounted_for[key]) { + update[key] = n[key]; + accounted_for[key] = 1; + } + } + levels[i] = n; + } + else { + for (const key in o) { + accounted_for[key] = 1; + } + } + } + for (const key in to_null_out) { + if (!(key in update)) + update[key] = undefined; + } + return update; + } + function get_spread_object(spread_props) { + return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; + } + function create_component(block) { + block && block.c(); + } + function mount_component(component, target, anchor, customElement) { + const { fragment, on_mount, on_destroy, after_update } = component.$$; + fragment && fragment.m(target, anchor); + if (!customElement) { + // onMount happens before the initial afterUpdate + add_render_callback(() => { + const new_on_destroy = on_mount.map(run).filter(is_function); + if (on_destroy) { + on_destroy.push(...new_on_destroy); + } + else { + // Edge case - component was destroyed immediately, + // most likely as a result of a binding initialising + run_all(new_on_destroy); + } + component.$$.on_mount = []; + }); + } + after_update.forEach(add_render_callback); + } + function destroy_component(component, detaching) { + const $$ = component.$$; + if ($$.fragment !== null) { + run_all($$.on_destroy); + $$.fragment && $$.fragment.d(detaching); + // TODO null out other refs, including component.$$ (but need to + // preserve final state?) + $$.on_destroy = $$.fragment = null; + $$.ctx = []; + } + } + function make_dirty(component, i) { + if (component.$$.dirty[0] === -1) { + dirty_components.push(component); + schedule_update(); + component.$$.dirty.fill(0); + } + component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); + } + function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { + const parent_component = current_component; + set_current_component(component); + const $$ = component.$$ = { + fragment: null, + ctx: null, + // state + props, + update: noop, + not_equal, + bound: blank_object(), + // lifecycle + on_mount: [], + on_destroy: [], + on_disconnect: [], + before_update: [], + after_update: [], + context: new Map(parent_component ? parent_component.$$.context : options.context || []), + // everything else + callbacks: blank_object(), + dirty, + skip_bound: false + }; + let ready = false; + $$.ctx = instance + ? instance(component, options.props || {}, (i, ret, ...rest) => { + const value = rest.length ? rest[0] : ret; + if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { + if (!$$.skip_bound && $$.bound[i]) + $$.bound[i](value); + if (ready) + make_dirty(component, i); + } + return ret; + }) + : []; + $$.update(); + ready = true; + run_all($$.before_update); + // `false` as a special case of no DOM component + $$.fragment = create_fragment ? create_fragment($$.ctx) : false; + if (options.target) { + if (options.hydrate) { + const nodes = children(options.target); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.l(nodes); + nodes.forEach(detach); + } + else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.c(); + } + if (options.intro) + transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + flush(); + } + set_current_component(parent_component); + } + /** + * Base class for Svelte components. Used when dev=false. + */ + class SvelteComponent { + $destroy() { + destroy_component(this, 1); + this.$destroy = noop; + } + $on(type, callback) { + const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); + callbacks.push(callback); + return () => { + const index = callbacks.indexOf(callback); + if (index !== -1) + callbacks.splice(index, 1); + }; + } + $set($$props) { + if (this.$$set && !is_empty($$props)) { + this.$$.skip_bound = true; + this.$$set($$props); + this.$$.skip_bound = false; + } + } + } + + function dispatch_dev(type, detail) { + document.dispatchEvent(custom_event(type, Object.assign({ version: '3.38.2' }, detail))); + } + function append_dev(target, node) { + dispatch_dev('SvelteDOMInsert', { target, node }); + append(target, node); + } + function insert_dev(target, node, anchor) { + dispatch_dev('SvelteDOMInsert', { target, node, anchor }); + insert(target, node, anchor); + } + function detach_dev(node) { + dispatch_dev('SvelteDOMRemove', { node }); + detach(node); + } + function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) { + const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : []; + if (has_prevent_default) + modifiers.push('preventDefault'); + if (has_stop_propagation) + modifiers.push('stopPropagation'); + dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers }); + const dispose = listen(node, event, handler, options); + return () => { + dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers }); + dispose(); + }; + } + function attr_dev(node, attribute, value) { + attr(node, attribute, value); + if (value == null) + dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute }); + else + dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value }); + } + function set_data_dev(text, data) { + data = '' + data; + if (text.wholeText === data) + return; + dispatch_dev('SvelteDOMSetData', { node: text, data }); + text.data = data; + } + function validate_each_argument(arg) { + if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) { + let msg = '{#each} only iterates over array-like objects.'; + if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) { + msg += ' You can use a spread to convert this iterable into an array.'; + } + throw new Error(msg); + } + } + function validate_slots(name, slot, keys) { + for (const slot_key of Object.keys(slot)) { + if (!~keys.indexOf(slot_key)) { + console.warn(`<${name}> received an unexpected slot "${slot_key}".`); + } + } + } + /** + * Base class for Svelte components with some minor dev-enhancements. Used when dev=true. + */ + class SvelteComponentDev extends SvelteComponent { + constructor(options) { + if (!options || (!options.target && !options.$$inline)) { + throw new Error("'target' is a required option"); + } + super(); + } + $destroy() { + super.$destroy(); + this.$destroy = () => { + console.warn('Component was already destroyed'); // eslint-disable-line no-console + }; + } + $capture_state() { } + $inject_state() { } + } + + const subscriber_queue = []; + /** + * Creates a `Readable` store that allows reading by subscription. + * @param value initial value + * @param {StartStopNotifier}start start and stop notifications for subscriptions + */ + function readable(value, start) { + return { + subscribe: writable(value, start).subscribe + }; + } + /** + * Create a `Writable` store that allows both updating and reading by subscription. + * @param {*=}value initial value + * @param {StartStopNotifier=}start start and stop notifications for subscriptions + */ + function writable(value, start = noop) { + let stop; + const subscribers = []; + function set(new_value) { + if (safe_not_equal(value, new_value)) { + value = new_value; + if (stop) { // store is ready + const run_queue = !subscriber_queue.length; + for (let i = 0; i < subscribers.length; i += 1) { + const s = subscribers[i]; + s[1](); + subscriber_queue.push(s, value); + } + if (run_queue) { + for (let i = 0; i < subscriber_queue.length; i += 2) { + subscriber_queue[i][0](subscriber_queue[i + 1]); + } + subscriber_queue.length = 0; + } + } + } + } + function update(fn) { + set(fn(value)); + } + function subscribe(run, invalidate = noop) { + const subscriber = [run, invalidate]; + subscribers.push(subscriber); + if (subscribers.length === 1) { + stop = start(set) || noop; + } + run(value); + return () => { + const index = subscribers.indexOf(subscriber); + if (index !== -1) { + subscribers.splice(index, 1); + } + if (subscribers.length === 0) { + stop(); + stop = null; + } + }; + } + return { set, update, subscribe }; + } + function derived(stores, fn, initial_value) { + const single = !Array.isArray(stores); + const stores_array = single + ? [stores] + : stores; + const auto = fn.length < 2; + return readable(initial_value, (set) => { + let inited = false; + const values = []; + let pending = 0; + let cleanup = noop; + const sync = () => { + if (pending) { + return; + } + cleanup(); + const result = fn(single ? values[0] : values, set); + if (auto) { + set(result); + } + else { + cleanup = is_function(result) ? result : noop; + } + }; + const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => { + values[i] = value; + pending &= ~(1 << i); + if (inited) { + sync(); + } + }, () => { + pending |= (1 << i); + })); + inited = true; + sync(); + return function stop() { + run_all(unsubscribers); + cleanup(); + }; + }); + } + + const LOCATION = {}; + const ROUTER = {}; + + /** + * Adapted from https://github.com/reach/router/blob/b60e6dd781d5d3a4bdaaf4de665649c0f6a7e78d/src/lib/history.js + * + * https://github.com/reach/router/blob/master/LICENSE + * */ + + function getLocation(source) { + return { + ...source.location, + state: source.history.state, + key: (source.history.state && source.history.state.key) || "initial" + }; + } + + function createHistory(source, options) { + const listeners = []; + let location = getLocation(source); + + return { + get location() { + return location; + }, + + listen(listener) { + listeners.push(listener); + + const popstateListener = () => { + location = getLocation(source); + listener({ location, action: "POP" }); + }; + + source.addEventListener("popstate", popstateListener); + + return () => { + source.removeEventListener("popstate", popstateListener); + + const index = listeners.indexOf(listener); + listeners.splice(index, 1); + }; + }, + + navigate(to, { state, replace = false } = {}) { + state = { ...state, key: Date.now() + "" }; + // try...catch iOS Safari limits to 100 pushState calls + try { + if (replace) { + source.history.replaceState(state, null, to); + } else { + source.history.pushState(state, null, to); + } + } catch (e) { + source.location[replace ? "replace" : "assign"](to); + } + + location = getLocation(source); + listeners.forEach(listener => listener({ location, action: "PUSH" })); + } + }; + } + + // Stores history entries in memory for testing or other platforms like Native + function createMemorySource(initialPathname = "/") { + let index = 0; + const stack = [{ pathname: initialPathname, search: "" }]; + const states = []; + + return { + get location() { + return stack[index]; + }, + addEventListener(name, fn) {}, + removeEventListener(name, fn) {}, + history: { + get entries() { + return stack; + }, + get index() { + return index; + }, + get state() { + return states[index]; + }, + pushState(state, _, uri) { + const [pathname, search = ""] = uri.split("?"); + index++; + stack.push({ pathname, search }); + states.push(state); + }, + replaceState(state, _, uri) { + const [pathname, search = ""] = uri.split("?"); + stack[index] = { pathname, search }; + states[index] = state; + } + } + }; + } + + // Global history uses window.history as the source if available, + // otherwise a memory history + const canUseDOM = Boolean( + typeof window !== "undefined" && + window.document && + window.document.createElement + ); + const globalHistory = createHistory(canUseDOM ? window : createMemorySource()); + const { navigate } = globalHistory; + + /** + * Adapted from https://github.com/reach/router/blob/b60e6dd781d5d3a4bdaaf4de665649c0f6a7e78d/src/lib/utils.js + * + * https://github.com/reach/router/blob/master/LICENSE + * */ + + const paramRe = /^:(.+)/; + + const SEGMENT_POINTS = 4; + const STATIC_POINTS = 3; + const DYNAMIC_POINTS = 2; + const SPLAT_PENALTY = 1; + const ROOT_POINTS = 1; + + /** + * Check if `string` starts with `search` + * @param {string} string + * @param {string} search + * @return {boolean} + */ + function startsWith(string, search) { + return string.substr(0, search.length) === search; + } + + /** + * Check if `segment` is a root segment + * @param {string} segment + * @return {boolean} + */ + function isRootSegment(segment) { + return segment === ""; + } + + /** + * Check if `segment` is a dynamic segment + * @param {string} segment + * @return {boolean} + */ + function isDynamic(segment) { + return paramRe.test(segment); + } + + /** + * Check if `segment` is a splat + * @param {string} segment + * @return {boolean} + */ + function isSplat(segment) { + return segment[0] === "*"; + } + + /** + * Split up the URI into segments delimited by `/` + * @param {string} uri + * @return {string[]} + */ + function segmentize(uri) { + return ( + uri + // Strip starting/ending `/` + .replace(/(^\/+|\/+$)/g, "") + .split("/") + ); + } + + /** + * Strip `str` of potential start and end `/` + * @param {string} str + * @return {string} + */ + function stripSlashes(str) { + return str.replace(/(^\/+|\/+$)/g, ""); + } + + /** + * Score a route depending on how its individual segments look + * @param {object} route + * @param {number} index + * @return {object} + */ + function rankRoute(route, index) { + const score = route.default + ? 0 + : segmentize(route.path).reduce((score, segment) => { + score += SEGMENT_POINTS; + + if (isRootSegment(segment)) { + score += ROOT_POINTS; + } else if (isDynamic(segment)) { + score += DYNAMIC_POINTS; + } else if (isSplat(segment)) { + score -= SEGMENT_POINTS + SPLAT_PENALTY; + } else { + score += STATIC_POINTS; + } + + return score; + }, 0); + + return { route, score, index }; + } + + /** + * Give a score to all routes and sort them on that + * @param {object[]} routes + * @return {object[]} + */ + function rankRoutes(routes) { + return ( + routes + .map(rankRoute) + // If two routes have the exact same score, we go by index instead + .sort((a, b) => + a.score < b.score ? 1 : a.score > b.score ? -1 : a.index - b.index + ) + ); + } + + /** + * Ranks and picks the best route to match. Each segment gets the highest + * amount of points, then the type of segment gets an additional amount of + * points where + * + * static > dynamic > splat > root + * + * This way we don't have to worry about the order of our routes, let the + * computers do it. + * + * A route looks like this + * + * { path, default, value } + * + * And a returned match looks like: + * + * { route, params, uri } + * + * @param {object[]} routes + * @param {string} uri + * @return {?object} + */ + function pick(routes, uri) { + let match; + let default_; + + const [uriPathname] = uri.split("?"); + const uriSegments = segmentize(uriPathname); + const isRootUri = uriSegments[0] === ""; + const ranked = rankRoutes(routes); + + for (let i = 0, l = ranked.length; i < l; i++) { + const route = ranked[i].route; + let missed = false; + + if (route.default) { + default_ = { + route, + params: {}, + uri + }; + continue; + } + + const routeSegments = segmentize(route.path); + const params = {}; + const max = Math.max(uriSegments.length, routeSegments.length); + let index = 0; + + for (; index < max; index++) { + const routeSegment = routeSegments[index]; + const uriSegment = uriSegments[index]; + + if (routeSegment !== undefined && isSplat(routeSegment)) { + // Hit a splat, just grab the rest, and return a match + // uri: /files/documents/work + // route: /files/* or /files/*splatname + const splatName = routeSegment === "*" ? "*" : routeSegment.slice(1); + + params[splatName] = uriSegments + .slice(index) + .map(decodeURIComponent) + .join("/"); + break; + } + + if (uriSegment === undefined) { + // URI is shorter than the route, no match + // uri: /users + // route: /users/:userId + missed = true; + break; + } + + let dynamicMatch = paramRe.exec(routeSegment); + + if (dynamicMatch && !isRootUri) { + const value = decodeURIComponent(uriSegment); + params[dynamicMatch[1]] = value; + } else if (routeSegment !== uriSegment) { + // Current segments don't match, not dynamic, not splat, so no match + // uri: /users/123/settings + // route: /users/:id/profile + missed = true; + break; + } + } + + if (!missed) { + match = { + route, + params, + uri: "/" + uriSegments.slice(0, index).join("/") + }; + break; + } + } + + return match || default_ || null; + } + + /** + * Check if the `path` matches the `uri`. + * @param {string} path + * @param {string} uri + * @return {?object} + */ + function match(route, uri) { + return pick([route], uri); + } + + /** + * Add the query to the pathname if a query is given + * @param {string} pathname + * @param {string} [query] + * @return {string} + */ + function addQuery(pathname, query) { + return pathname + (query ? `?${query}` : ""); + } + + /** + * Resolve URIs as though every path is a directory, no files. Relative URIs + * in the browser can feel awkward because not only can you be "in a directory", + * you can be "at a file", too. For example: + * + * browserSpecResolve('foo', '/bar/') => /bar/foo + * browserSpecResolve('foo', '/bar') => /foo + * + * But on the command line of a file system, it's not as complicated. You can't + * `cd` from a file, only directories. This way, links have to know less about + * their current path. To go deeper you can do this: + * + * + * // instead of + * + * + * Just like `cd`, if you want to go deeper from the command line, you do this: + * + * cd deeper + * # not + * cd $(pwd)/deeper + * + * By treating every path as a directory, linking to relative paths should + * require less contextual information and (fingers crossed) be more intuitive. + * @param {string} to + * @param {string} base + * @return {string} + */ + function resolve(to, base) { + // /foo/bar, /baz/qux => /foo/bar + if (startsWith(to, "/")) { + return to; + } + + const [toPathname, toQuery] = to.split("?"); + const [basePathname] = base.split("?"); + const toSegments = segmentize(toPathname); + const baseSegments = segmentize(basePathname); + + // ?a=b, /users?b=c => /users?a=b + if (toSegments[0] === "") { + return addQuery(basePathname, toQuery); + } + + // profile, /users/789 => /users/789/profile + if (!startsWith(toSegments[0], ".")) { + const pathname = baseSegments.concat(toSegments).join("/"); + + return addQuery((basePathname === "/" ? "" : "/") + pathname, toQuery); + } + + // ./ , /users/123 => /users/123 + // ../ , /users/123 => /users + // ../.. , /users/123 => / + // ../../one, /a/b/c/d => /a/b/one + // .././one , /a/b/c/d => /a/b/c/one + const allSegments = baseSegments.concat(toSegments); + const segments = []; + + allSegments.forEach(segment => { + if (segment === "..") { + segments.pop(); + } else if (segment !== ".") { + segments.push(segment); + } + }); + + return addQuery("/" + segments.join("/"), toQuery); + } + + /** + * Combines the `basepath` and the `path` into one path. + * @param {string} basepath + * @param {string} path + */ + function combinePaths(basepath, path) { + return `${stripSlashes( + path === "/" ? basepath : `${stripSlashes(basepath)}/${stripSlashes(path)}` + )}/`; + } + + /** + * Decides whether a given `event` should result in a navigation or not. + * @param {object} event + */ + function shouldNavigate(event) { + return ( + !event.defaultPrevented && + event.button === 0 && + !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) + ); + } + + /* node_modules/svelte-routing/src/Router.svelte generated by Svelte v3.38.2 */ + + function create_fragment$9(ctx) { + let current; + const default_slot_template = /*#slots*/ ctx[9].default; + const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[8], null); + + const block = { + c: function create() { + if (default_slot) default_slot.c(); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + if (default_slot) { + default_slot.m(target, anchor); + } + + current = true; + }, + p: function update(ctx, [dirty]) { + if (default_slot) { + if (default_slot.p && (!current || dirty & /*$$scope*/ 256)) { + update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[8], dirty, null, null); + } + } + }, + i: function intro(local) { + if (current) return; + transition_in(default_slot, local); + current = true; + }, + o: function outro(local) { + transition_out(default_slot, local); + current = false; + }, + d: function destroy(detaching) { + if (default_slot) default_slot.d(detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$9.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$9($$self, $$props, $$invalidate) { + let $base; + let $location; + let $routes; + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Router", slots, ['default']); + let { basepath = "/" } = $$props; + let { url = null } = $$props; + const locationContext = getContext(LOCATION); + const routerContext = getContext(ROUTER); + const routes = writable([]); + validate_store(routes, "routes"); + component_subscribe($$self, routes, value => $$invalidate(7, $routes = value)); + const activeRoute = writable(null); + let hasActiveRoute = false; // Used in SSR to synchronously set that a Route is active. + + // If locationContext is not set, this is the topmost Router in the tree. + // If the `url` prop is given we force the location to it. + const location = locationContext || writable(url ? { pathname: url } : globalHistory.location); + + validate_store(location, "location"); + component_subscribe($$self, location, value => $$invalidate(6, $location = value)); + + // If routerContext is set, the routerBase of the parent Router + // will be the base for this Router's descendants. + // If routerContext is not set, the path and resolved uri will both + // have the value of the basepath prop. + const base = routerContext + ? routerContext.routerBase + : writable({ path: basepath, uri: basepath }); + + validate_store(base, "base"); + component_subscribe($$self, base, value => $$invalidate(5, $base = value)); + + const routerBase = derived([base, activeRoute], ([base, activeRoute]) => { + // If there is no activeRoute, the routerBase will be identical to the base. + if (activeRoute === null) { + return base; + } + + const { path: basepath } = base; + const { route, uri } = activeRoute; + + // Remove the potential /* or /*splatname from + // the end of the child Routes relative paths. + const path = route.default + ? basepath + : route.path.replace(/\*.*$/, ""); + + return { path, uri }; + }); + + function registerRoute(route) { + const { path: basepath } = $base; + let { path } = route; + + // We store the original path in the _path property so we can reuse + // it when the basepath changes. The only thing that matters is that + // the route reference is intact, so mutation is fine. + route._path = path; + + route.path = combinePaths(basepath, path); + + if (typeof window === "undefined") { + // In SSR we should set the activeRoute immediately if it is a match. + // If there are more Routes being registered after a match is found, + // we just skip them. + if (hasActiveRoute) { + return; + } + + const matchingRoute = match(route, $location.pathname); + + if (matchingRoute) { + activeRoute.set(matchingRoute); + hasActiveRoute = true; + } + } else { + routes.update(rs => { + rs.push(route); + return rs; + }); + } + } + + function unregisterRoute(route) { + routes.update(rs => { + const index = rs.indexOf(route); + rs.splice(index, 1); + return rs; + }); + } + + if (!locationContext) { + // The topmost Router in the tree is responsible for updating + // the location store and supplying it through context. + onMount(() => { + const unlisten = globalHistory.listen(history => { + location.set(history.location); + }); + + return unlisten; + }); + + setContext(LOCATION, location); + } + + setContext(ROUTER, { + activeRoute, + base, + routerBase, + registerRoute, + unregisterRoute + }); + + const writable_props = ["basepath", "url"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$$set = $$props => { + if ("basepath" in $$props) $$invalidate(3, basepath = $$props.basepath); + if ("url" in $$props) $$invalidate(4, url = $$props.url); + if ("$$scope" in $$props) $$invalidate(8, $$scope = $$props.$$scope); + }; + + $$self.$capture_state = () => ({ + getContext, + setContext, + onMount, + writable, + derived, + LOCATION, + ROUTER, + globalHistory, + pick, + match, + stripSlashes, + combinePaths, + basepath, + url, + locationContext, + routerContext, + routes, + activeRoute, + hasActiveRoute, + location, + base, + routerBase, + registerRoute, + unregisterRoute, + $base, + $location, + $routes + }); + + $$self.$inject_state = $$props => { + if ("basepath" in $$props) $$invalidate(3, basepath = $$props.basepath); + if ("url" in $$props) $$invalidate(4, url = $$props.url); + if ("hasActiveRoute" in $$props) hasActiveRoute = $$props.hasActiveRoute; + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + $$self.$$.update = () => { + if ($$self.$$.dirty & /*$base*/ 32) { + // This reactive statement will update all the Routes' path when + // the basepath changes. + { + const { path: basepath } = $base; + + routes.update(rs => { + rs.forEach(r => r.path = combinePaths(basepath, r._path)); + return rs; + }); + } + } + + if ($$self.$$.dirty & /*$routes, $location*/ 192) { + // This reactive statement will be run when the Router is created + // when there are no Routes and then again the following tick, so it + // will not find an active Route in SSR and in the browser it will only + // pick an active Route after all Routes have been registered. + { + const bestMatch = pick($routes, $location.pathname); + activeRoute.set(bestMatch); + } + } + }; + + return [ + routes, + location, + base, + basepath, + url, + $base, + $location, + $routes, + $$scope, + slots + ]; + } + + class Router extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$9, create_fragment$9, safe_not_equal, { basepath: 3, url: 4 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Router", + options, + id: create_fragment$9.name + }); + } + + get basepath() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set basepath(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get url() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set url(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* node_modules/svelte-routing/src/Route.svelte generated by Svelte v3.38.2 */ + + const get_default_slot_changes = dirty => ({ + params: dirty & /*routeParams*/ 4, + location: dirty & /*$location*/ 16 + }); + + const get_default_slot_context = ctx => ({ + params: /*routeParams*/ ctx[2], + location: /*$location*/ ctx[4] + }); + + // (40:0) {#if $activeRoute !== null && $activeRoute.route === route} + function create_if_block$2(ctx) { + let current_block_type_index; + let if_block; + let if_block_anchor; + let current; + const if_block_creators = [create_if_block_1$1, create_else_block$1]; + const if_blocks = []; + + function select_block_type(ctx, dirty) { + if (/*component*/ ctx[0] !== null) return 0; + return 1; + } + + current_block_type_index = select_block_type(ctx); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + + const block = { + c: function create() { + if_block.c(); + if_block_anchor = empty(); + }, + m: function mount(target, anchor) { + if_blocks[current_block_type_index].m(target, anchor); + insert_dev(target, if_block_anchor, anchor); + current = true; + }, + p: function update(ctx, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx); + + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx, dirty); + } else { + group_outros(); + + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + + check_outros(); + if_block = if_blocks[current_block_type_index]; + + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + if_block.c(); + } else { + if_block.p(ctx, dirty); + } + + transition_in(if_block, 1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + }, + i: function intro(local) { + if (current) return; + transition_in(if_block); + current = true; + }, + o: function outro(local) { + transition_out(if_block); + current = false; + }, + d: function destroy(detaching) { + if_blocks[current_block_type_index].d(detaching); + if (detaching) detach_dev(if_block_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$2.name, + type: "if", + source: "(40:0) {#if $activeRoute !== null && $activeRoute.route === route}", + ctx + }); + + return block; + } + + // (43:2) {:else} + function create_else_block$1(ctx) { + let current; + const default_slot_template = /*#slots*/ ctx[10].default; + const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[9], get_default_slot_context); + + const block = { + c: function create() { + if (default_slot) default_slot.c(); + }, + m: function mount(target, anchor) { + if (default_slot) { + default_slot.m(target, anchor); + } + + current = true; + }, + p: function update(ctx, dirty) { + if (default_slot) { + if (default_slot.p && (!current || dirty & /*$$scope, routeParams, $location*/ 532)) { + update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[9], dirty, get_default_slot_changes, get_default_slot_context); + } + } + }, + i: function intro(local) { + if (current) return; + transition_in(default_slot, local); + current = true; + }, + o: function outro(local) { + transition_out(default_slot, local); + current = false; + }, + d: function destroy(detaching) { + if (default_slot) default_slot.d(detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_else_block$1.name, + type: "else", + source: "(43:2) {:else}", + ctx + }); + + return block; + } + + // (41:2) {#if component !== null} + function create_if_block_1$1(ctx) { + let switch_instance; + let switch_instance_anchor; + let current; + + const switch_instance_spread_levels = [ + { location: /*$location*/ ctx[4] }, + /*routeParams*/ ctx[2], + /*routeProps*/ ctx[3] + ]; + + var switch_value = /*component*/ ctx[0]; + + function switch_props(ctx) { + let switch_instance_props = {}; + + for (let i = 0; i < switch_instance_spread_levels.length; i += 1) { + switch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]); + } + + return { + props: switch_instance_props, + $$inline: true + }; + } + + if (switch_value) { + switch_instance = new switch_value(switch_props()); + } + + const block = { + c: function create() { + if (switch_instance) create_component(switch_instance.$$.fragment); + switch_instance_anchor = empty(); + }, + m: function mount(target, anchor) { + if (switch_instance) { + mount_component(switch_instance, target, anchor); + } + + insert_dev(target, switch_instance_anchor, anchor); + current = true; + }, + p: function update(ctx, dirty) { + const switch_instance_changes = (dirty & /*$location, routeParams, routeProps*/ 28) + ? get_spread_update(switch_instance_spread_levels, [ + dirty & /*$location*/ 16 && { location: /*$location*/ ctx[4] }, + dirty & /*routeParams*/ 4 && get_spread_object(/*routeParams*/ ctx[2]), + dirty & /*routeProps*/ 8 && get_spread_object(/*routeProps*/ ctx[3]) + ]) + : {}; + + if (switch_value !== (switch_value = /*component*/ ctx[0])) { + if (switch_instance) { + group_outros(); + const old_component = switch_instance; + + transition_out(old_component.$$.fragment, 1, 0, () => { + destroy_component(old_component, 1); + }); + + check_outros(); + } + + if (switch_value) { + switch_instance = new switch_value(switch_props()); + create_component(switch_instance.$$.fragment); + transition_in(switch_instance.$$.fragment, 1); + mount_component(switch_instance, switch_instance_anchor.parentNode, switch_instance_anchor); + } else { + switch_instance = null; + } + } else if (switch_value) { + switch_instance.$set(switch_instance_changes); + } + }, + i: function intro(local) { + if (current) return; + if (switch_instance) transition_in(switch_instance.$$.fragment, local); + current = true; + }, + o: function outro(local) { + if (switch_instance) transition_out(switch_instance.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(switch_instance_anchor); + if (switch_instance) destroy_component(switch_instance, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block_1$1.name, + type: "if", + source: "(41:2) {#if component !== null}", + ctx + }); + + return block; + } + + function create_fragment$8(ctx) { + let if_block_anchor; + let current; + let if_block = /*$activeRoute*/ ctx[1] !== null && /*$activeRoute*/ ctx[1].route === /*route*/ ctx[7] && create_if_block$2(ctx); + + const block = { + c: function create() { + if (if_block) if_block.c(); + if_block_anchor = empty(); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert_dev(target, if_block_anchor, anchor); + current = true; + }, + p: function update(ctx, [dirty]) { + if (/*$activeRoute*/ ctx[1] !== null && /*$activeRoute*/ ctx[1].route === /*route*/ ctx[7]) { + if (if_block) { + if_block.p(ctx, dirty); + + if (dirty & /*$activeRoute*/ 2) { + transition_in(if_block, 1); + } + } else { + if_block = create_if_block$2(ctx); + if_block.c(); + transition_in(if_block, 1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + } else if (if_block) { + group_outros(); + + transition_out(if_block, 1, 1, () => { + if_block = null; + }); + + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + transition_in(if_block); + current = true; + }, + o: function outro(local) { + transition_out(if_block); + current = false; + }, + d: function destroy(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach_dev(if_block_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$8.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$8($$self, $$props, $$invalidate) { + let $activeRoute; + let $location; + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Route", slots, ['default']); + let { path = "" } = $$props; + let { component = null } = $$props; + const { registerRoute, unregisterRoute, activeRoute } = getContext(ROUTER); + validate_store(activeRoute, "activeRoute"); + component_subscribe($$self, activeRoute, value => $$invalidate(1, $activeRoute = value)); + const location = getContext(LOCATION); + validate_store(location, "location"); + component_subscribe($$self, location, value => $$invalidate(4, $location = value)); + + const route = { + path, + // If no path prop is given, this Route will act as the default Route + // that is rendered if no other Route in the Router is a match. + default: path === "" + }; + + let routeParams = {}; + let routeProps = {}; + registerRoute(route); + + // There is no need to unregister Routes in SSR since it will all be + // thrown away anyway. + if (typeof window !== "undefined") { + onDestroy(() => { + unregisterRoute(route); + }); + } + + $$self.$$set = $$new_props => { + $$invalidate(13, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + if ("path" in $$new_props) $$invalidate(8, path = $$new_props.path); + if ("component" in $$new_props) $$invalidate(0, component = $$new_props.component); + if ("$$scope" in $$new_props) $$invalidate(9, $$scope = $$new_props.$$scope); + }; + + $$self.$capture_state = () => ({ + getContext, + onDestroy, + ROUTER, + LOCATION, + path, + component, + registerRoute, + unregisterRoute, + activeRoute, + location, + route, + routeParams, + routeProps, + $activeRoute, + $location + }); + + $$self.$inject_state = $$new_props => { + $$invalidate(13, $$props = assign(assign({}, $$props), $$new_props)); + if ("path" in $$props) $$invalidate(8, path = $$new_props.path); + if ("component" in $$props) $$invalidate(0, component = $$new_props.component); + if ("routeParams" in $$props) $$invalidate(2, routeParams = $$new_props.routeParams); + if ("routeProps" in $$props) $$invalidate(3, routeProps = $$new_props.routeProps); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + $$self.$$.update = () => { + if ($$self.$$.dirty & /*$activeRoute*/ 2) { + if ($activeRoute && $activeRoute.route === route) { + $$invalidate(2, routeParams = $activeRoute.params); + } + } + + { + const { path, component, ...rest } = $$props; + $$invalidate(3, routeProps = rest); + } + }; + + $$props = exclude_internal_props($$props); + + return [ + component, + $activeRoute, + routeParams, + routeProps, + $location, + activeRoute, + location, + route, + path, + $$scope, + slots + ]; + } + + class Route extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$8, create_fragment$8, safe_not_equal, { path: 8, component: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Route", + options, + id: create_fragment$8.name + }); + } + + get path() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set path(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get component() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set component(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* node_modules/svelte-routing/src/Link.svelte generated by Svelte v3.38.2 */ + const file$6 = "node_modules/svelte-routing/src/Link.svelte"; + + function create_fragment$7(ctx) { + let a; + let current; + let mounted; + let dispose; + const default_slot_template = /*#slots*/ ctx[16].default; + const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[15], null); + + let a_levels = [ + { href: /*href*/ ctx[0] }, + { "aria-current": /*ariaCurrent*/ ctx[2] }, + /*props*/ ctx[1], + /*$$restProps*/ ctx[6] + ]; + + let a_data = {}; + + for (let i = 0; i < a_levels.length; i += 1) { + a_data = assign(a_data, a_levels[i]); + } + + const block = { + c: function create() { + a = element("a"); + if (default_slot) default_slot.c(); + set_attributes(a, a_data); + add_location(a, file$6, 40, 0, 1249); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, a, anchor); + + if (default_slot) { + default_slot.m(a, null); + } + + current = true; + + if (!mounted) { + dispose = listen_dev(a, "click", /*onClick*/ ctx[5], false, false, false); + mounted = true; + } + }, + p: function update(ctx, [dirty]) { + if (default_slot) { + if (default_slot.p && (!current || dirty & /*$$scope*/ 32768)) { + update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[15], dirty, null, null); + } + } + + set_attributes(a, a_data = get_spread_update(a_levels, [ + (!current || dirty & /*href*/ 1) && { href: /*href*/ ctx[0] }, + (!current || dirty & /*ariaCurrent*/ 4) && { "aria-current": /*ariaCurrent*/ ctx[2] }, + dirty & /*props*/ 2 && /*props*/ ctx[1], + dirty & /*$$restProps*/ 64 && /*$$restProps*/ ctx[6] + ])); + }, + i: function intro(local) { + if (current) return; + transition_in(default_slot, local); + current = true; + }, + o: function outro(local) { + transition_out(default_slot, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(a); + if (default_slot) default_slot.d(detaching); + mounted = false; + dispose(); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$7.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$7($$self, $$props, $$invalidate) { + let ariaCurrent; + const omit_props_names = ["to","replace","state","getProps"]; + let $$restProps = compute_rest_props($$props, omit_props_names); + let $base; + let $location; + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Link", slots, ['default']); + let { to = "#" } = $$props; + let { replace = false } = $$props; + let { state = {} } = $$props; + let { getProps = () => ({}) } = $$props; + const { base } = getContext(ROUTER); + validate_store(base, "base"); + component_subscribe($$self, base, value => $$invalidate(13, $base = value)); + const location = getContext(LOCATION); + validate_store(location, "location"); + component_subscribe($$self, location, value => $$invalidate(14, $location = value)); + const dispatch = createEventDispatcher(); + let href, isPartiallyCurrent, isCurrent, props; + + function onClick(event) { + dispatch("click", event); + + if (shouldNavigate(event)) { + event.preventDefault(); + + // Don't push another entry to the history stack when the user + // clicks on a Link to the page they are currently on. + const shouldReplace = $location.pathname === href || replace; + + navigate(href, { state, replace: shouldReplace }); + } + } + + $$self.$$set = $$new_props => { + $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)); + $$invalidate(6, $$restProps = compute_rest_props($$props, omit_props_names)); + if ("to" in $$new_props) $$invalidate(7, to = $$new_props.to); + if ("replace" in $$new_props) $$invalidate(8, replace = $$new_props.replace); + if ("state" in $$new_props) $$invalidate(9, state = $$new_props.state); + if ("getProps" in $$new_props) $$invalidate(10, getProps = $$new_props.getProps); + if ("$$scope" in $$new_props) $$invalidate(15, $$scope = $$new_props.$$scope); + }; + + $$self.$capture_state = () => ({ + getContext, + createEventDispatcher, + ROUTER, + LOCATION, + navigate, + startsWith, + resolve, + shouldNavigate, + to, + replace, + state, + getProps, + base, + location, + dispatch, + href, + isPartiallyCurrent, + isCurrent, + props, + onClick, + $base, + $location, + ariaCurrent + }); + + $$self.$inject_state = $$new_props => { + if ("to" in $$props) $$invalidate(7, to = $$new_props.to); + if ("replace" in $$props) $$invalidate(8, replace = $$new_props.replace); + if ("state" in $$props) $$invalidate(9, state = $$new_props.state); + if ("getProps" in $$props) $$invalidate(10, getProps = $$new_props.getProps); + if ("href" in $$props) $$invalidate(0, href = $$new_props.href); + if ("isPartiallyCurrent" in $$props) $$invalidate(11, isPartiallyCurrent = $$new_props.isPartiallyCurrent); + if ("isCurrent" in $$props) $$invalidate(12, isCurrent = $$new_props.isCurrent); + if ("props" in $$props) $$invalidate(1, props = $$new_props.props); + if ("ariaCurrent" in $$props) $$invalidate(2, ariaCurrent = $$new_props.ariaCurrent); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + $$self.$$.update = () => { + if ($$self.$$.dirty & /*to, $base*/ 8320) { + $$invalidate(0, href = to === "/" ? $base.uri : resolve(to, $base.uri)); + } + + if ($$self.$$.dirty & /*$location, href*/ 16385) { + $$invalidate(11, isPartiallyCurrent = startsWith($location.pathname, href)); + } + + if ($$self.$$.dirty & /*href, $location*/ 16385) { + $$invalidate(12, isCurrent = href === $location.pathname); + } + + if ($$self.$$.dirty & /*isCurrent*/ 4096) { + $$invalidate(2, ariaCurrent = isCurrent ? "page" : undefined); + } + + if ($$self.$$.dirty & /*getProps, $location, href, isPartiallyCurrent, isCurrent*/ 23553) { + $$invalidate(1, props = getProps({ + location: $location, + href, + isPartiallyCurrent, + isCurrent + })); + } + }; + + return [ + href, + props, + ariaCurrent, + base, + location, + onClick, + $$restProps, + to, + replace, + state, + getProps, + isPartiallyCurrent, + isCurrent, + $base, + $location, + $$scope, + slots + ]; + } + + class Link extends SvelteComponentDev { + constructor(options) { + super(options); + + init(this, options, instance$7, create_fragment$7, safe_not_equal, { + to: 7, + replace: 8, + state: 9, + getProps: 10 + }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Link", + options, + id: create_fragment$7.name + }); + } + + get to() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set to(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get replace() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set replace(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get state() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set state(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + + get getProps() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set getProps(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/routes/Home.svelte generated by Svelte v3.38.2 */ + + const file$5 = "src/routes/Home.svelte"; + + function create_fragment$6(ctx) { + let section; + let div; + let p0; + let t1; + let p1; + + const block = { + c: function create() { + section = element("section"); + div = element("div"); + p0 = element("p"); + p0.textContent = "Shioriko"; + t1 = space(); + p1 = element("p"); + p1.textContent = "Booru-style gallery written in Go and Svelte"; + attr_dev(p0, "class", "title"); + add_location(p0, file$5, 6, 6, 99); + attr_dev(p1, "class", "subtitle"); + add_location(p1, file$5, 9, 6, 151); + attr_dev(div, "class", "hero-body"); + add_location(div, file$5, 5, 4, 69); + attr_dev(section, "class", "hero is-primary is-medium"); + add_location(section, file$5, 4, 0, 21); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, section, anchor); + append_dev(section, div); + append_dev(div, p0); + append_dev(div, t1); + append_dev(div, p1); + }, + p: noop, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(section); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$6.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$6($$self, $$props) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Home", slots, []); + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + return []; + } + + class Home extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$6, create_fragment$6, safe_not_equal, {}); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Home", + options, + id: create_fragment$6.name + }); + } + } + + const storedToken = localStorage.getItem("apiToken"); + + const token = writable(storedToken); + token.subscribe(value => { + localStorage.setItem("apiToken", value); + }); + + let url = window.BASE_URL; + token.subscribe(value => { + }); + async function login({ username, password }) { + const endpoint = url + "/api/auth/login"; + const response = await fetch(endpoint, { + method: "POST", + body: JSON.stringify({ + username, + password, + }), + }); + const data = await response.json(); + token.set(data.token); + return data; + } + + async function getPosts({ page }) { + const endpoint = url + "/api/post?page=" + page; + const response = await fetch(endpoint); + const data = await response.json(); + return data; + } + + async function getPostsTag({ page, tag }) { + const endpoint = url + "/api/post/tag/" + tag + "?page=" + page; + const response = await fetch(endpoint); + const data = await response.json(); + return data; + } + + async function getPost({ id }) { + const endpoint = url + "/api/post/" + id; + const response = await fetch(endpoint); + const data = await response.json(); + return data; + } + + /* src/routes/Posts.svelte generated by Svelte v3.38.2 */ + const file$4 = "src/routes/Posts.svelte"; + + function get_each_context$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[4] = list[i]; + return child_ctx; + } + + function get_each_context_1$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[7] = list[i]; + return child_ctx; + } + + // (32:24) + function create_default_slot_1$2(ctx) { + let img; + let img_src_value; + + const block = { + c: function create() { + img = element("img"); + if (img.src !== (img_src_value = /*post*/ ctx[4].image_path)) attr_dev(img, "src", img_src_value); + add_location(img, file$4, 32, 24, 839); + }, + m: function mount(target, anchor) { + insert_dev(target, img, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*posts*/ 1 && img.src !== (img_src_value = /*post*/ ctx[4].image_path)) { + attr_dev(img, "src", img_src_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(img); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_1$2.name, + type: "slot", + source: "(32:24) ", + ctx + }); + + return block; + } + + // (40:24) + function create_default_slot$3(ctx) { + let t_value = /*tag*/ ctx[7] + ""; + let t; + + const block = { + c: function create() { + t = text(t_value); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*posts*/ 1 && t_value !== (t_value = /*tag*/ ctx[7] + "")) set_data_dev(t, t_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot$3.name, + type: "slot", + source: "(40:24) ", + ctx + }); + + return block; + } + + // (39:24) {#each post.tags as tag (tag)} + function create_each_block_1$1(key_1, ctx) { + let first; + let link; + let current; + + link = new Link({ + props: { + to: "/tag/" + /*tag*/ ctx[7], + $$slots: { default: [create_default_slot$3] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + key: key_1, + first: null, + c: function create() { + first = empty(); + create_component(link.$$.fragment); + this.first = first; + }, + m: function mount(target, anchor) { + insert_dev(target, first, anchor); + mount_component(link, target, anchor); + current = true; + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + const link_changes = {}; + if (dirty & /*posts*/ 1) link_changes.to = "/tag/" + /*tag*/ ctx[7]; + + if (dirty & /*$$scope, posts*/ 1025) { + link_changes.$$scope = { dirty, ctx }; + } + + link.$set(link_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(first); + destroy_component(link, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_1$1.name, + type: "each", + source: "(39:24) {#each post.tags as tag (tag)}", + ctx + }); + + return block; + } + + // (28:12) {#each posts as post (post.id)} + function create_each_block$2(key_1, ctx) { + let div3; + let div0; + let figure; + let link; + let t0; + let div2; + let div1; + let each_blocks = []; + let each_1_lookup = new Map(); + let t1; + let current; + + link = new Link({ + props: { + to: "/post/" + /*post*/ ctx[4].id, + $$slots: { default: [create_default_slot_1$2] }, + $$scope: { ctx } + }, + $$inline: true + }); + + let each_value_1 = /*post*/ ctx[4].tags; + validate_each_argument(each_value_1); + const get_key = ctx => /*tag*/ ctx[7]; + validate_each_keys(ctx, each_value_1, get_each_context_1$1, get_key); + + for (let i = 0; i < each_value_1.length; i += 1) { + let child_ctx = get_each_context_1$1(ctx, each_value_1, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block_1$1(key, child_ctx)); + } + + const block = { + key: key_1, + first: null, + c: function create() { + div3 = element("div"); + div0 = element("div"); + figure = element("figure"); + create_component(link.$$.fragment); + t0 = space(); + div2 = element("div"); + div1 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + t1 = space(); + attr_dev(figure, "class", "image"); + add_location(figure, file$4, 30, 20, 740); + attr_dev(div0, "class", "card-image"); + add_location(div0, file$4, 29, 16, 695); + attr_dev(div1, "class", "content"); + add_location(div1, file$4, 37, 20, 1017); + attr_dev(div2, "class", "card-content"); + add_location(div2, file$4, 36, 16, 970); + attr_dev(div3, "class", "tile is-child is-4 card"); + add_location(div3, file$4, 28, 12, 641); + this.first = div3; + }, + m: function mount(target, anchor) { + insert_dev(target, div3, anchor); + append_dev(div3, div0); + append_dev(div0, figure); + mount_component(link, figure, null); + append_dev(div3, t0); + append_dev(div3, div2); + append_dev(div2, div1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div1, null); + } + + append_dev(div3, t1); + current = true; + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + const link_changes = {}; + if (dirty & /*posts*/ 1) link_changes.to = "/post/" + /*post*/ ctx[4].id; + + if (dirty & /*$$scope, posts*/ 1025) { + link_changes.$$scope = { dirty, ctx }; + } + + link.$set(link_changes); + + if (dirty & /*posts*/ 1) { + each_value_1 = /*post*/ ctx[4].tags; + validate_each_argument(each_value_1); + group_outros(); + validate_each_keys(ctx, each_value_1, get_each_context_1$1, get_key); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value_1, each_1_lookup, div1, outro_and_destroy_block, create_each_block_1$1, null, get_each_context_1$1); + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + + for (let i = 0; i < each_value_1.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div3); + destroy_component(link); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(); + } + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$2.name, + type: "each", + source: "(28:12) {#each posts as post (post.id)}", + ctx + }); + + return block; + } + + function create_fragment$5(ctx) { + let section0; + let div0; + let p; + let t1; + let section1; + let div2; + let div1; + let each_blocks = []; + let each_1_lookup = new Map(); + let current; + let each_value = /*posts*/ ctx[0]; + validate_each_argument(each_value); + const get_key = ctx => /*post*/ ctx[4].id; + validate_each_keys(ctx, each_value, get_each_context$2, get_key); + + for (let i = 0; i < each_value.length; i += 1) { + let child_ctx = get_each_context$2(ctx, each_value, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block$2(key, child_ctx)); + } + + const block = { + c: function create() { + section0 = element("section"); + div0 = element("div"); + p = element("p"); + p.textContent = "Posts"; + t1 = space(); + section1 = element("section"); + div2 = element("div"); + div1 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(p, "class", "title"); + add_location(p, file$4, 18, 6, 426); + attr_dev(div0, "class", "hero-body"); + add_location(div0, file$4, 17, 4, 396); + attr_dev(section0, "class", "hero is-primary"); + add_location(section0, file$4, 16, 0, 358); + attr_dev(div1, "class", "tile is-ancestor"); + add_location(div1, file$4, 26, 8, 554); + attr_dev(div2, "class", "container"); + add_location(div2, file$4, 25, 4, 522); + attr_dev(section1, "class", "section"); + add_location(section1, file$4, 24, 0, 492); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, section0, anchor); + append_dev(section0, div0); + append_dev(div0, p); + insert_dev(target, t1, anchor); + insert_dev(target, section1, anchor); + append_dev(section1, div2); + append_dev(div2, div1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div1, null); + } + + current = true; + }, + p: function update(ctx, [dirty]) { + if (dirty & /*posts*/ 1) { + each_value = /*posts*/ ctx[0]; + validate_each_argument(each_value); + group_outros(); + validate_each_keys(ctx, each_value, get_each_context$2, get_key); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div1, outro_and_destroy_block, create_each_block$2, null, get_each_context$2); + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(section0); + if (detaching) detach_dev(t1); + if (detaching) detach_dev(section1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(); + } + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$5.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$5($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Posts", slots, []); + let page = 1; + let totalPages = 1; + let posts = []; + + const getData = async () => { + const data = await getPosts({ page }); + $$invalidate(0, posts = data.posts); + }; + + onMount(() => { + getData(); + }); + + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$capture_state = () => ({ + onMount, + getPosts, + Link, + page, + totalPages, + posts, + getData + }); + + $$self.$inject_state = $$props => { + if ("page" in $$props) page = $$props.page; + if ("totalPages" in $$props) totalPages = $$props.totalPages; + if ("posts" in $$props) $$invalidate(0, posts = $$props.posts); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [posts]; + } + + class Posts extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$5, create_fragment$5, safe_not_equal, {}); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Posts", + options, + id: create_fragment$5.name + }); + } + } + + /* src/routes/Post.svelte generated by Svelte v3.38.2 */ + const file$3 = "src/routes/Post.svelte"; + + function get_each_context$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[3] = list[i]; + return child_ctx; + } + + // (18:8) {#if post} + function create_if_block_1(ctx) { + let p; + let t0; + let t1_value = /*post*/ ctx[0].id + ""; + let t1; + + const block = { + c: function create() { + p = element("p"); + t0 = text("Post ID: "); + t1 = text(t1_value); + attr_dev(p, "class", "title"); + add_location(p, file$3, 18, 6, 397); + }, + m: function mount(target, anchor) { + insert_dev(target, p, anchor); + append_dev(p, t0); + append_dev(p, t1); + }, + p: function update(ctx, dirty) { + if (dirty & /*post*/ 1 && t1_value !== (t1_value = /*post*/ ctx[0].id + "")) set_data_dev(t1, t1_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(p); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block_1.name, + type: "if", + source: "(18:8) {#if post}", + ctx + }); + + return block; + } + + // (25:0) {#if post} + function create_if_block$1(ctx) { + let div3; + let section; + let div2; + let div0; + let p0; + let t0; + let a; + let t1_value = /*post*/ ctx[0].source_url + ""; + let t1; + let a_href_value; + let t2; + let p1; + let t3; + let each_blocks = []; + let each_1_lookup = new Map(); + let t4; + let div1; + let figure; + let img; + let img_src_value; + let current; + let each_value = /*post*/ ctx[0].tags; + validate_each_argument(each_value); + const get_key = ctx => /*tag*/ ctx[3]; + validate_each_keys(ctx, each_value, get_each_context$1, get_key); + + for (let i = 0; i < each_value.length; i += 1) { + let child_ctx = get_each_context$1(ctx, each_value, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block$1(key, child_ctx)); + } + + const block = { + c: function create() { + div3 = element("div"); + section = element("section"); + div2 = element("div"); + div0 = element("div"); + p0 = element("p"); + t0 = text("Source URL: "); + a = element("a"); + t1 = text(t1_value); + t2 = space(); + p1 = element("p"); + t3 = text("Tags: \n "); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + t4 = space(); + div1 = element("div"); + figure = element("figure"); + img = element("img"); + attr_dev(a, "href", a_href_value = "//" + /*post*/ ctx[0].source_url); + add_location(a, file$3, 30, 36, 700); + add_location(p0, file$3, 29, 20, 660); + add_location(p1, file$3, 32, 20, 797); + attr_dev(div0, "class", "tile is-child is-4 box"); + add_location(div0, file$3, 28, 12, 603); + if (img.src !== (img_src_value = /*post*/ ctx[0].image_path)) attr_dev(img, "src", img_src_value); + add_location(img, file$3, 41, 20, 1121); + attr_dev(figure, "class", "image"); + add_location(figure, file$3, 40, 16, 1078); + attr_dev(div1, "class", "tile is-child"); + add_location(div1, file$3, 39, 12, 1034); + attr_dev(div2, "class", "tile is-ancestor"); + add_location(div2, file$3, 27, 8, 560); + attr_dev(section, "class", "section"); + add_location(section, file$3, 26, 4, 526); + attr_dev(div3, "class", "container"); + add_location(div3, file$3, 25, 0, 498); + }, + m: function mount(target, anchor) { + insert_dev(target, div3, anchor); + append_dev(div3, section); + append_dev(section, div2); + append_dev(div2, div0); + append_dev(div0, p0); + append_dev(p0, t0); + append_dev(p0, a); + append_dev(a, t1); + append_dev(div0, t2); + append_dev(div0, p1); + append_dev(p1, t3); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(p1, null); + } + + append_dev(div2, t4); + append_dev(div2, div1); + append_dev(div1, figure); + append_dev(figure, img); + current = true; + }, + p: function update(ctx, dirty) { + if ((!current || dirty & /*post*/ 1) && t1_value !== (t1_value = /*post*/ ctx[0].source_url + "")) set_data_dev(t1, t1_value); + + if (!current || dirty & /*post*/ 1 && a_href_value !== (a_href_value = "//" + /*post*/ ctx[0].source_url)) { + attr_dev(a, "href", a_href_value); + } + + if (dirty & /*post*/ 1) { + each_value = /*post*/ ctx[0].tags; + validate_each_argument(each_value); + group_outros(); + validate_each_keys(ctx, each_value, get_each_context$1, get_key); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, p1, outro_and_destroy_block, create_each_block$1, null, get_each_context$1); + check_outros(); + } + + if (!current || dirty & /*post*/ 1 && img.src !== (img_src_value = /*post*/ ctx[0].image_path)) { + attr_dev(img, "src", img_src_value); + } + }, + i: function intro(local) { + if (current) return; + + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div3); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(); + } + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block$1.name, + type: "if", + source: "(25:0) {#if post}", + ctx + }); + + return block; + } + + // (36:24) + function create_default_slot$2(ctx) { + let t_value = /*tag*/ ctx[3] + ""; + let t; + + const block = { + c: function create() { + t = text(t_value); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*post*/ 1 && t_value !== (t_value = /*tag*/ ctx[3] + "")) set_data_dev(t, t_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot$2.name, + type: "slot", + source: "(36:24) ", + ctx + }); + + return block; + } + + // (35:24) {#each post.tags as tag (tag)} + function create_each_block$1(key_1, ctx) { + let first; + let link; + let current; + + link = new Link({ + props: { + to: "/tag/" + /*tag*/ ctx[3], + $$slots: { default: [create_default_slot$2] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + key: key_1, + first: null, + c: function create() { + first = empty(); + create_component(link.$$.fragment); + this.first = first; + }, + m: function mount(target, anchor) { + insert_dev(target, first, anchor); + mount_component(link, target, anchor); + current = true; + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + const link_changes = {}; + if (dirty & /*post*/ 1) link_changes.to = "/tag/" + /*tag*/ ctx[3]; + + if (dirty & /*$$scope, post*/ 65) { + link_changes.$$scope = { dirty, ctx }; + } + + link.$set(link_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(first); + destroy_component(link, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block$1.name, + type: "each", + source: "(35:24) {#each post.tags as tag (tag)}", + ctx + }); + + return block; + } + + function create_fragment$4(ctx) { + let section; + let div; + let t; + let if_block1_anchor; + let current; + let if_block0 = /*post*/ ctx[0] && create_if_block_1(ctx); + let if_block1 = /*post*/ ctx[0] && create_if_block$1(ctx); + + const block = { + c: function create() { + section = element("section"); + div = element("div"); + if (if_block0) if_block0.c(); + t = space(); + if (if_block1) if_block1.c(); + if_block1_anchor = empty(); + attr_dev(div, "class", "hero-body"); + add_location(div, file$3, 16, 4, 348); + attr_dev(section, "class", "hero is-primary"); + add_location(section, file$3, 15, 0, 310); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, section, anchor); + append_dev(section, div); + if (if_block0) if_block0.m(div, null); + insert_dev(target, t, anchor); + if (if_block1) if_block1.m(target, anchor); + insert_dev(target, if_block1_anchor, anchor); + current = true; + }, + p: function update(ctx, [dirty]) { + if (/*post*/ ctx[0]) { + if (if_block0) { + if_block0.p(ctx, dirty); + } else { + if_block0 = create_if_block_1(ctx); + if_block0.c(); + if_block0.m(div, null); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } + + if (/*post*/ ctx[0]) { + if (if_block1) { + if_block1.p(ctx, dirty); + + if (dirty & /*post*/ 1) { + transition_in(if_block1, 1); + } + } else { + if_block1 = create_if_block$1(ctx); + if_block1.c(); + transition_in(if_block1, 1); + if_block1.m(if_block1_anchor.parentNode, if_block1_anchor); + } + } else if (if_block1) { + group_outros(); + + transition_out(if_block1, 1, 1, () => { + if_block1 = null; + }); + + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + transition_in(if_block1); + current = true; + }, + o: function outro(local) { + transition_out(if_block1); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(section); + if (if_block0) if_block0.d(); + if (detaching) detach_dev(t); + if (if_block1) if_block1.d(detaching); + if (detaching) detach_dev(if_block1_anchor); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$4.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$4($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Post", slots, []); + let { id } = $$props; + let post; + + const getData = async () => { + const data = await getPost({ id }); + $$invalidate(0, post = data); + }; + + onMount(() => { + getData(); + }); + + const writable_props = ["id"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$$set = $$props => { + if ("id" in $$props) $$invalidate(1, id = $$props.id); + }; + + $$self.$capture_state = () => ({ + onMount, + Link, + getPost, + id, + post, + getData + }); + + $$self.$inject_state = $$props => { + if ("id" in $$props) $$invalidate(1, id = $$props.id); + if ("post" in $$props) $$invalidate(0, post = $$props.post); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [post, id]; + } + + class Post extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$4, create_fragment$4, safe_not_equal, { id: 1 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Post", + options, + id: create_fragment$4.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*id*/ ctx[1] === undefined && !("id" in props)) { + console.warn(" was created without expected prop 'id'"); + } + } + + get id() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set id(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/routes/Login.svelte generated by Svelte v3.38.2 */ + const file$2 = "src/routes/Login.svelte"; + + function create_fragment$3(ctx) { + let div6; + let form; + let div1; + let label0; + let t1; + let div0; + let input0; + let t2; + let div3; + let label1; + let t4; + let div2; + let input1; + let t5; + let div5; + let div4; + let button; + let mounted; + let dispose; + + const block = { + c: function create() { + div6 = element("div"); + form = element("form"); + div1 = element("div"); + label0 = element("label"); + label0.textContent = "Username"; + t1 = space(); + div0 = element("div"); + input0 = element("input"); + t2 = space(); + div3 = element("div"); + label1 = element("label"); + label1.textContent = "Password"; + t4 = space(); + div2 = element("div"); + input1 = element("input"); + t5 = space(); + div5 = element("div"); + div4 = element("div"); + button = element("button"); + button.textContent = "Login"; + attr_dev(label0, "class", "label"); + add_location(label0, file$2, 15, 8, 382); + attr_dev(input0, "class", "input"); + attr_dev(input0, "type", "text"); + attr_dev(input0, "placeholder", "Username"); + input0.required = true; + add_location(input0, file$2, 17, 12, 462); + attr_dev(div0, "class", "control"); + add_location(div0, file$2, 16, 8, 428); + attr_dev(div1, "class", "field"); + add_location(div1, file$2, 14, 8, 354); + attr_dev(label1, "class", "label"); + add_location(label1, file$2, 21, 8, 616); + attr_dev(input1, "class", "input"); + attr_dev(input1, "type", "password"); + attr_dev(input1, "placeholder", "Password"); + input1.required = true; + add_location(input1, file$2, 23, 12, 696); + attr_dev(div2, "class", "control"); + add_location(div2, file$2, 22, 8, 662); + attr_dev(div3, "class", "field"); + add_location(div3, file$2, 20, 8, 588); + attr_dev(button, "class", "button is-link"); + add_location(button, file$2, 28, 12, 890); + attr_dev(div4, "class", "control"); + add_location(div4, file$2, 27, 10, 856); + attr_dev(div5, "class", "field"); + add_location(div5, file$2, 26, 8, 826); + add_location(form, file$2, 13, 4, 304); + attr_dev(div6, "class", "container"); + add_location(div6, file$2, 12, 0, 276); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, div6, anchor); + append_dev(div6, form); + append_dev(form, div1); + append_dev(div1, label0); + append_dev(div1, t1); + append_dev(div1, div0); + append_dev(div0, input0); + set_input_value(input0, /*username*/ ctx[0]); + append_dev(form, t2); + append_dev(form, div3); + append_dev(div3, label1); + append_dev(div3, t4); + append_dev(div3, div2); + append_dev(div2, input1); + set_input_value(input1, /*password*/ ctx[1]); + append_dev(form, t5); + append_dev(form, div5); + append_dev(div5, div4); + append_dev(div4, button); + + if (!mounted) { + dispose = [ + listen_dev(input0, "input", /*input0_input_handler*/ ctx[3]), + listen_dev(input1, "input", /*input1_input_handler*/ ctx[4]), + listen_dev(form, "submit", prevent_default(/*doLogin*/ ctx[2]), false, true, false) + ]; + + mounted = true; + } + }, + p: function update(ctx, [dirty]) { + if (dirty & /*username*/ 1 && input0.value !== /*username*/ ctx[0]) { + set_input_value(input0, /*username*/ ctx[0]); + } + + if (dirty & /*password*/ 2 && input1.value !== /*password*/ ctx[1]) { + set_input_value(input1, /*password*/ ctx[1]); + } + }, + i: noop, + o: noop, + d: function destroy(detaching) { + if (detaching) detach_dev(div6); + mounted = false; + run_all(dispose); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$3.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$3($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Login", slots, []); + let username = ""; + let password = ""; + + const doLogin = async () => { + await login({ username, password }); + navigate("/"); + }; + + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + function input0_input_handler() { + username = this.value; + $$invalidate(0, username); + } + + function input1_input_handler() { + password = this.value; + $$invalidate(1, password); + } + + $$self.$capture_state = () => ({ + login, + navigate, + username, + password, + doLogin + }); + + $$self.$inject_state = $$props => { + if ("username" in $$props) $$invalidate(0, username = $$props.username); + if ("password" in $$props) $$invalidate(1, password = $$props.password); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [username, password, doLogin, input0_input_handler, input1_input_handler]; + } + + class Login extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$3, create_fragment$3, safe_not_equal, {}); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Login", + options, + id: create_fragment$3.name + }); + } + } + + /* src/routes/Logout.svelte generated by Svelte v3.38.2 */ + + function create_fragment$2(ctx) { + const block = { + c: noop, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: noop, + p: noop, + i: noop, + o: noop, + d: noop + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$2.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$2($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Logout", slots, []); + + onMount(() => { + token.set(""); + navigate("/"); + }); + + const writable_props = []; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$capture_state = () => ({ token, navigate, onMount }); + return []; + } + + class Logout extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$2, create_fragment$2, safe_not_equal, {}); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Logout", + options, + id: create_fragment$2.name + }); + } + } + + /* src/routes/Tag.svelte generated by Svelte v3.38.2 */ + const file$1 = "src/routes/Tag.svelte"; + + function get_each_context(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[5] = list[i]; + return child_ctx; + } + + function get_each_context_1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[8] = list[i]; + return child_ctx; + } + + // (37:24) + function create_default_slot_1$1(ctx) { + let img; + let img_src_value; + + const block = { + c: function create() { + img = element("img"); + if (img.src !== (img_src_value = /*post*/ ctx[5].image_path)) attr_dev(img, "src", img_src_value); + add_location(img, file$1, 37, 24, 923); + }, + m: function mount(target, anchor) { + insert_dev(target, img, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*posts*/ 2 && img.src !== (img_src_value = /*post*/ ctx[5].image_path)) { + attr_dev(img, "src", img_src_value); + } + }, + d: function destroy(detaching) { + if (detaching) detach_dev(img); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_1$1.name, + type: "slot", + source: "(37:24) ", + ctx + }); + + return block; + } + + // (45:24) + function create_default_slot$1(ctx) { + let t_value = /*tag*/ ctx[8] + ""; + let t; + + const block = { + c: function create() { + t = text(t_value); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + p: function update(ctx, dirty) { + if (dirty & /*posts*/ 2 && t_value !== (t_value = /*tag*/ ctx[8] + "")) set_data_dev(t, t_value); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot$1.name, + type: "slot", + source: "(45:24) ", + ctx + }); + + return block; + } + + // (44:24) {#each post.tags as tag (tag)} + function create_each_block_1(key_1, ctx) { + let first; + let link; + let current; + + link = new Link({ + props: { + to: "/tag/" + /*tag*/ ctx[8], + $$slots: { default: [create_default_slot$1] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + key: key_1, + first: null, + c: function create() { + first = empty(); + create_component(link.$$.fragment); + this.first = first; + }, + m: function mount(target, anchor) { + insert_dev(target, first, anchor); + mount_component(link, target, anchor); + current = true; + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + const link_changes = {}; + if (dirty & /*posts*/ 2) link_changes.to = "/tag/" + /*tag*/ ctx[8]; + + if (dirty & /*$$scope, posts*/ 2050) { + link_changes.$$scope = { dirty, ctx }; + } + + link.$set(link_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(first); + destroy_component(link, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block_1.name, + type: "each", + source: "(44:24) {#each post.tags as tag (tag)}", + ctx + }); + + return block; + } + + // (33:12) {#each posts as post (post.id)} + function create_each_block(key_1, ctx) { + let div3; + let div0; + let figure; + let link; + let t0; + let div2; + let div1; + let each_blocks = []; + let each_1_lookup = new Map(); + let t1; + let current; + + link = new Link({ + props: { + to: "/post/" + /*post*/ ctx[5].id, + $$slots: { default: [create_default_slot_1$1] }, + $$scope: { ctx } + }, + $$inline: true + }); + + let each_value_1 = /*post*/ ctx[5].tags; + validate_each_argument(each_value_1); + const get_key = ctx => /*tag*/ ctx[8]; + validate_each_keys(ctx, each_value_1, get_each_context_1, get_key); + + for (let i = 0; i < each_value_1.length; i += 1) { + let child_ctx = get_each_context_1(ctx, each_value_1, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block_1(key, child_ctx)); + } + + const block = { + key: key_1, + first: null, + c: function create() { + div3 = element("div"); + div0 = element("div"); + figure = element("figure"); + create_component(link.$$.fragment); + t0 = space(); + div2 = element("div"); + div1 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + t1 = space(); + attr_dev(figure, "class", "image"); + add_location(figure, file$1, 35, 20, 824); + attr_dev(div0, "class", "card-image"); + add_location(div0, file$1, 34, 16, 779); + attr_dev(div1, "class", "content"); + add_location(div1, file$1, 42, 20, 1101); + attr_dev(div2, "class", "card-content"); + add_location(div2, file$1, 41, 16, 1054); + attr_dev(div3, "class", "tile is-child is-4 card"); + add_location(div3, file$1, 33, 12, 725); + this.first = div3; + }, + m: function mount(target, anchor) { + insert_dev(target, div3, anchor); + append_dev(div3, div0); + append_dev(div0, figure); + mount_component(link, figure, null); + append_dev(div3, t0); + append_dev(div3, div2); + append_dev(div2, div1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div1, null); + } + + append_dev(div3, t1); + current = true; + }, + p: function update(new_ctx, dirty) { + ctx = new_ctx; + const link_changes = {}; + if (dirty & /*posts*/ 2) link_changes.to = "/post/" + /*post*/ ctx[5].id; + + if (dirty & /*$$scope, posts*/ 2050) { + link_changes.$$scope = { dirty, ctx }; + } + + link.$set(link_changes); + + if (dirty & /*posts*/ 2) { + each_value_1 = /*post*/ ctx[5].tags; + validate_each_argument(each_value_1); + group_outros(); + validate_each_keys(ctx, each_value_1, get_each_context_1, get_key); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value_1, each_1_lookup, div1, outro_and_destroy_block, create_each_block_1, null, get_each_context_1); + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + + for (let i = 0; i < each_value_1.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div3); + destroy_component(link); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(); + } + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_each_block.name, + type: "each", + source: "(33:12) {#each posts as post (post.id)}", + ctx + }); + + return block; + } + + function create_fragment$1(ctx) { + let section0; + let div0; + let p0; + let t0; + let t1; + let p1; + let t3; + let section1; + let div2; + let div1; + let each_blocks = []; + let each_1_lookup = new Map(); + let current; + let each_value = /*posts*/ ctx[1]; + validate_each_argument(each_value); + const get_key = ctx => /*post*/ ctx[5].id; + validate_each_keys(ctx, each_value, get_each_context, get_key); + + for (let i = 0; i < each_value.length; i += 1) { + let child_ctx = get_each_context(ctx, each_value, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx)); + } + + const block = { + c: function create() { + section0 = element("section"); + div0 = element("div"); + p0 = element("p"); + t0 = text(/*id*/ ctx[0]); + t1 = space(); + p1 = element("p"); + p1.textContent = "Tag"; + t3 = space(); + section1 = element("section"); + div2 = element("div"); + div1 = element("div"); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr_dev(p0, "class", "title"); + add_location(p0, file$1, 20, 6, 461); + attr_dev(p1, "class", "subtitle"); + add_location(p1, file$1, 23, 6, 509); + attr_dev(div0, "class", "hero-body"); + add_location(div0, file$1, 19, 4, 431); + attr_dev(section0, "class", "hero is-primary"); + add_location(section0, file$1, 18, 0, 393); + attr_dev(div1, "class", "tile is-ancestor"); + add_location(div1, file$1, 31, 8, 638); + attr_dev(div2, "class", "container"); + add_location(div2, file$1, 30, 4, 606); + attr_dev(section1, "class", "section"); + add_location(section1, file$1, 29, 0, 576); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + insert_dev(target, section0, anchor); + append_dev(section0, div0); + append_dev(div0, p0); + append_dev(p0, t0); + append_dev(div0, t1); + append_dev(div0, p1); + insert_dev(target, t3, anchor); + insert_dev(target, section1, anchor); + append_dev(section1, div2); + append_dev(div2, div1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div1, null); + } + + current = true; + }, + p: function update(ctx, [dirty]) { + if (!current || dirty & /*id*/ 1) set_data_dev(t0, /*id*/ ctx[0]); + + if (dirty & /*posts*/ 2) { + each_value = /*posts*/ ctx[1]; + validate_each_argument(each_value); + group_outros(); + validate_each_keys(ctx, each_value, get_each_context, get_key); + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div1, outro_and_destroy_block, create_each_block, null, get_each_context); + check_outros(); + } + }, + i: function intro(local) { + if (current) return; + + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + + current = true; + }, + o: function outro(local) { + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(section0); + if (detaching) detach_dev(t3); + if (detaching) detach_dev(section1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(); + } + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment$1.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance$1($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("Tag", slots, []); + let { id } = $$props; + let page = 1; + let totalPages = 1; + let posts = []; + + const getData = async () => { + const data = await getPostsTag({ page, tag: id }); + $$invalidate(1, posts = data.posts); + }; + + onMount(() => { + getData(); + }); + + const writable_props = ["id"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$$set = $$props => { + if ("id" in $$props) $$invalidate(0, id = $$props.id); + }; + + $$self.$capture_state = () => ({ + onMount, + getPostsTag, + Link, + id, + page, + totalPages, + posts, + getData + }); + + $$self.$inject_state = $$props => { + if ("id" in $$props) $$invalidate(0, id = $$props.id); + if ("page" in $$props) page = $$props.page; + if ("totalPages" in $$props) totalPages = $$props.totalPages; + if ("posts" in $$props) $$invalidate(1, posts = $$props.posts); + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [id, posts]; + } + + class Tag extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance$1, create_fragment$1, safe_not_equal, { id: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "Tag", + options, + id: create_fragment$1.name + }); + + const { ctx } = this.$$; + const props = options.props || {}; + + if (/*id*/ ctx[0] === undefined && !("id" in props)) { + console.warn(" was created without expected prop 'id'"); + } + } + + get id() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set id(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + /* src/App.svelte generated by Svelte v3.38.2 */ + const file = "src/App.svelte"; + + // (25:4) + function create_default_slot_5(ctx) { + let t; + + const block = { + c: function create() { + t = text("Shioriko"); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_5.name, + type: "slot", + source: "(25:4) ", + ctx + }); + + return block; + } + + // (38:3) + function create_default_slot_4(ctx) { + let t; + + const block = { + c: function create() { + t = text("Posts"); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_4.name, + type: "slot", + source: "(38:3) ", + ctx + }); + + return block; + } + + // (52:5) {:else} + function create_else_block(ctx) { + let div1; + let div0; + let link0; + let t; + let link1; + let current; + + link0 = new Link({ + props: { + to: "/auth/register", + class: "button is-primary", + $$slots: { default: [create_default_slot_3] }, + $$scope: { ctx } + }, + $$inline: true + }); + + link1 = new Link({ + props: { + to: "/auth/login", + class: "button is-light", + $$slots: { default: [create_default_slot_2] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + c: function create() { + div1 = element("div"); + div0 = element("div"); + create_component(link0.$$.fragment); + t = space(); + create_component(link1.$$.fragment); + attr_dev(div0, "class", "buttons"); + add_location(div0, file, 53, 4, 1362); + attr_dev(div1, "class", "navbar-item"); + add_location(div1, file, 52, 5, 1332); + }, + m: function mount(target, anchor) { + insert_dev(target, div1, anchor); + append_dev(div1, div0); + mount_component(link0, div0, null); + append_dev(div0, t); + mount_component(link1, div0, null); + current = true; + }, + i: function intro(local) { + if (current) return; + transition_in(link0.$$.fragment, local); + transition_in(link1.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link0.$$.fragment, local); + transition_out(link1.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div1); + destroy_component(link0); + destroy_component(link1); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_else_block.name, + type: "else", + source: "(52:5) {:else}", + ctx + }); + + return block; + } + + // (44:5) {#if loggedIn} + function create_if_block(ctx) { + let div1; + let div0; + let link; + let current; + + link = new Link({ + props: { + to: "/auth/logout", + class: "button is-light", + $$slots: { default: [create_default_slot_1] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + c: function create() { + div1 = element("div"); + div0 = element("div"); + create_component(link.$$.fragment); + attr_dev(div0, "class", "buttons"); + add_location(div0, file, 45, 4, 1187); + attr_dev(div1, "class", "navbar-item"); + add_location(div1, file, 44, 5, 1157); + }, + m: function mount(target, anchor) { + insert_dev(target, div1, anchor); + append_dev(div1, div0); + mount_component(link, div0, null); + current = true; + }, + i: function intro(local) { + if (current) return; + transition_in(link.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(div1); + destroy_component(link); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_if_block.name, + type: "if", + source: "(44:5) {#if loggedIn}", + ctx + }); + + return block; + } + + // (55:6) + function create_default_slot_3(ctx) { + let strong; + + const block = { + c: function create() { + strong = element("strong"); + strong.textContent = "Register"; + add_location(strong, file, 55, 5, 1448); + }, + m: function mount(target, anchor) { + insert_dev(target, strong, anchor); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(strong); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_3.name, + type: "slot", + source: "(55:6) ", + ctx + }); + + return block; + } + + // (58:6) + function create_default_slot_2(ctx) { + let t; + + const block = { + c: function create() { + t = text("Log in"); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_2.name, + type: "slot", + source: "(58:6) ", + ctx + }); + + return block; + } + + // (47:6) + function create_default_slot_1(ctx) { + let t; + + const block = { + c: function create() { + t = text("Log out"); + }, + m: function mount(target, anchor) { + insert_dev(target, t, anchor); + }, + d: function destroy(detaching) { + if (detaching) detach_dev(t); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot_1.name, + type: "slot", + source: "(47:6) ", + ctx + }); + + return block; + } + + // (22:0) + function create_default_slot(ctx) { + let nav; + let div0; + let link0; + let t0; + let a; + let span0; + let t1; + let span1; + let t2; + let span2; + let t3; + let div3; + let div1; + let link1; + let t4; + let div2; + let current_block_type_index; + let if_block; + let t5; + let div4; + let route0; + let t6; + let route1; + let t7; + let route2; + let t8; + let route3; + let t9; + let route4; + let t10; + let route5; + let current; + + link0 = new Link({ + props: { + class: "navbar-item", + to: "/", + $$slots: { default: [create_default_slot_5] }, + $$scope: { ctx } + }, + $$inline: true + }); + + link1 = new Link({ + props: { + class: "navbar-item", + to: "/posts", + $$slots: { default: [create_default_slot_4] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const if_block_creators = [create_if_block, create_else_block]; + const if_blocks = []; + + function select_block_type(ctx, dirty) { + if (/*loggedIn*/ ctx[1]) return 0; + return 1; + } + + current_block_type_index = select_block_type(ctx); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + + route0 = new Route({ + props: { path: "/", component: Home }, + $$inline: true + }); + + route1 = new Route({ + props: { path: "/posts", component: Posts }, + $$inline: true + }); + + route2 = new Route({ + props: { path: "/tag/:id", component: Tag }, + $$inline: true + }); + + route3 = new Route({ + props: { path: "/post/:id", component: Post }, + $$inline: true + }); + + route4 = new Route({ + props: { path: "/auth/login", component: Login }, + $$inline: true + }); + + route5 = new Route({ + props: { path: "/auth/logout", component: Logout }, + $$inline: true + }); + + const block = { + c: function create() { + nav = element("nav"); + div0 = element("div"); + create_component(link0.$$.fragment); + t0 = space(); + a = element("a"); + span0 = element("span"); + t1 = space(); + span1 = element("span"); + t2 = space(); + span2 = element("span"); + t3 = space(); + div3 = element("div"); + div1 = element("div"); + create_component(link1.$$.fragment); + t4 = space(); + div2 = element("div"); + if_block.c(); + t5 = space(); + div4 = element("div"); + create_component(route0.$$.fragment); + t6 = space(); + create_component(route1.$$.fragment); + t7 = space(); + create_component(route2.$$.fragment); + t8 = space(); + create_component(route3.$$.fragment); + t9 = space(); + create_component(route4.$$.fragment); + t10 = space(); + create_component(route5.$$.fragment); + attr_dev(span0, "aria-hidden", "true"); + add_location(span0, file, 29, 3, 816); + attr_dev(span1, "aria-hidden", "true"); + add_location(span1, file, 30, 3, 852); + attr_dev(span2, "aria-hidden", "true"); + add_location(span2, file, 31, 3, 888); + attr_dev(a, "role", "button"); + attr_dev(a, "class", "navbar-burger"); + attr_dev(a, "aria-label", "menu"); + attr_dev(a, "aria-expanded", "false"); + attr_dev(a, "data-target", "navbarBasicExample"); + add_location(a, file, 28, 4, 700); + attr_dev(div0, "class", "navbar-brand"); + add_location(div0, file, 23, 2, 603); + attr_dev(div1, "class", "navbar-start"); + add_location(div1, file, 36, 4, 999); + attr_dev(div2, "class", "navbar-end"); + add_location(div2, file, 42, 4, 1107); + attr_dev(div3, "id", "navbarBasicExample"); + attr_dev(div3, "class", "navbar-menu"); + add_location(div3, file, 35, 2, 945); + attr_dev(nav, "class", "navbar"); + attr_dev(nav, "role", "navigation"); + attr_dev(nav, "aria-label", "main navigation"); + add_location(nav, file, 22, 1, 533); + add_location(div4, file, 66, 3, 1635); + }, + m: function mount(target, anchor) { + insert_dev(target, nav, anchor); + append_dev(nav, div0); + mount_component(link0, div0, null); + append_dev(div0, t0); + append_dev(div0, a); + append_dev(a, span0); + append_dev(a, t1); + append_dev(a, span1); + append_dev(a, t2); + append_dev(a, span2); + append_dev(nav, t3); + append_dev(nav, div3); + append_dev(div3, div1); + mount_component(link1, div1, null); + append_dev(div3, t4); + append_dev(div3, div2); + if_blocks[current_block_type_index].m(div2, null); + insert_dev(target, t5, anchor); + insert_dev(target, div4, anchor); + mount_component(route0, div4, null); + append_dev(div4, t6); + mount_component(route1, div4, null); + append_dev(div4, t7); + mount_component(route2, div4, null); + append_dev(div4, t8); + mount_component(route3, div4, null); + append_dev(div4, t9); + mount_component(route4, div4, null); + append_dev(div4, t10); + mount_component(route5, div4, null); + current = true; + }, + p: function update(ctx, dirty) { + const link0_changes = {}; + + if (dirty & /*$$scope*/ 8) { + link0_changes.$$scope = { dirty, ctx }; + } + + link0.$set(link0_changes); + const link1_changes = {}; + + if (dirty & /*$$scope*/ 8) { + link1_changes.$$scope = { dirty, ctx }; + } + + link1.$set(link1_changes); + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx); + + if (current_block_type_index !== previous_block_index) { + group_outros(); + + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + + check_outros(); + if_block = if_blocks[current_block_type_index]; + + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + if_block.c(); + } + + transition_in(if_block, 1); + if_block.m(div2, null); + } + }, + i: function intro(local) { + if (current) return; + transition_in(link0.$$.fragment, local); + transition_in(link1.$$.fragment, local); + transition_in(if_block); + transition_in(route0.$$.fragment, local); + transition_in(route1.$$.fragment, local); + transition_in(route2.$$.fragment, local); + transition_in(route3.$$.fragment, local); + transition_in(route4.$$.fragment, local); + transition_in(route5.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(link0.$$.fragment, local); + transition_out(link1.$$.fragment, local); + transition_out(if_block); + transition_out(route0.$$.fragment, local); + transition_out(route1.$$.fragment, local); + transition_out(route2.$$.fragment, local); + transition_out(route3.$$.fragment, local); + transition_out(route4.$$.fragment, local); + transition_out(route5.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + if (detaching) detach_dev(nav); + destroy_component(link0); + destroy_component(link1); + if_blocks[current_block_type_index].d(); + if (detaching) detach_dev(t5); + if (detaching) detach_dev(div4); + destroy_component(route0); + destroy_component(route1); + destroy_component(route2); + destroy_component(route3); + destroy_component(route4); + destroy_component(route5); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_default_slot.name, + type: "slot", + source: "(22:0) ", + ctx + }); + + return block; + } + + function create_fragment(ctx) { + let router; + let current; + + router = new Router({ + props: { + url: /*url*/ ctx[0], + $$slots: { default: [create_default_slot] }, + $$scope: { ctx } + }, + $$inline: true + }); + + const block = { + c: function create() { + create_component(router.$$.fragment); + }, + l: function claim(nodes) { + throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); + }, + m: function mount(target, anchor) { + mount_component(router, target, anchor); + current = true; + }, + p: function update(ctx, [dirty]) { + const router_changes = {}; + if (dirty & /*url*/ 1) router_changes.url = /*url*/ ctx[0]; + + if (dirty & /*$$scope, loggedIn*/ 10) { + router_changes.$$scope = { dirty, ctx }; + } + + router.$set(router_changes); + }, + i: function intro(local) { + if (current) return; + transition_in(router.$$.fragment, local); + current = true; + }, + o: function outro(local) { + transition_out(router.$$.fragment, local); + current = false; + }, + d: function destroy(detaching) { + destroy_component(router, detaching); + } + }; + + dispatch_dev("SvelteRegisterBlock", { + block, + id: create_fragment.name, + type: "component", + source: "", + ctx + }); + + return block; + } + + function instance($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + validate_slots("App", slots, []); + let loggedIn = false; + + token.subscribe(value => { + $$invalidate(1, loggedIn = value !== ""); + }); + + let { url = "" } = $$props; + let baseURL = window.BASE_URL; + const writable_props = ["url"]; + + Object.keys($$props).forEach(key => { + if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(` was created with unknown prop '${key}'`); + }); + + $$self.$$set = $$props => { + if ("url" in $$props) $$invalidate(0, url = $$props.url); + }; + + $$self.$capture_state = () => ({ + Router, + Link, + Route, + Home, + Posts, + Post, + Login, + Logout, + Tag, + token, + loggedIn, + url, + baseURL + }); + + $$self.$inject_state = $$props => { + if ("loggedIn" in $$props) $$invalidate(1, loggedIn = $$props.loggedIn); + if ("url" in $$props) $$invalidate(0, url = $$props.url); + if ("baseURL" in $$props) baseURL = $$props.baseURL; + }; + + if ($$props && "$$inject" in $$props) { + $$self.$inject_state($$props.$$inject); + } + + return [url, loggedIn]; + } + + class App extends SvelteComponentDev { + constructor(options) { + super(options); + init(this, options, instance, create_fragment, safe_not_equal, { url: 0 }); + + dispatch_dev("SvelteRegisterComponent", { + component: this, + tagName: "App", + options, + id: create_fragment.name + }); + } + + get url() { + throw new Error(": Props cannot be read directly from the component instance unless compiling with 'accessors: true' or ''"); + } + + set url(value) { + throw new Error(": Props cannot be set directly on the component instance unless compiling with 'accessors: true' or ''"); + } + } + + const app = new App({ + target: document.body, + hydrate: false, + }); + + return app; + +}()); +//# sourceMappingURL=bundle.js.map diff --git a/web/static/bundle.js.map b/web/static/bundle.js.map new file mode 100644 index 0000000..1a24d0e --- /dev/null +++ b/web/static/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bundle.js","sources":["../app/node_modules/svelte/internal/index.mjs","../app/node_modules/svelte/store/index.mjs","../app/node_modules/svelte-routing/src/contexts.js","../app/node_modules/svelte-routing/src/history.js","../app/node_modules/svelte-routing/src/utils.js","../app/node_modules/svelte-routing/src/Router.svelte","../app/node_modules/svelte-routing/src/Route.svelte","../app/node_modules/svelte-routing/src/Link.svelte","../app/src/stores.js","../app/src/api.js","../app/src/routes/Posts.svelte","../app/src/routes/Post.svelte","../app/src/routes/Login.svelte","../app/src/routes/Logout.svelte","../app/src/routes/Tag.svelte","../app/src/App.svelte","../app/src/main.js"],"sourcesContent":["function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot_spread(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_spread_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_spread_changes_fn(dirty) | get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value = ret) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction claim_element(nodes, name, attributes, svg) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeName === name) {\n let j = 0;\n const remove = [];\n while (j < node.attributes.length) {\n const attribute = node.attributes[j++];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n for (let k = 0; k < remove.length; k++) {\n node.removeAttribute(remove[k]);\n }\n return nodes.splice(i, 1)[0];\n }\n }\n return svg ? svg_element(name) : element(name);\n}\nfunction claim_text(nodes, data) {\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 3) {\n node.data = '' + data;\n return nodes.splice(i, 1)[0];\n }\n }\n return text(data);\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, false, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor(anchor = null) {\n this.a = anchor;\n this.e = this.n = null;\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.h(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = node.ownerDocument;\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n callbacks.slice().forEach(fn => fn(event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = program.b - t;\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\nfunction update_await_block_branch(info, ctx, dirty) {\n const child_ctx = ctx.slice();\n const { resolved } = info;\n if (info.current === info.then) {\n child_ctx[info.value] = resolved;\n }\n if (info.current === info.catch) {\n child_ctx[info.error] = resolved;\n }\n info.block.p(child_ctx, dirty);\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${String(value).replace(/\"/g, '"').replace(/'/g, ''')}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '"',\n \"'\": ''',\n '&': '&',\n '<': '<',\n '>': '>'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots, context) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : context || []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, $$slots, context);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : options.context || []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false\n };\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.38.2' }, detail)));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * \n * \n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to seperate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_space, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, escape, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getContext, get_binding_group_value, get_current_component, get_custom_elements_slots, get_slot_changes, get_slot_context, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, identity, init, insert, insert_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, update_await_block_branch, update_keyed_each, update_slot, update_slot_spread, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","import { noop, safe_not_equal, subscribe, run_all, is_function } from '../internal/index.mjs';\nexport { get_store_value as get } from '../internal/index.mjs';\n\nconst subscriber_queue = [];\n/**\n * Creates a `Readable` store that allows reading by subscription.\n * @param value initial value\n * @param {StartStopNotifier}start start and stop notifications for subscriptions\n */\nfunction readable(value, start) {\n return {\n subscribe: writable(value, start).subscribe\n };\n}\n/**\n * Create a `Writable` store that allows both updating and reading by subscription.\n * @param {*=}value initial value\n * @param {StartStopNotifier=}start start and stop notifications for subscriptions\n */\nfunction writable(value, start = noop) {\n let stop;\n const subscribers = [];\n function set(new_value) {\n if (safe_not_equal(value, new_value)) {\n value = new_value;\n if (stop) { // store is ready\n const run_queue = !subscriber_queue.length;\n for (let i = 0; i < subscribers.length; i += 1) {\n const s = subscribers[i];\n s[1]();\n subscriber_queue.push(s, value);\n }\n if (run_queue) {\n for (let i = 0; i < subscriber_queue.length; i += 2) {\n subscriber_queue[i][0](subscriber_queue[i + 1]);\n }\n subscriber_queue.length = 0;\n }\n }\n }\n }\n function update(fn) {\n set(fn(value));\n }\n function subscribe(run, invalidate = noop) {\n const subscriber = [run, invalidate];\n subscribers.push(subscriber);\n if (subscribers.length === 1) {\n stop = start(set) || noop;\n }\n run(value);\n return () => {\n const index = subscribers.indexOf(subscriber);\n if (index !== -1) {\n subscribers.splice(index, 1);\n }\n if (subscribers.length === 0) {\n stop();\n stop = null;\n }\n };\n }\n return { set, update, subscribe };\n}\nfunction derived(stores, fn, initial_value) {\n const single = !Array.isArray(stores);\n const stores_array = single\n ? [stores]\n : stores;\n const auto = fn.length < 2;\n return readable(initial_value, (set) => {\n let inited = false;\n const values = [];\n let pending = 0;\n let cleanup = noop;\n const sync = () => {\n if (pending) {\n return;\n }\n cleanup();\n const result = fn(single ? values[0] : values, set);\n if (auto) {\n set(result);\n }\n else {\n cleanup = is_function(result) ? result : noop;\n }\n };\n const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {\n values[i] = value;\n pending &= ~(1 << i);\n if (inited) {\n sync();\n }\n }, () => {\n pending |= (1 << i);\n }));\n inited = true;\n sync();\n return function stop() {\n run_all(unsubscribers);\n cleanup();\n };\n });\n}\n\nexport { derived, readable, writable };\n","export const LOCATION = {};\nexport const ROUTER = {};\n","/**\n * Adapted from https://github.com/reach/router/blob/b60e6dd781d5d3a4bdaaf4de665649c0f6a7e78d/src/lib/history.js\n *\n * https://github.com/reach/router/blob/master/LICENSE\n * */\n\nfunction getLocation(source) {\n return {\n ...source.location,\n state: source.history.state,\n key: (source.history.state && source.history.state.key) || \"initial\"\n };\n}\n\nfunction createHistory(source, options) {\n const listeners = [];\n let location = getLocation(source);\n\n return {\n get location() {\n return location;\n },\n\n listen(listener) {\n listeners.push(listener);\n\n const popstateListener = () => {\n location = getLocation(source);\n listener({ location, action: \"POP\" });\n };\n\n source.addEventListener(\"popstate\", popstateListener);\n\n return () => {\n source.removeEventListener(\"popstate\", popstateListener);\n\n const index = listeners.indexOf(listener);\n listeners.splice(index, 1);\n };\n },\n\n navigate(to, { state, replace = false } = {}) {\n state = { ...state, key: Date.now() + \"\" };\n // try...catch iOS Safari limits to 100 pushState calls\n try {\n if (replace) {\n source.history.replaceState(state, null, to);\n } else {\n source.history.pushState(state, null, to);\n }\n } catch (e) {\n source.location[replace ? \"replace\" : \"assign\"](to);\n }\n\n location = getLocation(source);\n listeners.forEach(listener => listener({ location, action: \"PUSH\" }));\n }\n };\n}\n\n// Stores history entries in memory for testing or other platforms like Native\nfunction createMemorySource(initialPathname = \"/\") {\n let index = 0;\n const stack = [{ pathname: initialPathname, search: \"\" }];\n const states = [];\n\n return {\n get location() {\n return stack[index];\n },\n addEventListener(name, fn) {},\n removeEventListener(name, fn) {},\n history: {\n get entries() {\n return stack;\n },\n get index() {\n return index;\n },\n get state() {\n return states[index];\n },\n pushState(state, _, uri) {\n const [pathname, search = \"\"] = uri.split(\"?\");\n index++;\n stack.push({ pathname, search });\n states.push(state);\n },\n replaceState(state, _, uri) {\n const [pathname, search = \"\"] = uri.split(\"?\");\n stack[index] = { pathname, search };\n states[index] = state;\n }\n }\n };\n}\n\n// Global history uses window.history as the source if available,\n// otherwise a memory history\nconst canUseDOM = Boolean(\n typeof window !== \"undefined\" &&\n window.document &&\n window.document.createElement\n);\nconst globalHistory = createHistory(canUseDOM ? window : createMemorySource());\nconst { navigate } = globalHistory;\n\nexport { globalHistory, navigate, createHistory, createMemorySource };\n","/**\n * Adapted from https://github.com/reach/router/blob/b60e6dd781d5d3a4bdaaf4de665649c0f6a7e78d/src/lib/utils.js\n *\n * https://github.com/reach/router/blob/master/LICENSE\n * */\n\nconst paramRe = /^:(.+)/;\n\nconst SEGMENT_POINTS = 4;\nconst STATIC_POINTS = 3;\nconst DYNAMIC_POINTS = 2;\nconst SPLAT_PENALTY = 1;\nconst ROOT_POINTS = 1;\n\n/**\n * Check if `string` starts with `search`\n * @param {string} string\n * @param {string} search\n * @return {boolean}\n */\nexport function startsWith(string, search) {\n return string.substr(0, search.length) === search;\n}\n\n/**\n * Check if `segment` is a root segment\n * @param {string} segment\n * @return {boolean}\n */\nfunction isRootSegment(segment) {\n return segment === \"\";\n}\n\n/**\n * Check if `segment` is a dynamic segment\n * @param {string} segment\n * @return {boolean}\n */\nfunction isDynamic(segment) {\n return paramRe.test(segment);\n}\n\n/**\n * Check if `segment` is a splat\n * @param {string} segment\n * @return {boolean}\n */\nfunction isSplat(segment) {\n return segment[0] === \"*\";\n}\n\n/**\n * Split up the URI into segments delimited by `/`\n * @param {string} uri\n * @return {string[]}\n */\nfunction segmentize(uri) {\n return (\n uri\n // Strip starting/ending `/`\n .replace(/(^\\/+|\\/+$)/g, \"\")\n .split(\"/\")\n );\n}\n\n/**\n * Strip `str` of potential start and end `/`\n * @param {string} str\n * @return {string}\n */\nfunction stripSlashes(str) {\n return str.replace(/(^\\/+|\\/+$)/g, \"\");\n}\n\n/**\n * Score a route depending on how its individual segments look\n * @param {object} route\n * @param {number} index\n * @return {object}\n */\nfunction rankRoute(route, index) {\n const score = route.default\n ? 0\n : segmentize(route.path).reduce((score, segment) => {\n score += SEGMENT_POINTS;\n\n if (isRootSegment(segment)) {\n score += ROOT_POINTS;\n } else if (isDynamic(segment)) {\n score += DYNAMIC_POINTS;\n } else if (isSplat(segment)) {\n score -= SEGMENT_POINTS + SPLAT_PENALTY;\n } else {\n score += STATIC_POINTS;\n }\n\n return score;\n }, 0);\n\n return { route, score, index };\n}\n\n/**\n * Give a score to all routes and sort them on that\n * @param {object[]} routes\n * @return {object[]}\n */\nfunction rankRoutes(routes) {\n return (\n routes\n .map(rankRoute)\n // If two routes have the exact same score, we go by index instead\n .sort((a, b) =>\n a.score < b.score ? 1 : a.score > b.score ? -1 : a.index - b.index\n )\n );\n}\n\n/**\n * Ranks and picks the best route to match. Each segment gets the highest\n * amount of points, then the type of segment gets an additional amount of\n * points where\n *\n * static > dynamic > splat > root\n *\n * This way we don't have to worry about the order of our routes, let the\n * computers do it.\n *\n * A route looks like this\n *\n * { path, default, value }\n *\n * And a returned match looks like:\n *\n * { route, params, uri }\n *\n * @param {object[]} routes\n * @param {string} uri\n * @return {?object}\n */\nfunction pick(routes, uri) {\n let match;\n let default_;\n\n const [uriPathname] = uri.split(\"?\");\n const uriSegments = segmentize(uriPathname);\n const isRootUri = uriSegments[0] === \"\";\n const ranked = rankRoutes(routes);\n\n for (let i = 0, l = ranked.length; i < l; i++) {\n const route = ranked[i].route;\n let missed = false;\n\n if (route.default) {\n default_ = {\n route,\n params: {},\n uri\n };\n continue;\n }\n\n const routeSegments = segmentize(route.path);\n const params = {};\n const max = Math.max(uriSegments.length, routeSegments.length);\n let index = 0;\n\n for (; index < max; index++) {\n const routeSegment = routeSegments[index];\n const uriSegment = uriSegments[index];\n\n if (routeSegment !== undefined && isSplat(routeSegment)) {\n // Hit a splat, just grab the rest, and return a match\n // uri: /files/documents/work\n // route: /files/* or /files/*splatname\n const splatName = routeSegment === \"*\" ? \"*\" : routeSegment.slice(1);\n\n params[splatName] = uriSegments\n .slice(index)\n .map(decodeURIComponent)\n .join(\"/\");\n break;\n }\n\n if (uriSegment === undefined) {\n // URI is shorter than the route, no match\n // uri: /users\n // route: /users/:userId\n missed = true;\n break;\n }\n\n let dynamicMatch = paramRe.exec(routeSegment);\n\n if (dynamicMatch && !isRootUri) {\n const value = decodeURIComponent(uriSegment);\n params[dynamicMatch[1]] = value;\n } else if (routeSegment !== uriSegment) {\n // Current segments don't match, not dynamic, not splat, so no match\n // uri: /users/123/settings\n // route: /users/:id/profile\n missed = true;\n break;\n }\n }\n\n if (!missed) {\n match = {\n route,\n params,\n uri: \"/\" + uriSegments.slice(0, index).join(\"/\")\n };\n break;\n }\n }\n\n return match || default_ || null;\n}\n\n/**\n * Check if the `path` matches the `uri`.\n * @param {string} path\n * @param {string} uri\n * @return {?object}\n */\nfunction match(route, uri) {\n return pick([route], uri);\n}\n\n/**\n * Add the query to the pathname if a query is given\n * @param {string} pathname\n * @param {string} [query]\n * @return {string}\n */\nfunction addQuery(pathname, query) {\n return pathname + (query ? `?${query}` : \"\");\n}\n\n/**\n * Resolve URIs as though every path is a directory, no files. Relative URIs\n * in the browser can feel awkward because not only can you be \"in a directory\",\n * you can be \"at a file\", too. For example:\n *\n * browserSpecResolve('foo', '/bar/') => /bar/foo\n * browserSpecResolve('foo', '/bar') => /foo\n *\n * But on the command line of a file system, it's not as complicated. You can't\n * `cd` from a file, only directories. This way, links have to know less about\n * their current path. To go deeper you can do this:\n *\n * \n * // instead of\n * \n *\n * Just like `cd`, if you want to go deeper from the command line, you do this:\n *\n * cd deeper\n * # not\n * cd $(pwd)/deeper\n *\n * By treating every path as a directory, linking to relative paths should\n * require less contextual information and (fingers crossed) be more intuitive.\n * @param {string} to\n * @param {string} base\n * @return {string}\n */\nfunction resolve(to, base) {\n // /foo/bar, /baz/qux => /foo/bar\n if (startsWith(to, \"/\")) {\n return to;\n }\n\n const [toPathname, toQuery] = to.split(\"?\");\n const [basePathname] = base.split(\"?\");\n const toSegments = segmentize(toPathname);\n const baseSegments = segmentize(basePathname);\n\n // ?a=b, /users?b=c => /users?a=b\n if (toSegments[0] === \"\") {\n return addQuery(basePathname, toQuery);\n }\n\n // profile, /users/789 => /users/789/profile\n if (!startsWith(toSegments[0], \".\")) {\n const pathname = baseSegments.concat(toSegments).join(\"/\");\n\n return addQuery((basePathname === \"/\" ? \"\" : \"/\") + pathname, toQuery);\n }\n\n // ./ , /users/123 => /users/123\n // ../ , /users/123 => /users\n // ../.. , /users/123 => /\n // ../../one, /a/b/c/d => /a/b/one\n // .././one , /a/b/c/d => /a/b/c/one\n const allSegments = baseSegments.concat(toSegments);\n const segments = [];\n\n allSegments.forEach(segment => {\n if (segment === \"..\") {\n segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n\n return addQuery(\"/\" + segments.join(\"/\"), toQuery);\n}\n\n/**\n * Combines the `basepath` and the `path` into one path.\n * @param {string} basepath\n * @param {string} path\n */\nfunction combinePaths(basepath, path) {\n return `${stripSlashes(\n path === \"/\" ? basepath : `${stripSlashes(basepath)}/${stripSlashes(path)}`\n )}/`;\n}\n\n/**\n * Decides whether a given `event` should result in a navigation or not.\n * @param {object} event\n */\nfunction shouldNavigate(event) {\n return (\n !event.defaultPrevented &&\n event.button === 0 &&\n !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey)\n );\n}\n\nfunction hostMatches(anchor) {\n const host = location.host\n return (\n anchor.host == host ||\n // svelte seems to kill anchor.host value in ie11, so fall back to checking href\n anchor.href.indexOf(`https://${host}`) === 0 ||\n anchor.href.indexOf(`http://${host}`) === 0\n )\n}\n\nexport { stripSlashes, pick, match, resolve, combinePaths, shouldNavigate, hostMatches };\n","\n\n\n","\n\n{#if $activeRoute !== null && $activeRoute.route === route}\n {#if component !== null}\n \n {:else}\n \n {/if}\n{/if}\n","\n\n\n \n\n","import { writable } from \"svelte/store\";\n\nconst storedToken = localStorage.getItem(\"apiToken\");\n\nexport const token = writable(storedToken);\ntoken.subscribe(value => {\n localStorage.setItem(\"apiToken\", value);\n});","import { token } from \"./stores.js\"\n\nlet url = window.BASE_URL;\nlet current_token;\nconst unsub_token = token.subscribe(value => {\n current_token = token;\n})\nexport async function login({ username, password }) {\n const endpoint = url + \"/api/auth/login\";\n const response = await fetch(endpoint, {\n method: \"POST\",\n body: JSON.stringify({\n username,\n password,\n }),\n })\n const data = await response.json();\n token.set(data.token);\n return data;\n}\n\nexport async function getPosts({ page }) {\n const endpoint = url + \"/api/post?page=\" + page;\n const response = await fetch(endpoint);\n const data = await response.json();\n return data;\n}\n\nexport async function getPostsTag({ page, tag }) {\n const endpoint = url + \"/api/post/tag/\" + tag + \"?page=\" + page;\n const response = await fetch(endpoint);\n const data = await response.json();\n return data;\n}\n\nexport async function getPost({ id }) {\n const endpoint = url + \"/api/post/\" + id;\n const response = await fetch(endpoint);\n const data = await response.json();\n return data;\n}","\n\n
\n
\n

\n Posts\n

\n
\n
\n\n
\n
\n
\n {#each posts as post (post.id)}\n
\n
\n
\n \n \n \n
\n
\n
\n
\n {#each post.tags as tag (tag)}\n {tag}\n {/each}\n
\n
\n
\n {/each}\n
\n
\n
\n","\n\n\n
\n
\n {#if post}\n

\n Post ID: {post.id}\n

\n {/if}\n
\n
\n{#if post}\n
\n
\n
\n
\n

\n Source URL: {post.source_url}\n

\n

\n Tags: \n {#each post.tags as tag (tag)}\n {tag}\n {/each}\n

\n
\n
\n
\n \n
\n
\n
\n
\n
\n{/if}","\n
\n
\n
\n \n
\n \n
\n
\n
\n \n
\n \n
\n
\n
\n
\n \n
\n
\n
\n
\n","\n","\n\n
\n
\n

\n {id}\n

\n

\n Tag\n

\n
\n
\n\n
\n
\n
\n {#each posts as post (post.id)}\n
\n
\n
\n \n \n \n
\n
\n
\n
\n {#each post.tags as tag (tag)}\n {tag}\n {/each}\n
\n
\n
\n {/each}\n
\n
\n
\n","\n\n\n\t\n\t
\n\t\t \n\t\t \n\t\t \n\t\t \n\t\t \n\t\t \n\t
\n
","import App from './App.svelte';\n\nconst app = new App({\n\ttarget: document.body,\n\thydrate: false,\n});\n\nexport default app;"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web/template/layout/footer.html b/web/template/layout/footer.html new file mode 100644 index 0000000..20d332a --- /dev/null +++ b/web/template/layout/footer.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/web/template/layout/header.html b/web/template/layout/header.html new file mode 100644 index 0000000..2d6c575 --- /dev/null +++ b/web/template/layout/header.html @@ -0,0 +1,15 @@ + + + + + {{ .title }} + + + + + + + + \ No newline at end of file diff --git a/web/template/pages/index.html b/web/template/pages/index.html new file mode 100644 index 0000000..918a04a --- /dev/null +++ b/web/template/pages/index.html @@ -0,0 +1,3 @@ +{{ template "header.html" .}} + +{{ template "footer.html" }} \ No newline at end of file