diff --git a/.dockerignore b/.dockerignore index 79c150fd..21bf48da 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,7 @@ evdist/evdist frontend/frontend repochecker/repochecker frontend/ui/node_modules +qa/ui/node_modules fickit-backend-initrd.img fickit-backend-kernel fickit-backend-squashfs.img diff --git a/.drone.yml b/.drone.yml index 5bdabb24..39577b26 100644 --- a/.drone.yml +++ b/.drone.yml @@ -29,6 +29,15 @@ steps: - go get -v -d srs.epita.fr/fic-server/qa - mkdir deploy + - name: build qa ui + image: node:19-alpine + commands: + - cd qa/ui + - npm install --network-timeout=100000 + - sed -i 's!@popperjs/core/dist/esm/popper!@popperjs/core!' node_modules/sveltestrap/src/*.js node_modules/sveltestrap/src/*.svelte + - npm run build + - tar chjf ../../deploy/htdocs-qa.tar.bz2 build + - name: vet image: golang:alpine commands: @@ -81,9 +90,8 @@ steps: CGO_ENABLED: 0 - name: build frontend ui - image: node:19-alpine3.15 + image: node:19-alpine commands: - - apk --no-cache add python2 build-base - cd frontend/ui - npm install --network-timeout=100000 - sed -i 's!@popperjs/core/dist/esm/popper!@popperjs/core!' node_modules/sveltestrap/src/*.js node_modules/sveltestrap/src/*.svelte @@ -124,7 +132,6 @@ steps: image: golang:alpine commands: - go build -v -buildvcs=false -o deploy/qa-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} srs.epita.fr/fic-server/qa - - tar chjf deploy/htdocs-qa.tar.bz2 htdocs-qa environment: CGO_ENABLED: 0 @@ -372,9 +379,8 @@ steps: CGO_ENABLED: 0 - name: build frontend ui - image: node:19-alpine3.15 + image: node:19-alpine commands: - - apk --no-cache add python2 build-base - cd frontend/ui - npm install --network-timeout=100000 - sed -i 's!@popperjs/core/dist/esm/popper!@popperjs/core!' node_modules/sveltestrap/src/*.js node_modules/sveltestrap/src/*.svelte @@ -405,6 +411,15 @@ steps: GOOS: darwin GOARCH: arm64 + - name: build qa ui + image: node:19-alpine + commands: + - cd qa/ui + - npm install --network-timeout=100000 + - sed -i 's!@popperjs/core/dist/esm/popper!@popperjs/core!' node_modules/sveltestrap/src/*.js node_modules/sveltestrap/src/*.svelte + - npm run build + - tar chjf ../../deploy/htdocs-qa.tar.bz2 build + - name: build qa image: golang:alpine commands: diff --git a/Dockerfile-dashboard b/Dockerfile-dashboard index 2c049ec7..ad5243fd 100644 --- a/Dockerfile-dashboard +++ b/Dockerfile-dashboard @@ -25,7 +25,7 @@ VOLUME /srv/htdocs-dashboard/ COPY --from=gobuild /go/src/srs.epita.fr/fic-server/dashboard/dashboard /srv/dashboard COPY dashboard/static/index.html /srv/htdocs-dashboard/ -COPY admin/static/css/bootstrap.min.css qa/static/css/fic.css admin/static/css/glyphicon.css /srv/htdocs-dashboard/css/ +COPY admin/static/css/bootstrap.min.css dashboard/static/css/fic.css admin/static/css/glyphicon.css /srv/htdocs-dashboard/css/ COPY admin/static/fonts /srv/htdocs-dashboard/fonts COPY frontend/ui/static/img/ dashboard/static/img/logo-epita-bw.png dashboard/static/img/sii.png /srv/htdocs-dashboard/img/ COPY dashboard/static/js/dashboard.js admin/static/js/angular.min.js dashboard/static/js/angular-animate.min.js admin/static/js/angular-route.min.js admin/static/js/angular-sanitize.min.js admin/static/js/bootstrap.min.js admin/static/js/common.js admin/static/js/d3.v3.min.js admin/static/js/jquery.min.js /srv/htdocs-dashboard/js/ diff --git a/Dockerfile-qa b/Dockerfile-qa index af929afa..1d6dbb36 100644 --- a/Dockerfile-qa +++ b/Dockerfile-qa @@ -1,3 +1,14 @@ +FROM node:19-alpine as nodebuild + +WORKDIR /ui + +COPY qa/ui/ . + +RUN npm install --network-timeout=100000 && \ + sed -i 's!@popperjs/core/dist/esm/popper!@popperjs/core!' node_modules/sveltestrap/src/*.js node_modules/sveltestrap/src/*.svelte && \ + npm run build + + FROM golang:1-alpine as gobuild RUN apk add --no-cache git @@ -7,6 +18,7 @@ WORKDIR /go/src/srs.epita.fr/fic-server/ COPY go.mod go.sum ./ COPY settings settings/ COPY libfic ./libfic/ +COPY --from=nodebuild /ui ./qa/ui COPY qa ./qa/ RUN go get -d -v ./qa && \ @@ -24,9 +36,3 @@ ENTRYPOINT ["/srv/qa", "--bind=:8083"] VOLUME /srv/htdocs-qa/ COPY --from=gobuild /go/src/srs.epita.fr/fic-server/qa/qa /srv/qa -COPY qa/static/index.html /srv/htdocs-qa/ -COPY admin/static/css/bootstrap.min.css qa/static/css/fic.css admin/static/css/glyphicon.css /srv/htdocs-qa/css/ -COPY admin/static/fonts /srv/htdocs-qa/fonts -COPY frontend/ui/static/img/ /srv/htdocs-qa/img/ -COPY qa/static/js/qa.js admin/static/js/angular.min.js qa/static/js/angular-resource.min.js admin/static/js/angular-route.min.js admin/static/js/angular-sanitize.min.js admin/static/js/bootstrap.min.js admin/static/js/common.js admin/static/js/i18n admin/static/js/jquery.min.js /srv/htdocs-qa/js/ -COPY qa/static/views/ /srv/htdocs-qa/views/ diff --git a/dashboard/static/css/fic.css b/dashboard/static/css/fic.css deleted file mode 120000 index d925f895..00000000 --- a/dashboard/static/css/fic.css +++ /dev/null @@ -1 +0,0 @@ -../../../qa/static/css/fic.css \ No newline at end of file diff --git a/dashboard/static/css/fic.css b/dashboard/static/css/fic.css new file mode 100644 index 00000000..fc12b00d --- /dev/null +++ b/dashboard/static/css/fic.css @@ -0,0 +1,387 @@ +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_R.woff') format('woff'); +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RB.woff') format('woff'); + font-weight: bold; +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RI.woff') format('woff'); + font-style: italic; +} +@font-face { + font-family: 'FantasqueSansMonoRegular'; + src: url('../fonts/FantasqueSansMono-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +b, strong { + font-weight: bold; +} + +[ng-cloak] { + display:none !important; +} + +.popover.bs-popover-left .arrow::after { + border-left-color: #7A8288; +} + +body { + overflow-y: scroll; +} + +.bg-public { + background-image: url('../img/logo-epita-bw.png'); + background-repeat: no-repeat; + background-size: contain; + height: 100vh; +} + +.bg-public .carousel h3 { + font-size: 1.5rem; + line-height: 1.1rem; +} + +.flag { + font-family: 'FantasqueSansMonoRegular', monospace; +} + +.card-img-top { + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} +.theme-card { + height: 10rem; +} + +.beautiful { + font-family: "Linux Biolinum",Helvetica,Arial,sans-serif; +} +.beautiful ol { + font-size: 133%; +} +.beautiful ol ol { + font-size: 90%; +} + +.text-bold { + font-weight: bolder; +} +.text-indent p { + text-indent: 1em; +} + +.navbar { + margin-bottom: 0; +} +.niceborder { + border-bottom: 5px #4eaee6 solid; +} +.navbar img { + margin: 3px auto; + height: 100px; +} +.navbar .clock { + font-size: 70px; +} +.clock:not(.expired):not(.wait) .point, .clock.expired { + transition: color text-shadow 1s; + position: relative; + animation: clockanim 1s ease infinite; + -moz-animation: clockanim 1s ease infinite; + -webkit-animation: clockanim 1s ease infinite; +} +.clock.wait .point { + transition: color text-shadow 1s; + position: relative; + animation: clockwait 1s ease infinite; + -moz-animation: clockwait 1s ease infinite; + -webkit-animation: clockwait 1s ease infinite; +} +.end { + color: #e64143; +} +.point { + text-shadow: 0 0 20px #4eaee6; +} +.end .point { + text-shadow: 0 0 20px #e64143; +} +@-webkit-keyframes clockanim { + 0% { opacity: 1.0; } + 50% { opacity: 0; } + 100% { opacity: 1.0; }; +} +@-moz-keyframes clockanim { + 0% { opacity: 1.0; } + 50% { opacity: 0; } + 100% { opacity: 1.0; }; +} +keyframes clockanim { + 0% { opacity: 1.0; } + 50% { opacity: 0; } + 100% { opacity: 1.0; }; +} +@-webkit-keyframes clockwait { + 0% { text-shadow: 0 0 20px #A6D6F2; } + 50% { text-shadow: 0 0 2px #A6D6F2; } + 100% { text-shadow: 0 0 20px #A6D6F2; } +} +@-moz-keyframes clockwait { + 0% { text-shadow: 0 0 20px #A6D6F2; } + 50% { text-shadow: 0 0 2px #A6D6F2; } + 100% { text-shadow: 0 0 20px #A6D6F2; } +} +keyframes clockwait { + 0% { text-shadow: 0 0 20px #A6D6F2; } + 50% { text-shadow: 0 0 2px #A6D6F2; } + 100% { text-shadow: 0 0 20px #A6D6F2; } +} + +samp.cksum { + overflow-x: hidden; + text-overflow: ellipsis; + max-width: 16vw; + display: inline-block; + vertical-align: middle; + word-wrap: normal; +} + +h1 small.authors { + float: right; + font-style: italic; + font-size: 42%; +} +.lead small.authors { + color: #7a8288; + font-style: italic; +} + +a.badge:hover { + text-decoration: none; +} +.teamname { + -webkit-filter: invert(100%); + filter: invert(100%); +} +a:hover .teamname { + text-shadow: 0px 0px 10px #888888; +} + +.authors a { + color: #3A3F44; +} + +.heading { + font-style: italic; + margin-top: -7px; + text-align: right; +} + +#eventsList { + overflow:hidden; + max-height: 90vh; +} + +.swap-animation .alert { + margin-bottom: 0px; +} +.swap-animation { + margin-bottom: 0.5rem; + max-height: 30vh; + transition: max-height 1.0s linear,opacity 1.0s linear,transform 0.5s linear; +} +.swap-animation.ng-enter { + transform: translateY(-25vh); + max-height: 0vh; +} +.swap-animation.ng-enter-active { + opacity: 1; + transform: translateY(0px); + max-height: 30vh; +} +.swap-animation.ng-leave { + opacity: 1; + max-height: 30vh; + transform: translateY(0px); +} +.swap-animation.ng-leave-active { + opacity: 0; + transform: translateX(120vw); + max-height: 0vh; +} + +.carousel-indicators { + bottom: -10px; +} +.carousel-caption { + padding: 0; + position: static; +} +.carousel .table { + margin-bottom: 0; +} +.carousel .table-sm td { + padding: 2px; +} + +.table th.frotated { + border: 0; +} +.table th.rotated { + height: 100px; + width: 40px; + min-width: 40px; + max-width: 40px; + position: relative; + vertical-align: bottom; + padding: 0; + font-size: 12px; + line-height: 0.9; + border: 0; +} + +th.rotated > div { + position: relative; + top: 0px; + left: -50px; + height: 100%; + transform: skew(45deg,0deg); + overflow: hidden; + border: 1px solid #000; +} +th.rotated div span { + transform: skew(-45deg,0deg) rotate(45deg); + position: absolute; + bottom: 40px; + left: -35px; + display: inline-block; + width: 110px; + text-align: left; + text-overflow: ellipsis; +} + +ul.list-inline li { + display: inline; +} +ul.list-inline li:not(:last-child)::after { + content: " ● " +} + +.breadcrumb-item + .breadcrumb-item::before { + content: ">" +} + +.excard { + transition: transform 250ms; +} +.excard:hover { + transform: scale(1.07); +} + +#tagsMenu + .dropdown-menu div { + overflow-y: auto; + max-height: calc(66vh - 100px); +} + +blockquote { + border-left: solid 2px; + margin-left: 1em; + padding-left: 1em; +} + +.jumbotron img { + margin-left: -1em; + padding-left: 2em; + padding-right: 2em; +} +img { + max-width: 100%; +} + +#eventsList .card { + border-left-color: rgba(0,0,0,.125) !important; + border-right-color: rgba(0,0,0,.125) !important; + border-top-color: rgba(0,0,0,.125) !important; +} + +.bg-public .card-body { + padding:1rem; + padding-bottom:0; +} + +#themesSummary .card-body { + padding:0; +} +#themesSummary h3 { + background: rgba(64,64,64,0.66); + border-radius: 2px; + padding: 0.5rem; + margin-left: 0.5rem; + margin-right: 0.5rem; + margin-top: -40px; +} +#themesSummary p { + font-size: 90%; + margin: 0.2rem; + text-indent: 0.6em; +} + +.card-sm .card-header, .card-sm .card-footer { + padding: 0.2rem 0.75rem; +} +.card-sm .card-body { + padding: 0.4rem 0.75rem; +} +.card-sm .card-body.text-indent p { + text-indent: 0.4rem; +} + +.carousel-item, .carousel-caption { + height: inherit; +} + +.page-header { + background-size: cover; + background-position: center; + margin-bottom: -15rem; +} +.page-header h1 { + text-shadow: 0 0 15px rgba(255,255,255,0.95), 0 0 5px rgb(255,255,255) +} +.page-header h1, .page-header h1 a { + color: black; +} +.page-header h1 a:hover { + text-decoration: none; +} +.page-header h2 { + font-size: 100%; + text-shadow: 1px 1px 1px rgba(0,0,0,0.9) +} +.page-header h2, .page-header h2 a { + color: #4eaee6; +} +.page-header h1 { + padding-top: 4rem; + text-align: center; +} +.page-header h2 { + padding-bottom: 14rem; + text-align: center; +} + +.page-header .headerfade { + background: linear-gradient(transparent 0%, rgb(233,236,239) 100%); + height: 3rem; +} + +a.list-group-item:hover { + text-decoration: none; +} diff --git a/htdocs-qa b/htdocs-qa deleted file mode 120000 index 2c4757cb..00000000 --- a/htdocs-qa +++ /dev/null @@ -1 +0,0 @@ -qa/static \ No newline at end of file diff --git a/qa/assets-dev.go b/qa/assets-dev.go new file mode 100644 index 00000000..dee90bca --- /dev/null +++ b/qa/assets-dev.go @@ -0,0 +1,32 @@ +//go:build dev +// +build dev + +package main + +import ( + "flag" + "net/http" + "os" + "path/filepath" +) + +var ( + Assets http.FileSystem + StaticDir string = "ui/" +) + +func init() { + flag.StringVar(&StaticDir, "static", StaticDir, "Directory containing static files") +} + +func sanitizeStaticOptions() error { + StaticDir, _ = filepath.Abs(StaticDir) + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + StaticDir, _ = filepath.Abs(filepath.Join(filepath.Dir(os.Args[0]), "ui")) + if _, err := os.Stat(StaticDir); os.IsNotExist(err) { + return err + } + } + Assets = http.Dir(StaticDir) + return nil +} diff --git a/qa/assets.go b/qa/assets.go new file mode 100644 index 00000000..fc457afb --- /dev/null +++ b/qa/assets.go @@ -0,0 +1,28 @@ +//go:build !dev +// +build !dev + +package main + +import ( + "embed" + "io/fs" + "log" + "net/http" +) + +//go:embed ui/build/* ui/build/_app/assets/pages/* ui/build/_app/pages/* +var _assets embed.FS + +var Assets http.FileSystem + +func init() { + sub, err := fs.Sub(_assets, "ui/build") + if err != nil { + log.Fatal("Unable to cd to ui/build directory:", err) + } + Assets = http.FS(sub) +} + +func sanitizeStaticOptions() error { + return nil +} diff --git a/qa/main.go b/qa/main.go index f6ad9003..8a6fc3b3 100644 --- a/qa/main.go +++ b/qa/main.go @@ -2,14 +2,12 @@ package main import ( "flag" - "io/fs" "log" "net/http" "net/url" "os" "os/signal" "path" - "path/filepath" "strings" "syscall" @@ -17,8 +15,6 @@ import ( "srs.epita.fr/fic-server/qa/api" ) -var StaticDir string - type ResponseWriterPrefix struct { real http.ResponseWriter prefix string @@ -69,7 +65,7 @@ func main() { var bind = flag.String("bind", "127.0.0.1:8083", "Bind port/socket") var dsn = flag.String("dsn", fic.DSNGenerator(), "DSN to connect to the MySQL server") flag.StringVar(&BaseURL, "baseurl", BaseURL, "URL prepended to each URL") - flag.StringVar(&StaticDir, "static", "./htdocs-qa/", "Directory containing static files") + flag.StringVar(&DevProxy, "dev", DevProxy, "Proxify traffic to this host for static assets") flag.StringVar(&api.TeamsDir, "teams", "./TEAMS", "Base directory where save teams JSON files") flag.StringVar(&api.Simulator, "simulator", "", "Auth string to simulate (for development only)") flag.Parse() @@ -79,21 +75,6 @@ func main() { // Sanitize options var err error log.Println("Checking paths...") - if StaticDir != "" { - if sDir, err := filepath.Abs(StaticDir); err != nil { - log.Fatal(err) - } else { - log.Println("Serving pages from", sDir) - staticFS = http.Dir(sDir) - } - } else { - sub, err := fs.Sub(assets, "static") - if err != nil { - log.Fatal("Unable to cd to static/ directory:", err) - } - log.Println("Serving pages from memory.") - staticFS = http.FS(sub) - } if BaseURL != "/" { BaseURL = path.Clean(BaseURL) } else { diff --git a/qa/static.go b/qa/static.go index 60d39f1d..d466a94c 100644 --- a/qa/static.go +++ b/qa/static.go @@ -2,74 +2,96 @@ package main import ( "bytes" - "embed" + "io" "io/ioutil" "log" "net/http" - "os" + "net/url" "path" "strings" "github.com/gin-gonic/gin" ) -//go:embed static -var assets embed.FS +var ( + BaseURL = "/" + DevProxy string + indexTmpl []byte +) -var BaseURL = "/" +func getIndexHtml(w io.Writer, file io.Reader) { + var err error + if indexTmpl, err = ioutil.ReadAll(file); err != nil { + log.Println("Cannot read whole index.html: ", err) + } else { + indexTmpl = bytes.Replace(indexTmpl, []byte("{{.urlbase}}"), []byte(path.Clean(path.Join(BaseURL+"/", "nuke"))[:len(path.Clean(path.Join(BaseURL+"/", "nuke")))-4]), -1) + } -var indexTmpl []byte + w.Write(indexTmpl) +} -func getIndexHtml(c *gin.Context) { - if len(indexTmpl) == 0 { - if file, err := os.Open(path.Join(StaticDir, "index.html")); err != nil { - log.Println("Unable to open index.html: ", err) - } else { - defer file.Close() - - if indexTmpl, err = ioutil.ReadAll(file); err != nil { - log.Println("Cannot read whole index.html: ", err) +func serveOrReverse(forced_url string, baseURL string) func(c *gin.Context) { + return func(c *gin.Context) { + if DevProxy != "" { + if u, err := url.Parse(DevProxy); err != nil { + http.Error(c.Writer, err.Error(), http.StatusInternalServerError) } else { - indexTmpl = bytes.Replace(indexTmpl, []byte("{{.urlbase}}"), []byte(path.Clean(path.Join(BaseURL+"/", "nuke"))[:len(path.Clean(path.Join(BaseURL+"/", "nuke")))-4]), -1) + if forced_url != "" { + u.Path = path.Join(u.Path, forced_url) + } else { + u.Path = path.Join(u.Path, strings.TrimPrefix(c.Request.URL.Path, baseURL)) + } + + if r, err := http.NewRequest(c.Request.Method, u.String(), c.Request.Body); err != nil { + http.Error(c.Writer, err.Error(), http.StatusInternalServerError) + } else if resp, err := http.DefaultClient.Do(r); err != nil { + http.Error(c.Writer, err.Error(), http.StatusBadGateway) + } else { + defer resp.Body.Close() + + for key := range resp.Header { + c.Writer.Header().Add(key, resp.Header.Get(key)) + } + c.Writer.WriteHeader(resp.StatusCode) + + if r.URL.Path == path.Join(u.Path, "/") { + getIndexHtml(c.Writer, resp.Body) + } else { + io.Copy(c.Writer, resp.Body) + } + } + } + } else { + if forced_url != "" { + c.Request.URL.Path = forced_url + } else { + c.Request.URL.Path = strings.TrimPrefix(c.Request.URL.Path, baseURL) + } + + if c.Request.URL.Path == "/" { + if len(indexTmpl) == 0 { + if file, err := Assets.Open("index.html"); err != nil { + log.Println("Unable to open index.html: ", err) + } else { + defer file.Close() + + getIndexHtml(c.Writer, file) + } + } else { + c.Writer.Write(indexTmpl) + } + } else { + http.FileServer(Assets).ServeHTTP(c.Writer, c.Request) } } } - - c.Writer.Write(indexTmpl) -} - -var staticFS http.FileSystem - -func serveFile(c *gin.Context, url string) { - c.Request.URL.Path = url - http.FileServer(staticFS).ServeHTTP(c.Writer, c.Request) } func declareStaticRoutes(router *gin.RouterGroup, baseURL string) { - router.GET("/", func(c *gin.Context) { - getIndexHtml(c) - }) - - router.GET("/exercices/*_", func(c *gin.Context) { - getIndexHtml(c) - }) - router.GET("/themes/*_", func(c *gin.Context) { - getIndexHtml(c) - }) - - router.GET("/css/*_", func(c *gin.Context) { - serveFile(c, strings.TrimPrefix(c.Request.URL.Path, baseURL)) - }) - router.GET("/fonts/*_", func(c *gin.Context) { - serveFile(c, strings.TrimPrefix(c.Request.URL.Path, baseURL)) - }) - router.GET("/img/*_", func(c *gin.Context) { - serveFile(c, strings.TrimPrefix(c.Request.URL.Path, baseURL)) - }) - router.GET("/js/*_", func(c *gin.Context) { - serveFile(c, strings.TrimPrefix(c.Request.URL.Path, baseURL)) - }) - router.GET("/views/*_", func(c *gin.Context) { - serveFile(c, strings.TrimPrefix(c.Request.URL.Path, baseURL)) - }) + router.GET("/", serveOrReverse("", baseURL)) + router.GET("/exercices", serveOrReverse("/", baseURL)) + router.GET("/exercices/*_", serveOrReverse("/", baseURL)) + router.GET("/themes", serveOrReverse("/", baseURL)) + router.GET("/themes/*_", serveOrReverse("/", baseURL)) + router.GET("/_app/*_", serveOrReverse("", baseURL)) } diff --git a/qa/static/css/bootstrap.min.css b/qa/static/css/bootstrap.min.css deleted file mode 120000 index 8dd0a066..00000000 --- a/qa/static/css/bootstrap.min.css +++ /dev/null @@ -1 +0,0 @@ -../../../admin/static/css/bootstrap.min.css \ No newline at end of file diff --git a/qa/static/css/fic.css b/qa/static/css/fic.css deleted file mode 100644 index fc12b00d..00000000 --- a/qa/static/css/fic.css +++ /dev/null @@ -1,387 +0,0 @@ -@font-face { - font-family: "Linux Biolinum"; - src: url('../fonts/LinBiolinum_R.woff') format('woff'); -} -@font-face { - font-family: "Linux Biolinum"; - src: url('../fonts/LinBiolinum_RB.woff') format('woff'); - font-weight: bold; -} -@font-face { - font-family: "Linux Biolinum"; - src: url('../fonts/LinBiolinum_RI.woff') format('woff'); - font-style: italic; -} -@font-face { - font-family: 'FantasqueSansMonoRegular'; - src: url('../fonts/FantasqueSansMono-Regular.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -b, strong { - font-weight: bold; -} - -[ng-cloak] { - display:none !important; -} - -.popover.bs-popover-left .arrow::after { - border-left-color: #7A8288; -} - -body { - overflow-y: scroll; -} - -.bg-public { - background-image: url('../img/logo-epita-bw.png'); - background-repeat: no-repeat; - background-size: contain; - height: 100vh; -} - -.bg-public .carousel h3 { - font-size: 1.5rem; - line-height: 1.1rem; -} - -.flag { - font-family: 'FantasqueSansMonoRegular', monospace; -} - -.card-img-top { - background-position: center; - background-repeat: no-repeat; - background-size: cover; -} -.theme-card { - height: 10rem; -} - -.beautiful { - font-family: "Linux Biolinum",Helvetica,Arial,sans-serif; -} -.beautiful ol { - font-size: 133%; -} -.beautiful ol ol { - font-size: 90%; -} - -.text-bold { - font-weight: bolder; -} -.text-indent p { - text-indent: 1em; -} - -.navbar { - margin-bottom: 0; -} -.niceborder { - border-bottom: 5px #4eaee6 solid; -} -.navbar img { - margin: 3px auto; - height: 100px; -} -.navbar .clock { - font-size: 70px; -} -.clock:not(.expired):not(.wait) .point, .clock.expired { - transition: color text-shadow 1s; - position: relative; - animation: clockanim 1s ease infinite; - -moz-animation: clockanim 1s ease infinite; - -webkit-animation: clockanim 1s ease infinite; -} -.clock.wait .point { - transition: color text-shadow 1s; - position: relative; - animation: clockwait 1s ease infinite; - -moz-animation: clockwait 1s ease infinite; - -webkit-animation: clockwait 1s ease infinite; -} -.end { - color: #e64143; -} -.point { - text-shadow: 0 0 20px #4eaee6; -} -.end .point { - text-shadow: 0 0 20px #e64143; -} -@-webkit-keyframes clockanim { - 0% { opacity: 1.0; } - 50% { opacity: 0; } - 100% { opacity: 1.0; }; -} -@-moz-keyframes clockanim { - 0% { opacity: 1.0; } - 50% { opacity: 0; } - 100% { opacity: 1.0; }; -} -keyframes clockanim { - 0% { opacity: 1.0; } - 50% { opacity: 0; } - 100% { opacity: 1.0; }; -} -@-webkit-keyframes clockwait { - 0% { text-shadow: 0 0 20px #A6D6F2; } - 50% { text-shadow: 0 0 2px #A6D6F2; } - 100% { text-shadow: 0 0 20px #A6D6F2; } -} -@-moz-keyframes clockwait { - 0% { text-shadow: 0 0 20px #A6D6F2; } - 50% { text-shadow: 0 0 2px #A6D6F2; } - 100% { text-shadow: 0 0 20px #A6D6F2; } -} -keyframes clockwait { - 0% { text-shadow: 0 0 20px #A6D6F2; } - 50% { text-shadow: 0 0 2px #A6D6F2; } - 100% { text-shadow: 0 0 20px #A6D6F2; } -} - -samp.cksum { - overflow-x: hidden; - text-overflow: ellipsis; - max-width: 16vw; - display: inline-block; - vertical-align: middle; - word-wrap: normal; -} - -h1 small.authors { - float: right; - font-style: italic; - font-size: 42%; -} -.lead small.authors { - color: #7a8288; - font-style: italic; -} - -a.badge:hover { - text-decoration: none; -} -.teamname { - -webkit-filter: invert(100%); - filter: invert(100%); -} -a:hover .teamname { - text-shadow: 0px 0px 10px #888888; -} - -.authors a { - color: #3A3F44; -} - -.heading { - font-style: italic; - margin-top: -7px; - text-align: right; -} - -#eventsList { - overflow:hidden; - max-height: 90vh; -} - -.swap-animation .alert { - margin-bottom: 0px; -} -.swap-animation { - margin-bottom: 0.5rem; - max-height: 30vh; - transition: max-height 1.0s linear,opacity 1.0s linear,transform 0.5s linear; -} -.swap-animation.ng-enter { - transform: translateY(-25vh); - max-height: 0vh; -} -.swap-animation.ng-enter-active { - opacity: 1; - transform: translateY(0px); - max-height: 30vh; -} -.swap-animation.ng-leave { - opacity: 1; - max-height: 30vh; - transform: translateY(0px); -} -.swap-animation.ng-leave-active { - opacity: 0; - transform: translateX(120vw); - max-height: 0vh; -} - -.carousel-indicators { - bottom: -10px; -} -.carousel-caption { - padding: 0; - position: static; -} -.carousel .table { - margin-bottom: 0; -} -.carousel .table-sm td { - padding: 2px; -} - -.table th.frotated { - border: 0; -} -.table th.rotated { - height: 100px; - width: 40px; - min-width: 40px; - max-width: 40px; - position: relative; - vertical-align: bottom; - padding: 0; - font-size: 12px; - line-height: 0.9; - border: 0; -} - -th.rotated > div { - position: relative; - top: 0px; - left: -50px; - height: 100%; - transform: skew(45deg,0deg); - overflow: hidden; - border: 1px solid #000; -} -th.rotated div span { - transform: skew(-45deg,0deg) rotate(45deg); - position: absolute; - bottom: 40px; - left: -35px; - display: inline-block; - width: 110px; - text-align: left; - text-overflow: ellipsis; -} - -ul.list-inline li { - display: inline; -} -ul.list-inline li:not(:last-child)::after { - content: " ● " -} - -.breadcrumb-item + .breadcrumb-item::before { - content: ">" -} - -.excard { - transition: transform 250ms; -} -.excard:hover { - transform: scale(1.07); -} - -#tagsMenu + .dropdown-menu div { - overflow-y: auto; - max-height: calc(66vh - 100px); -} - -blockquote { - border-left: solid 2px; - margin-left: 1em; - padding-left: 1em; -} - -.jumbotron img { - margin-left: -1em; - padding-left: 2em; - padding-right: 2em; -} -img { - max-width: 100%; -} - -#eventsList .card { - border-left-color: rgba(0,0,0,.125) !important; - border-right-color: rgba(0,0,0,.125) !important; - border-top-color: rgba(0,0,0,.125) !important; -} - -.bg-public .card-body { - padding:1rem; - padding-bottom:0; -} - -#themesSummary .card-body { - padding:0; -} -#themesSummary h3 { - background: rgba(64,64,64,0.66); - border-radius: 2px; - padding: 0.5rem; - margin-left: 0.5rem; - margin-right: 0.5rem; - margin-top: -40px; -} -#themesSummary p { - font-size: 90%; - margin: 0.2rem; - text-indent: 0.6em; -} - -.card-sm .card-header, .card-sm .card-footer { - padding: 0.2rem 0.75rem; -} -.card-sm .card-body { - padding: 0.4rem 0.75rem; -} -.card-sm .card-body.text-indent p { - text-indent: 0.4rem; -} - -.carousel-item, .carousel-caption { - height: inherit; -} - -.page-header { - background-size: cover; - background-position: center; - margin-bottom: -15rem; -} -.page-header h1 { - text-shadow: 0 0 15px rgba(255,255,255,0.95), 0 0 5px rgb(255,255,255) -} -.page-header h1, .page-header h1 a { - color: black; -} -.page-header h1 a:hover { - text-decoration: none; -} -.page-header h2 { - font-size: 100%; - text-shadow: 1px 1px 1px rgba(0,0,0,0.9) -} -.page-header h2, .page-header h2 a { - color: #4eaee6; -} -.page-header h1 { - padding-top: 4rem; - text-align: center; -} -.page-header h2 { - padding-bottom: 14rem; - text-align: center; -} - -.page-header .headerfade { - background: linear-gradient(transparent 0%, rgb(233,236,239) 100%); - height: 3rem; -} - -a.list-group-item:hover { - text-decoration: none; -} diff --git a/qa/static/css/glyphicon.css b/qa/static/css/glyphicon.css deleted file mode 120000 index 14cd8c56..00000000 --- a/qa/static/css/glyphicon.css +++ /dev/null @@ -1 +0,0 @@ -../../../admin/static/css/glyphicon.css \ No newline at end of file diff --git a/qa/static/fonts b/qa/static/fonts deleted file mode 120000 index 0ef2f8d8..00000000 --- a/qa/static/fonts +++ /dev/null @@ -1 +0,0 @@ -../../admin/static/fonts/ \ No newline at end of file diff --git a/qa/static/img/fic.png b/qa/static/img/fic.png deleted file mode 120000 index 838a2cc9..00000000 --- a/qa/static/img/fic.png +++ /dev/null @@ -1 +0,0 @@ -../../../frontend/ui/static/img/fic.png \ No newline at end of file diff --git a/qa/static/index.html b/qa/static/index.html deleted file mode 100644 index e86d9086..00000000 --- a/qa/static/index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Challenge Forensic - QA - - - - - - - - -
-
-
- -
- -
- -
- - - - - - - - - - - diff --git a/qa/static/js/angular-resource.min.js b/qa/static/js/angular-resource.min.js deleted file mode 100644 index 8b924c37..00000000 --- a/qa/static/js/angular-resource.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - AngularJS v1.7.9 - (c) 2010-2018 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(T,a){'use strict';function M(m,f){f=f||{};a.forEach(f,function(a,d){delete f[d]});for(var d in m)!m.hasOwnProperty(d)||"$"===d.charAt(0)&&"$"===d.charAt(1)||(f[d]=m[d]);return f}var B=a.$$minErr("$resource"),H=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;a.module("ngResource",["ng"]).info({angularVersion:"1.7.9"}).provider("$resource",function(){var m=/^https?:\/\/\[[^\]]*][^/]*/,f=this;this.defaults={stripTrailingSlashes:!0,cancellable:!1,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET", -isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}};this.$get=["$http","$log","$q","$timeout",function(d,F,G,N){function C(a,d){this.template=a;this.defaults=n({},f.defaults,d);this.urlParams={}}var O=a.noop,r=a.forEach,n=a.extend,R=a.copy,P=a.isArray,D=a.isDefined,x=a.isFunction,I=a.isNumber,y=a.$$encodeUriQuery,S=a.$$encodeUriSegment;C.prototype={setUrlParams:function(a,d,f){var g=this,c=f||g.template,s,h,n="",b=g.urlParams=Object.create(null);r(c.split(/\W/),function(a){if("hasOwnProperty"=== -a)throw B("badname");!/^\d+$/.test(a)&&a&&(new RegExp("(^|[^\\\\]):"+a+"(\\W|$)")).test(c)&&(b[a]={isQueryParamValue:(new RegExp("\\?.*=:"+a+"(?:\\W|$)")).test(c)})});c=c.replace(/\\:/g,":");c=c.replace(m,function(b){n=b;return""});d=d||{};r(g.urlParams,function(b,a){s=d.hasOwnProperty(a)?d[a]:g.defaults[a];D(s)&&null!==s?(h=b.isQueryParamValue?y(s,!0):S(s),c=c.replace(new RegExp(":"+a+"(\\W|$)","g"),function(b,a){return h+a})):c=c.replace(new RegExp("(/?):"+a+"(\\W|$)","g"),function(b,a,e){return"/"=== -e.charAt(0)?e:a+e})});g.defaults.stripTrailingSlashes&&(c=c.replace(/\/+$/,"")||"/");c=c.replace(/\/\.(?=\w+($|\?))/,".");a.url=n+c.replace(/\/(\\|%5C)\./,"/.");r(d,function(b,c){g.urlParams[c]||(a.params=a.params||{},a.params[c]=b)})}};return function(m,y,z,g){function c(b,c){var d={};c=n({},y,c);r(c,function(c,f){x(c)&&(c=c(b));var e;if(c&&c.charAt&&"@"===c.charAt(0)){e=b;var k=c.substr(1);if(null==k||""===k||"hasOwnProperty"===k||!H.test("."+k))throw B("badmember",k);for(var k=k.split("."),h=0, -n=k.length;h -
-    - - just now - -
-
-
- - -
- ` - }); - -angular.module("FICApp") - .factory("Version", function($resource) { - return $resource("api/version") - }) - .factory("Todo", function($resource) { - return $resource("api/qa_work.json") - }) - .factory("TodoWorked", function($resource) { - return $resource("api/qa_mywork.json") - }) - .factory("MyExercices", function($resource) { - return $resource("api/qa_myexercices.json") - }) - .factory("ExercicesTested", function($resource) { - return $resource("api/qa_exercices.json") - }) - .factory("Team", function($resource) { - return $resource("api/teams/:teamId", { teamId: '@id' }, { - 'update': {method: 'PUT'}, - }) - }) - .factory("Teams", function($resource) { - return $resource("api/teams.json") - }) - .factory("Theme", function($resource) { - return $resource("api/themes/:themeId", { themeId: '@id' }, { - update: {method: 'PUT'} - }); - }) - .factory("Themes", function($resource) { - return $resource("api/themes.json", null, { - 'get': {method: 'GET'}, - }) - }) - .factory("ThemedExercice", function($resource) { - return $resource("api/themes/:themeId/exercices/:exerciceId", { themeId: '@id', exerciceId: '@idExercice' }, { - update: {method: 'PUT'} - }) - }) - .factory("Exercice", function($resource) { - return $resource("api/exercices/:exerciceId", { exerciceId: '@id' }, { - update: {method: 'PUT'}, - patch: {method: 'PATCH'} - }) - }) - .factory("ExerciceQA", function($resource) { - return $resource("api/qa/:exerciceId/:qaId", { exerciceId: '@idExercice', qaId: '@id' }, { - update: {method: 'PUT'}, - patch: {method: 'PATCH'} - }) - }); - -angular.module("FICApp") - .filter("toColor", function() { - return function(num) { - num >>>= 0; - var b = num & 0xFF, - g = (num & 0xFF00) >>> 8, - r = (num & 0xFF0000) >>> 16, - a = ( (num & 0xFF000000) >>> 24 ) / 255 ; - return "#" + r.toString(16) + g.toString(16) + b.toString(16); - } - }) - .filter("cksum", function() { - return function(input) { - if (input == undefined) - return input; - var raw = atob(input).toString(16); - var hex = ''; - for (var i = 0; i < raw.length; i++ ) { - var _hex = raw.charCodeAt(i).toString(16) - hex += (_hex.length == 2 ? _hex : '0' + _hex); - } - return hex - } - }) - - .directive('color', function() { - return { - require: 'ngModel', - link: function(scope, ele, attr, ctrl){ - ctrl.$formatters.unshift(function(num){ - num >>>= 0; - var b = num & 0xFF, - g = (num & 0xFF00) >>> 8, - r = (num & 0xFF0000) >>> 16, - a = ( (num & 0xFF000000) >>> 24 ) / 255 ; - return "#" + r.toString(16) + g.toString(16) + b.toString(16); - }); - ctrl.$parsers.unshift(function(viewValue){ - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(viewValue); - return result ? ( - parseInt(result[1], 16) * 256 * 256 + - parseInt(result[2], 16) * 256 + - parseInt(result[3], 16) - - ) : 0; - }); - } - }; - }) - - .directive('integer', function() { - return { - require: 'ngModel', - link: function(scope, ele, attr, ctrl){ - ctrl.$parsers.unshift(function(viewValue){ - return parseInt(viewValue, 10); - }); - } - }; - }) - - .directive('float', function() { - return { - require: 'ngModel', - link: function(scope, ele, attr, ctrl){ - ctrl.$parsers.unshift(function(viewValue){ - return parseFloat(viewValue, 10); - }); - } - }; - }) - - .run(function($rootScope, $http, $interval) { - $rootScope.toasts = []; - $rootScope.addToast = function(kind, title, msg, yesFunc, noFunc, tmout) { - $rootScope.toasts.unshift({ - variant: kind, - title: title, - msg: msg, - timeout: tmout, - yesFunc: yesFunc, - noFunc: noFunc, - }); - } - }) - - .controller("VersionController", function($scope, Version) { - $scope.v = Version.get(); - }) - - .controller("ToDoController", function($scope, Todo, TodoWorked, ExercicesTested, $location) { - $scope.todos = Todo.query(); - $scope.exo_done = ExercicesTested.get(); - $scope.tododone = {} - $scope.work = TodoWorked.query(function(tw) { - tw.forEach(function(t) { - $scope.tododone[t.id_exercice] = t - }) - }); - - $scope.show = function(id) { - $location.url("/exercices/" + id); - }; - }) - - .controller("MyExercicesController", function($scope, MyExercices, $location) { - $scope.my_exercices = MyExercices.query(); - - $scope.show = function(id) { - $location.url("/exercices/" + id); - }; - }) - - .controller("ThemesListController", function($scope, Theme, $location, $rootScope, $http) { - $scope.themes = Theme.query(); - $scope.fields = ["name", "authors", "headline"]; - - $scope.validateSearch = function(keyEvent) { - if (keyEvent.which === 13) { - var myTheme = null; - $scope.themes.forEach(function(theme) { - if (String(theme.name.toLowerCase()).indexOf($scope.query.toLowerCase()) >= 0) { - if (myTheme === null) - myTheme = theme; - else - myTheme = false; - } - }); - if (myTheme) - $location.url("themes/" + myTheme.id); - } - }; - - $scope.show = function(id) { - $location.url("/themes/" + id); - }; - }) - .controller("ThemeController", function($scope, Theme, $routeParams, $location, $rootScope, $http) { - $scope.theme = Theme.get({ themeId: $routeParams.themeId }); - $scope.fields = ["name", "urlid", "authors", "headline", "intro", "image"]; - }) - - .controller("AllExercicesListController", function($scope, Exercice, Theme, $routeParams, $location, $rootScope, $http, $filter) { - $http({ - url: "api/themes.json", - method: "GET" - }).then(function(response) { - $scope.themes = response.data - }); - - $scope.exercices = Exercice.query(); - $scope.exercice = {}; // Array used to save fields to updates in selected exercices - $scope.fields = ["title", "headline"]; - - $scope.validateSearch = function(keyEvent) { - if (keyEvent.which === 13) { - var myExercice = null; - $scope.exercices.forEach(function(exercice) { - if (String(exercice.title.toLowerCase()).indexOf($scope.query.toLowerCase()) >= 0) { - if (myExercice === null) - myExercice = exercice; - else - myExercice = false; - } - }); - if (myExercice) - $location.url("exercices/" + myExercice.id); - } - }; - - $scope.show = function(id) { - $location.url("/exercices/" + id); - }; - }) - .controller("ExercicesListController", function($scope, ThemedExercice, $location, $rootScope, $http) { - $scope.exercices = ThemedExercice.query({ themeId: $scope.theme.id }); - $scope.fields = ["title", "headline"]; - - $scope.show = function(id) { - $location.url("/themes/" + $scope.theme.id + "/exercices/" + id); - }; - }) - - .controller("MyTodoExerciceController", function($scope, Exercice, ExerciceQA, Theme) { - $scope.mytheme = null - $scope.myexercice = Exercice.get({ exerciceId: $scope.todo.id_exercice }, function(e) { - $scope.mytheme = Theme.get({ themeId: e.id_theme }) - }); - }) - - .controller("ExerciceController", function($scope, $rootScope, Exercice, ThemedExercice, $routeParams, $location, $http) { - if ($routeParams.themeId && $routeParams.exerciceId == "new") { - $scope.exercice = new ThemedExercice(); - } else { - $scope.exercice = Exercice.get({ exerciceId: $routeParams.exerciceId }); - } - $http({ - url: "api/themes.json", - method: "GET" - }).then(function(response) { - $scope.themes = response.data - var last_exercice = null; - angular.forEach($scope.themes[$scope.exercice.id_theme].exercices, function(exercice, k) { - if (last_exercice != null) { - $scope.themes[$scope.exercice.id_theme].exercices[last_exercice].next = k; - exercice.previous = last_exercice; - } - last_exercice = k; - exercice.id = k; - }); - }); - $scope.exercices = Exercice.query(); - }) - - .controller("ExerciceQAController", function($scope, $rootScope, ExerciceQA, $routeParams, $location, $http) { - if ($routeParams.exerciceId) { - $scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId }); - } else { - $scope.queries = ExerciceQA.query({ exerciceId: $scope.todo.id_exercice }); - } - $scope.queriesNSolved = "N/A" - $scope.queriesNClosed = "N/A" - $scope.queries.$promise.then(function (queries) { - var nbResolved = 0; - var nbClosed = 0; - queries.forEach(function(q) { - if (q.solved) { - nbResolved++; - } - if (q.closed) { - nbClosed++; - } - }) - $scope.queriesNSolved = queries.length - nbResolved - $scope.queriesNClosed = queries.length - nbClosed - }) - $scope.fields = ["state", "subject", "user", "creation"]; - $scope.namedFields = { - "state": "État", - "subject": "Sujet", - "content": "Description", - }; - $scope.states = { - "ok": "OK", - "orthograph": "Orthographe et grammaire", - "issue-statement": "Pas compris", - "issue-flag": "Problème de flag", - "issue-mcq": "Problème de QCM/QCU", - "issue-hint": "Problème d'indice", - "issue-file": "Problème de fichier", - "issue": "Problème autre", - "suggest": "Suggestion", - "too-hard": "Trop dur", - "too-easy": "Trop facile", - }; - - $scope.newQuery = new ExerciceQA(); - - $scope.query_comments = null - $scope.query_selected = null - $scope.showComments = function(qid) { - if ($scope.query_selected == qid) { - $scope.query_selected = null - $scope.queries_comments = null - } else { - $scope.query_selected = qid - $http({ - url: "api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments" - }).then(function(response) { - $scope.queries_comments = response.data - }) - } - } - - $scope.newComment = {content: ""} - $scope.addComment = function() { - $http({ - url: "api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments", - method: "POST", - data: $scope.newComment, - }).then(function(response) { - $scope.newComment = {content: ""} - $http({ - url: "api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments" - }).then(function(response) { - $scope.queries_comments = response.data - }) - }, function(response) { - $scope.addToast('danger', 'An error occurs when trying to respond to QA entry:', response.data.errmsg); - }) - } - - $scope.thumbUp = function(qid) { - $http({ - url: "api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[qid].id + "/comments", - method: "POST", - data: { "content": "+1" }, - }).then(function(response) { - $http({ - url: "api/qa/" + $routeParams.exerciceId + "/" + $scope.queries[$scope.query_selected].id + "/comments" - }).then(function(response) { - $scope.queries_comments = response.data - }) - }, function(response) { - $scope.addToast('danger', 'An error occurs when trying to respond to QA entry:', response.data.errmsg); - }) - } - - $scope.updateQA = function(qid) { - $scope.newQuery = $scope.queries[$scope.query_selected] - } - - $scope.deleteQA = function(qid) { - var myq = $scope.queries[$scope.query_selected] - myq.$delete( - { exerciceId: $routeParams.exerciceId, qaId: qid }, - function() { - $scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId }); - $scope.query_selected = null - }, function(response) { - $scope.addToast('danger', 'An error occurs when trying to delete QA query:', response.data.errmsg); - } - ) - } - - $scope.solveQA = function(qid) { - var myq = $scope.queries[$scope.query_selected] - myq.solved = (new Date()).toISOString() - myq.$update({ exerciceId: $routeParams.exerciceId, qaId: qid }) - } - - $scope.closeQA = function(qid) { - var myq = $scope.queries[$scope.query_selected] - myq.closed = (new Date()).toISOString() - myq.$update({ exerciceId: $routeParams.exerciceId, qaId: qid }) - } - - $scope.saveQuery = function() { - if (this.newQuery.id) { - this.newQuery.$update({ exerciceId: $routeParams.exerciceId, qaId: this.newQuery.id }); - } else { - this.newQuery.$save({ exerciceId: $routeParams.exerciceId }, function() { - //$scope.saveComment(); - $scope.addToast('success', 'QA query created!'); - $scope.queries = ExerciceQA.query({ exerciceId: $routeParams.exerciceId }); - $scope.newQuery = new ExerciceQA(); - }, function(response) { - $scope.addToast('danger', 'An error occurs when trying to create QA query:', response.data.errmsg); - }); - } - } - }); diff --git a/qa/static/views/exercice-list.html b/qa/static/views/exercice-list.html deleted file mode 100644 index dc3855f5..00000000 --- a/qa/static/views/exercice-list.html +++ /dev/null @@ -1,27 +0,0 @@ -

- Défis -

- -
-

- - - - - - - - - - - - - -
- {{ field }} - - Scénario -
- {{ themes[exercice.id_theme].name }} -
-
diff --git a/qa/static/views/exercice.html b/qa/static/views/exercice.html deleted file mode 100644 index 6cc669e2..00000000 --- a/qa/static/views/exercice.html +++ /dev/null @@ -1,110 +0,0 @@ -

- {{exercice.title}} - {{themes[exercice.id_theme].name}} -
- - -
- Site du challenge -

- -
-
-
-
- -
-
-
- Qu'avez-vous pensé de ce défi ? -
-
-
- -
- - - -
-
- -
-
- - - - - - - - - - - - - - - - - - - -
- {{ field }} -
- -
Aucun requête enregistrée
- -
-
-

{{ queries[query_selected].subject }}

-
-
-
-
-
Qui ?
-
{{ queries[query_selected].user }} (team #{{ queries[query_selected].id_team}})
- -
État
-
{{ queries[query_selected].state }}
- -
Date de création
-
{{ queries[query_selected].creation }}
- -
Date de résolution
-
{{ queries[query_selected].solved }}
- -
Date de clôture
-
{{ queries[query_selected].closed }}
-
-
- - - -
-
- - - - -
- Le {{ comment.date }}, {{ comment.user }} a écrit : {{ comment.content }} -
-
- Répondre : - - - -
-
-
diff --git a/qa/static/views/home.html b/qa/static/views/home.html deleted file mode 100644 index 6cf7271c..00000000 --- a/qa/static/views/home.html +++ /dev/null @@ -1,57 +0,0 @@ -
-
-
-

Challenges à valider

- - - - - - - - - - - - - - - - - -
AvancementScénarioDéfi
- À tester - - À commenter - - Commenté mais pas testé - - {{ mytheme.name }} - - {{ myexercice.title }} -
-
-
-

Vos challenges

- - - - - - - - - - - - - -
DéfiRequêtes
- {{ mytheme.name }} – - {{ myexercice.title }} - - {{ queriesNSolved }} / {{ queriesNClosed }} -
-
-
-
diff --git a/qa/static/views/theme-list.html b/qa/static/views/theme-list.html deleted file mode 100644 index daf7ff81..00000000 --- a/qa/static/views/theme-list.html +++ /dev/null @@ -1,19 +0,0 @@ -

- Scénarios -

- -

- - - - - - - - - - - -
- {{ field }} -
diff --git a/qa/static/views/theme.html b/qa/static/views/theme.html deleted file mode 100644 index 88086d3b..00000000 --- a/qa/static/views/theme.html +++ /dev/null @@ -1,25 +0,0 @@ -

{{theme.name}} {{theme.authors | stripHTML}}

- -
- -
-

- Défis ({{ exercices.length }}) -

- -

- - - - - - - - - - - -
- {{ field }} -
-
diff --git a/qa/ui/.eslintrc.cjs b/qa/ui/.eslintrc.cjs new file mode 100644 index 00000000..e496918e --- /dev/null +++ b/qa/ui/.eslintrc.cjs @@ -0,0 +1,15 @@ +module.exports = { + root: true, + extends: ['eslint:recommended', 'prettier'], + plugins: ['svelte3'], + overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2019 + }, + env: { + browser: true, + es2017: true, + node: true + } +}; diff --git a/qa/ui/.gitignore b/qa/ui/.gitignore new file mode 100644 index 00000000..bbde1f50 --- /dev/null +++ b/qa/ui/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* diff --git a/qa/ui/.prettierrc b/qa/ui/.prettierrc new file mode 100644 index 00000000..ff2677ef --- /dev/null +++ b/qa/ui/.prettierrc @@ -0,0 +1,6 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100 +} diff --git a/qa/ui/README.md b/qa/ui/README.md new file mode 100644 index 00000000..82510ca0 --- /dev/null +++ b/qa/ui/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte); + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm init svelte@next + +# create a new project in my-app +npm init svelte@next my-app +``` + +> Note: the `@next` is temporary + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Before creating a production version of your app, install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. Then: + +```bash +npm run build +``` + +> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production. diff --git a/qa/ui/jsconfig.json b/qa/ui/jsconfig.json new file mode 100644 index 00000000..3757b0e2 --- /dev/null +++ b/qa/ui/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "$lib": ["src/lib"], + "$lib/*": ["src/lib/*"] + } + }, + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/qa/ui/package-lock.json b/qa/ui/package-lock.json new file mode 100644 index 00000000..ea569b60 --- /dev/null +++ b/qa/ui/package-lock.json @@ -0,0 +1,1399 @@ +{ + "name": "qa", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/highlight": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "@rollup/pluginutils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.1.tgz", + "integrity": "sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@sveltejs/adapter-auto": { + "version": "1.0.0-next.3", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-1.0.0-next.3.tgz", + "integrity": "sha512-FVNLtr0bj/slQqA0TuoylnVsGrvBYdYL+hpp2Qy5Kg3q1m8i9bJ0aifKnaGn7m01II2KUSnpnhuRbX/HwKVDcA==", + "dev": true, + "requires": { + "@sveltejs/adapter-cloudflare": "1.0.0-next.2", + "@sveltejs/adapter-netlify": "1.0.0-next.35", + "@sveltejs/adapter-vercel": "1.0.0-next.31" + } + }, + "@sveltejs/adapter-cloudflare": { + "version": "1.0.0-next.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-1.0.0-next.2.tgz", + "integrity": "sha512-4Q7ZuoMck7wwzIO7gd8gqnm7gWflztTDHU/C1DzLr8V2UprQFQwsUE/padtQhFPXkgAiXJ8AwLksey4A8qjOsA==", + "dev": true, + "requires": { + "esbuild": "^0.13.4" + } + }, + "@sveltejs/adapter-netlify": { + "version": "1.0.0-next.35", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-netlify/-/adapter-netlify-1.0.0-next.35.tgz", + "integrity": "sha512-3PC1RaRReu652ot+LC9EOjkebnZehdwvUm0zhPC8OFPJJccQwq6Y1kbHDeACIIFRTaKLIRBpuYh3idP6ffUGdw==", + "dev": true, + "requires": { + "@iarna/toml": "^2.2.5", + "esbuild": "^0.13.4" + } + }, + "@sveltejs/adapter-static": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-1.0.0-next.21.tgz", + "integrity": "sha512-B4+QoUVAaANKx+mHntG8SqF45zbj3Ct4Akg/cGauo6COyfKZRhO5OsMa+wPuT2TKJBZC4eEDK0p+p9nyQBkxKQ==", + "dev": true + }, + "@sveltejs/adapter-vercel": { + "version": "1.0.0-next.31", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-vercel/-/adapter-vercel-1.0.0-next.31.tgz", + "integrity": "sha512-W8p/U00B6ihVrDpwMkgEexfVUzaLmn4MRtXj//Gw4NDFfsrZR4P5wBidrOAIkCYBMvqCOHD+vbAvIiAMOaN23g==", + "dev": true, + "requires": { + "esbuild": "^0.13.4" + } + }, + "@sveltejs/kit": { + "version": "1.0.0-next.201", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.201.tgz", + "integrity": "sha512-WcYexOEPWgDWOk0oOteTU5QwWykdIcOFJig+akeHqwE/jVtPURLZFtTNx0ymUWXN4S+dUXf60KF6HEMv74FHpA==", + "dev": true, + "requires": { + "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30", + "cheap-watch": "^1.0.4", + "sade": "^1.7.4", + "vite": "^2.6.12" + } + }, + "@sveltejs/vite-plugin-svelte": { + "version": "1.0.0-next.31", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.31.tgz", + "integrity": "sha512-8K3DcGP1V+XBv389u32S6wt8xiun6hHd5wn28AKLSoNTIhOmJOA2RJUJzp0seTRI86Shme4lzHI2Fgq4qz1wXQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^4.1.1", + "debug": "^4.3.3", + "kleur": "^4.1.4", + "magic-string": "^0.25.7", + "require-relative": "^0.8.7", + "svelte-hmr": "^0.14.7" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "cheap-watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cheap-watch/-/cheap-watch-1.0.4.tgz", + "integrity": "sha512-QR/9FrtRL5fjfUJBhAKCdi0lSRQ3rVRRum3GF9wDKp2TJbEIMGhUEr2yU8lORzm9Isdjx7/k9S0DFDx+z5VGtw==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "esbuild": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz", + "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==", + "dev": true, + "requires": { + "esbuild-android-arm64": "0.13.15", + "esbuild-darwin-64": "0.13.15", + "esbuild-darwin-arm64": "0.13.15", + "esbuild-freebsd-64": "0.13.15", + "esbuild-freebsd-arm64": "0.13.15", + "esbuild-linux-32": "0.13.15", + "esbuild-linux-64": "0.13.15", + "esbuild-linux-arm": "0.13.15", + "esbuild-linux-arm64": "0.13.15", + "esbuild-linux-mips64le": "0.13.15", + "esbuild-linux-ppc64le": "0.13.15", + "esbuild-netbsd-64": "0.13.15", + "esbuild-openbsd-64": "0.13.15", + "esbuild-sunos-64": "0.13.15", + "esbuild-windows-32": "0.13.15", + "esbuild-windows-64": "0.13.15", + "esbuild-windows-arm64": "0.13.15" + } + }, + "esbuild-android-arm64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz", + "integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz", + "integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz", + "integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz", + "integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz", + "integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz", + "integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz", + "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz", + "integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz", + "integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz", + "integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz", + "integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz", + "integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz", + "integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz", + "integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz", + "integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz", + "integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.13.15", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz", + "integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==", + "dev": true, + "optional": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true + }, + "eslint-plugin-svelte3": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte3/-/eslint-plugin-svelte3-3.2.1.tgz", + "integrity": "sha512-YoBR9mLoKCjGghJ/gvpnFZKaMEu/VRcuxpSRS8KuozuEo7CdBH7bmBHa6FmMm0i4kJnOyx+PVsaptz96K6H/4Q==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "kleur": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", + "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "postcss": { + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.4.tgz", + "integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==", + "dev": true, + "requires": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.1" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true + }, + "prettier-plugin-svelte": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-2.5.1.tgz", + "integrity": "sha512-IhZUcqr7Bg4LY15d87t9lDr7EyC0IPehkzH5ya5igG8zYwf3UYaYDFnVW2mckREaZyLREcH9YOouesmt4f5Ozg==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.2.tgz", + "integrity": "sha512-1Bgjpq61sPjgoZzuiDSGvbI1tD91giZABgjCQBKM5aYLnzjq52GoDuWVwT/cm/MCxCMPU8gqQvkj8doQ5C8Oqw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "sade": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz", + "integrity": "sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==", + "dev": true, + "requires": { + "mri": "^1.1.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "svelte": { + "version": "3.44.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.44.2.tgz", + "integrity": "sha512-jrZhZtmH3ZMweXg1Q15onb8QlWD+a5T5Oca4C1jYvSURp2oD35h4A5TV6t6MEa93K4LlX6BkafZPdQoFjw/ylA==", + "dev": true + }, + "svelte-hmr": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.14.7.tgz", + "integrity": "sha512-pDrzgcWSoMaK6AJkBWkmgIsecW0GChxYZSZieIYfCP0v2oPyx2CYU/zm7TBIcjLVUPP714WxmViE9Thht4etog==", + "dev": true + }, + "table": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", + "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vite": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.7.1.tgz", + "integrity": "sha512-TDXXhcu5lyQ6uosK4ZWaOyB4VzOiizk0biitRzDzaEtgSUi8rVYPc4k1xgOjLSf0OuceDJmojFKXHOX9DB1WuQ==", + "dev": true, + "requires": { + "esbuild": "^0.13.12", + "fsevents": "~2.3.2", + "postcss": "^8.3.11", + "resolve": "^1.20.0", + "rollup": "^2.59.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/qa/ui/package.json b/qa/ui/package.json new file mode 100644 index 00000000..f3380e7a --- /dev/null +++ b/qa/ui/package.json @@ -0,0 +1,24 @@ +{ + "name": "qa", + "version": "0.0.1", + "scripts": { + "dev": "svelte-kit dev", + "build": "svelte-kit build", + "package": "svelte-kit package", + "preview": "svelte-kit preview", + "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", + "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." + }, + "devDependencies": { + "@sveltejs/adapter-auto": "next", + "@sveltejs/adapter-static": "^1.0.0-next.21", + "@sveltejs/kit": "next", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-svelte3": "^3.2.1", + "prettier": "^2.4.1", + "prettier-plugin-svelte": "^2.4.0", + "svelte": "^3.44.0" + }, + "type": "module" +} diff --git a/qa/ui/src/app.html b/qa/ui/src/app.html new file mode 100644 index 00000000..3f132067 --- /dev/null +++ b/qa/ui/src/app.html @@ -0,0 +1,16 @@ + + + + + + + + + + + %svelte.head% + + +
%svelte.body%
+ + diff --git a/qa/ui/src/global.d.ts b/qa/ui/src/global.d.ts new file mode 100644 index 00000000..63908c66 --- /dev/null +++ b/qa/ui/src/global.d.ts @@ -0,0 +1 @@ +/// diff --git a/qa/ui/src/routes/index.svelte b/qa/ui/src/routes/index.svelte new file mode 100644 index 00000000..5982b0ae --- /dev/null +++ b/qa/ui/src/routes/index.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit kit.svelte.dev to read the documentation

diff --git a/qa/ui/static/favicon.png b/qa/ui/static/favicon.png new file mode 100644 index 00000000..825b9e65 Binary files /dev/null and b/qa/ui/static/favicon.png differ diff --git a/qa/ui/svelte.config.js b/qa/ui/svelte.config.js new file mode 100644 index 00000000..e2b41dce --- /dev/null +++ b/qa/ui/svelte.config.js @@ -0,0 +1,18 @@ +import adapt from '@sveltejs/adapter-static'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + adapter: adapt({ + fallback: 'index.html' + }), + paths: { + // base: '{{.urlbase}}', + }, + ssr: false, + // hydrate the
element in src/app.html + target: '#svelte' + } +}; + +export default config;