aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--.gitlab-ci.yml63
-rw-r--r--Dockerfile12
-rw-r--r--Dockerfile.dev2
-rw-r--r--Dockerfile.updater21
-rw-r--r--Dockerfile.updater.dev2
-rw-r--r--LICENSE339
-rw-r--r--README.md11
-rw-r--r--assets/pgo5.pngbin17468 -> 0 bytes
-rw-r--r--assets/pgo6.pngbin112793 -> 0 bytes
-rwxr-xr-xbin/fullupdate.sh9
-rwxr-xr-xbin/sokobin18788936 -> 0 bytes
-rwxr-xr-xbin/update.sh9
-rw-r--r--docker-compose.yml9
-rw-r--r--go.mod69
-rw-r--r--go.sum696
-rw-r--r--package-lock.json9912
-rw-r--r--package.json42
-rw-r--r--pkg/api/graphql/generated/generated.go96
-rw-r--r--pkg/api/graphql/graphiql/graphiql.go17
-rw-r--r--pkg/api/graphql/graphiql/graphiql.templ33
-rw-r--r--pkg/api/graphql/resolvers/resolver.go21
-rw-r--r--pkg/app/handler/about/feedback.go8
-rw-r--r--pkg/app/handler/about/feedback.templ80
-rw-r--r--pkg/app/handler/about/feeds.go8
-rw-r--r--pkg/app/handler/about/feeds.templ38
-rw-r--r--pkg/app/handler/about/help.go8
-rw-r--r--pkg/app/handler/about/help.templ42
-rw-r--r--pkg/app/handler/about/index.go10
-rw-r--r--pkg/app/handler/about/index.templ59
-rw-r--r--pkg/app/handler/about/status.go35
-rw-r--r--pkg/app/handler/about/status.templ49
-rw-r--r--pkg/app/handler/about/utils.go33
-rw-r--r--pkg/app/handler/arches/changedVersions.templ49
-rw-r--r--pkg/app/handler/arches/index.go12
-rw-r--r--pkg/app/handler/arches/show.go89
-rw-r--r--pkg/app/handler/arches/utils.go90
-rw-r--r--pkg/app/handler/categories/feeds.go38
-rw-r--r--pkg/app/handler/categories/index.go13
-rw-r--r--pkg/app/handler/categories/index.templ51
-rw-r--r--pkg/app/handler/categories/show.go252
-rw-r--r--pkg/app/handler/categories/show.templ112
-rw-r--r--pkg/app/handler/categories/utils.go86
-rw-r--r--pkg/app/handler/feeds/changes.go11
-rw-r--r--pkg/app/handler/feeds/packages.go10
-rw-r--r--pkg/app/handler/index/index.go26
-rw-r--r--pkg/app/handler/index/index.templ113
-rw-r--r--pkg/app/handler/index/utils.go149
-rw-r--r--pkg/app/handler/maintainer/browse.go32
-rw-r--r--pkg/app/handler/maintainer/browse.templ94
-rw-r--r--pkg/app/handler/maintainer/show.go393
-rw-r--r--pkg/app/handler/maintainer/show.templ256
-rw-r--r--pkg/app/handler/maintainer/utils.go142
-rw-r--r--pkg/app/handler/packages/added.go19
-rw-r--r--pkg/app/handler/packages/changed_versions.templ76
-rw-r--r--pkg/app/handler/packages/components/bugs.templ152
-rw-r--r--pkg/app/handler/packages/components/changelog.templ121
-rw-r--r--pkg/app/handler/packages/components/outdated.templ66
-rw-r--r--pkg/app/handler/packages/components/pullrequests.templ91
-rw-r--r--pkg/app/handler/packages/components/stabilization.templ58
-rw-r--r--pkg/app/handler/packages/dependencies.templ139
-rw-r--r--pkg/app/handler/packages/json.go16
-rw-r--r--pkg/app/handler/packages/keyworded.go20
-rw-r--r--pkg/app/handler/packages/overview.templ467
-rw-r--r--pkg/app/handler/packages/qareport.templ70
-rw-r--r--pkg/app/handler/packages/resolve.go6
-rw-r--r--pkg/app/handler/packages/search.go80
-rw-r--r--pkg/app/handler/packages/search.templ61
-rw-r--r--pkg/app/handler/packages/show.go142
-rw-r--r--pkg/app/handler/packages/show.templ163
-rw-r--r--pkg/app/handler/packages/stabilized.go20
-rw-r--r--pkg/app/handler/packages/suggest.go55
-rw-r--r--pkg/app/handler/packages/updated.go20
-rw-r--r--pkg/app/handler/packages/utils.go393
-rw-r--r--pkg/app/handler/useflags/expand.templ60
-rw-r--r--pkg/app/handler/useflags/global.go46
-rw-r--r--pkg/app/handler/useflags/global.templ44
-rw-r--r--pkg/app/handler/useflags/index.go45
-rw-r--r--pkg/app/handler/useflags/local.go55
-rw-r--r--pkg/app/handler/useflags/local.templ48
-rw-r--r--pkg/app/handler/useflags/popular.go64
-rw-r--r--pkg/app/handler/useflags/popular.templ31
-rw-r--r--pkg/app/handler/useflags/search.go54
-rw-r--r--pkg/app/handler/useflags/search.templ92
-rw-r--r--pkg/app/handler/useflags/show.go139
-rw-r--r--pkg/app/handler/useflags/show.templ175
-rw-r--r--pkg/app/handler/useflags/suggest.go51
-rw-r--r--pkg/app/handler/useflags/utils.go20
-rw-r--r--pkg/app/handler/user/general.templ89
-rw-r--r--pkg/app/handler/user/maintainers.templ91
-rw-r--r--pkg/app/handler/user/packages.templ126
-rw-r--r--pkg/app/handler/user/preferences.go245
-rw-r--r--pkg/app/handler/user/preferences.templ80
-rw-r--r--pkg/app/handler/user/utils.go71
-rw-r--r--pkg/app/layout/page.templ188
-rw-r--r--pkg/app/serve.go153
-rw-r--r--pkg/app/utils/applicationdata.go6
-rw-r--r--pkg/app/utils/bugs.go21
-rw-r--r--pkg/app/utils/changedVersion.templ130
-rw-r--r--pkg/app/utils/outdated.go29
-rw-r--r--pkg/app/utils/stabilization.go86
-rw-r--r--pkg/app/utils/userdata.go17
-rw-r--r--pkg/app/utils/version.go19
-rw-r--r--pkg/config/config.go19
-rw-r--r--pkg/database/connection.go82
-rw-r--r--pkg/logger/loggers.go39
-rw-r--r--pkg/metrics/metrics.go37
-rw-r--r--pkg/models/category.go16
-rw-r--r--pkg/models/commit.go10
-rw-r--r--pkg/models/deprecated.go19
-rw-r--r--pkg/models/github.go73
-rw-r--r--pkg/models/package.go86
-rw-r--r--pkg/models/userpreferences.go217
-rw-r--r--pkg/models/version.go64
-rw-r--r--pkg/portage/bugs/bugs.go334
-rw-r--r--pkg/portage/bugs/security.go332
-rw-r--r--pkg/portage/dependencies/dependency.go205
-rw-r--r--pkg/portage/github/pullrequests.go173
-rw-r--r--pkg/portage/maintainers/update.go109
-rw-r--r--pkg/portage/pkgcheck/parse.go113
-rw-r--r--pkg/portage/projects/update.go84
-rw-r--r--pkg/portage/repology/outdated.go337
-rw-r--r--pkg/portage/repository/category.go144
-rw-r--r--pkg/portage/repository/commit.go240
-rw-r--r--pkg/portage/repository/deprecated.go154
-rw-r--r--pkg/portage/repository/mask.go200
-rw-r--r--pkg/portage/repository/package.go173
-rw-r--r--pkg/portage/repository/use.go95
-rw-r--r--pkg/portage/repository/version.go127
-rw-r--r--pkg/portage/update.go232
-rw-r--r--pkg/portage/utils/files.go7
-rw-r--r--pkg/portage/utils/git.go24
-rw-r--r--pkg/portage/utils/misc.go13
-rw-r--r--pkg/portage/utils/version.go145
-rw-r--r--pkg/selfcheck/check.go45
-rw-r--r--pkg/selfcheck/portage/category.go15
-rw-r--r--pkg/selfcheck/portage/mask.go17
-rw-r--r--pkg/selfcheck/portage/package.go17
-rw-r--r--pkg/selfcheck/portage/use.go9
-rw-r--r--pkg/selfcheck/portage/version.go4
-rw-r--r--pkg/selfcheck/serve.go19
-rw-r--r--soko.go88
-rw-r--r--web/packs/application.js2
-rw-r--r--web/packs/index.js2
-rw-r--r--web/packs/packages.js1
-rw-r--r--web/packs/src/javascript/arches.js2
-rw-r--r--web/packs/src/javascript/kkuleomi.js8
-rw-r--r--web/packs/src/javascript/packages/show.js12
-rw-r--r--web/packs/src/stylesheets/application.scss2
-rw-r--r--web/packs/src/stylesheets/misc.scss4
-rw-r--r--web/packs/src/vendor/javascripts/.keep0
-rw-r--r--web/packs/src/vendor/javascripts/d3.min.js5
-rw-r--r--web/packs/src/vendor/javascripts/jquery.typeahead.min.js10
-rw-r--r--web/packs/src/vendor/javascripts/moment.min.js7
-rw-r--r--web/packs/src/vendor/stylesheets/.keep0
-rw-r--r--web/packs/src/vendor/stylesheets/jquery.typeahead.min.css1
-rw-r--r--web/packs/useflags.js2
-rw-r--r--web/templates/about/feedback.tmpl84
-rw-r--r--web/templates/about/feeds.tmpl43
-rw-r--r--web/templates/about/help.tmpl48
-rw-r--r--web/templates/about/index.tmpl44
-rw-r--r--web/templates/about/status.tmpl47
-rw-r--r--web/templates/api/explore/graphiql.tmpl25
-rw-r--r--web/templates/arches/archesheader.tmpl31
-rw-r--r--web/templates/arches/changedVersionRows.tmpl77
-rw-r--r--web/templates/arches/changedVersions.tmpl50
-rw-r--r--web/templates/arches/index.tmpl149
-rw-r--r--web/templates/categories/browsecategoriesheader.tmpl36
-rw-r--r--web/templates/categories/categoryheader.tmpl30
-rw-r--r--web/templates/categories/index.tmpl51
-rw-r--r--web/templates/categories/packageline.tmpl6
-rw-r--r--web/templates/categories/show.tmpl69
-rw-r--r--web/templates/index/show.tmpl86
-rw-r--r--web/templates/layout/footer.tmpl49
-rw-r--r--web/templates/layout/head.tmpl14
-rw-r--r--web/templates/layout/header.tmpl6
-rw-r--r--web/templates/layout/sitetitle.tmpl37
-rw-r--r--web/templates/layout/tyriannav.tmpl45
-rw-r--r--web/templates/maintainer/browse.tmpl103
-rw-r--r--web/templates/maintainer/components/bugs.tmpl136
-rw-r--r--web/templates/maintainer/components/changelog.tmpl173
-rw-r--r--web/templates/maintainer/components/outdated.tmpl52
-rw-r--r--web/templates/maintainer/components/packages.tmpl121
-rw-r--r--web/templates/maintainer/components/pullrequests.tmpl73
-rw-r--r--web/templates/maintainer/components/security.tmpl52
-rw-r--r--web/templates/maintainer/components/stabilization.tmpl96
-rw-r--r--web/templates/maintainer/maintainerheader.tmpl68
-rw-r--r--web/templates/maintainer/maintainersbrowseheader.tmpl31
-rw-r--r--web/templates/maintainer/show.tmpl33
-rw-r--r--web/templates/packages/browsepackagesheader.tmpl34
-rw-r--r--web/templates/packages/changedVersionRow.tmpl76
-rw-r--r--web/templates/packages/changedVersions.tmpl37
-rw-r--r--web/templates/packages/changelog/changelog.tmpl175
-rw-r--r--web/templates/packages/changelogwrapper.tmpl17
-rw-r--r--web/templates/packages/components/bugs.tmpl127
-rw-r--r--web/templates/packages/components/changelog.tmpl153
-rw-r--r--web/templates/packages/components/dependencies.tmpl63
-rw-r--r--web/templates/packages/components/overview.tmpl86
-rw-r--r--web/templates/packages/components/pullrequests.tmpl75
-rw-r--r--web/templates/packages/components/qareport.tmpl82
-rw-r--r--web/templates/packages/components/reverse-dependencies.tmpl59
-rw-r--r--web/templates/packages/components/security.tmpl72
-rw-r--r--web/templates/packages/metadata.tmpl171
-rw-r--r--web/templates/packages/packageheader.tmpl72
-rw-r--r--web/templates/packages/resources.tmpl65
-rw-r--r--web/templates/packages/search.tmpl71
-rw-r--r--web/templates/packages/show.tmpl41
-rw-r--r--web/templates/packages/useflag.tmpl40
-rw-r--r--web/templates/packages/versionrows.tmpl75
-rw-r--r--web/templates/packages/versions.tmpl25
-rw-r--r--web/templates/useflags/browseuseflagsheader.tmpl33
-rw-r--r--web/templates/useflags/index.tmpl47
-rw-r--r--web/templates/useflags/list.tmpl45
-rw-r--r--web/templates/useflags/listlocal.tmpl61
-rw-r--r--web/templates/useflags/search.tmpl68
-rw-r--r--web/templates/useflags/show.tmpl67
-rw-r--r--web/templates/useflags/showexpand.tmpl65
-rw-r--r--web/templates/useflags/useflagsheader.tmpl34
-rw-r--r--web/templates/user/preferences.tmpl49
-rw-r--r--web/templates/user/preferences/arches.tmpl77
-rw-r--r--web/templates/user/preferences/general.tmpl46
-rw-r--r--web/templates/user/preferences/maintainers.tmpl44
-rw-r--r--web/templates/user/preferences/packages.tmpl319
-rw-r--r--web/templates/user/preferences/useflags.tmpl46
-rw-r--r--web/templates/user/userheader.tmpl34
-rw-r--r--webpack.config.js40
226 files changed, 9990 insertions, 17106 deletions
diff --git a/.gitignore b/.gitignore
index 163c741..a1685cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,7 @@ assets/
.idea
.bin/soko
+__debug*
+
+*_templ.go
+*_templ.txt
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 611b35c..af22518 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,6 +6,9 @@ stages:
build:
stage: build
+ image:
+ name: gcr.io/kaniko-project/executor:v1.9.1-debug
+ entrypoint: [""]
except:
- tags
variables:
@@ -13,21 +16,24 @@ build:
UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater-$CI_COMMIT_BRANCH:$CI_COMMIT_SHA
LATEST_IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:latest
LATEST_UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater-$CI_COMMIT_BRANCH:latest
- script:
+ before_script:
- echo $IMAGE_TAG
- echo $UPDATER_IMAGE_TAG
- echo $LATEST_IMAGE_TAG
- echo $LATEST_UPDATER_IMAGE_TAG
- - docker info
- - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
- - docker pull gentoo/portage:latest
- - docker pull gentoo/stage3-amd64
- - docker build --no-cache -t $IMAGE_TAG -t $LATEST_IMAGE_TAG .
- - docker build --no-cache -t $UPDATER_IMAGE_TAG -t $LATEST_UPDATER_IMAGE_TAG -f Dockerfile.updater .
- - docker push $LATEST_IMAGE_TAG
- - docker push $IMAGE_TAG
- - docker push $UPDATER_IMAGE_TAG
- - docker push $LATEST_UPDATER_IMAGE_TAG
+ script:
+ - /kaniko/executor
+ --cache=true
+ --context "${CI_PROJECT_DIR}"
+ --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
+ --destination "${IMAGE_TAG}"
+ --destination "${LATEST_IMAGE_TAG}"
+ - /kaniko/executor
+ --cache=true
+ --context "${CI_PROJECT_DIR}"
+ --dockerfile "${CI_PROJECT_DIR}/Dockerfile.updater"
+ --destination "${UPDATER_IMAGE_TAG}"
+ --destination "${LATEST_UPDATER_IMAGE_TAG}"
build-tag:
stage: build
@@ -36,32 +42,23 @@ build-tag:
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE/web:$CI_COMMIT_TAG
UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater:$CI_COMMIT_TAG
- script:
+ before_script:
- echo $IMAGE_TAG
- echo $UPDATER_IMAGE_TAG
- - docker info
- - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
- - docker pull gentoo/portage:latest
- - docker pull gentoo/stage3-amd64
- - docker build -t $IMAGE_TAG .
- - docker build -t $UPDATER_IMAGE_TAG -f Dockerfile.updater .
- - docker push $IMAGE_TAG
- - docker push $UPDATER_IMAGE_TAG
+ script:
+ - /kaniko/executor
+ --cache=true
+ --context "${CI_PROJECT_DIR}"
+ --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
+ --destination "${IMAGE_TAG}"
+ - /kaniko/executor
+ --cache=true
+ --context "${CI_PROJECT_DIR}"
+ --dockerfile "${CI_PROJECT_DIR}/Dockerfile.updater"
+ --destination "${UPDATER_IMAGE_TAG}"
go-test:
stage: go-test
- image: golang:1.14.0
+ image: golang:1.22.2
script:
- go test -v ./pkg/models/...
-
-include:
- - template: Dependency-Scanning.gitlab-ci.yml
- - template: Container-Scanning.gitlab-ci.yml
- - template: SAST.gitlab-ci.yml
- - template: DAST.gitlab-ci.yml
-
-variables:
- DS_DISABLE_DIND: "true"
- SAST_DISABLE_DIND: "true"
- DAST_WEBSITE: https://packagestest.gentoo.org
-# DAST_FULL_SCAN_ENABLED: "true"
diff --git a/Dockerfile b/Dockerfile
index 77e83ca..98d19fd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,15 +1,13 @@
-FROM golang:1.14.0 AS builder
+FROM golang:1.22.2 AS builder
+RUN go install github.com/a-h/templ/cmd/templ@v0.2.663
WORKDIR /go/src/soko
COPY . /go/src/soko
-RUN go get github.com/go-pg/pg/v9
-RUN go get github.com/mcuadros/go-version
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
+RUN templ generate && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
-FROM node:13 AS assetsbuilder
+FROM node:21 AS assetsbuilder
WORKDIR /go/src/soko
COPY . /go/src/soko
-RUN npm install && cd node_modules/@gentoo/tyrian && npm install && npm run dist && cd /go/src/soko
-RUN npx webpack
+RUN npm install && npx webpack
FROM scratch
WORKDIR /go/src/soko
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 1d8dad7..b90726f 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,4 +1,4 @@
-FROM golang:1.14.0
+FROM golang:1.22.2
RUN apt update && apt install -y ca-certificates ntp ntpdate
WORKDIR /go/src/soko
COPY . /go/src/soko
diff --git a/Dockerfile.updater b/Dockerfile.updater
index 4129dad..5255acc 100644
--- a/Dockerfile.updater
+++ b/Dockerfile.updater
@@ -1,25 +1,12 @@
-FROM golang:1.14.0 AS builder
+FROM golang:1.22.2 AS builder
+RUN go install github.com/a-h/templ/cmd/templ@v0.2.663
WORKDIR /go/src/soko
COPY . /go/src/soko
-RUN go get github.com/go-pg/pg/v9
-RUN go get github.com/mcuadros/go-version
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
+RUN templ generate && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin .
-FROM gentoo/stage3-amd64 as gentoobuilder
-# Need a portage tree to build, use last nights.
-COPY --from=gentoo/portage:latest /var/db/repos/gentoo /var/db/repos/gentoo
-# Sandbox doesn't work well in docker.
-ENV FEATURES="-userpriv -usersandbox -sandbox"
-ENV USE="-bindist"
-RUN emerge -C openssh
-RUN emerge --quiet-build dev-vcs/git
-RUN echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf
-RUN rm -rf /var/db/repos/gentoo
+FROM ghcr.io/pkgcore/pkgcheck:latest
-
-FROM scratch
-COPY --from=gentoobuilder / /
COPY --from=builder /go/src/soko/assets /go/src/soko/assets
COPY --from=builder /go/src/soko/bin /go/src/soko/bin
COPY --from=builder /go/src/soko/pkg /go/src/soko/pkg
diff --git a/Dockerfile.updater.dev b/Dockerfile.updater.dev
index c6327a3..ea4a482 100644
--- a/Dockerfile.updater.dev
+++ b/Dockerfile.updater.dev
@@ -1,4 +1,4 @@
-FROM golang:1.14.0
+FROM golang:1.22.2
RUN apt update && apt install -y ca-certificates ntp ntpdate git
WORKDIR /go/src/soko
COPY . /go/src/soko
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/README.md b/README.md
index 9dcf412..0064308 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
<p align="center">
<a href="https://gitlab.com/gentoo/soko/-/pipelines"> <img src="https://gitlab.com/gentoo/soko/badges/master/pipeline.svg"></a>
-<a href="https://blog.golang.org/go1.14" ><img src="https://img.shields.io/badge/Go-v1.14-blue"></a>
+<a href="https://blog.golang.org/go1.22" ><img src="https://img.shields.io/badge/Go-v1.22-blue"></a>
<a href="#contributing"> <img src="https://img.shields.io/badge/contributions-welcome-orange.svg"></a>
<a href="https://packagestest.gentoo.org"><img src="https://img.shields.io/badge/staging%20environment-develop-blue" /></a>
<a href="https://opensource.org/licenses/TBD"><img src="https://img.shields.io/badge/license-TBD-blue.svg"></a>
@@ -14,7 +14,7 @@
This the code that powers [packages.gentoo.org](https://packages.gentoo.org/), internally codenamed soko which is Korean for package (who would have thought!)
-## Table Of Contents
+## Table Of Contents
- [Usage](#usage)
- [Contributing](#contributing)
@@ -23,7 +23,7 @@ This the code that powers [packages.gentoo.org](https://packages.gentoo.org/), i
## Usage
-To get started quickly you can use docker-compose:
+To get started quickly you can use docker-compose:
```
$ docker-compose up
```
@@ -48,9 +48,10 @@ Some of the rewrites were complete flops, and never went public.
* Golang
* PostgreSQL backend.
* Authors:
- * [Max Magorsch](mailto:arzano@gentoo.org)
+ * [Max Magorsch (arzano)](mailto:arzano@gentoo.org)
* Contributors:
* [Alec Warner (antarus)](mailto:antarus@gentoo.org)
+ * [Arthur Zamarin (arthurzam)](mailto:arthurzam@gentoo.org)
### 2016-2019: 'kkuleomi'
* https://gitweb.gentoo.org/sites/packages.git/
@@ -108,4 +109,4 @@ Some of the rewrites were complete flops, and never went public.
* [Albert Hopkins (marduk)](mailto:marduk@gentoo.org)
* Contributors: (unknown)
-## License \ No newline at end of file
+## License
diff --git a/assets/pgo5.png b/assets/pgo5.png
deleted file mode 100644
index 933d2aa..0000000
--- a/assets/pgo5.png
+++ /dev/null
Binary files differ
diff --git a/assets/pgo6.png b/assets/pgo6.png
deleted file mode 100644
index a889239..0000000
--- a/assets/pgo6.png
+++ /dev/null
Binary files differ
diff --git a/bin/fullupdate.sh b/bin/fullupdate.sh
index a4627a3..c4d5be3 100755
--- a/bin/fullupdate.sh
+++ b/bin/fullupdate.sh
@@ -27,15 +27,8 @@ update_repository(){
update_md5cache(){
mkdir -p /var/cache/pgo-egencache
- cd /mnt/packages-tree/gentoo/ || exit 1
-
- #echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf
-
- egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo]
- location = /mnt/packages-tree/gentoo' --update
- egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo]
- location = /mnt/packages-tree/gentoo' --update-use-local-desc
+ pmaint regen --threads "${JOBS}" --use-local-desc --pkg-desc-index /mnt/packages-tree/gentoo/
}
fullupdate_database(){
diff --git a/bin/soko b/bin/soko
deleted file mode 100755
index 99ef2d6..0000000
--- a/bin/soko
+++ /dev/null
Binary files differ
diff --git a/bin/update.sh b/bin/update.sh
index 1774e34..77ac70e 100755
--- a/bin/update.sh
+++ b/bin/update.sh
@@ -27,15 +27,8 @@ update_repository(){
update_md5cache(){
mkdir -p /var/cache/pgo-egencache
- cd /mnt/packages-tree/gentoo/ || exit 1
-
- #echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf
-
- egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo]
- location = /mnt/packages-tree/gentoo' --update
- egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo]
- location = /mnt/packages-tree/gentoo' --update-use-local-desc
+ pmaint regen --threads "${JOBS}" --use-local-desc --pkg-desc-index /mnt/packages-tree/gentoo/
}
update_database(){
diff --git a/docker-compose.yml b/docker-compose.yml
index def3280..90444fe 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -69,6 +69,11 @@ services:
image: containrrr/watchtower:0.3.10
restart: always
volumes:
- - /var/run/docker.sock:/var/run/docker.sock
+ # docker has an issue, that if it mounts a socket directly, upon daemon restart,
+ # the socket is recreated and the new one isn't mounted. Mounting the whole /var/run
+ # directory is scatchy, so add another socket position for the daemon to create, and
+ # bind mount it. Add to docker daemon those args:
+ # --host=unix:///var/run/docker.sock --host=unix:///var/run/docker-watchtower/docker.sock
+ - /var/run/docker-watchtower:/var/run/docker-watchtower
- /root/.docker/config.json:/config.json
- command: --label-enable
+ command: --label-enable --host unix:///var/run/docker-watchtower/docker.sock
diff --git a/go.mod b/go.mod
index 2d2e8f1..c287d14 100644
--- a/go.mod
+++ b/go.mod
@@ -1,15 +1,66 @@
module soko
-go 1.13
+go 1.22
require (
- github.com/99designs/gqlgen v0.11.3
- github.com/go-git/go-git/v5 v5.2.0
- github.com/go-pg/pg v8.0.6+incompatible
- github.com/go-pg/pg/v9 v9.1.3
- github.com/gorilla/feeds v1.1.1
+ github.com/99designs/gqlgen v0.17.45
+ github.com/a-h/templ v0.2.663
+ github.com/go-git/go-git/v5 v5.12.0
+ github.com/go-pg/pg v8.0.7+incompatible
+ github.com/go-pg/pg/v10 v10.12.0
+ github.com/gorilla/feeds v1.1.2
github.com/jasonlvhit/gocron v0.0.1
- github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2
- github.com/prometheus/client_golang v1.8.0
- github.com/vektah/gqlparser/v2 v2.0.1
+ github.com/lmittmann/tint v1.0.4
+ github.com/prometheus/client_golang v1.19.0
+ github.com/samber/slog-multi v1.0.2
+ github.com/ulikunitz/xz v0.5.12
+ github.com/vektah/gqlparser/v2 v2.5.11
+ golang.org/x/time v0.5.0
+)
+
+require (
+ dario.cat/mergo v1.0.0 // indirect
+ github.com/Microsoft/go-winio v0.6.1 // indirect
+ github.com/ProtonMail/go-crypto v1.0.0 // indirect
+ github.com/agnivade/levenshtein v1.1.1 // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/cyphar/filepath-securejoin v0.2.4 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
+ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
+ github.com/go-git/go-billy/v5 v5.5.0 // indirect
+ github.com/go-pg/zerochecker v0.2.0 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/gorilla/websocket v1.5.1 // indirect
+ github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
+ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/kevinburke/ssh_config v1.2.0 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/pjbgf/sha1cd v0.3.0 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.52.3 // indirect
+ github.com/prometheus/procfs v0.13.0 // indirect
+ github.com/samber/lo v1.39.0 // indirect
+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
+ github.com/skeema/knownhosts v1.2.2 // indirect
+ github.com/sosodev/duration v1.2.0 // indirect
+ github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
+ github.com/vmihailenco/bufpool v0.1.11 // indirect
+ github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
+ github.com/vmihailenco/tagparser v0.1.2 // indirect
+ github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
+ github.com/xanzy/ssh-agent v0.3.3 // indirect
+ golang.org/x/crypto v0.22.0 // indirect
+ golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
+ golang.org/x/mod v0.17.0 // indirect
+ golang.org/x/net v0.24.0 // indirect
+ golang.org/x/sync v0.7.0 // indirect
+ golang.org/x/sys v0.19.0 // indirect
+ golang.org/x/tools v0.20.0 // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
+ gopkg.in/warnings.v0 v0.1.2 // indirect
+ mellium.im/sasl v0.3.1 // indirect
)
diff --git a/go.sum b/go.sum
index bbdcf19..2a35ff9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,555 +1,245 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4=
-github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
-github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
-github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
-github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
-github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
-github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
-github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
-github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik=
+github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0=
+github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
+github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
+github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
+github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
+github.com/a-h/templ v0.2.663 h1:aa0WMm27InkYHGjimcM7us6hJ6BLhg98ZbfaiDPyjHE=
+github.com/a-h/templ v0.2.663/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8=
+github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
+github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
-github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
+github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
-github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
-github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
-github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
-github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
-github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
-github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
-github.com/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA=
-github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
+github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
+github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
-github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
-github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
-github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
-github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
-github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
-github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
+github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
-github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
-github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
-github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
-github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
-github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4=
-github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA=
-github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
-github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
-github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-pg/pg v8.0.6+incompatible h1:Hi7yUJ2zwmHFq1Mar5XqhCe3NJ7j9r+BaiNmd+vqf+A=
-github.com/go-pg/pg v8.0.6+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA=
-github.com/go-pg/pg/v9 v9.0.0-beta.14/go.mod h1:T2Sr6bpTCOr2lUqOUMiXLMJqZHSUBKk1LdgSqjwhZfA=
-github.com/go-pg/pg/v9 v9.0.3/go.mod h1:Tm/Q3Vt6gdQOH6TTN1H/xLlIXc+Qrka7TZ6uREtu/eA=
-github.com/go-pg/pg/v9 v9.1.3 h1:gmE7k5ib45+NcRJBGUDPD/keJGCMqhH7TPqbd9xbdz4=
-github.com/go-pg/pg/v9 v9.1.3/go.mod h1:QM13HBLkdml4zcKOfUfGLymM6hb72aKTJLrmaH8rsFg=
-github.com/go-pg/urlstruct v0.1.0/go.mod h1:2Nag+BIny6G/KYCkdt++ZnqU/VinzimGapKfs4kwlN0=
-github.com/go-pg/urlstruct v0.2.6/go.mod h1:dxENwVISWSOX+k87hDt0ueEJadD+gZWv3tHzwfmZPu8=
-github.com/go-pg/urlstruct v0.3.0 h1:ORiTb205uT7v7lvq4VUOQ4ddJ5TjFRlVRWqWsMBgek4=
-github.com/go-pg/urlstruct v0.3.0/go.mod h1:/XKyiUOUUS3onjF+LJxbfmSywYAdl6qMfVbX33Q8rgg=
-github.com/go-pg/zerochecker v0.1.1 h1:av77Qe7Gs+1oYGGh51k0sbZ0bUaxJEdeP0r8YE64Dco=
-github.com/go-pg/zerochecker v0.1.1/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
+github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
+github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
+github.com/go-pg/pg v8.0.7+incompatible h1:ty/sXL1OZLo+47KK9N8llRcmbA9tZasqbQ/OO4ld53g=
+github.com/go-pg/pg v8.0.7+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA=
+github.com/go-pg/pg/v10 v10.12.0 h1:rBmfDDHTN7FQW0OemYmcn5UuBy6wkYWgh/Oqt1OBEB8=
+github.com/go-pg/pg/v10 v10.12.0/go.mod h1:USA08CdIasAn0F6wC1nBf5nQhMHewVQodWoH89RPXaI=
+github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU=
+github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
-github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
-github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
-github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY=
-github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA=
-github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
-github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
-github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
-github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
-github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
-github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
-github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
-github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
-github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
-github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
-github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw=
+github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
+github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
+github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
-github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
-github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU=
github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
-github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
-github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
-github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
-github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg=
-github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=
-github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
-github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
-github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
-github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8=
-github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
-github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
-github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
-github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
-github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
-github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
-github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
-github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
-github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
+github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
+github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
+github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
-github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
-github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
-github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
-github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
-github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
-github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
-github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
-github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
-github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
-github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
-github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
+github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
-github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4=
-github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
-github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
-github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
-github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/segmentio/encoding v0.1.10 h1:0b8dva47cSuNQR5ZcU3d0pfi9EnPpSK6q7y5ZGEW36Q=
-github.com/segmentio/encoding v0.1.10/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw=
-github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
-github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
-github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
-github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
-github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
-github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
+github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
+github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
+github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
+github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
+github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
+github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
+github.com/samber/slog-multi v1.0.2 h1:6BVH9uHGAsiGkbbtQgAOQJMpKgV8unMrHhhJaw+X1EQ=
+github.com/samber/slog-multi v1.0.2/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
+github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us=
+github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
-github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
-github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=
-github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
-github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
-github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
-github.com/vmihailenco/bufpool v0.1.5 h1:mEO/biwhAgiY97yPMmAdH4PvaIu63C6uGBdfSdoMo/I=
-github.com/vmihailenco/bufpool v0.1.5/go.mod h1:fL9i/PRTuS7AELqAHwSU1Zf1c70xhkhGe/cD5ud9pJk=
-github.com/vmihailenco/msgpack/v4 v4.3.5/go.mod h1:DuaveEe48abshDmz5UBKyZ+yDugvaeFk5ayfrewUOaw=
-github.com/vmihailenco/msgpack/v4 v4.3.7 h1:Aj4eMY2qXTRfWRwHKJ2n/CWKVy15pCYN327QMJ/OUVs=
-github.com/vmihailenco/msgpack/v4 v4.3.7/go.mod h1:Ii+PksJlvFT5ZRcB/4YLAInMIp6a0WOCm0L3BU0aNG4=
-github.com/vmihailenco/tagparser v0.1.0/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
-github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
-github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
-github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
-github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
-github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
-go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
-go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
+github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
+github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
+github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8=
+github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
+github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
+github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
+github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
+github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
+github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
+github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
+github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
+github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
+github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
+golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
+golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222033325-078779b8f2d8 h1:4l6HGmcZuPkox4Zl1b7SZQfYo8KIKvPe+5VG6ibuUEg=
-golang.org/x/net v0.0.0-20200222033325-078779b8f2d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
+golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88=
-golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
+golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
+golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
-golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
+golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
-gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
-gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w=
-mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ=
-sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
-sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
-sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
-sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo=
+mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
diff --git a/package-lock.json b/package-lock.json
index 50437ba..c6a313c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8416 +1,2808 @@
{
+ "name": "soko",
+ "lockfileVersion": 3,
"requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "@csstools/convert-colors": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
- "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw=="
- },
- "@csstools/sass-import-resolve": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz",
- "integrity": "sha512-pH4KCsbtBLLe7eqUrw8brcuFO8IZlN36JjdKlOublibVdAIPHCzEnpBWOVUXK5sCf+DpBi8ZtuWtjF0srybdeA=="
- },
- "@gentoo/tyrian": {
- "version": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#5b6b8e70fb7067b54fa4f2fac3966ae74fcb713c",
- "from": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git",
- "requires": {
- "autoprefixer": "^7.2.4",
- "bootstrap": "4.3.1",
- "font-awesome": "4.7.0",
- "jquery": "^3.3.1",
- "popper.js": "1.14.7"
+ "packages": {
+ "": {
+ "dependencies": {
+ "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#v2.0.2",
+ "core-js": "^3.36.0",
+ "d3": "3.5.17",
+ "jquery": "^3.6.4",
+ "jquery-typeahead": "^2.11.1",
+ "jquery-ujs": "^1.2.3",
+ "regenerator-runtime": "^0.14.1",
+ "turbolinks": "^5.2.0"
+ },
+ "devDependencies": {
+ "css-loader": "^6.10.0",
+ "mini-css-extract-plugin": "^2.8.0",
+ "resolve-url-loader": "^5.0.0",
+ "sass": "^1.71.1",
+ "sass-loader": "^14.1.1",
+ "webpack": "^5.90.3",
+ "webpack-cli": "^5.1.4"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz",
+ "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz",
+ "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==",
+ "peer": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.3",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.2",
+ "@babel/parser": "^7.23.3",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.3",
+ "@babel/types": "^7.23.3",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
},
- "dependencies": {
- "autoprefixer": {
- "version": "7.2.6",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz",
- "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==",
- "requires": {
- "browserslist": "^2.11.3",
- "caniuse-lite": "^1.0.30000805",
- "normalize-range": "^0.1.2",
- "num2fraction": "^1.2.2",
- "postcss": "^6.0.17",
- "postcss-value-parser": "^3.2.3"
- }
- },
- "browserslist": {
- "version": "2.11.3",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz",
- "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==",
- "requires": {
- "caniuse-lite": "^1.0.30000792",
- "electron-to-chromium": "^1.3.30"
- }
- },
- "popper.js": {
- "version": "1.14.7",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz",
- "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ=="
- }
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
}
},
- "@types/events": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
- "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
- "dev": true
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "@types/glob": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
- "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
- "dev": true,
- "requires": {
- "@types/events": "*",
- "@types/minimatch": "*",
- "@types/node": "*"
+ "node_modules/@babel/generator": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz",
+ "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.23.3",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@types/minimatch": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
- "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
- "dev": true
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
+ "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-validator-option": "^7.22.15",
+ "browserslist": "^4.21.9",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "@types/node": {
- "version": "13.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz",
- "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==",
- "dev": true
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "@webassemblyjs/ast": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
- "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
- "requires": {
- "@webassemblyjs/helper-module-context": "1.8.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
- "@webassemblyjs/wast-parser": "1.8.5"
- }
- },
- "@webassemblyjs/floating-point-hex-parser": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
- "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ=="
- },
- "@webassemblyjs/helper-api-error": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
- "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA=="
- },
- "@webassemblyjs/helper-buffer": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
- "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q=="
- },
- "@webassemblyjs/helper-code-frame": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
- "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
- "requires": {
- "@webassemblyjs/wast-printer": "1.8.5"
- }
- },
- "@webassemblyjs/helper-fsm": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
- "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow=="
- },
- "@webassemblyjs/helper-module-context": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
- "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "mamacro": "^0.0.3"
- }
- },
- "@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
- "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ=="
- },
- "@webassemblyjs/helper-wasm-section": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
- "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-buffer": "1.8.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
- "@webassemblyjs/wasm-gen": "1.8.5"
- }
- },
- "@webassemblyjs/ieee754": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
- "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
- "requires": {
- "@xtuc/ieee754": "^1.2.0"
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@webassemblyjs/leb128": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
- "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
- "requires": {
- "@xtuc/long": "4.2.2"
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@webassemblyjs/utf8": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
- "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw=="
- },
- "@webassemblyjs/wasm-edit": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
- "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-buffer": "1.8.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
- "@webassemblyjs/helper-wasm-section": "1.8.5",
- "@webassemblyjs/wasm-gen": "1.8.5",
- "@webassemblyjs/wasm-opt": "1.8.5",
- "@webassemblyjs/wasm-parser": "1.8.5",
- "@webassemblyjs/wast-printer": "1.8.5"
- }
- },
- "@webassemblyjs/wasm-gen": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
- "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
- "@webassemblyjs/ieee754": "1.8.5",
- "@webassemblyjs/leb128": "1.8.5",
- "@webassemblyjs/utf8": "1.8.5"
- }
- },
- "@webassemblyjs/wasm-opt": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
- "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-buffer": "1.8.5",
- "@webassemblyjs/wasm-gen": "1.8.5",
- "@webassemblyjs/wasm-parser": "1.8.5"
- }
- },
- "@webassemblyjs/wasm-parser": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
- "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-api-error": "1.8.5",
- "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
- "@webassemblyjs/ieee754": "1.8.5",
- "@webassemblyjs/leb128": "1.8.5",
- "@webassemblyjs/utf8": "1.8.5"
- }
- },
- "@webassemblyjs/wast-parser": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
- "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/floating-point-hex-parser": "1.8.5",
- "@webassemblyjs/helper-api-error": "1.8.5",
- "@webassemblyjs/helper-code-frame": "1.8.5",
- "@webassemblyjs/helper-fsm": "1.8.5",
- "@xtuc/long": "4.2.2"
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@webassemblyjs/wast-printer": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
- "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/wast-parser": "1.8.5",
- "@xtuc/long": "4.2.2"
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@xtuc/ieee754": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
- "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
},
- "@xtuc/long": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
- "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "accepts": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
- "dev": true,
- "requires": {
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "acorn": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
- "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
+ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "adjust-sourcemap-loader": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz",
- "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==",
- "requires": {
- "assert": "1.4.1",
- "camelcase": "5.0.0",
- "loader-utils": "1.2.3",
- "object-path": "0.11.4",
- "regex-parser": "2.2.10"
+ "node_modules/@babel/helpers": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
+ "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.2",
+ "@babel/types": "^7.23.0"
},
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "peer": true,
"dependencies": {
- "assert": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
- "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
- "requires": {
- "util": "0.10.3"
- }
- },
- "camelcase": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
- "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="
- },
- "inherits": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
- },
- "util": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
- "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
- "requires": {
- "inherits": "2.0.1"
- }
- }
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "ajv": {
- "version": "6.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
- "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
- "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"
+ "node_modules/@babel/parser": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz",
+ "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==",
+ "peer": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "ajv-errors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
- "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
+ "node_modules/@babel/register": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz",
+ "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==",
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "find-cache-dir": "^2.0.0",
+ "make-dir": "^2.1.0",
+ "pirates": "^4.0.5",
+ "source-map-support": "^0.5.16"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz",
+ "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.3",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.3",
+ "@babel/types": "^7.23.3",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "ajv-keywords": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
- "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ=="
+ "node_modules/@babel/types": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz",
+ "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "amdefine": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
},
- "ansi-colors": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
- "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
- "dev": true
+ "node_modules/@gentoo/tyrian": {
+ "version": "2.0.0",
+ "resolved": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#7a60004f46a8d48e9b9369ddc180f35f17e26a90",
+ "dependencies": {
+ "autoprefixer": "^10.4.14",
+ "bootstrap": "4.6.2",
+ "font-awesome": "4.7.0",
+ "jquery": "^3.6.4",
+ "popper.js": "^1.16.0"
+ }
},
- "ansi-html": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
- "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
- "dev": true
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
},
- "ansi-regex": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
},
- "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==",
- "requires": {
- "color-convert": "^1.9.0"
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
- "requires": {
- "micromatch": "^3.1.4",
- "normalize-path": "^2.1.1"
- },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
"dependencies": {
- "normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
- "requires": {
- "remove-trailing-separator": "^1.0.1"
- }
- }
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
}
},
- "aproba": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
- "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
- "are-we-there-yet": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
- "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.20",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "~1.0.2"
+ "node_modules/@types/eslint": {
+ "version": "8.44.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz",
+ "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
}
},
- "arity-n": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz",
- "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U="
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
},
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true
},
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
},
- "arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ "node_modules/@types/node": {
+ "version": "20.11.20",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
+ "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
},
- "array-find-index": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ }
},
- "array-flatten": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
- "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
"dev": true
},
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
"dev": true,
- "requires": {
- "array-uniq": "^1.0.1"
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@xtuc/long": "4.2.2"
}
},
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
"dev": true
},
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
- },
- "asn1": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
- "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
- "requires": {
- "safer-buffer": "~2.1.0"
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
}
},
- "asn1.js": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
- "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
- "requires": {
- "bn.js": "^4.0.0",
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
}
},
- "assert": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
- "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
- "requires": {
- "object-assign": "^4.1.1",
- "util": "0.10.3"
- },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "dev": true,
"dependencies": {
- "inherits": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
- },
- "util": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
- "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
- "requires": {
- "inherits": "2.0.1"
- }
- }
+ "@xtuc/long": "4.2.2"
}
},
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- },
- "assign-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
- "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "dev": true
},
- "async": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
- "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
"dev": true,
- "requires": {
- "lodash": "^4.17.14"
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
}
},
- "async-each": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
- "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
- },
- "async-foreach": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
- "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
},
- "async-limiter": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
- "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
- "dev": true
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
+ }
},
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
},
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
- },
- "autoprefixer": {
- "version": "9.7.4",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz",
- "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==",
- "requires": {
- "browserslist": "^4.8.3",
- "caniuse-lite": "^1.0.30001020",
- "chalk": "^2.4.2",
- "normalize-range": "^0.1.2",
- "num2fraction": "^1.2.2",
- "postcss": "^7.0.26",
- "postcss-value-parser": "^4.0.2"
- },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-value-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
- "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "@webassemblyjs/ast": "1.11.6",
+ "@xtuc/long": "4.2.2"
}
},
- "aws-sign2": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ "node_modules/@webpack-cli/configtest": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
},
- "aws4": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
- "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
+ "node_modules/@webpack-cli/info": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
},
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
+ "node_modules/@webpack-cli/serve": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
},
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
}
}
},
- "base64-js": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
- "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
},
- "batch": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
- "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"dev": true
},
- "bcrypt-pbkdf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
- "requires": {
- "tweetnacl": "^0.14.3"
+ "node_modules/acorn": {
+ "version": "8.11.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
+ "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
}
},
- "big.js": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
- "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
- },
- "binary-extensions": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
- "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw=="
+ "node_modules/acorn-import-assertions": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
},
- "bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "optional": true,
- "requires": {
- "file-uri-to-path": "1.0.0"
- }
- },
- "block-stream": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
- "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
- "requires": {
- "inherits": "~2.0.0"
- }
- },
- "bluebird": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
- "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
- },
- "bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
- },
- "body-parser": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
- "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "node_modules/adjust-sourcemap-loader": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz",
+ "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==",
"dev": true,
- "requires": {
- "bytes": "3.1.0",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "http-errors": "1.7.2",
- "iconv-lite": "0.4.24",
- "on-finished": "~2.3.0",
- "qs": "6.7.0",
- "raw-body": "2.4.0",
- "type-is": "~1.6.17"
- },
"dependencies": {
- "bytes": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
- "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
- "dev": true
- }
+ "loader-utils": "^2.0.0",
+ "regex-parser": "^2.2.11"
+ },
+ "engines": {
+ "node": ">=8.9"
}
},
- "bonjour": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
- "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dev": true,
- "requires": {
- "array-flatten": "^2.1.0",
- "deep-equal": "^1.0.1",
- "dns-equal": "^1.0.0",
- "dns-txt": "^2.0.2",
- "multicast-dns": "^6.0.1",
- "multicast-dns-service-types": "^1.1.0"
- }
- },
- "bootstrap": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
- "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
},
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
"dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
}
}
},
- "brorand": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
- },
- "browserify-aes": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
- "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
- "requires": {
- "buffer-xor": "^1.0.3",
- "cipher-base": "^1.0.0",
- "create-hash": "^1.1.0",
- "evp_bytestokey": "^1.0.3",
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "browserify-cipher": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
- "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
- "requires": {
- "browserify-aes": "^1.0.4",
- "browserify-des": "^1.0.0",
- "evp_bytestokey": "^1.0.0"
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
}
},
- "browserify-des": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
- "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
- "requires": {
- "cipher-base": "^1.0.1",
- "des.js": "^1.0.0",
- "inherits": "^2.0.1",
- "safe-buffer": "^5.1.2"
+ "node_modules/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==",
+ "peer": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "browserify-rsa": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
- "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
- "requires": {
- "bn.js": "^4.1.0",
- "randombytes": "^2.0.1"
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "browserify-sign": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
- "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
- "requires": {
- "bn.js": "^4.1.1",
- "browserify-rsa": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.2",
- "elliptic": "^6.0.0",
- "inherits": "^2.0.1",
- "parse-asn1": "^5.0.0"
- }
- },
- "browserify-zlib": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
- "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
- "requires": {
- "pako": "~1.0.5"
- }
- },
- "browserslist": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz",
- "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==",
- "requires": {
- "caniuse-lite": "^1.0.30001030",
- "electron-to-chromium": "^1.3.363",
- "node-releases": "^1.1.50"
- }
- },
- "buffer": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
- "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
- "requires": {
- "base64-js": "^1.0.2",
- "ieee754": "^1.1.4",
- "isarray": "^1.0.0"
- }
- },
- "buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
- },
- "buffer-indexof": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
- "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
- "dev": true
- },
- "buffer-xor": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
- "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
- },
- "builtin-status-codes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
- "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
- },
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true
- },
- "cacache": {
- "version": "12.0.3",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
- "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
- "requires": {
- "bluebird": "^3.5.5",
- "chownr": "^1.1.1",
- "figgy-pudding": "^3.5.1",
- "glob": "^7.1.4",
- "graceful-fs": "^4.1.15",
- "infer-owner": "^1.0.3",
- "lru-cache": "^5.1.1",
- "mississippi": "^3.0.0",
- "mkdirp": "^0.5.1",
- "move-concurrently": "^1.0.1",
- "promise-inflight": "^1.0.1",
- "rimraf": "^2.6.3",
- "ssri": "^6.0.1",
- "unique-filename": "^1.1.1",
- "y18n": "^4.0.0"
+ "node_modules/autoprefixer": {
+ "version": "10.4.16",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
+ "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.21.10",
+ "caniuse-lite": "^1.0.30001538",
+ "fraction.js": "^4.3.6",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- }
- },
- "caller-callsite": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
- "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
- "requires": {
- "callsites": "^2.0.0"
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
}
},
- "caller-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
- "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
- "requires": {
- "caller-callsite": "^2.0.0"
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
}
},
- "callsites": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
- "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
- },
- "camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
+ "node_modules/bootstrap": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz",
+ "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "jquery": "1.9.1 - 3",
+ "popper.js": "^1.16.1"
+ }
},
- "camelcase-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
- "requires": {
- "camelcase": "^2.0.0",
- "map-obj": "^1.0.0"
- },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
"dependencies": {
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001541",
+ "electron-to-chromium": "^1.4.535",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
- "caniuse-lite": {
- "version": "1.0.30001035",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz",
- "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ=="
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
- "caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001563",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz",
+ "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
},
- "chalk": {
+ "node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "requires": {
+ "peer": true,
+ "dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
- "dependencies": {
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
+ "engines": {
+ "node": ">=4"
}
},
- "chokidar": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
- "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
- "requires": {
- "anymatch": "^2.0.0",
- "async-each": "^1.0.1",
- "braces": "^2.3.2",
- "fsevents": "^1.2.7",
- "glob-parent": "^3.1.0",
- "inherits": "^2.0.3",
- "is-binary-path": "^1.0.0",
- "is-glob": "^4.0.0",
- "normalize-path": "^3.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.2.1",
- "upath": "^1.1.1"
- }
- },
- "chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
- },
- "chrome-trace-event": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
- "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "cipher-base": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "^0.1.0"
- }
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
}
},
- "cliui": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
- "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
- "requires": {
- "string-width": "^3.1.0",
- "strip-ansi": "^5.2.0",
- "wrap-ansi": "^5.1.0"
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0"
}
},
- "clone-deep": {
+ "node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
- "requires": {
+ "dependencies": {
"is-plain-object": "^2.0.4",
"kind-of": "^6.0.2",
"shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
- },
- "coffeescript": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz",
- "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ=="
- },
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- }
- },
- "color-convert": {
+ "node_modules/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==",
- "requires": {
+ "peer": true,
+ "dependencies": {
"color-name": "1.1.3"
}
},
- "color-name": {
+ "node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "peer": true
},
- "combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
},
- "commander": {
+ "node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
},
- "commondir": {
+ "node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
- "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs="
- },
- "component-emitter": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
- "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
- },
- "compose-function": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz",
- "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=",
- "requires": {
- "arity-n": "^1.0.4"
- }
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
},
- "compressible": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
- "dev": true,
- "requires": {
- "mime-db": ">= 1.43.0 < 2"
- }
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "peer": true
},
- "compression": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
- "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
- "dev": true,
- "requires": {
- "accepts": "~1.3.5",
- "bytes": "3.0.0",
- "compressible": "~2.0.16",
- "debug": "2.6.9",
- "on-headers": "~1.0.2",
- "safe-buffer": "5.1.2",
- "vary": "~1.1.2"
- }
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "requires": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
+ "node_modules/core-js": {
+ "version": "3.36.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz",
+ "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
}
},
- "connect-history-api-fallback": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
- "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
- "dev": true
- },
- "console-browserify": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
- "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
- },
- "console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
- },
- "constants-browserify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
- "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
- },
- "content-disposition": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "node_modules/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": {
- "safe-buffer": "5.1.2"
- }
- },
- "content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
- "dev": true
- },
- "convert-source-map": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
- "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
- "requires": {
- "safe-buffer": "~5.1.1"
- }
- },
- "cookie": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
- "dev": true
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
- "dev": true
- },
- "copy-concurrently": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
- "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
- "requires": {
- "aproba": "^1.1.1",
- "fs-write-stream-atomic": "^1.0.8",
- "iferr": "^0.1.5",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.5.4",
- "run-queue": "^1.0.0"
- }
- },
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
- },
- "core-js": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz",
- "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw=="
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "cosmiconfig": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
- "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
- "requires": {
- "import-fresh": "^2.0.0",
- "is-directory": "^0.3.1",
- "js-yaml": "^3.13.1",
- "parse-json": "^4.0.0"
- },
"dependencies": {
- "parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
- "requires": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- }
- }
- }
- },
- "create-ecdh": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
- "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
- "requires": {
- "bn.js": "^4.1.0",
- "elliptic": "^6.0.0"
- }
- },
- "create-hash": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
- "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
- "requires": {
- "cipher-base": "^1.0.1",
- "inherits": "^2.0.1",
- "md5.js": "^1.3.4",
- "ripemd160": "^2.0.1",
- "sha.js": "^2.4.0"
- }
- },
- "create-hmac": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
- "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
- "requires": {
- "cipher-base": "^1.0.3",
- "create-hash": "^1.1.0",
- "inherits": "^2.0.1",
- "ripemd160": "^2.0.0",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
- }
- },
- "cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "requires": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "crypto-browserify": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
- "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
- "requires": {
- "browserify-cipher": "^1.0.0",
- "browserify-sign": "^4.0.0",
- "create-ecdh": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.0",
- "diffie-hellman": "^5.0.0",
- "inherits": "^2.0.1",
- "pbkdf2": "^3.0.3",
- "public-encrypt": "^4.0.0",
- "randombytes": "^2.0.0",
- "randomfill": "^1.0.3"
- }
- },
- "css": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
- "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
- "requires": {
- "inherits": "^2.0.3",
- "source-map": "^0.6.1",
- "source-map-resolve": "^0.5.2",
- "urix": "^0.1.0"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
},
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "engines": {
+ "node": ">= 8"
}
},
- "css-blank-pseudo": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz",
- "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==",
- "requires": {
- "postcss": "^7.0.5"
- },
+ "node_modules/css-loader": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz",
+ "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "css-has-pseudo": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz",
- "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==",
- "requires": {
- "postcss": "^7.0.6",
- "postcss-selector-parser": "^5.0.0-rc.4"
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.4.33",
+ "postcss-modules-extract-imports": "^3.0.0",
+ "postcss-modules-local-by-default": "^4.0.4",
+ "postcss-modules-scope": "^3.1.1",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.5.4"
},
- "dependencies": {
- "cssesc": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
- "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg=="
- },
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-selector-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
- "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
- "requires": {
- "cssesc": "^2.0.0",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "css-loader": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz",
- "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==",
- "requires": {
- "camelcase": "^5.3.1",
- "cssesc": "^3.0.0",
- "icss-utils": "^4.1.1",
- "loader-utils": "^1.2.3",
- "normalize-path": "^3.0.0",
- "postcss": "^7.0.23",
- "postcss-modules-extract-imports": "^2.0.0",
- "postcss-modules-local-by-default": "^3.0.2",
- "postcss-modules-scope": "^2.1.1",
- "postcss-modules-values": "^3.0.0",
- "postcss-value-parser": "^4.0.2",
- "schema-utils": "^2.6.0"
+ "engines": {
+ "node": ">= 12.13.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-value-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
- "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
- },
- "schema-utils": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
- "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
- "requires": {
- "ajv": "^6.12.0",
- "ajv-keywords": "^3.4.1"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "css-prefers-color-scheme": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz",
- "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==",
- "requires": {
- "postcss": "^7.0.5"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
},
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ "webpack": {
+ "optional": true
}
}
},
- "cssdb": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz",
- "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ=="
- },
- "cssesc": {
+ "node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
- },
- "currently-unhandled": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
- "requires": {
- "array-find-index": "^1.0.1"
- }
- },
- "cyclist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
- "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk="
- },
- "d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "requires": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
- }
- },
- "d3": {
- "version": "3.5.6",
- "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.6.tgz",
- "integrity": "sha1-lFHGUcpzP7lnLIH7fyZVFkpzpC0="
- },
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
- },
- "decode-uri-component": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
- },
- "deep-equal": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
- "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
- "requires": {
- "is-arguments": "^1.0.4",
- "is-date-object": "^1.0.1",
- "is-regex": "^1.0.4",
- "object-is": "^1.0.1",
- "object-keys": "^1.1.1",
- "regexp.prototype.flags": "^1.2.0"
- }
- },
- "default-gateway": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
- "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
- "dev": true,
- "requires": {
- "execa": "^1.0.0",
- "ip-regex": "^2.1.0"
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "define-properties": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
- "dev": true,
- "requires": {
- "object-keys": "^1.0.12"
- }
+ "node_modules/d3": {
+ "version": "3.5.17",
+ "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
+ "integrity": "sha512-yFk/2idb8OHPKkbAL8QaOaqENNoMhIaSHZerk3oQsECwkObkCpJyjYwCe+OHiq6UEdhe1m8ZGARRRO3ljFjlKg=="
},
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "peer": true,
"dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
}
}
},
- "del": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
- "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
- "dev": true,
- "requires": {
- "@types/glob": "^7.1.1",
- "globby": "^6.1.0",
- "is-path-cwd": "^2.0.0",
- "is-path-in-cwd": "^2.0.0",
- "p-map": "^2.0.0",
- "pify": "^4.0.1",
- "rimraf": "^2.6.3"
- }
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "delegates": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.587",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.587.tgz",
+ "integrity": "sha512-RyJX0q/zOkAoefZhB9XHghGeATVP0Q3mwA253XD/zj2OeXc+JZB9pCaEv6R578JUYaWM9PRhye0kXvd/V1cQ3Q=="
},
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
- "dev": true
- },
- "des.js": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
- "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
- "requires": {
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
- }
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
- "dev": true
- },
- "detect-file": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
- "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
- },
- "detect-node": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
- "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
- "dev": true
- },
- "diffie-hellman": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
- "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
- "requires": {
- "bn.js": "^4.1.0",
- "miller-rabin": "^4.0.0",
- "randombytes": "^2.0.0"
- }
- },
- "dns-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
- "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
- "dev": true
- },
- "dns-packet": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
- "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
- "requires": {
- "ip": "^1.1.0",
- "safe-buffer": "^5.0.1"
+ "engines": {
+ "node": ">= 4"
}
},
- "dns-txt": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
- "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "node_modules/enhanced-resolve": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dev": true,
- "requires": {
- "buffer-indexof": "^1.0.0"
- }
- },
- "domain-browser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
- "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA=="
- },
- "duplexify": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
- "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
- "requires": {
- "end-of-stream": "^1.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0",
- "stream-shift": "^1.0.0"
- }
- },
- "ecc-jsbn": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
- "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
- "requires": {
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.1.0"
- }
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
- "dev": true
- },
- "electron-to-chromium": {
- "version": "1.3.376",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz",
- "integrity": "sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw=="
- },
- "elliptic": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
- "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
- "requires": {
- "bn.js": "^4.4.0",
- "brorand": "^1.0.1",
- "hash.js": "^1.0.0",
- "hmac-drbg": "^1.0.0",
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0",
- "minimalistic-crypto-utils": "^1.0.0"
- }
- },
- "emoji-regex": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
- "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
- },
- "emojis-list": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
- "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
- "dev": true
- },
- "end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "requires": {
- "once": "^1.4.0"
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
}
},
- "enhanced-resolve": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz",
- "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
- "requires": {
- "graceful-fs": "^4.1.2",
- "memory-fs": "^0.4.0",
- "tapable": "^1.0.0"
- }
- },
- "errno": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
- "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
- "requires": {
- "prr": "~1.0.1"
- }
- },
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "requires": {
- "is-arrayish": "^0.2.1"
- }
- },
- "es-abstract": {
- "version": "1.17.4",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
- "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
- "dev": true,
- "requires": {
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1",
- "is-callable": "^1.1.5",
- "is-regex": "^1.0.5",
- "object-inspect": "^1.7.0",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.0",
- "string.prototype.trimleft": "^2.1.1",
- "string.prototype.trimright": "^2.1.1"
- }
- },
- "es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "node_modules/envinfo": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
+ "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
"dev": true,
- "requires": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
- }
- },
- "es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
- "requires": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
+ "node_modules/es-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "dev": true
},
- "es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "requires": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "engines": {
+ "node": ">=6"
}
},
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
- "dev": true
- },
- "escape-string-regexp": {
+ "node_modules/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="
- },
- "eslint-scope": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
- "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
- "requires": {
- "esrecurse": "^4.1.0",
- "estraverse": "^4.1.1"
- }
- },
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- },
- "esrecurse": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
- "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
- "requires": {
- "estraverse": "^4.1.0"
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.0"
}
},
- "estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
- "dev": true
- },
- "eventemitter3": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
- "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
- "dev": true
- },
- "events": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
- "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg=="
- },
- "eventsource": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
- "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+ "node_modules/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": {
- "original": "^1.0.0"
- }
- },
- "evp_bytestokey": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
- "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
- "requires": {
- "md5.js": "^1.3.4",
- "safe-buffer": "^5.1.1"
- }
- },
- "execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
- "requires": {
- "cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
"dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "expand-tilde": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
- "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
- "requires": {
- "homedir-polyfill": "^1.0.1"
- }
- },
- "exports-loader": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.7.0.tgz",
- "integrity": "sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA==",
- "requires": {
- "loader-utils": "^1.1.0",
- "source-map": "0.5.0"
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
},
- "dependencies": {
- "source-map": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.0.tgz",
- "integrity": "sha1-D+llA6yGpa213mP05BKuSHLNvoY="
- }
+ "engines": {
+ "node": ">=8.0.0"
}
},
- "expose-loader": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-0.7.5.tgz",
- "integrity": "sha512-iPowgKUZkTPX5PznYsmifVj9Bob0w2wTHVkt/eYNPSzyebkUgIedmskf/kcfEIWpiWjg3JRjnW+a17XypySMuw=="
- },
- "express": {
- "version": "4.17.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
- "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "node_modules/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": {
- "accepts": "~1.3.7",
- "array-flatten": "1.1.1",
- "body-parser": "1.19.0",
- "content-disposition": "0.5.3",
- "content-type": "~1.0.4",
- "cookie": "0.4.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "~1.1.2",
- "fresh": "0.5.2",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.5",
- "qs": "6.7.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.1.2",
- "send": "0.17.1",
- "serve-static": "1.14.1",
- "setprototypeof": "1.1.1",
- "statuses": "~1.5.0",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
"dependencies": {
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
- "dev": true
- }
- }
- },
- "ext": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
- "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
- "requires": {
- "type": "^2.0.0"
+ "estraverse": "^5.2.0"
},
- "dependencies": {
- "type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
- "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow=="
- }
+ "engines": {
+ "node": ">=4.0"
}
},
- "extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
- },
- "extend-shallow": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
- "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "requires": {
- "assign-symbols": "^1.0.0",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
}
},
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
}
},
- "extsprintf": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
},
- "fast-deep-equal": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
- "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
+ "node_modules/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": {
+ "node_modules/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=="
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
},
- "faye-websocket": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
- "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
"dev": true,
- "requires": {
- "websocket-driver": ">=0.5.1"
+ "engines": {
+ "node": ">= 4.9.1"
}
},
- "figgy-pudding": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
- "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w=="
- },
- "file-loader": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz",
- "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==",
- "requires": {
- "loader-utils": "^1.4.0",
- "schema-utils": "^2.5.0"
- },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
"dependencies": {
- "emojis-list": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
- "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
- },
- "loader-utils": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
- "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^1.0.1"
- }
- },
- "schema-utils": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
- "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
- "requires": {
- "ajv": "^6.12.0",
- "ajv-keywords": "^3.4.1"
- }
- }
- }
- },
- "file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "optional": true
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
+ "to-regex-range": "^5.0.1"
},
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "finalhandler": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.3",
- "statuses": "~1.5.0",
- "unpipe": "~1.0.0"
- }
- },
- "find-cache-dir": {
+ "node_modules/find-cache-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
"integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
- "requires": {
+ "dependencies": {
"commondir": "^1.0.1",
"make-dir": "^2.0.0",
"pkg-dir": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "find-up": {
+ "node_modules/find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
- "requires": {
+ "dependencies": {
"locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "findup-sync": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
- "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
- "requires": {
- "detect-file": "^1.0.0",
- "is-glob": "^4.0.0",
- "micromatch": "^3.0.4",
- "resolve-dir": "^1.0.1"
- }
- },
- "flatten": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
- "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg=="
- },
- "flush-write-stream": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
- "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
- "requires": {
- "inherits": "^2.0.3",
- "readable-stream": "^2.3.6"
- }
- },
- "follow-redirects": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz",
- "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==",
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
"dev": true,
- "requires": {
- "debug": "^3.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "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
- }
+ "bin": {
+ "flat": "cli.js"
}
},
- "font-awesome": {
+ "node_modules/font-awesome": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
- "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
- },
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
- },
- "form-data": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
- "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
+ "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==",
+ "engines": {
+ "node": ">=0.10.3"
}
},
- "forwarded": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
- "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
- "dev": true
- },
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "requires": {
- "map-cache": "^0.2.2"
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
}
},
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
- "dev": true
- },
- "from2": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
- "requires": {
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0"
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "fs-write-stream-atomic": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
- "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
- "requires": {
- "graceful-fs": "^4.1.2",
- "iferr": "^0.1.5",
- "imurmurhash": "^0.1.4",
- "readable-stream": "1 || 2"
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "fsevents": {
- "version": "1.2.11",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz",
- "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==",
- "optional": true,
- "requires": {
- "bindings": "^1.5.0",
- "nan": "^2.12.1",
- "node-pre-gyp": "*"
- },
+ "node_modules/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,
"dependencies": {
- "abbrev": {
- "version": "1.1.1",
- "bundled": true,
- "optional": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true,
- "optional": true
- },
- "aproba": {
- "version": "1.2.0",
- "bundled": true,
- "optional": true
- },
- "are-we-there-yet": {
- "version": "1.1.5",
- "bundled": true,
- "optional": true,
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "brace-expansion": {
- "version": "1.1.11",
- "bundled": true,
- "optional": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "chownr": {
- "version": "1.1.3",
- "bundled": true,
- "optional": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true,
- "optional": true
- },
- "concat-map": {
- "version": "0.0.1",
- "bundled": true,
- "optional": true
- },
- "console-control-strings": {
- "version": "1.1.0",
- "bundled": true,
- "optional": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "debug": {
- "version": "3.2.6",
- "bundled": true,
- "optional": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "deep-extend": {
- "version": "0.6.0",
- "bundled": true,
- "optional": true
- },
- "delegates": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "detect-libc": {
- "version": "1.0.3",
- "bundled": true,
- "optional": true
- },
- "fs-minipass": {
- "version": "1.2.7",
- "bundled": true,
- "optional": true,
- "requires": {
- "minipass": "^2.6.0"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "gauge": {
- "version": "2.7.4",
- "bundled": true,
- "optional": true,
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
- "glob": {
- "version": "7.1.6",
- "bundled": true,
- "optional": 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"
- }
- },
- "has-unicode": {
- "version": "2.0.1",
- "bundled": true,
- "optional": true
- },
- "iconv-lite": {
- "version": "0.4.24",
- "bundled": true,
- "optional": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "ignore-walk": {
- "version": "3.0.3",
- "bundled": true,
- "optional": true,
- "requires": {
- "minimatch": "^3.0.4"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "bundled": true,
- "optional": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "bundled": true,
- "optional": true
- },
- "ini": {
- "version": "1.3.5",
- "bundled": true,
- "optional": true
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "bundled": true,
- "optional": true
- },
- "minimatch": {
- "version": "3.0.4",
- "bundled": true,
- "optional": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "bundled": true,
- "optional": true
- },
- "minipass": {
- "version": "2.9.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "safe-buffer": "^5.1.2",
- "yallist": "^3.0.0"
- }
- },
- "minizlib": {
- "version": "1.3.3",
- "bundled": true,
- "optional": true,
- "requires": {
- "minipass": "^2.9.0"
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.1.2",
- "bundled": true,
- "optional": true
- },
- "needle": {
- "version": "2.4.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "debug": "^3.2.6",
- "iconv-lite": "^0.4.4",
- "sax": "^1.2.4"
- }
- },
- "node-pre-gyp": {
- "version": "0.14.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "detect-libc": "^1.0.2",
- "mkdirp": "^0.5.1",
- "needle": "^2.2.1",
- "nopt": "^4.0.1",
- "npm-packlist": "^1.1.6",
- "npmlog": "^4.0.2",
- "rc": "^1.2.7",
- "rimraf": "^2.6.1",
- "semver": "^5.3.0",
- "tar": "^4.4.2"
- }
- },
- "nopt": {
- "version": "4.0.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "abbrev": "1",
- "osenv": "^0.1.4"
- }
- },
- "npm-bundled": {
- "version": "1.1.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "npm-normalize-package-bin": "^1.0.1"
- }
- },
- "npm-normalize-package-bin": {
- "version": "1.0.1",
- "bundled": true,
- "optional": true
- },
- "npm-packlist": {
- "version": "1.4.7",
- "bundled": true,
- "optional": true,
- "requires": {
- "ignore-walk": "^3.0.1",
- "npm-bundled": "^1.0.1"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "bundled": true,
- "optional": true
- },
- "object-assign": {
- "version": "4.1.1",
- "bundled": true,
- "optional": true
- },
- "once": {
- "version": "1.4.0",
- "bundled": true,
- "optional": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "os-homedir": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "osenv": {
- "version": "0.1.5",
- "bundled": true,
- "optional": true,
- "requires": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "bundled": true,
- "optional": true
- },
- "process-nextick-args": {
- "version": "2.0.1",
- "bundled": true,
- "optional": true
- },
- "rc": {
- "version": "1.2.8",
- "bundled": true,
- "optional": true,
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "bundled": true,
- "optional": true
- }
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "bundled": true,
- "optional": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "rimraf": {
- "version": "2.7.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "glob": "^7.1.3"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "bundled": true,
- "optional": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "bundled": true,
- "optional": true
- },
- "sax": {
- "version": "1.2.4",
- "bundled": true,
- "optional": true
- },
- "semver": {
- "version": "5.7.1",
- "bundled": true,
- "optional": true
- },
- "set-blocking": {
- "version": "2.0.0",
- "bundled": true,
- "optional": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "bundled": true,
- "optional": true
- },
- "string-width": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "bundled": true,
- "optional": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "bundled": true,
- "optional": true
- },
- "tar": {
- "version": "4.4.13",
- "bundled": true,
- "optional": true,
- "requires": {
- "chownr": "^1.1.1",
- "fs-minipass": "^1.2.5",
- "minipass": "^2.8.6",
- "minizlib": "^1.2.1",
- "mkdirp": "^0.5.0",
- "safe-buffer": "^5.1.2",
- "yallist": "^3.0.3"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "wide-align": {
- "version": "1.1.3",
- "bundled": true,
- "optional": true,
- "requires": {
- "string-width": "^1.0.2 || 2"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "bundled": true,
- "optional": true
- },
- "yallist": {
- "version": "3.1.1",
- "bundled": true,
- "optional": true
- }
- }
- },
- "fstream": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
- "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
- "requires": {
- "graceful-fs": "^4.1.2",
- "inherits": "~2.0.0",
- "mkdirp": ">=0.5 0",
- "rimraf": "2"
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
- "gauge": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- }
- }
- },
- "gaze": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
- "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
- "requires": {
- "globule": "^1.0.0"
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
}
},
- "get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
- },
- "get-stdin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
},
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "requires": {
- "pump": "^3.0.0"
- }
- },
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
- },
- "getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
- "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": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
- "requires": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
}
},
- "global-modules": {
+ "node_modules/hasown": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "requires": {
- "global-prefix": "^3.0.0"
- },
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
+ "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "dev": true,
"dependencies": {
- "global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "requires": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- }
- }
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
- "global-prefix": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
- "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
- "requires": {
- "expand-tilde": "^2.0.2",
- "homedir-polyfill": "^1.0.1",
- "ini": "^1.3.4",
- "is-windows": "^1.0.1",
- "which": "^1.2.14"
- }
- },
- "globby": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
- "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "node_modules/icss-utils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
"dev": true,
- "requires": {
- "array-union": "^1.0.1",
- "glob": "^7.0.3",
- "object-assign": "^4.0.1",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
},
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "globule": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
- "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
- "requires": {
- "glob": "~7.1.1",
- "lodash": "~4.17.12",
- "minimatch": "~3.0.2"
- }
- },
- "graceful-fs": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
- "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
- },
- "handle-thing": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
- "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==",
+ "node_modules/immutable": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
+ "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
"dev": true
},
- "har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
- },
- "har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
- "requires": {
- "ajv": "^6.5.5",
- "har-schema": "^2.0.0"
- }
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
"dev": true,
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "^2.0.0"
- },
"dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- }
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
- },
- "has-symbols": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
- "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
- "dev": true
- },
- "has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
- },
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
},
- "dependencies": {
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "hash-base": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "hash.js": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
- "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
- "requires": {
- "inherits": "^2.0.3",
- "minimalistic-assert": "^1.0.1"
- }
- },
- "hmac-drbg": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
- "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
- "requires": {
- "hash.js": "^1.0.3",
- "minimalistic-assert": "^1.0.0",
- "minimalistic-crypto-utils": "^1.0.1"
- }
- },
- "homedir-polyfill": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
- "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
- "requires": {
- "parse-passwd": "^1.0.0"
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "hosted-git-info": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
- "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
- },
- "hpack.js": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
- "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+ "node_modules/import-local/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "obuf": "^1.0.0",
- "readable-stream": "^2.0.1",
- "wbuf": "^1.1.0"
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "html-entities": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
- "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
- "dev": true
- },
- "http-deceiver": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
- "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
- "dev": true
- },
- "http-errors": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
- "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "node_modules/import-local/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.1",
- "statuses": ">= 1.5.0 < 2",
- "toidentifier": "1.0.0"
- },
"dependencies": {
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- }
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "http-parser-js": {
- "version": "0.4.10",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
- "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=",
- "dev": true
- },
- "http-proxy": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
- "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
+ "node_modules/import-local/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
- "requires": {
- "eventemitter3": "^4.0.0",
- "follow-redirects": "^1.0.0",
- "requires-port": "^1.0.0"
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "http-proxy-middleware": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
- "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+ "node_modules/import-local/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
- "requires": {
- "http-proxy": "^1.17.0",
- "is-glob": "^4.0.0",
- "lodash": "^4.17.11",
- "micromatch": "^3.1.10"
+ "engines": {
+ "node": ">=8"
}
},
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "requires": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "https-browserify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
- "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "node_modules/import-local/node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "icss-utils": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
- "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
- "requires": {
- "postcss": "^7.0.14"
- },
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "ieee754": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
- "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
- },
- "iferr": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
- "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
- },
- "import-cwd": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
- "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
- "requires": {
- "import-from": "^2.1.0"
- }
- },
- "import-fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
- "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
- "requires": {
- "caller-path": "^2.0.0",
- "resolve-from": "^3.0.0"
- }
- },
- "import-from": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
- "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
- "requires": {
- "resolve-from": "^3.0.0"
- }
- },
- "import-local": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
- "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
- "requires": {
- "pkg-dir": "^3.0.0",
- "resolve-cwd": "^2.0.0"
- }
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
- },
- "in-publish": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
- "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ=="
- },
- "indent-string": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
- "requires": {
- "repeating": "^2.0.0"
- }
- },
- "indexes-of": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
- "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc="
- },
- "infer-owner": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "ini": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
- "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
- },
- "internal-ip": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
- "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
"dev": true,
- "requires": {
- "default-gateway": "^4.2.0",
- "ipaddr.js": "^1.9.0"
+ "engines": {
+ "node": ">=10.13.0"
}
},
- "interpret": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
- "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw=="
- },
- "invert-kv": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
- "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
- },
- "ip": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
- "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
- "dev": true
- },
- "ip-regex": {
+ "node_modules/is-binary-path": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
- "dev": true
- },
- "ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "dev": true
- },
- "is-absolute-url": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
- "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
- "dev": true
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "requires": {
- "kind-of": "^3.0.2"
- },
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
"dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-arguments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
- "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
- "dev": true
- },
- "is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
- },
- "is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "requires": {
- "binary-extensions": "^1.0.0"
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- },
- "is-callable": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
- "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
- "dev": true
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "requires": {
- "kind-of": "^3.0.2"
+ "binary-extensions": "^2.0.0"
},
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "is-date-object": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
- "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
- "dev": true
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "dev": true,
"dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
- }
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "is-directory": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
- "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
- },
- "is-extglob": {
+ "node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
- },
- "is-finite": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
- "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w=="
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
- },
- "is-glob": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
- "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "is-path-cwd": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
- "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
- "dev": true
- },
- "is-path-in-cwd": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
- "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+ "node_modules/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-path-inside": "^2.1.0"
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "is-path-inside": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
- "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
- "requires": {
- "path-is-inside": "^1.0.2"
+ "engines": {
+ "node": ">=0.12.0"
}
},
- "is-plain-object": {
+ "node_modules/is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "requires": {
+ "dependencies": {
"isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "is-regex": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
- "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
- "dev": true,
- "requires": {
- "has": "^1.0.3"
- }
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
- },
- "is-symbol": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
- "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
- "dev": true,
- "requires": {
- "has-symbols": "^1.0.1"
- }
- },
- "is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
- },
- "is-utf8": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
- },
- "is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
- },
- "is-wsl": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
- "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "isexe": {
+ "node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
},
- "isobject": {
+ "node_modules/isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
- "isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
- },
- "jquery": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
- "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
- },
- "jquery-ujs": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/jquery-ujs/-/jquery-ujs-1.2.2.tgz",
- "integrity": "sha1-ao7xAg5rbdo4W5CkvdwSjCHFY5c=",
- "requires": {
- "jquery": ">=1.8.0"
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
}
},
- "js-base64": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
- "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ=="
+ "node_modules/jest-worker/node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
},
- "js-yaml": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
- "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ "node_modules/jquery": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+ "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
},
- "json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ "node_modules/jquery-typeahead": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/jquery-typeahead/-/jquery-typeahead-2.11.1.tgz",
+ "integrity": "sha512-iuNRruN5bWtck+VPxdCTijD6BD9bVuBj3NCD25vITOdMb7P3fYlkBWcmnLEazD8O+VAtbcJ9aLxRi+qrpopNZA==",
+ "dependencies": {
+ "@babel/register": "^7.6.2",
+ "jquery": ">=1.7.2",
+ "lz-string": "^1.4.4"
+ }
},
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ "node_modules/jquery-ujs": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jquery-ujs/-/jquery-ujs-1.2.3.tgz",
+ "integrity": "sha512-59wvfx5vcCTHMeQT1/OwFiAj+UffLIwjRIoXdpO7Z7BCFGepzq9T9oLVeoItjTqjoXfUrHJvV7QU6pUR+UzOoA==",
+ "peerDependencies": {
+ "jquery": ">=1.8.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=="
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "peer": true
},
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "peer": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
},
- "json3": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
- "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
- "json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "requires": {
- "minimist": "^1.2.0"
- }
+ "node_modules/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
},
- "jsprim": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.3.0",
- "json-schema": "0.2.3",
- "verror": "1.10.0"
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "killable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
- "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
- "dev": true
- },
- "kind-of": {
+ "node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
- },
- "lcid": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
- "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
- "requires": {
- "invert-kv": "^2.0.0"
- }
- },
- "load-json-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- },
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- }
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "loader-runner": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
- "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw=="
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
},
- "loader-utils": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
- "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
- "requires": {
+ "node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "dependencies": {
"big.js": "^5.2.2",
- "emojis-list": "^2.0.0",
- "json5": "^1.0.1"
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
}
},
- "locate-path": {
+ "node_modules/locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
- "requires": {
+ "dependencies": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "lodash": {
- "version": "4.17.15",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
- },
- "lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
- },
- "lodash.template": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
- "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
- "requires": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.templatesettings": "^4.0.0"
- }
- },
- "lodash.templatesettings": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
- "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
- "requires": {
- "lodash._reinterpolate": "^3.0.0"
- }
- },
- "loglevel": {
- "version": "1.6.7",
- "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz",
- "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==",
- "dev": true
- },
- "loud-rejection": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
- "requires": {
- "currently-unhandled": "^0.4.1",
- "signal-exit": "^3.0.0"
- }
- },
- "lru-cache": {
+ "node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "requires": {
+ "peer": true,
+ "dependencies": {
"yallist": "^3.0.2"
}
},
- "make-dir": {
+ "node_modules/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
- "requires": {
+ "dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "mamacro": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
- "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA=="
- },
- "map-age-cleaner": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
- "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
- "requires": {
- "p-defer": "^1.0.0"
- }
- },
- "map-cache": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
- },
- "map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
- },
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
- "requires": {
- "object-visit": "^1.0.0"
- }
- },
- "md5.js": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
- "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
- "requires": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1",
- "safe-buffer": "^5.1.2"
- }
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
- "dev": true
- },
- "mem": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
- "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
- "requires": {
- "map-age-cleaner": "^0.1.1",
- "mimic-fn": "^2.0.0",
- "p-is-promise": "^2.0.0"
- }
- },
- "memory-fs": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
- "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
- "requires": {
- "errno": "^0.1.3",
- "readable-stream": "^2.0.1"
- }
- },
- "meow": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
- "requires": {
- "camelcase-keys": "^2.0.0",
- "decamelize": "^1.1.2",
- "loud-rejection": "^1.0.0",
- "map-obj": "^1.0.1",
- "minimist": "^1.1.3",
- "normalize-package-data": "^2.3.4",
- "object-assign": "^4.0.1",
- "read-pkg-up": "^1.0.1",
- "redent": "^1.0.0",
- "trim-newlines": "^1.0.0"
- }
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
- "dev": true
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
- },
- "miller-rabin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
- "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
- "requires": {
- "bn.js": "^4.0.0",
- "brorand": "^1.0.1"
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
}
},
- "mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
- "mime-db": {
- "version": "1.43.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
- "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
- },
- "mime-types": {
- "version": "2.1.26",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
- "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
- "requires": {
- "mime-db": "1.43.0"
- }
- },
- "mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
- },
- "minimalistic-assert": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
- },
- "minimalistic-crypto-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "^1.1.7"
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
}
},
- "minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
- },
- "mississippi": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
- "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
- "requires": {
- "concat-stream": "^1.5.0",
- "duplexify": "^3.4.2",
- "end-of-stream": "^1.1.0",
- "flush-write-stream": "^1.0.0",
- "from2": "^2.1.0",
- "parallel-transform": "^1.1.0",
- "pump": "^3.0.0",
- "pumpify": "^1.3.3",
- "stream-each": "^1.1.0",
- "through2": "^2.0.0"
- }
- },
- "mixin-deep": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
- "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
- "requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
"dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "requires": {
- "minimist": "0.0.8"
+ "mime-db": "1.52.0"
},
- "dependencies": {
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
- }
+ "engines": {
+ "node": ">= 0.6"
}
},
- "move-concurrently": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
- "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
- "requires": {
- "aproba": "^1.1.1",
- "copy-concurrently": "^1.0.0",
- "fs-write-stream-atomic": "^1.0.8",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.5.4",
- "run-queue": "^1.0.3"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "multicast-dns": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
- "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "node_modules/mini-css-extract-plugin": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz",
+ "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==",
"dev": true,
- "requires": {
- "dns-packet": "^1.3.1",
- "thunky": "^1.0.2"
- }
- },
- "multicast-dns-service-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
- "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
- "dev": true
- },
- "nan": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
- "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
- },
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- }
- },
- "negotiator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
- "dev": true
- },
- "neo-async": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
- "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw=="
- },
- "next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
- },
- "nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
- },
- "node-forge": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
- "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
- "dev": true
- },
- "node-gyp": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
- "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
- "requires": {
- "fstream": "^1.0.0",
- "glob": "^7.0.3",
- "graceful-fs": "^4.1.2",
- "mkdirp": "^0.5.0",
- "nopt": "2 || 3",
- "npmlog": "0 || 1 || 2 || 3 || 4",
- "osenv": "0",
- "request": "^2.87.0",
- "rimraf": "2",
- "semver": "~5.3.0",
- "tar": "^2.0.0",
- "which": "1"
- },
"dependencies": {
- "semver": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
- "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
- }
- }
- },
- "node-libs-browser": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
- "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
- "requires": {
- "assert": "^1.1.1",
- "browserify-zlib": "^0.2.0",
- "buffer": "^4.3.0",
- "console-browserify": "^1.1.0",
- "constants-browserify": "^1.0.0",
- "crypto-browserify": "^3.11.0",
- "domain-browser": "^1.1.1",
- "events": "^3.0.0",
- "https-browserify": "^1.0.0",
- "os-browserify": "^0.3.0",
- "path-browserify": "0.0.1",
- "process": "^0.11.10",
- "punycode": "^1.2.4",
- "querystring-es3": "^0.2.0",
- "readable-stream": "^2.3.3",
- "stream-browserify": "^2.0.1",
- "stream-http": "^2.7.2",
- "string_decoder": "^1.0.0",
- "timers-browserify": "^2.0.4",
- "tty-browserify": "0.0.0",
- "url": "^0.11.0",
- "util": "^0.11.0",
- "vm-browserify": "^1.0.1"
+ "schema-utils": "^4.0.0",
+ "tapable": "^2.2.1"
},
- "dependencies": {
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
- }
- }
- },
- "node-releases": {
- "version": "1.1.52",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz",
- "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==",
- "requires": {
- "semver": "^6.3.0"
+ "engines": {
+ "node": ">= 12.13.0"
},
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
- }
- },
- "node-sass": {
- "version": "4.13.1",
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
- "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
- "requires": {
- "async-foreach": "^0.1.3",
- "chalk": "^1.1.1",
- "cross-spawn": "^3.0.0",
- "gaze": "^1.0.0",
- "get-stdin": "^4.0.1",
- "glob": "^7.0.3",
- "in-publish": "^2.0.0",
- "lodash": "^4.17.15",
- "meow": "^3.7.0",
- "mkdirp": "^0.5.1",
- "nan": "^2.13.2",
- "node-gyp": "^3.8.0",
- "npmlog": "^4.0.0",
- "request": "^2.88.0",
- "sass-graph": "^2.2.4",
- "stdout-stream": "^1.4.0",
- "true-case-path": "^1.0.2"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
},
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "cross-spawn": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
- "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
- "requires": {
- "lru-cache": "^4.0.1",
- "which": "^1.2.9"
- }
- },
- "lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- },
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
- }
+ "peerDependencies": {
+ "webpack": "^5.0.0"
}
},
- "nopt": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
- "requires": {
- "abbrev": "1"
- }
- },
- "normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
- },
- "normalize-range": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
- "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI="
- },
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
- "requires": {
- "path-key": "^2.0.0"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "num2fraction": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
- "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4="
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "peer": true
},
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
- },
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
- "object-inspect": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
- "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
- "dev": true
- },
- "object-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz",
- "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==",
- "dev": true
- },
- "object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "dev": true
- },
- "object-path": {
- "version": "0.11.4",
- "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
- "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk="
- },
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "requires": {
- "isobject": "^3.0.0"
- }
- },
- "object.assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.2",
- "function-bind": "^1.1.1",
- "has-symbols": "^1.0.0",
- "object-keys": "^1.0.11"
- }
- },
- "object.pick": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
- "requires": {
- "isobject": "^3.0.1"
- }
- },
- "obuf": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
- "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
- "dev": true
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "dev": true,
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "on-headers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
- "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1"
- }
+ "node_modules/node-releases": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
},
- "opn": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
- "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
- "dev": true,
- "requires": {
- "is-wsl": "^1.1.0"
- }
- },
- "original": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
- "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
- "requires": {
- "url-parse": "^1.4.3"
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "os-browserify": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
- "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
- },
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
- },
- "os-locale": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
- "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
- "requires": {
- "execa": "^1.0.0",
- "lcid": "^2.0.0",
- "mem": "^4.0.0"
- }
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
- "osenv": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
- "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
- "requires": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "p-defer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
- "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
- },
- "p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
- },
- "p-is-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
- "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg=="
- },
- "p-limit": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
- "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
- "requires": {
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
"p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "p-locate": {
+ "node_modules/p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
- "requires": {
+ "dependencies": {
"p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "p-map": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
- "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
- "dev": true
- },
- "p-retry": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
- "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
- "dev": true,
- "requires": {
- "retry": "^0.12.0"
- }
- },
- "p-try": {
+ "node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
- },
- "pako": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
- "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
- },
- "parallel-transform": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
- "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
- "requires": {
- "cyclist": "^1.0.1",
- "inherits": "^2.0.3",
- "readable-stream": "^2.1.5"
- }
- },
- "parse-asn1": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
- "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
- "requires": {
- "asn1.js": "^4.0.0",
- "browserify-aes": "^1.0.0",
- "create-hash": "^1.1.0",
- "evp_bytestokey": "^1.0.0",
- "pbkdf2": "^3.0.3",
- "safe-buffer": "^5.1.1"
- }
- },
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "requires": {
- "error-ex": "^1.2.0"
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "engines": {
+ "node": ">=6"
}
},
- "parse-passwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
- "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
- },
- "parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "dev": true
- },
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
- },
- "path-browserify": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
- "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ=="
- },
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
- },
- "path-exists": {
+ "node_modules/path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "engines": {
+ "node": ">=4"
+ }
},
- "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="
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
},
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "node_modules/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
},
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
- },
- "path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
- },
- "path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
- "dev": true
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
- "path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
- "requires": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
},
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- }
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "pbkdf2": {
- "version": "3.0.17",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
- "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
- "requires": {
- "create-hash": "^1.1.2",
- "create-hmac": "^1.1.4",
- "ripemd160": "^2.0.1",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
- }
- },
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
- },
- "pify": {
+ "node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
},
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "requires": {
- "pinkie": "^2.0.0"
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "engines": {
+ "node": ">= 6"
}
},
- "pkg-dir": {
+ "node_modules/pkg-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
"integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
- "requires": {
+ "dependencies": {
"find-up": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "popper.js": {
+ "node_modules/popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
- "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
- },
- "portfinder": {
- "version": "1.0.25",
- "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
- "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
- "dev": true,
- "requires": {
- "async": "^2.6.2",
- "debug": "^3.1.1",
- "mkdirp": "^0.5.1"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "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
- }
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
+ "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
}
},
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
- },
- "postcss": {
- "version": "6.0.23",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
- "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
- "requires": {
- "chalk": "^2.4.1",
- "source-map": "^0.6.1",
- "supports-color": "^5.4.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ "node_modules/postcss": {
+ "version": "8.4.35",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
+ "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
},
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
- }
- },
- "postcss-advanced-variables": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/postcss-advanced-variables/-/postcss-advanced-variables-3.0.1.tgz",
- "integrity": "sha512-JqVjfkmqPoazMobVeQYzbt7djcDGJfMlpwBd9abTqmzWR40tvIUMXpTU5w3riqz7h+wYPY7V6GF8BIXL/ybEfg==",
- "requires": {
- "@csstools/sass-import-resolve": "^1.0.0",
- "postcss": "^7.0.6"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
},
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
- }
- },
- "postcss-atroot": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/postcss-atroot/-/postcss-atroot-0.1.3.tgz",
- "integrity": "sha1-Z1LAIwx0UUBUk0WysOMOvtoBpAU=",
- "requires": {
- "postcss": "^5.0.5"
- },
+ ],
"dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- },
- "dependencies": {
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- }
- }
- },
- "has-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
- "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
- },
- "postcss": {
- "version": "5.2.18",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
- "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
- "requires": {
- "chalk": "^1.1.3",
- "js-base64": "^2.1.9",
- "source-map": "^0.5.6",
- "supports-color": "^3.2.3"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
- "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
- "requires": {
- "has-flag": "^1.0.0"
- }
- }
- }
- },
- "postcss-attribute-case-insensitive": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz",
- "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-selector-parser": "^6.0.2"
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "engines": {
+ "node": "^10 || ^12 || >=14"
}
},
- "postcss-color-functional-notation": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz",
- "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
+ "node_modules/postcss-modules-extract-imports": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
+ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
+ "dev": true,
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "postcss-color-gray": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz",
- "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==",
- "requires": {
- "@csstools/convert-colors": "^1.4.0",
- "postcss": "^7.0.5",
- "postcss-values-parser": "^2.0.0"
- },
+ "node_modules/postcss-modules-local-by-default": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz",
+ "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-color-hex-alpha": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz",
- "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==",
- "requires": {
- "postcss": "^7.0.14",
- "postcss-values-parser": "^2.0.1"
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-color-mod-function": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz",
- "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==",
- "requires": {
- "@csstools/convert-colors": "^1.4.0",
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "postcss-color-rebeccapurple": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz",
- "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
- },
+ "node_modules/postcss-modules-scope": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz",
+ "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-custom-media": {
- "version": "7.0.8",
- "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz",
- "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==",
- "requires": {
- "postcss": "^7.0.14"
+ "postcss-selector-parser": "^6.0.4"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-custom-properties": {
- "version": "8.0.11",
- "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz",
- "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==",
- "requires": {
- "postcss": "^7.0.17",
- "postcss-values-parser": "^2.0.1"
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "postcss-custom-selectors": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz",
- "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-selector-parser": "^5.0.0-rc.3"
- },
+ "node_modules/postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "dev": true,
"dependencies": {
- "cssesc": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
- "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg=="
- },
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-selector-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
- "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
- "requires": {
- "cssesc": "^2.0.0",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-dir-pseudo-class": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz",
- "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-selector-parser": "^5.0.0-rc.3"
+ "icss-utils": "^5.0.0"
},
- "dependencies": {
- "cssesc": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
- "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg=="
- },
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-selector-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
- "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
- "requires": {
- "cssesc": "^2.0.0",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-double-position-gradients": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz",
- "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==",
- "requires": {
- "postcss": "^7.0.5",
- "postcss-values-parser": "^2.0.0"
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "postcss-env-function": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz",
- "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
- },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.0.15",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
+ "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-extend-rule": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-extend-rule/-/postcss-extend-rule-2.0.0.tgz",
- "integrity": "sha512-dgr1GJzW3lUBczZJO5Fm51rktn34Uc99xR1uQyC2Td8JPep/Y+TRx6TjK0yngikOd4LxV1xyuohMMpcaOBgrfA==",
- "requires": {
- "postcss": "^6.0.22",
- "postcss-nesting": "^5.0.0"
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "postcss-flexbugs-fixes": {
+ "node_modules/postcss-value-parser": {
"version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.0.tgz",
- "integrity": "sha512-QRE0n3hpkxxS/OGvzOa+PDuy4mh/Jg4o9ui22/ko5iGYOG3M5dfJabjnAZjTdh2G9F85c7Hv8hWcEDEKW/xceQ==",
- "requires": {
- "postcss": "^7.0.26"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
- "postcss-focus-visible": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz",
- "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==",
- "requires": {
- "postcss": "^7.0.2"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
}
},
- "postcss-focus-within": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz",
- "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==",
- "requires": {
- "postcss": "^7.0.2"
- },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "safe-buffer": "^5.1.0"
}
},
- "postcss-font-variant": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz",
- "integrity": "sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg==",
- "requires": {
- "postcss": "^7.0.2"
- },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-gap-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz",
- "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==",
- "requires": {
- "postcss": "^7.0.2"
+ "picomatch": "^2.2.1"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "engines": {
+ "node": ">=8.10.0"
}
},
- "postcss-image-set-function": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz",
- "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
- },
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-import": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
- "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
- "requires": {
- "postcss": "^7.0.1",
- "postcss-value-parser": "^3.2.3",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
+ "resolve": "^1.20.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "engines": {
+ "node": ">= 10.13.0"
}
},
- "postcss-initial": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz",
- "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==",
- "requires": {
- "lodash.template": "^4.5.0",
- "postcss": "^7.0.2"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
- "postcss-lab-function": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz",
- "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==",
- "requires": {
- "@csstools/convert-colors": "^1.4.0",
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
+ "node_modules/regex-parser": {
+ "version": "2.2.11",
+ "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz",
+ "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==",
+ "dev": true
},
- "postcss-load-config": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz",
- "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==",
- "requires": {
- "cosmiconfig": "^5.0.0",
- "import-cwd": "^2.0.0"
+ "node_modules/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,
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "postcss-loader": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
- "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
- "requires": {
- "loader-utils": "^1.1.0",
- "postcss": "^7.0.0",
- "postcss-load-config": "^2.0.0",
- "schema-utils": "^1.0.0"
- },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "postcss-logical": {
+ "node_modules/resolve-cwd": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz",
- "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==",
- "requires": {
- "postcss": "^7.0.2"
- },
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "postcss-media-minmax": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz",
- "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==",
- "requires": {
- "postcss": "^7.0.2"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
}
},
- "postcss-modules-extract-imports": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
- "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
- "requires": {
- "postcss": "^7.0.5"
- },
+ "node_modules/resolve-url-loader": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz",
+ "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "adjust-sourcemap-loader": "^4.0.0",
+ "convert-source-map": "^1.7.0",
+ "loader-utils": "^2.0.0",
+ "postcss": "^8.2.14",
+ "source-map": "0.6.1"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "postcss-modules-local-by-default": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz",
- "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==",
- "requires": {
- "icss-utils": "^4.1.1",
- "postcss": "^7.0.16",
- "postcss-selector-parser": "^6.0.2",
- "postcss-value-parser": "^4.0.0"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
+ "node_modules/resolve-url-loader/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
},
- "postcss-value-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
- "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
},
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
}
- }
+ ]
},
- "postcss-modules-scope": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz",
- "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==",
- "requires": {
- "postcss": "^7.0.6",
- "postcss-selector-parser": "^6.0.0"
- },
+ "node_modules/sass": {
+ "version": "1.71.1",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz",
+ "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-modules-values": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
- "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
- "requires": {
- "icss-utils": "^4.0.0",
- "postcss": "^7.0.6"
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-nested": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.1.tgz",
- "integrity": "sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw==",
- "requires": {
- "postcss": "^7.0.21",
- "postcss-selector-parser": "^6.0.2"
+ "bin": {
+ "sass": "sass.js"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "engines": {
+ "node": ">=14.0.0"
}
},
- "postcss-nesting": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-5.0.0.tgz",
- "integrity": "sha512-Yoe3w2mcVslnEJl5zLyz1yBxCFUpYu138apEEOCwS2HRdDw/TDxTwD1fXBrIarL8J1cPzHfVwO1m40B2/UpGCw==",
- "requires": {
- "postcss": "^6.0.21"
- }
- },
- "postcss-overflow-shorthand": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz",
- "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==",
- "requires": {
- "postcss": "^7.0.2"
- },
+ "node_modules/sass-loader": {
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.1.tgz",
+ "integrity": "sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-page-break": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz",
- "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==",
- "requires": {
- "postcss": "^7.0.2"
+ "neo-async": "^2.6.2"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-place": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz",
- "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-values-parser": "^2.0.0"
+ "engines": {
+ "node": ">= 18.12.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-preset-env": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz",
- "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==",
- "requires": {
- "autoprefixer": "^9.6.1",
- "browserslist": "^4.6.4",
- "caniuse-lite": "^1.0.30000981",
- "css-blank-pseudo": "^0.1.4",
- "css-has-pseudo": "^0.10.0",
- "css-prefers-color-scheme": "^3.1.1",
- "cssdb": "^4.4.0",
- "postcss": "^7.0.17",
- "postcss-attribute-case-insensitive": "^4.0.1",
- "postcss-color-functional-notation": "^2.0.1",
- "postcss-color-gray": "^5.0.0",
- "postcss-color-hex-alpha": "^5.0.3",
- "postcss-color-mod-function": "^3.0.3",
- "postcss-color-rebeccapurple": "^4.0.1",
- "postcss-custom-media": "^7.0.8",
- "postcss-custom-properties": "^8.0.11",
- "postcss-custom-selectors": "^5.1.2",
- "postcss-dir-pseudo-class": "^5.0.0",
- "postcss-double-position-gradients": "^1.0.0",
- "postcss-env-function": "^2.0.2",
- "postcss-focus-visible": "^4.0.0",
- "postcss-focus-within": "^3.0.0",
- "postcss-font-variant": "^4.0.0",
- "postcss-gap-properties": "^2.0.0",
- "postcss-image-set-function": "^3.0.1",
- "postcss-initial": "^3.0.0",
- "postcss-lab-function": "^2.0.1",
- "postcss-logical": "^3.0.0",
- "postcss-media-minmax": "^4.0.0",
- "postcss-nesting": "^7.0.0",
- "postcss-overflow-shorthand": "^2.0.0",
- "postcss-page-break": "^2.0.0",
- "postcss-place": "^4.0.1",
- "postcss-pseudo-class-any-link": "^6.0.0",
- "postcss-replace-overflow-wrap": "^3.0.0",
- "postcss-selector-matches": "^4.0.0",
- "postcss-selector-not": "^4.0.0"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
},
- "dependencies": {
- "autoprefixer": {
- "version": "9.7.4",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz",
- "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==",
- "requires": {
- "browserslist": "^4.8.3",
- "caniuse-lite": "^1.0.30001020",
- "chalk": "^2.4.2",
- "normalize-range": "^0.1.2",
- "num2fraction": "^1.2.2",
- "postcss": "^7.0.26",
- "postcss-value-parser": "^4.0.2"
- }
- },
- "browserslist": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz",
- "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==",
- "requires": {
- "caniuse-lite": "^1.0.30001030",
- "electron-to-chromium": "^1.3.363",
- "node-releases": "^1.1.50"
- }
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
+ "sass": "^1.3.0",
+ "sass-embedded": "*",
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
},
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
+ "node-sass": {
+ "optional": true
},
- "postcss-nesting": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz",
- "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==",
- "requires": {
- "postcss": "^7.0.2"
- }
+ "sass": {
+ "optional": true
},
- "postcss-value-parser": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
- "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
+ "sass-embedded": {
+ "optional": true
},
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ "webpack": {
+ "optional": true
}
}
},
- "postcss-property-lookup": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postcss-property-lookup/-/postcss-property-lookup-2.0.0.tgz",
- "integrity": "sha512-KUb53a7UZWDMVb0SRODOonc4H1wlbgQ0VfYwmJaR1xWPorhariEz0U7x0ri3W/imFs6HqLYWP7hl2yMvi5Ty+w==",
- "requires": {
- "object-assign": "^4.0.1",
- "postcss": "^6.0.6",
- "tcomb": "^3.2.21"
- }
- },
- "postcss-pseudo-class-any-link": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz",
- "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==",
- "requires": {
- "postcss": "^7.0.2",
- "postcss-selector-parser": "^5.0.0-rc.3"
- },
+ "node_modules/schema-utils": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
+ "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+ "dev": true,
"dependencies": {
- "cssesc": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
- "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg=="
- },
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "postcss-selector-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
- "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
- "requires": {
- "cssesc": "^2.0.0",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-replace-overflow-wrap": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz",
- "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==",
- "requires": {
- "postcss": "^7.0.2"
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-selector-matches": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz",
- "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==",
- "requires": {
- "balanced-match": "^1.0.0",
- "postcss": "^7.0.2"
+ "engines": {
+ "node": ">= 12.13.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
- "postcss-selector-not": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz",
- "integrity": "sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ==",
- "requires": {
- "balanced-match": "^1.0.0",
- "postcss": "^7.0.2"
- },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
"dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "postcss-selector-parser": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
- "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
- "requires": {
- "cssesc": "^3.0.0",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "postcss-value-parser": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
- "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
- },
- "postcss-values-parser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz",
- "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==",
- "requires": {
- "flatten": "^1.0.2",
- "indexes-of": "^1.0.1",
- "uniq": "^1.0.1"
- }
- },
- "precss": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/precss/-/precss-4.0.0.tgz",
- "integrity": "sha512-cRPZMKpHLZXR6gJlrXRjJe7SQMf+wYxg6rKp+TwYsYABjApSj9z8E8yIlagqADaWyikeIZttaNU6xqSjFIAP/g==",
- "requires": {
- "postcss": "^7.0.6",
- "postcss-advanced-variables": "^3.0.0",
- "postcss-atroot": "^0.1.3",
- "postcss-extend-rule": "^2.0.0",
- "postcss-nested": "^4.1.0",
- "postcss-preset-env": "^6.4.0",
- "postcss-property-lookup": "^2.0.0"
+ "lru-cache": "^6.0.0"
},
- "dependencies": {
- "postcss": {
- "version": "7.0.27",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
- "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "process": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
- },
- "process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
- },
- "promise-inflight": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
- "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM="
- },
- "proxy-addr": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
- "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "node_modules/semver/node_modules/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": {
- "forwarded": "~0.1.2",
- "ipaddr.js": "1.9.1"
- }
- },
- "prr": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
- "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
- },
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
- },
- "psl": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
- "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ=="
- },
- "public-encrypt": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
- "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
- "requires": {
- "bn.js": "^4.1.0",
- "browserify-rsa": "^4.0.0",
- "create-hash": "^1.1.0",
- "parse-asn1": "^5.0.0",
- "randombytes": "^2.0.1",
- "safe-buffer": "^5.1.2"
- }
- },
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "pumpify": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
- "requires": {
- "duplexify": "^3.6.0",
- "inherits": "^2.0.3",
- "pump": "^2.0.0"
- },
"dependencies": {
- "pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- }
- }
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
- },
- "qs": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
- "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
- "dev": true
- },
- "querystring": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
- "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
- },
- "querystring-es3": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
- "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
- },
- "querystringify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
- "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
- "dev": true
- },
- "randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "requires": {
- "safe-buffer": "^5.1.0"
- }
- },
- "randomfill": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
- "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
- "requires": {
- "randombytes": "^2.0.5",
- "safe-buffer": "^5.1.0"
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "node_modules/semver/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
- "raw-body": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
- "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
- "requires": {
- "bytes": "3.1.0",
- "http-errors": "1.7.2",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
"dependencies": {
- "bytes": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
- "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
- "dev": true
- }
+ "randombytes": "^2.1.0"
}
},
- "read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
- "requires": {
- "pify": "^2.3.0"
- },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- }
- }
- },
- "read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
- "requires": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
- "requires": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
+ "kind-of": "^6.0.2"
},
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
- "requires": {
- "pinkie-promise": "^2.0.0"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
- "requires": {
- "graceful-fs": "^4.1.11",
- "micromatch": "^3.1.10",
- "readable-stream": "^2.0.2"
- }
- },
- "redent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
- "requires": {
- "indent-string": "^2.1.0",
- "strip-indent": "^1.0.1"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.5",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
- "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
- },
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
- }
- },
- "regex-parser": {
- "version": "2.2.10",
- "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz",
- "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA=="
- },
- "regexp.prototype.flags": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
- "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+ "node_modules/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": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.0-next.1"
- }
- },
- "remove-trailing-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
- },
- "repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
- },
- "repeating": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
- "requires": {
- "is-finite": "^1.0.0"
- }
- },
- "request": {
- "version": "2.88.2",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
- "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
- "requires": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.8.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.6",
- "extend": "~3.0.2",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.2",
- "har-validator": "~5.1.3",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.19",
- "oauth-sign": "~0.9.0",
- "performance-now": "^2.1.0",
- "qs": "~6.5.2",
- "safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.3.2"
- },
"dependencies": {
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
- }
- }
- },
- "require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
- },
- "require-main-filename": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
- "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
- },
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
- },
- "resolve": {
- "version": "1.15.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
- "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
- "requires": {
- "path-parse": "^1.0.6"
- }
- },
- "resolve-cwd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
- "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
- "requires": {
- "resolve-from": "^3.0.0"
- }
- },
- "resolve-dir": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
- "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
- "requires": {
- "expand-tilde": "^2.0.0",
- "global-modules": "^1.0.0"
+ "shebang-regex": "^3.0.0"
},
- "dependencies": {
- "global-modules": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
- "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
- "requires": {
- "global-prefix": "^1.0.1",
- "is-windows": "^1.0.1",
- "resolve-dir": "^1.0.0"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "resolve-from": {
+ "node_modules/shebang-regex": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
- "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
- },
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
- },
- "resolve-url-loader": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz",
- "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==",
- "requires": {
- "adjust-sourcemap-loader": "2.0.0",
- "camelcase": "5.3.1",
- "compose-function": "3.0.3",
- "convert-source-map": "1.7.0",
- "es6-iterator": "2.0.3",
- "loader-utils": "1.2.3",
- "postcss": "7.0.21",
- "rework": "1.0.1",
- "rework-visit": "1.0.0",
- "source-map": "0.6.1"
- },
- "dependencies": {
- "postcss": {
- "version": "7.0.21",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
- "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
- "requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
- },
- "retry": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
- "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
- "dev": true
- },
- "rework": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
- "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=",
- "requires": {
- "convert-source-map": "^0.3.3",
- "css": "^2.0.0"
- },
- "dependencies": {
- "convert-source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
- "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA="
- }
- }
- },
- "rework-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz",
- "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo="
- },
- "rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "requires": {
- "glob": "^7.1.3"
- }
- },
- "ripemd160": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
- "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
- "requires": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1"
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
}
},
- "run-queue": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
- "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
- "requires": {
- "aproba": "^1.1.1"
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "requires": {
- "ret": "~0.1.10"
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "sass-graph": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
- "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
- "requires": {
- "glob": "^7.0.0",
- "lodash": "^4.0.0",
- "scss-tokenizer": "^0.2.3",
- "yargs": "^7.0.0"
- },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- }
- },
- "get-caller-file": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
- "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
- },
- "invert-kv": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
- "requires": {
- "invert-kv": "^1.0.0"
- }
- },
- "os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "requires": {
- "lcid": "^1.0.0"
- }
- },
- "require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
- },
- "wrap-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
- }
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
- },
- "yargs": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
- "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
- "requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^5.0.0"
- }
- },
- "yargs-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
- "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
- "requires": {
- "camelcase": "^3.0.0"
- }
- }
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
}
},
- "sass-loader": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
- "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
- "requires": {
- "clone-deep": "^4.0.1",
- "loader-utils": "^1.2.3",
- "neo-async": "^2.6.1",
- "schema-utils": "^2.6.1",
- "semver": "^6.3.0"
- },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "peer": true,
"dependencies": {
- "schema-utils": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
- "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
- "requires": {
- "ajv": "^6.12.0",
- "ajv-keywords": "^3.4.1"
- }
- },
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "schema-utils": {
+ "node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
- "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
- "requires": {
- "ajv": "^6.1.0",
- "ajv-errors": "^1.0.0",
- "ajv-keywords": "^3.1.0"
- }
- },
- "scss-tokenizer": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
- "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
- "requires": {
- "js-base64": "^2.1.8",
- "source-map": "^0.4.2"
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
},
- "dependencies": {
- "source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "select-hose": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
- "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
- "dev": true
- },
- "selfsigned": {
- "version": "1.10.7",
- "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
- "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"dev": true,
- "requires": {
- "node-forge": "0.9.0"
+ "engines": {
+ "node": ">=6"
}
},
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- },
- "send": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
- "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "node_modules/terser": {
+ "version": "5.27.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.2.tgz",
+ "integrity": "sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w==",
"dev": true,
- "requires": {
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "~1.7.2",
- "mime": "1.6.0",
- "ms": "2.1.1",
- "on-finished": "~2.3.0",
- "range-parser": "~1.2.1",
- "statuses": "~1.5.0"
- },
"dependencies": {
- "ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
- "dev": true
- }
- }
- },
- "serialize-javascript": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
- "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ=="
- },
- "serve-index": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
- "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "batch": "0.6.1",
- "debug": "2.6.9",
- "escape-html": "~1.0.3",
- "http-errors": "~1.6.2",
- "mime-types": "~2.1.17",
- "parseurl": "~1.3.2"
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
},
- "dependencies": {
- "http-errors": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
- "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
- "dev": true,
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.0",
- "statuses": ">= 1.4.0 < 2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- },
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
- "dev": true
- }
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "serve-static": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
- "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.10",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+ "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
"dev": true,
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.17.1"
- }
- },
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
- },
- "set-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
- "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
"dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
- },
- "setprototypeof": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
- "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
- "dev": true
- },
- "sha.js": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "shallow-clone": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
- "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
- "requires": {
- "kind-of": "^6.0.2"
- }
- },
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "requires": {
- "shebang-regex": "^1.0.0"
- }
- },
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
- },
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
- },
- "simple-html-tokenizer": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.1.1.tgz",
- "integrity": "sha1-BcLuxXn//+FFoDCsJs/qYbmA+r4="
- },
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
+ "@jridgewell/trace-mapping": "^0.3.20",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.26.0"
},
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
+ "engines": {
+ "node": ">= 10.13.0"
},
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "requires": {
- "kind-of": "^3.2.0"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
},
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "sockjs": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
- "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
- "dev": true,
- "requires": {
- "faye-websocket": "^0.10.0",
- "uuid": "^3.0.1"
- }
- },
- "sockjs-client": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
- "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
- "dev": true,
- "requires": {
- "debug": "^3.2.5",
- "eventsource": "^1.0.7",
- "faye-websocket": "~0.11.1",
- "inherits": "^2.0.3",
- "json3": "^3.3.2",
- "url-parse": "^1.4.3"
+ "peerDependencies": {
+ "webpack": "^5.1.0"
},
- "dependencies": {
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
},
- "faye-websocket": {
- "version": "0.11.3",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
- "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
- "dev": true,
- "requires": {
- "websocket-driver": ">=0.5.1"
- }
+ "esbuild": {
+ "optional": 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
- }
- }
- },
- "source-list-map": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
- "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
- },
- "source-map-resolve": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
- "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
- "requires": {
- "atob": "^2.1.2",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
- }
- },
- "source-map-support": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
- "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
- "requires": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ "uglify-js": {
+ "optional": true
}
}
},
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
- },
- "spdx-correct": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
- "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
- "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
- },
- "spdx-expression-parse": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
- "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
- "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
- },
- "spdy": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz",
- "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==",
+ "node_modules/terser-webpack-plugin/node_modules/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": {
- "debug": "^4.1.0",
- "handle-thing": "^2.0.0",
- "http-deceiver": "^1.2.7",
- "select-hose": "^2.0.0",
- "spdy-transport": "^3.0.0"
- },
"dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "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
- }
- }
- },
- "spdy-transport": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
- "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
- "dev": true,
- "requires": {
- "debug": "^4.1.0",
- "detect-node": "^2.0.4",
- "hpack.js": "^2.1.6",
- "obuf": "^1.1.2",
- "readable-stream": "^3.0.6",
- "wbuf": "^1.7.3"
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
},
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "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
- },
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- }
- }
- },
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "requires": {
- "extend-shallow": "^3.0.0"
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
- "sshpk": {
- "version": "1.16.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
- "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
- "requires": {
- "asn1": "~0.2.3",
- "assert-plus": "^1.0.0",
- "bcrypt-pbkdf": "^1.0.0",
- "dashdash": "^1.12.0",
- "ecc-jsbn": "~0.1.1",
- "getpass": "^0.1.1",
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.0.2",
- "tweetnacl": "~0.14.0"
- }
- },
- "ssri": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
- "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
- "requires": {
- "figgy-pudding": "^3.5.1"
- }
- },
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
}
},
- "statuses": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "node_modules/terser-webpack-plugin/node_modules/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
},
- "stdout-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
- "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
- "requires": {
- "readable-stream": "^2.0.1"
- }
- },
- "stream-browserify": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
- "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
- "requires": {
- "inherits": "~2.0.1",
- "readable-stream": "^2.0.2"
- }
- },
- "stream-each": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
- "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
- "requires": {
- "end-of-stream": "^1.1.0",
- "stream-shift": "^1.0.0"
- }
- },
- "stream-http": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
- "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
- "requires": {
- "builtin-status-codes": "^3.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.3.6",
- "to-arraybuffer": "^1.0.0",
- "xtend": "^4.0.0"
- }
- },
- "stream-shift": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
- "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
- },
- "string-width": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
- "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
- "requires": {
- "emoji-regex": "^7.0.1",
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^5.1.0"
- }
- },
- "string.prototype.trimleft": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
- "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
- "requires": {
- "define-properties": "^1.1.3",
- "function-bind": "^1.1.1"
- }
- },
- "string.prototype.trimright": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
- "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.3",
- "function-bind": "^1.1.1"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
- "requires": {
- "ansi-regex": "^4.1.0"
- }
- },
- "strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
- "requires": {
- "is-utf8": "^0.2.0"
- }
- },
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
- },
- "strip-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
- "requires": {
- "get-stdin": "^4.0.1"
- }
- },
- "style-loader": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz",
- "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==",
- "requires": {
- "loader-utils": "^1.2.3",
- "schema-utils": "^2.6.4"
- },
"dependencies": {
- "schema-utils": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
- "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
- "requires": {
- "ajv": "^6.12.0",
- "ajv-keywords": "^3.4.1"
- }
- }
- }
- },
- "supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "svg-inline-loader": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/svg-inline-loader/-/svg-inline-loader-0.8.2.tgz",
- "integrity": "sha512-kbrcEh5n5JkypaSC152eGfGcnT4lkR0eSfvefaUJkLqgGjRQJyKDvvEE/CCv5aTSdfXuc+N98w16iAojhShI3g==",
- "requires": {
- "loader-utils": "^1.1.0",
- "object-assign": "^4.0.1",
- "simple-html-tokenizer": "^0.1.1"
- }
- },
- "tapable": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
- "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
- },
- "tar": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
- "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
- "requires": {
- "block-stream": "*",
- "fstream": "^1.0.12",
- "inherits": "2"
- }
- },
- "tcomb": {
- "version": "3.2.29",
- "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz",
- "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ=="
- },
- "terser": {
- "version": "4.6.6",
- "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz",
- "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==",
- "requires": {
- "commander": "^2.20.0",
- "source-map": "~0.6.1",
- "source-map-support": "~0.5.12"
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
},
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "terser-webpack-plugin": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
- "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
- "requires": {
- "cacache": "^12.0.2",
- "find-cache-dir": "^2.1.0",
- "is-wsl": "^1.1.0",
- "schema-utils": "^1.0.0",
- "serialize-javascript": "^2.1.2",
- "source-map": "^0.6.1",
- "terser": "^4.1.2",
- "webpack-sources": "^1.4.0",
- "worker-farm": "^1.7.0"
+ "engines": {
+ "node": ">= 10.13.0"
},
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
- }
- },
- "through2": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
- "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
- "requires": {
- "readable-stream": "~2.3.6",
- "xtend": "~4.0.1"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
- "thunky": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
- "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
- "dev": true
- },
- "timers-browserify": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
- "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
- "requires": {
- "setimmediate": "^1.0.4"
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
}
},
- "to-arraybuffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
- "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
- },
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
- "requires": {
- "kind-of": "^3.0.2"
- },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
"dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- }
- },
- "to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
- "requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
- }
- },
- "toidentifier": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
- "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
- "dev": true
- },
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- },
- "trim-newlines": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
- },
- "true-case-path": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
- "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
- "requires": {
- "glob": "^7.1.2"
- }
- },
- "tslib": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
- "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA=="
- },
- "tty-browserify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
- "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
- },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "requires": {
- "safe-buffer": "^5.0.1"
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
}
},
- "turbolinks": {
+ "node_modules/turbolinks": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/turbolinks/-/turbolinks-5.2.0.tgz",
"integrity": "sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw=="
},
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
- },
- "type": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
- "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
- },
- "type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "dev": true,
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- }
- },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
- },
- "union-value": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
- "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
- "requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^2.0.1"
- }
- },
- "uniq": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
- "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
- },
- "unique-filename": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
- "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
- "requires": {
- "unique-slug": "^2.0.0"
- }
- },
- "unique-slug": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
- "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
- "requires": {
- "imurmurhash": "^0.1.4"
- }
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
},
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
},
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
- }
- },
- "upath": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
- "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
- },
- "uri-js": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
- "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
- },
- "url": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
- "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
- "requires": {
- "punycode": "1.3.2",
- "querystring": "0.2.0"
- },
+ ],
"dependencies": {
- "punycode": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
- "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
- }
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
}
},
- "url-parse": {
- "version": "1.4.7",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
- "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+ "node_modules/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": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
- "use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
- },
- "util": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
- "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
- "requires": {
- "inherits": "2.0.3"
- },
"dependencies": {
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- }
+ "punycode": "^2.1.0"
}
},
- "util-deprecate": {
+ "node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
- "dev": true
- },
- "uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
- },
- "v8-compile-cache": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
- "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w=="
- },
- "validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
- "verror": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "requires": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
}
},
- "vm-browserify": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
- "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
- },
- "watchpack": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
- "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
- "requires": {
- "chokidar": "^2.0.2",
- "graceful-fs": "^4.1.2",
- "neo-async": "^2.5.0"
- }
- },
- "wbuf": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
- "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "node_modules/webpack": {
+ "version": "5.90.3",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
+ "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
"dev": true,
- "requires": {
- "minimalistic-assert": "^1.0.0"
- }
- },
- "webpack": {
- "version": "4.42.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz",
- "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==",
- "requires": {
- "@webassemblyjs/ast": "1.8.5",
- "@webassemblyjs/helper-module-context": "1.8.5",
- "@webassemblyjs/wasm-edit": "1.8.5",
- "@webassemblyjs/wasm-parser": "1.8.5",
- "acorn": "^6.2.1",
- "ajv": "^6.10.2",
- "ajv-keywords": "^3.4.1",
- "chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^4.1.0",
- "eslint-scope": "^4.0.3",
- "json-parse-better-errors": "^1.0.2",
- "loader-runner": "^2.4.0",
- "loader-utils": "^1.2.3",
- "memory-fs": "^0.4.1",
- "micromatch": "^3.1.10",
- "mkdirp": "^0.5.1",
- "neo-async": "^2.6.1",
- "node-libs-browser": "^2.2.1",
- "schema-utils": "^1.0.0",
- "tapable": "^1.1.3",
- "terser-webpack-plugin": "^1.4.3",
- "watchpack": "^1.6.0",
- "webpack-sources": "^1.4.1"
- }
- },
- "webpack-cli": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz",
- "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==",
- "requires": {
- "chalk": "2.4.2",
- "cross-spawn": "6.0.5",
- "enhanced-resolve": "4.1.0",
- "findup-sync": "3.0.0",
- "global-modules": "2.0.0",
- "import-local": "2.0.0",
- "interpret": "1.2.0",
- "loader-utils": "1.2.3",
- "supports-color": "6.1.0",
- "v8-compile-cache": "2.0.3",
- "yargs": "13.2.4"
- }
- },
- "webpack-dev-middleware": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz",
- "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
- "dev": true,
- "requires": {
- "memory-fs": "^0.4.1",
- "mime": "^2.4.4",
- "mkdirp": "^0.5.1",
- "range-parser": "^1.2.1",
- "webpack-log": "^2.0.0"
- },
"dependencies": {
- "mime": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
- "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
- "dev": true
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^1.0.5",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.9.0",
+ "browserslist": "^4.21.10",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.2.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.10",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
}
}
},
- "webpack-dev-server": {
- "version": "3.10.3",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz",
- "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==",
+ "node_modules/webpack-cli": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
- "requires": {
- "ansi-html": "0.0.7",
- "bonjour": "^3.5.0",
- "chokidar": "^2.1.8",
- "compression": "^1.7.4",
- "connect-history-api-fallback": "^1.6.0",
- "debug": "^4.1.1",
- "del": "^4.1.1",
- "express": "^4.17.1",
- "html-entities": "^1.2.1",
- "http-proxy-middleware": "0.19.1",
- "import-local": "^2.0.0",
- "internal-ip": "^4.3.0",
- "ip": "^1.1.5",
- "is-absolute-url": "^3.0.3",
- "killable": "^1.0.1",
- "loglevel": "^1.6.6",
- "opn": "^5.5.0",
- "p-retry": "^3.0.1",
- "portfinder": "^1.0.25",
- "schema-utils": "^1.0.0",
- "selfsigned": "^1.10.7",
- "semver": "^6.3.0",
- "serve-index": "^1.9.1",
- "sockjs": "0.3.19",
- "sockjs-client": "1.4.0",
- "spdy": "^4.0.1",
- "strip-ansi": "^3.0.1",
- "supports-color": "^6.1.0",
- "url": "^0.11.0",
- "webpack-dev-middleware": "^3.7.2",
- "webpack-log": "^2.0.0",
- "ws": "^6.2.1",
- "yargs": "12.0.5"
- },
"dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "cliui": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
- "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
- "dev": true,
- "requires": {
- "string-width": "^2.1.1",
- "strip-ansi": "^4.0.0",
- "wrap-ansi": "^2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "get-caller-file": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
- "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
- "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
- },
- "require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
- "dev": true
- },
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "wrap-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
- "dev": true,
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
- },
- "dependencies": {
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "dev": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- }
- }
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
+ "colorette": "^2.0.14",
+ "commander": "^10.0.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
},
- "yargs": {
- "version": "12.0.5",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
- "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
- "dev": true,
- "requires": {
- "cliui": "^4.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^3.0.0",
- "get-caller-file": "^1.0.1",
- "os-locale": "^3.0.0",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^2.0.0",
- "which-module": "^2.0.0",
- "y18n": "^3.2.1 || ^4.0.0",
- "yargs-parser": "^11.1.1"
- }
+ "webpack-bundle-analyzer": {
+ "optional": true
},
- "yargs-parser": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
- "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
+ "webpack-dev-server": {
+ "optional": true
}
}
},
- "webpack-log": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
- "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
- "requires": {
- "ansi-colors": "^3.0.0",
- "uuid": "^3.3.2"
+ "engines": {
+ "node": ">=14"
}
},
- "webpack-sources": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
- "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
- "requires": {
- "source-list-map": "^2.0.0",
- "source-map": "~0.6.1"
- },
+ "node_modules/webpack-merge": {
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+ "dev": true,
"dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ "clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
}
},
- "websocket-driver": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
- "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
"dev": true,
- "requires": {
- "http-parser-js": ">=0.4.0 <0.4.11",
- "safe-buffer": ">=5.1.0",
- "websocket-extensions": ">=0.1.1"
+ "engines": {
+ "node": ">=10.13.0"
}
},
- "websocket-extensions": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
- "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
- "dev": true
- },
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "requires": {
- "isexe": "^2.0.0"
- }
- },
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
- },
- "wide-align": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
- "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
- "requires": {
- "string-width": "^1.0.2 || 2"
- },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
"dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "worker-farm": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
- "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
- "requires": {
- "errno": "~0.1.7"
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "wrap-ansi": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
- "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
- "requires": {
- "ansi-styles": "^3.2.0",
- "string-width": "^3.0.0",
- "strip-ansi": "^5.0.0"
+ "node_modules/webpack/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
}
},
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "node_modules/webpack/node_modules/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
},
- "ws": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
- "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
- "requires": {
- "async-limiter": "~1.0.0"
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
- "xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
},
- "y18n": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
- "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
+ "node_modules/wildcard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+ "dev": true
},
- "yallist": {
+ "node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
- },
- "yargs": {
- "version": "13.2.4",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz",
- "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
- "requires": {
- "cliui": "^5.0.0",
- "find-up": "^3.0.0",
- "get-caller-file": "^2.0.1",
- "os-locale": "^3.1.0",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^3.0.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^13.1.0"
- }
- },
- "yargs-parser": {
- "version": "13.1.2",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
- "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "peer": true
}
}
}
diff --git a/package.json b/package.json
index a405b80..72b34f2 100644
--- a/package.json
+++ b/package.json
@@ -1,33 +1,21 @@
{
"dependencies": {
- "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git",
- "autoprefixer": "^9.7.4",
- "bootstrap": "4.3.1",
- "coffeescript": "^2.5.0",
- "core-js": "^3.6.4",
- "css-loader": "^3.4.2",
- "d3": "^3.5.6",
- "exports-loader": "^0.7.0",
- "expose-loader": "^0.7.5",
- "file-loader": "^5.1.0",
- "jquery": "^3.4.1",
- "jquery-ujs": "^1.2.2",
- "node-sass": "^4.13.1",
- "popper.js": "^1.16.0",
- "postcss-flexbugs-fixes": "^4.2.0",
- "postcss-import": "^12.0.1",
- "postcss-loader": "^3.0.0",
- "precss": "^4.0.0",
- "regenerator-runtime": "^0.13.5",
- "resolve-url-loader": "^3.1.1",
- "sass-loader": "^8.0.2",
- "style-loader": "^1.1.3",
- "svg-inline-loader": "^0.8.2",
- "turbolinks": "^5.2.0",
- "webpack": "^4.42.0",
- "webpack-cli": "^3.3.11"
+ "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#v2.0.2",
+ "core-js": "^3.36.0",
+ "d3": "3.5.17",
+ "jquery": "^3.6.4",
+ "jquery-typeahead": "^2.11.1",
+ "jquery-ujs": "^1.2.3",
+ "regenerator-runtime": "^0.14.1",
+ "turbolinks": "^5.2.0"
},
"devDependencies": {
- "webpack-dev-server": "^3.10.1"
+ "css-loader": "^6.10.0",
+ "mini-css-extract-plugin": "^2.8.0",
+ "resolve-url-loader": "^5.0.0",
+ "sass": "^1.71.1",
+ "sass-loader": "^14.1.1",
+ "webpack": "^5.90.3",
+ "webpack-cli": "^5.1.4"
}
}
diff --git a/pkg/api/graphql/generated/generated.go b/pkg/api/graphql/generated/generated.go
index 36b27a9..b7b9b89 100644
--- a/pkg/api/graphql/generated/generated.go
+++ b/pkg/api/graphql/generated/generated.go
@@ -9456,7 +9456,7 @@ func (ec *executionContext) _Application(ctx context.Context, sel ast.SelectionS
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9508,7 +9508,7 @@ func (ec *executionContext) _Bug(ctx context.Context, sel ast.SelectionSet, obj
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9545,7 +9545,7 @@ func (ec *executionContext) _Category(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9577,7 +9577,7 @@ func (ec *executionContext) _ChangedFile(ctx context.Context, sel ast.SelectionS
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9614,7 +9614,7 @@ func (ec *executionContext) _ChangedFiles(ctx context.Context, sel ast.Selection
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9701,7 +9701,7 @@ func (ec *executionContext) _Commit(ctx context.Context, sel ast.SelectionSet, o
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9738,7 +9738,7 @@ func (ec *executionContext) _GitHubPullRequestFileNode(ctx context.Context, sel
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9770,7 +9770,7 @@ func (ec *executionContext) _GitHubPullRequestLabelNode(ctx context.Context, sel
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9852,7 +9852,7 @@ func (ec *executionContext) _GithubPullRequest(ctx context.Context, sel ast.Sele
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9924,7 +9924,7 @@ func (ec *executionContext) _KeywordChange(ctx context.Context, sel ast.Selectio
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -9966,7 +9966,7 @@ func (ec *executionContext) _Maintainer(ctx context.Context, sel ast.SelectionSe
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10013,7 +10013,7 @@ func (ec *executionContext) _Mask(ctx context.Context, sel ast.SelectionSet, obj
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10050,7 +10050,7 @@ func (ec *executionContext) _OutdatedPackage(ctx context.Context, sel ast.Select
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10137,7 +10137,7 @@ func (ec *executionContext) _Package(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10194,7 +10194,7 @@ func (ec *executionContext) _PkgCheckResult(ctx context.Context, sel ast.Selecti
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10218,7 +10218,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
out.Values[i] = graphql.MarshalString("Query")
case "category":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10229,7 +10229,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "categories":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10240,7 +10240,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "commit":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10251,7 +10251,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "commits":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10262,7 +10262,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "mask":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10273,7 +10273,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "masks":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10284,7 +10284,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "outdatedPackage":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10295,7 +10295,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "outdatedPackages":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10306,7 +10306,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "pkgCheckResult":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10317,7 +10317,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "pkgCheckResults":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10328,7 +10328,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "package":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10339,7 +10339,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "packages":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10350,7 +10350,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "packageSearch":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10361,7 +10361,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "useflag":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10372,7 +10372,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "useflags":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10383,7 +10383,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "version":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10394,7 +10394,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "versions":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10405,7 +10405,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "application":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10416,7 +10416,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "lastCommitTime":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10427,7 +10427,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "addedPackages":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10438,7 +10438,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "updatedVersions":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10449,7 +10449,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "stabilizedVersions":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10460,7 +10460,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
})
case "keywordedVersions":
field := field
- out.Concurrently(i, func() (res graphql.Marshaler) {
+ out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@@ -10477,7 +10477,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10526,7 +10526,7 @@ func (ec *executionContext) _ReverseDependency(ctx context.Context, sel ast.Sele
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10578,7 +10578,7 @@ func (ec *executionContext) _Useflag(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10695,7 +10695,7 @@ func (ec *executionContext) _Version(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10734,7 +10734,7 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10770,7 +10770,7 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10816,7 +10816,7 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10852,7 +10852,7 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10893,7 +10893,7 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet,
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
@@ -10936,7 +10936,7 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
panic("unknown field " + strconv.Quote(field.Name))
}
}
- out.Dispatch()
+ out.Dispatch(ctx)
if invalids > 0 {
return graphql.Null
}
diff --git a/pkg/api/graphql/graphiql/graphiql.go b/pkg/api/graphql/graphiql/graphiql.go
deleted file mode 100644
index afc58df..0000000
--- a/pkg/api/graphql/graphiql/graphiql.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package graphiql
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/config"
-)
-
-func Show(w http.ResponseWriter, r *http.Request) {
- w.Header().Add("Content-Type", "text/html")
-
- templates := template.Must(
- template.New("graphiql").
- ParseGlob("web/templates/api/explore/*.tmpl"))
-
- templates.ExecuteTemplate(w, "graphiql.tmpl", template.URL(config.GraphiqlEndpoint()))
-}
diff --git a/pkg/api/graphql/graphiql/graphiql.templ b/pkg/api/graphql/graphiql/graphiql.templ
new file mode 100644
index 0000000..c392a54
--- /dev/null
+++ b/pkg/api/graphql/graphiql/graphiql.templ
@@ -0,0 +1,33 @@
+package graphiql
+
+import "net/http"
+import "soko/pkg/config"
+
+templ show() {
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <title>GraphiQL - Gentoo Packages</title>
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+ <meta name="theme-color" content="#54487a"/>
+ <meta name="description" content="Gentoo Packages GraphiQL GraphQL API Explorer"/>
+ <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"/>
+ <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
+ <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
+ <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css"/>
+ </head>
+ <body>
+ <div id="graphiql">
+ Loading...
+ </div>
+ <script src="https://unpkg.com/graphiql@0.17.5/graphiql.min.js" type="application/javascript"></script>
+ @templ.Raw(`<script>window.graphqlEndpoint = '` + config.GraphiqlEndpoint() + `';</script>`)
+ <script src="/assets/graphiql.js" type="application/javascript"></script>
+ </body>
+ </html>
+}
+
+func Show(w http.ResponseWriter, r *http.Request) {
+ show().Render(r.Context(), w)
+}
diff --git a/pkg/api/graphql/resolvers/resolver.go b/pkg/api/graphql/resolvers/resolver.go
index 2712cf1..d1a7b6f 100644
--- a/pkg/api/graphql/resolvers/resolver.go
+++ b/pkg/api/graphql/resolvers/resolver.go
@@ -5,7 +5,6 @@ package resolvers
import (
"context"
"errors"
- "github.com/go-pg/pg/v9/orm"
"soko/pkg/api/graphql/generated"
"soko/pkg/app/handler/packages"
"soko/pkg/app/utils"
@@ -13,6 +12,8 @@ import (
"soko/pkg/models"
"strings"
"time"
+
+ "github.com/go-pg/pg/v10"
)
type Resolver struct{}
@@ -26,7 +27,7 @@ func (r *queryResolver) Application(ctx context.Context) (*models.Application, e
func (r *queryResolver) LastCommitTime(ctx context.Context) (*time.Time, error) {
data := utils.GetApplicationData()
lastCommit := &models.Commit{Id: data.LastCommit}
- err := database.DBCon.Select(lastCommit)
+ err := database.DBCon.Model(lastCommit).WherePK().Select()
if err != nil {
return nil, err
}
@@ -218,17 +219,15 @@ func (r *queryResolver) PackageSearch(ctx context.Context, searchTerm *string, r
WhereOr("atom LIKE ? ", wildcardSearchTerm).
WhereOr("name LIKE ? ", wildcardSearchTerm).
Relation("PkgCheckResults").Relation("Bugs").Relation("PullRequests").Relation("ReverseDependencies").Relation("Commits").Relation("Versions").Relation("Versions.Masks").Relation("Versions.PkgCheckResults").Relation("Versions.Dependencies").Relation("PkgCheckResults").Relation("Outdated").
- OrderExpr("name <-> '" + *searchTerm + "'").
+ OrderExpr("name <-> ?", searchTerm).
Limit(limit).
Select()
} else {
// if the query contains no wildcards do a fuzzy search
- searchQuery := packages.BuildSearchQuery(*searchTerm)
- err = database.DBCon.Model(&gpackages).
- Where(searchQuery).
- WhereOr("atom LIKE ? ", ("%" + *searchTerm + "%")).
+ err = packages.BuildSearchQuery(database.DBCon.Model(&gpackages), *searchTerm).
+ WhereOr("atom LIKE ? ", "%"+*searchTerm+"%").
Relation("PkgCheckResults").Relation("Bugs").Relation("PullRequests").Relation("ReverseDependencies").Relation("Commits").Relation("Versions").Relation("Versions.Masks").Relation("Versions.PkgCheckResults").Relation("Versions.Dependencies").Relation("PkgCheckResults").Relation("Outdated").
- OrderExpr("name <-> '" + *searchTerm + "'").
+ OrderExpr("name <-> ?", searchTerm).
Limit(limit).
Select()
}
@@ -339,7 +338,7 @@ func getLimit(limit *int, defaultLimit int) int {
return n
}
-func addStringParams(query *orm.Query, params map[string]*string) *orm.Query {
+func addStringParams(query *pg.Query, params map[string]*string) *pg.Query {
for key, value := range params {
if value != nil {
query = query.Where(key+" = ? ", *value)
@@ -348,7 +347,7 @@ func addStringParams(query *orm.Query, params map[string]*string) *orm.Query {
return query
}
-func addIntParams(query *orm.Query, params map[string]*int) *orm.Query {
+func addIntParams(query *pg.Query, params map[string]*int) *pg.Query {
for key, value := range params {
if value != nil {
query = query.Where(key+" = ? ", *value)
@@ -357,7 +356,7 @@ func addIntParams(query *orm.Query, params map[string]*int) *orm.Query {
return query
}
-func addTimeParams(query *orm.Query, params map[string]*time.Time) *orm.Query {
+func addTimeParams(query *pg.Query, params map[string]*time.Time) *pg.Query {
for key, value := range params {
if value != nil {
query = query.Where(key+" = ? ", *value)
diff --git a/pkg/app/handler/about/feedback.go b/pkg/app/handler/about/feedback.go
deleted file mode 100644
index 24889d5..0000000
--- a/pkg/app/handler/about/feedback.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package about
-
-import "net/http"
-
-// Feedback shows the feedback about page
-func Feedback(w http.ResponseWriter, r *http.Request) {
- renderAboutTemplate(w, r, "feedback")
-}
diff --git a/pkg/app/handler/about/feedback.templ b/pkg/app/handler/about/feedback.templ
new file mode 100644
index 0000000..edd20a2
--- /dev/null
+++ b/pkg/app/handler/about/feedback.templ
@@ -0,0 +1,80 @@
+package about
+
+import "net/http"
+import "soko/pkg/app/layout"
+
+templ feedback() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><a href="/">Home</a></li>
+ <li class="breadcrumb-item"><a href="/about">About</a></li>
+ <li class="breadcrumb-item active">Feedback</li>
+ </ol>
+ <h1>Feedback</h1>
+ <p class="lead">
+ Thanks for checking out the new packages.gentoo.org!
+ </p>
+ <p>
+ This site is currently in an <abbr title="minimum viable product">MVP</abbr> state and will be extended further to provide more useful features.
+ To help us prioritize new features and learn about your use case for the site, please share your ideas below.
+ <br/>
+ <br/>
+ </p>
+ <div class="row">
+ <div class="col-md-8">
+ <div class="card">
+ <h4 class="card-header">
+ Send Feedback
+ </h4>
+ <div class="card-body">
+ <form class="form-horizontal" method="post" action="/about/feedback">
+ <div class="form-group row">
+ <label for="feedback" class="col-sm-2 col-form-label font-weight-bold text-right">Your Feedback:</label>
+ <div class="col-sm-10">
+ <textarea name="feedback" id="feedback" class="form-control" rows="10" placeholder="Please be sure to explain issues in detail and with exact URL references."></textarea>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="contact" class="col-sm-2 col-form-label font-weight-bold text-right">Contact (optional):</label>
+ <div class="col-sm-10">
+ <input type="text" name="contact" class="form-control" id="contact" placeholder="How can we reach you to follow up on your feedback?"/>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="offset-sm-2 col-sm-10">
+ <button type="submit" class="btn btn-outline-primary">Send</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-4">
+ <div class="card">
+ <h4 class="card-header">
+ Other ways to get in touch
+ </h4>
+ <div class="list-group">
+ <a href="mailto:gpackages@gentoo.org" class="list-group-item list-group-item-action text-dark">
+ <span class="fa fa-fw fa-envelope"></span>
+ E-Mail: gpackages@gentoo.org
+ </a>
+ <a href="irc://irc.gentoo.org/gentoo-www" class="list-group-item list-group-item-action text-dark">
+ <span class="fa fa-fw fa-comments-o"></span>
+ IRC: #gentoo-www
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+// Feedback shows the feedback about page
+func Feedback(w http.ResponseWriter, r *http.Request) {
+ layout.Layout("About", "about", feedback()).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/about/feeds.go b/pkg/app/handler/about/feeds.go
deleted file mode 100644
index 3268d76..0000000
--- a/pkg/app/handler/about/feeds.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package about
-
-import "net/http"
-
-// Feeds shows the feeds about page
-func Feeds(w http.ResponseWriter, r *http.Request) {
- renderAboutTemplate(w, r, "feeds")
-}
diff --git a/pkg/app/handler/about/feeds.templ b/pkg/app/handler/about/feeds.templ
new file mode 100644
index 0000000..3b66538
--- /dev/null
+++ b/pkg/app/handler/about/feeds.templ
@@ -0,0 +1,38 @@
+package about
+
+import "net/http"
+import "soko/pkg/app/layout"
+
+templ feeds() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><a href="/">Home</a></li>
+ <li class="breadcrumb-item"><a href="/about">About</a></li>
+ <li class="breadcrumb-item active">Update Feeds</li>
+ </ol>
+ <h1>Update Feeds</h1>
+ <p>
+ You can find Atom feeds here:
+ </p>
+ <ul>
+ <li>
+ For all packages: Right column on the <a href="/categories">category listing</a>.
+ </li>
+ <li>
+ For specific architectures: In the <a href="/arches">architectures section</a>.
+ </li>
+ <li>
+ For specific packages: In the <em>Resources</em> box on the respective package pages.
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+}
+
+// Feeds shows the feeds about page
+func Feeds(w http.ResponseWriter, r *http.Request) {
+ layout.Layout("About", "about", feeds()).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/about/help.go b/pkg/app/handler/about/help.go
deleted file mode 100644
index d697146..0000000
--- a/pkg/app/handler/about/help.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package about
-
-import "net/http"
-
-// Help shows the help about page
-func Help(w http.ResponseWriter, r *http.Request) {
- renderAboutTemplate(w, r, "help")
-}
diff --git a/pkg/app/handler/about/help.templ b/pkg/app/handler/about/help.templ
new file mode 100644
index 0000000..4487600
--- /dev/null
+++ b/pkg/app/handler/about/help.templ
@@ -0,0 +1,42 @@
+package about
+
+import "net/http"
+import "soko/pkg/app/layout"
+
+templ help() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><a href="/">Home</a></li>
+ <li class="breadcrumb-item"><a href="/about">About</a></li>
+ <li class="breadcrumb-item active">Help</li>
+ </ol>
+ <h1>Help</h1>
+ <h2 id="keyword-legend">Keyword table legend</h2>
+ <ul class="list-group kk-keyword-legend">
+ <li class="list-group-item kk-keyword-stable">
+ <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg> &nbsp;Stable
+ </li>
+ <li class="list-group-item kk-keyword-testing">
+ <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg> &nbsp;Testing
+ </li>
+ <li class="list-group-item kk-keyword-unavailable">
+ <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> &nbsp;Explicitly unavailable
+ </li>
+ <li class="list-group-item kk-keyword-masked">
+ <svg height="16" class="octicon octicon-diff-ignored" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> &nbsp;Masked
+ </li>
+ <li class="list-group-item kk-keyword-unknown">
+ <span class="kk-octicon-spacer"></span>&nbsp;Unknown
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+}
+
+// Help shows the help about page
+func Help(w http.ResponseWriter, r *http.Request) {
+ layout.Layout("About", "about", help()).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/about/index.go b/pkg/app/handler/about/index.go
deleted file mode 100644
index d2b1bdf..0000000
--- a/pkg/app/handler/about/index.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package about
-
-import (
- "net/http"
-)
-
-// Index shows the landing page of the about pages
-func Index(w http.ResponseWriter, r *http.Request) {
- renderAboutTemplate(w, r, "index")
-}
diff --git a/pkg/app/handler/about/index.templ b/pkg/app/handler/about/index.templ
new file mode 100644
index 0000000..033b09a
--- /dev/null
+++ b/pkg/app/handler/about/index.templ
@@ -0,0 +1,59 @@
+package about
+
+import "net/http"
+import "runtime/debug"
+import "soko/pkg/app/layout"
+import "soko/pkg/config"
+
+func getCommitId() string {
+ if info, ok := debug.ReadBuildInfo(); ok {
+ for _, setting := range info.Settings {
+ if setting.Key == "vcs.revision" {
+ return setting.Value[:8]
+ }
+ }
+ }
+ return ""
+}
+
+func versionText() string {
+ commitId := getCommitId()
+ version := config.Version()
+ if commitId == "" {
+ return "Currently " + version + " is running."
+ }
+ return "Currently " + version + " is running, based on commit " + commitId + "."
+}
+
+templ index() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12 text-center">
+ <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1>
+ <span style="font-size: 90%;" class="text-muted">
+ Feel free to <a href="/about/feedback">get in touch</a> { "if" } you have any questions that are not answered on this page.
+ <br/>
+ And welcome to the new packages.gentoo.org!
+ </span>
+ </div>
+ <div class="col-12 mt-5 pt-4">
+ <h2>FAQ</h2>
+ <dl>
+ <dt>Which version is currently running?</dt>
+ <dd>{ versionText() }</dd>
+ <br/>
+ <dt>How often is the site updated?</dt>
+ <dd>
+ Updates are scheduled <strong>every 5 minutes now</strong>.
+ You can find the last time an import task was started in the footer.
+ </dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+}
+
+// Index shows the landing page of the about pages
+func Index(w http.ResponseWriter, r *http.Request) {
+ layout.Layout("About", "about", index()).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/about/status.go b/pkg/app/handler/about/status.go
deleted file mode 100644
index 611520d..0000000
--- a/pkg/app/handler/about/status.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package about
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
- "time"
-)
-
-// Index shows the landing page of the about pages
-func Status(w http.ResponseWriter, r *http.Request) {
- templates := template.Must(
- template.Must(
- template.New("status").
- Funcs(template.FuncMap{
- "timeSince": time.Since,
- }).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/about/status.tmpl"))
-
- var applicationData []*models.Application
- database.DBCon.Model(&applicationData).Select()
-
- templates.ExecuteTemplate(w, "status.tmpl", struct {
- Header models.Header
- Application models.Application
- Applications []*models.Application
- }{
- Header: models.Header{Title: "About – ", Tab: "about"},
- Application: utils.GetApplicationData(),
- Applications: applicationData,
- })
-}
diff --git a/pkg/app/handler/about/status.templ b/pkg/app/handler/about/status.templ
new file mode 100644
index 0000000..3c9193b
--- /dev/null
+++ b/pkg/app/handler/about/status.templ
@@ -0,0 +1,49 @@
+package about
+
+import "net/http"
+import "soko/pkg/app/layout"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "time"
+
+templ status(applications []*models.Application) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12 text-center">
+ <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1>
+ <span style="font-size: 90%;" class="text-muted">
+ Feel free to <a href="/about/feedback">get in touch</a> { "if" } you have any questions that are not answered on this page.
+ <br/>
+ And welcome to the new packages.gentoo.org!
+ </span>
+ </div>
+ <div class="col-8 offset-md-2 mt-5 pt-4">
+ <table class="table">
+ <thead>
+ <tr>
+ <th scope="col">Type</th>
+ <th scope="col">Last Update</th>
+ <th scope="col">Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ for _, app := range applications {
+ <tr>
+ <th scope="row" class="text-capitalize">{ app.Id }</th>
+ <td>{ app.LastUpdate.Format(time.DateTime) } UTC</td>
+ <td>{ time.Since(app.LastUpdate).Round(time.Second).String() }</td>
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+}
+
+// Status shows the sync status of updater
+func Status(w http.ResponseWriter, r *http.Request) {
+ var applicationData []*models.Application
+ database.DBCon.Model(&applicationData).Order("id").Column("id", "last_update").Select()
+ layout.Layout("About", "about", status(applicationData)).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/about/utils.go b/pkg/app/handler/about/utils.go
deleted file mode 100644
index e7d692b..0000000
--- a/pkg/app/handler/about/utils.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// miscellaneous utility functions used for the about pages
-
-package about
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/models"
-)
-
-// renderAboutTemplate renders a specific about template
-func renderAboutTemplate(w http.ResponseWriter, r *http.Request, page string) {
- templates := template.Must(
- template.Must(
- template.New(page).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/about/" + page + ".tmpl"))
-
- templates.ExecuteTemplate(w, page+".tmpl", getPageData())
-}
-
-// getPageData returns the data used
-// in all about templates
-func getPageData() interface{} {
- return struct {
- Header models.Header
- Application models.Application
- }{
- Header: models.Header{Title: "About – ", Tab: "about"},
- Application: utils.GetApplicationData(),
- }
-}
diff --git a/pkg/app/handler/arches/changedVersions.templ b/pkg/app/handler/arches/changedVersions.templ
new file mode 100644
index 0000000..fb65fc3
--- /dev/null
+++ b/pkg/app/handler/arches/changedVersions.templ
@@ -0,0 +1,49 @@
+package arches
+
+import "net/http"
+import "soko/pkg/app/layout"
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+
+templ changedVersions(currentArch string, feedName string, versions []*models.Version) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-11">
+ if feedName == "keyworded" {
+ <h3>
+ <a class="text-dark"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a>
+ <a href={ templ.URL("/arches/" + currentArch + "/stable") } class="ml-3 text-muted"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a>
+ </h3>
+ } else {
+ <h3>
+ <a href={ templ.URL("/arches/" + currentArch + "/keyworded") } class="text-muted"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a>
+ <a class="ml-3 text-dark"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a>
+ </h3>
+ }
+ </div>
+ <div class="col-1 text-right">
+ <h3>
+ <a title="Atom feed" href={ templ.URL("/arches/" + currentArch + "/" + feedName + ".atom") } class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
+ </h3>
+ </div>
+ <div class="col-12">
+ <li class="list-group">
+ @utils.ChangedVersionsTable(versions)
+ </li>
+ </div>
+ </div>
+ </div>
+}
+
+var tabs []layout.SubTab
+
+func init() {
+ tabs = make([]layout.SubTab, len(models.AllArches))
+ for i, arch := range models.AllArches {
+ tabs[i] = layout.SubTab{Name: arch, Link: templ.URL("/arches/" + arch + "/keyworded")}
+ }
+}
+
+func renderPage(w http.ResponseWriter, r *http.Request, arch string, content templ.Component) {
+ layout.TabbedLayout("Architectures", "arches", "Architectures", "fa fa-fw fa-server", "", tabs, arch, content).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/arches/index.go b/pkg/app/handler/arches/index.go
deleted file mode 100644
index 41e8178..0000000
--- a/pkg/app/handler/arches/index.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package arches
-
-import (
- "net/http"
- utils2 "soko/pkg/app/utils"
-)
-
-// Index renders a template to show a the landing page containing links to all arches feeds
-func Index(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils2.GetUserPreferences(r)
- http.Redirect(w, r, "/arches/"+userPreferences.Arches.DefaultArch+"/"+userPreferences.Arches.DefaultPage, http.StatusSeeOther)
-}
diff --git a/pkg/app/handler/arches/show.go b/pkg/app/handler/arches/show.go
index a8677b6..40fb048 100644
--- a/pkg/app/handler/arches/show.go
+++ b/pkg/app/handler/arches/show.go
@@ -3,48 +3,59 @@ package arches
import (
"net/http"
"soko/pkg/app/handler/feeds"
- "soko/pkg/app/handler/packages"
- "soko/pkg/app/utils"
"strings"
)
-// Show renders a template to show a list of recently changed version by arch
-func Show(w http.ResponseWriter, r *http.Request) {
- urlParts := strings.Split(r.URL.Path[len("/arches/"):], "/")
- if len(urlParts) == 2 {
- if urlParts[1] == "stable" {
- stabilizedVersions, err := getStabilizedVersionsForArch(urlParts[0], 50)
- if err != nil {
- http.NotFound(w, r)
- return
- }
- renderPackageTemplates("changedVersions", packages.GetFuncMap(), createFeedData(urlParts[0], "Newly Stable", "stable", stabilizedVersions, utils.GetUserPreferences(r)), w)
- } else if urlParts[1] == "stable.atom" {
- stabilizedVersions, err := getStabilizedVersionsForArch(urlParts[0], 250)
- if err != nil {
- http.NotFound(w, r)
- return
- }
- feedTitle := "Stabilized packages in Gentoo on " + urlParts[0]
- feedDescription := feedTitle
- feeds.Changes(feedTitle, feedDescription, stabilizedVersions, w)
- } else if urlParts[1] == "keyworded" {
- keywordedVersions, err := getKeywordedVersionsForArch(urlParts[0], 50)
- if err != nil {
- http.NotFound(w, r)
- return
- }
- renderPackageTemplates("changedVersions", packages.GetFuncMap(), createFeedData(urlParts[0], "Keyworded", "keyworded", keywordedVersions, utils.GetUserPreferences(r)), w)
- } else if urlParts[1] == "keyworded.atom" {
- keywordedVersions, err := getKeywordedVersionsForArch(urlParts[0], 250)
- if err != nil {
- http.NotFound(w, r)
- return
- }
+func ShowStable(w http.ResponseWriter, r *http.Request) {
+ arch := r.PathValue("arch")
+ stabilizedVersions, err := getStabilizedVersionsForArch(arch, 50)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ renderPage(w, r, arch, changedVersions(arch, "stable", stabilizedVersions))
+}
+
+func ShowStableFeed(w http.ResponseWriter, r *http.Request) {
+ arch := r.PathValue("arch")
+ stabilizedVersions, err := getStabilizedVersionsForArch(arch, 250)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ feedTitle := "Stabilized packages in Gentoo on " + arch
+ feedDescription := feedTitle
+ feeds.Changes(feedTitle, feedDescription, stabilizedVersions, w)
+}
+
+func ShowKeyworded(w http.ResponseWriter, r *http.Request) {
+ arch := r.PathValue("arch")
+ keywordedVersions, err := getKeywordedVersionsForArch(arch, 50)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ renderPage(w, r, arch, changedVersions(arch, "keyworded", keywordedVersions))
+}
+
+func ShowKeywordedFeed(w http.ResponseWriter, r *http.Request) {
+ arch := r.PathValue("arch")
+ keywordedVersions, err := getKeywordedVersionsForArch(arch, 250)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ feedTitle := "Keyworded packages in Gentoo on " + arch
+ feedDescription := feedTitle
+ feeds.Changes(feedTitle, feedDescription, keywordedVersions, w)
+}
- feedTitle := "Keyworded packages in Gentoo on " + urlParts[0]
- feedDescription := feedTitle
- feeds.Changes(feedTitle, feedDescription, keywordedVersions, w)
- }
+func ShowLeafPackages(w http.ResponseWriter, r *http.Request) {
+ arch := r.PathValue("arch")
+ leafs, err := getLeafPackagesForArch(arch)
+ if err != nil {
+ http.NotFound(w, r)
+ return
}
+ w.Write([]byte(strings.Join(leafs, "\n")))
}
diff --git a/pkg/app/handler/arches/utils.go b/pkg/app/handler/arches/utils.go
index 3b5144d..8144a3d 100644
--- a/pkg/app/handler/arches/utils.go
+++ b/pkg/app/handler/arches/utils.go
@@ -3,111 +3,69 @@
package arches
import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
"soko/pkg/database"
"soko/pkg/models"
)
-// getPageData creates the data used in all
-// templates used in the arches section
-func getPageData() interface{} {
- return struct {
- Header models.Header
- Application models.Application
- }{
- Header: models.Header{Title: "Architectures – ", Tab: "arches"},
- Application: utils.GetApplicationData(),
- }
-}
-
// getStabilizedVersionsForArch returns the given number of recently
// stabilized versions of a specific arch
func getStabilizedVersionsForArch(arch string, n int) ([]*models.Version, error) {
- var stabilizedVersions []*models.Version
var updates []models.KeywordChange
err := database.DBCon.Model(&updates).
Relation("Version").
Relation("Commit").
Order("commit.preceding_commits DESC").
Where("stabilized::jsonb @> ?", "\""+arch+"\"").
+ Where("version.id IS NOT NULL").
Limit(n).
Select()
if err != nil {
return nil, err
}
- for _, update := range updates {
- if update.Version != nil {
- update.Version.Commits = []*models.Commit{update.Commit}
- stabilizedVersions = append(stabilizedVersions, update.Version)
- }
+ stabilizedVersions := make([]*models.Version, len(updates))
+ for i, update := range updates {
+ update.Version.Commits = []*models.Commit{update.Commit}
+ stabilizedVersions[i] = update.Version
}
-
return stabilizedVersions, err
}
// getKeywordedVersionsForArch returns the given number of recently
// keyworded versions of a specific arch
func getKeywordedVersionsForArch(arch string, n int) ([]*models.Version, error) {
- var stabilizedVersions []*models.Version
var updates []models.KeywordChange
err := database.DBCon.Model(&updates).
Relation("Version").
Relation("Commit").
Order("commit.preceding_commits DESC").
Where("added::jsonb @> ?", "\""+arch+"\"").
+ Where("version.id IS NOT NULL").
Limit(n).
Select()
if err != nil {
return nil, err
}
- for _, update := range updates {
- if update.Version != nil {
- update.Version.Commits = []*models.Commit{update.Commit}
- stabilizedVersions = append(stabilizedVersions, update.Version)
- }
+ keywordedVersions := make([]*models.Version, len(updates))
+ for i, update := range updates {
+ update.Version.Commits = []*models.Commit{update.Commit}
+ keywordedVersions[i] = update.Version
}
-
- return stabilizedVersions, err
+ return keywordedVersions, err
}
-// RenderPackageTemplates renders the arches templates using the given data
-func renderPackageTemplates(page string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) {
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.Must(
- template.New(page).
- Funcs(funcMap).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/arches/archesheader.tmpl")).
- ParseGlob("web/templates/arches/changedVersionRows.tmpl")).
- ParseGlob("web/templates/arches/changedVersions.tmpl"))
-
- templates.ExecuteTemplate(w, page+".tmpl", data)
-}
-
-// CreateFeedData creates the data used in changedVersions template
-func createFeedData(arch string, name string, feedtype string, versions []*models.Version, userPreferences models.UserPreferences) interface{} {
- return struct {
- Header models.Header
- Arch string
- Name string
- FeedName string
- Versions []*models.Version
- Application models.Application
- UserPreferences models.UserPreferences
- }{
- Header: models.Header{Title: "Architectures – ", Tab: "arches"},
- Arch: arch,
- Name: name,
- FeedName: feedtype,
- Versions: versions,
- Application: utils.GetApplicationData(),
- UserPreferences: userPreferences,
- }
+func getLeafPackagesForArch(arch string) ([]string, error) {
+ var atoms []string
+ atomsWithReverse := database.DBCon.Model((*models.ReverseDependency)(nil)).
+ Join("JOIN versions").JoinOn("reverse_dependency.reverse_dependency_atom = versions.atom").
+ Where("keywords LIKE ?", "%"+arch+"%").
+ ColumnExpr("DISTINCT reverse_dependency.atom")
+ err := database.DBCon.Model((*models.Version)(nil)).
+ Where("keywords LIKE ?", "%"+arch+"%").
+ Where("atom NOT IN (?)", atomsWithReverse).
+ Order("atom").
+ ColumnExpr("DISTINCT atom").
+ Select(&atoms)
+ return atoms, err
}
diff --git a/pkg/app/handler/categories/feeds.go b/pkg/app/handler/categories/feeds.go
new file mode 100644
index 0000000..0ccfdeb
--- /dev/null
+++ b/pkg/app/handler/categories/feeds.go
@@ -0,0 +1,38 @@
+package categories
+
+import (
+ "net/http"
+ "soko/pkg/app/utils"
+ "soko/pkg/database"
+ "soko/pkg/models"
+)
+
+func OutdatedFeed(w http.ResponseWriter, r *http.Request) {
+ categoryName := r.PathValue("category")
+ var outdated []models.OutdatedPackages
+ err := database.DBCon.Model(&outdated).
+ Where("atom LIKE ?", categoryName+"/%").
+ Order("atom").
+ Select()
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ utils.OutdatedFeed(w, "https://packages.gentoo.org/categories/"+categoryName+"/outdated", "category "+categoryName, outdated)
+}
+
+func StabilizationFeed(w http.ResponseWriter, r *http.Request) {
+ categoryName := r.PathValue("category")
+ var results []*models.PkgCheckResult
+ err := database.DBCon.Model(&results).
+ Column("atom", "cpv", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom LIKE ?", categoryName+"/%").
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ utils.StabilizationFeed(w, "https://packages.gentoo.org/categories/"+categoryName+"/stabilization", "category "+categoryName, results)
+}
diff --git a/pkg/app/handler/categories/index.go b/pkg/app/handler/categories/index.go
index 18b9f20..7214942 100644
--- a/pkg/app/handler/categories/index.go
+++ b/pkg/app/handler/categories/index.go
@@ -9,19 +9,6 @@ import (
"soko/pkg/models"
)
-// Index renders a template to show all categories
-func Index(w http.ResponseWriter, r *http.Request) {
-
- var categories []*models.Category
- err := database.DBCon.Model(&categories).Order("name ASC").Select()
- if err != nil {
- http.NotFound(w, r)
- return
- }
-
- renderCategoryTemplate("index", createCategoriesData(categories), w)
-}
-
// build the json for the categories overview page
func JSONCategories(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/app/handler/categories/index.templ b/pkg/app/handler/categories/index.templ
new file mode 100644
index 0000000..683e58d
--- /dev/null
+++ b/pkg/app/handler/categories/index.templ
@@ -0,0 +1,51 @@
+package categories
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+
+templ index(categories []*models.Category) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="row">
+ <div class="col-md-12">
+ <h3 class="d-none mb-2">Browse all Categories</h3>
+ <div class="card rounded" style="background: none;border: none;">
+ <div class="card-body">
+ <ul class="kk-col-list kk-6col-list kk-category-listing">
+ for i, cat := range categories {
+ if i == 0 || cat.Name[0] != categories[i-1].Name[0] {
+ <li class="kk-col-list-header"><span class="kk-group-header">{ cat.Name[0:1] }</span></li>
+ }
+ <li>
+ <a
+ title={ cat.Description }
+ data-toggle="tooltip"
+ data-placement="right"
+ href={ templ.URL("/categories/" + cat.Name) }
+ >
+ { cat.Name }
+ </a>
+ </li>
+ }
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+// Index renders a template to show all categories
+func Index(w http.ResponseWriter, r *http.Request) {
+ var categories []*models.Category
+ err := database.DBCon.Model(&categories).Order("name ASC").Select()
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ RenderPage(w, r, "Categories", "Categories", index(categories))
+}
diff --git a/pkg/app/handler/categories/show.go b/pkg/app/handler/categories/show.go
index 381405b..5e9151b 100644
--- a/pkg/app/handler/categories/show.go
+++ b/pkg/app/handler/categories/show.go
@@ -4,93 +4,233 @@ package categories
import (
"encoding/json"
- "github.com/go-pg/pg/v9/orm"
"net/http"
+ "strings"
+
+ "github.com/go-pg/pg/v10"
+
+ "soko/pkg/app/handler/packages/components"
+ "soko/pkg/app/utils"
"soko/pkg/database"
"soko/pkg/models"
- "strings"
)
-// Show renders a template to show a given category
-func Show(w http.ResponseWriter, r *http.Request) {
+func common(w http.ResponseWriter, r *http.Request) (categoryName string, category models.Category, err error) {
+ categoryName = r.PathValue("category")
- if strings.HasSuffix(r.URL.Path, ".json") {
- buildJson(w, r)
+ err = database.DBCon.Model(&category).
+ Where("category.name = ?", categoryName).
+ Relation("PackagesInformation").Select()
+ if err == pg.ErrNoRows {
+ http.NotFound(w, r)
+ return
+ } else if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
+ return
+}
- category := new(models.Category)
- err := database.DBCon.Model(category).
- Where("name = ?", getCategoryName(r)).
- Relation("Packages", func(q *orm.Query) (*orm.Query, error) {
- return q.Order("name ASC"), nil
- }).
- Relation("Packages.Versions").
- Select()
+type packageInfo struct {
+ Package string
+ Description string
+}
+
+func ShowPackages(w http.ResponseWriter, r *http.Request) {
+ categoryName := r.PathValue("category")
+ if strings.HasSuffix(categoryName, ".json") {
+ buildJson(w, categoryName[:len(categoryName)-5])
+ return
+ }
+ categoryName, category, err := common(w, r)
if err != nil {
- http.NotFound(w, r)
return
}
- renderCategoryTemplate("show", createCategoryData(*category), w)
+ var packages []packageInfo
+ err = database.DBCon.Model((*models.Version)(nil)).
+ DistinctOn("package").
+ Column("package", "description").
+ Where("category = ?", categoryName).
+ Order("package ASC").
+ Select(&packages)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ renderShowPage(w, r, "Packages", &category,
+ showPackages(categoryName, packages))
}
-// build the json for the category
-func buildJson(w http.ResponseWriter, r *http.Request) {
-
- category := new(models.Category)
- err := database.DBCon.Model(category).
- Where("name = ?", getCategoryName(r)).
- Relation("Packages").
- Relation("Packages.Versions").
- Select()
+func ShowOutdated(w http.ResponseWriter, r *http.Request) {
+ categoryName, category, err := common(w, r)
if err != nil {
- http.NotFound(w, r)
return
}
- categoryPackages := getJSONPackages(category)
+ var outdated []components.OutdatedItem
+ descriptionQuery := database.DBCon.Model((*models.Version)(nil)).
+ Column("description").
+ Where("atom = outdated_packages.atom").
+ Limit(1)
+ err = database.DBCon.Model((*models.OutdatedPackages)(nil)).
+ Column("atom").ColumnExpr("(?) AS description", descriptionQuery).
+ Where("atom LIKE ?", categoryName+"/%").
+ Order("atom").
+ Select(&outdated)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ renderShowPage(w, r, "Outdated", &category,
+ components.Outdated(outdated))
+}
- jsonCategory := Category{
- Name: category.Name,
- Href: "https://packages.gentoo.org/categories/" + category.Name,
- Packages: categoryPackages,
+func ShowPullRequests(w http.ResponseWriter, r *http.Request) {
+ categoryName, category, err := common(w, r)
+ if err != nil {
+ return
}
- b, err := json.Marshal(jsonCategory)
+ var pullRequests []*models.GithubPullRequest
+ err = database.DBCon.Model(&pullRequests).
+ Join("JOIN package_to_github_pull_requests ON package_to_github_pull_requests.github_pull_request_id = github_pull_request.id").
+ Where("package_to_github_pull_requests.package_atom LIKE ?", categoryName+"/%").
+ Group("github_pull_request.id").
+ Order("github_pull_request.created_at DESC").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ renderShowPage(w, r, "Pull requests", &category,
+ components.PullRequests(pullRequests))
+}
+func ShowBugs(w http.ResponseWriter, r *http.Request) {
+ categoryName, category, err := common(w, r)
if err != nil {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
return
}
+ var bugs []*models.Bug
+ err = database.DBCon.Model(&bugs).
+ DistinctOn("id::INT").
+ Column("id", "summary", "component", "assignee").
+ OrderExpr("id::INT").
+ Where("id IN (?)",
+ database.DBCon.Model((*models.PackageToBug)(nil)).
+ Column("bug_id").
+ Where("package_atom LIKE ?", categoryName+"/%")).
+ WhereOr("id IN (?)",
+ database.DBCon.Model((*models.VersionToBug)(nil)).
+ Column("bug_id").
+ Join("JOIN versions").JoinOn("version_id = versions.id").
+ Where("versions.atom LIKE ?", categoryName+"/%")).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ generalCount, stabilizationCount, keywordingCount := utils.CountBugsCategories(bugs)
+ renderShowPage(w, r, "Bugs", &category,
+ components.Bugs("", generalCount, stabilizationCount, keywordingCount, bugs))
+}
- w.Header().Set("Content-Type", "application/json")
- w.Write(b)
+func ShowSecurity(w http.ResponseWriter, r *http.Request) {
+ categoryName, category, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var bugs []*models.Bug
+ err = database.DBCon.Model(&bugs).
+ DistinctOn("id::INT").
+ Column("id", "summary", "component", "assignee").
+ OrderExpr("id::INT").
+ Where("component = ?", "Vulnerabilities").
+ Where("id IN (?)",
+ database.DBCon.Model((*models.PackageToBug)(nil)).
+ Column("bug_id").
+ Where("package_atom LIKE ?", categoryName+"/%")).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ renderShowPage(w, r, "Security", &category,
+ components.SecurityBugs("", bugs))
}
-// get all maintainers of the package in a format
-// that is intended to be used to convert it to json
-func getJSONPackages(category *models.Category) []Package {
- var categoryPackages []Package
- for _, gpackage := range category.Packages {
- categoryPackages = append(categoryPackages, Package{
- Name: gpackage.Name,
- Href: gpackage.Versions[0].Homepage[0],
- Description: gpackage.Versions[0].Description,
- })
- }
- return categoryPackages
+func ShowStabilizations(w http.ResponseWriter, r *http.Request) {
+ categoryName, category, err := common(w, r)
+ if err != nil {
+ return
+ }
+
+ var results []*models.PkgCheckResult
+ err = database.DBCon.Model(&results).
+ Column("atom", "cpv", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom LIKE ?", categoryName+"/%").
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ renderShowPage(w, r, "Stabilization", &category,
+ components.Stabilizations(results))
}
-type Category struct {
- Name string `json:"name"`
- Href string `json:"href"`
- Packages []Package `json:"packages"`
+func ShowStabilizationFile(w http.ResponseWriter, r *http.Request) {
+ categoryName := r.PathValue("category")
+ var results []*models.PkgCheckResult
+ err := database.DBCon.Model(&results).
+ Column("category", "package", "version", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom LIKE ?", categoryName+"/%").
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ pageName := r.URL.Path[strings.LastIndexByte(r.URL.Path, '/')+1:]
+ utils.StabilizationExport(w, pageName, results)
}
-type Package struct {
- Name string `json:"name"`
- Href string `json:"href"`
- Description string `json:"description"`
+// build the json for the category
+func buildJson(w http.ResponseWriter, categoryName string) {
+ var jsonCategory struct {
+ Name string `json:"name"`
+ Href string `json:"href"`
+ Packages []struct {
+ Package string `json:"name"`
+ Href string `json:"href"`
+ Description string `json:"description"`
+ } `json:"packages"`
+ }
+
+ err := database.DBCon.Model((*models.Version)(nil)).
+ DistinctOn("package").
+ Column("package", "description").
+ ColumnExpr("homepage ->> 0 AS href").
+ Where("category = ?", categoryName).
+ Order("package ASC").
+ Select(&jsonCategory.Packages)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ jsonCategory.Name = categoryName
+ jsonCategory.Href = "https://packages.gentoo.org/categories/" + categoryName
+
+ b, err := json.Marshal(jsonCategory)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.Write(b)
}
diff --git a/pkg/app/handler/categories/show.templ b/pkg/app/handler/categories/show.templ
new file mode 100644
index 0000000..cf80fb6
--- /dev/null
+++ b/pkg/app/handler/categories/show.templ
@@ -0,0 +1,112 @@
+package categories
+
+import "net/http"
+import "strconv"
+import "strings"
+import "soko/pkg/app/layout"
+import "soko/pkg/models"
+
+func packageLetter(name string) string {
+ return strings.ToLower(strings.TrimLeft(name, "_")[:1])
+}
+
+script filter() {
+ const value = document.querySelector("#filter").value.toLowerCase();
+ const rows = document.querySelectorAll("#table tr");
+ for (let i = 0; i < rows.length; i++) {
+ rows[i].style.display = rows[i].cells[0].innerText.toLowerCase().includes(value) ? "" : "none";
+ }
+}
+
+templ showPackages(categoryName string, packages []packageInfo) {
+ <div class="row">
+ <div class="col-12">
+ <div class="row">
+ <div class="col-md-9">
+ <p>
+ <input onKeyup={ filter() } id="filter" type="text" class="form-control form-control-xl" placeholder={ "Search packages in " + categoryName }/>
+ </p>
+ <div class="card border-top-0 rounded">
+ <table class="table mb-0 rounded" id="table">
+ for i, pkg := range packages {
+ <tr
+ if i == 0 || packageLetter(pkg.Package) != packageLetter(packages[i-1].Package) {
+ id={ packageLetter(pkg.Package) }
+ }
+ >
+ <th class="kk-nobreak-cell"><a href={ templ.URL("/packages/" + categoryName + "/" + pkg.Package) }>{ pkg.Package }</a></th>
+ <td>{ pkg.Description }</td>
+ </tr>
+ }
+ </table>
+ </div>
+ @filter()
+ </div>
+ <div class="col-md-3">
+ <h4>Statistics</h4>
+ <dd class="ml-3">
+ <dl>Packages: { strconv.Itoa(len(packages)) }</dl>
+ </dd>
+ <h4 class="mt-4">Filter by Category</h4>
+ <div class="row pl-4 pr-5 mr-5">
+ for i, pkg := range packages {
+ if i == 0 || packageLetter(pkg.Package) != packageLetter(packages[i-1].Package) {
+ <div class="col-md-2 px-2">
+ <a href={ templ.URL("#" + packageLetter(pkg.Package)) } class="text-muted text-capitalize">
+ { packageLetter(pkg.Package) }
+ </a>
+ </div>
+ }
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+templ show(component templ.Component) {
+ <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
+ @component
+ </div>
+}
+
+func renderShowPage(w http.ResponseWriter, r *http.Request, currentTab string, category *models.Category, component templ.Component) {
+ layout.TabbedLayout(category.Name, "packages", category.Name, "fa fa-fw fa-cubes", category.Description, []layout.SubTab{
+ {
+ Name: "Packages",
+ Link: templ.URL("/categories/" + category.Name),
+ Icon: "fa fa-list-ul mr-1",
+ },
+ {
+ Name: "Stabilization",
+ Link: templ.URL("/categories/" + category.Name + "/stabilization"),
+ Icon: "fa fa-check-circle-o mr-1",
+ BadgeValue: strconv.Itoa(category.PackagesInformation.StableRequests),
+ },
+ {
+ Name: "Outdated",
+ Link: templ.URL("/categories/" + category.Name + "/outdated"),
+ Icon: "fa fa-tag mr-1",
+ BadgeValue: strconv.Itoa(category.PackagesInformation.Outdated),
+ },
+ {
+ Name: "Pull requests",
+ Link: templ.URL("/categories/" + category.Name + "/pull-requests"),
+ Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1",
+ BadgeValue: strconv.Itoa(category.PackagesInformation.PullRequests),
+ },
+ {
+ Name: "Bugs",
+ Link: templ.URL("/categories/" + category.Name + "/bugs"),
+ Icon: "fa fa-bug",
+ BadgeValue: strconv.Itoa(category.PackagesInformation.Bugs),
+ },
+ {
+ Name: "Security",
+ Link: templ.URL("/categories/" + category.Name + "/security"),
+ Icon: "fa fa-shield",
+ BadgeValue: strconv.Itoa(category.PackagesInformation.SecurityBugs),
+ },
+ }, currentTab, show(component)).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/categories/utils.go b/pkg/app/handler/categories/utils.go
index bb0c6ee..7c75819 100644
--- a/pkg/app/handler/categories/utils.go
+++ b/pkg/app/handler/categories/utils.go
@@ -1,63 +1,41 @@
-// miscellaneous utility functions used for categories
-
package categories
import (
- "html/template"
"net/http"
- "soko/pkg/app/utils"
- "soko/pkg/models"
- "strings"
-)
-
-// getCategoryName returns the name of the
-// category based on the given URL
-func getCategoryName(r *http.Request) string {
- return strings.ReplaceAll(r.URL.Path[len("/categories/"):], ".json", "")
-}
+ "soko/pkg/app/layout"
-// createCategoriesData creates the data used in
-// the template to display all categories
-func createCategoriesData(categories []*models.Category) interface{} {
- return struct {
- Header models.Header
- Name string
- Categories []*models.Category
- Application models.Application
- }{
- Header: models.Header{Title: "Categories – ", Tab: "packages"},
- Name: "Categories",
- Categories: categories,
- Application: utils.GetApplicationData(),
- }
-}
+ "github.com/a-h/templ"
+)
-// createCategoriesData creates the data used in
-// the template to display a specific category
-func createCategoryData(category models.Category) interface{} {
- return struct {
- Header models.Header
- Category models.Category
- Application models.Application
- }{
- Header: models.Header{Title: category.Name + " – ", Tab: "packages"},
- Category: category,
- Application: utils.GetApplicationData(),
- }
+var categoriesViewTabs = []layout.SubTab{
+ {
+ Name: "Categories",
+ Link: "/categories",
+ Icon: "fa fa-list-ul mr-1",
+ },
+ {
+ Name: "Added",
+ Link: "/packages/added",
+ Icon: "fa fa-history mr-1",
+ },
+ {
+ Name: "Updated",
+ Link: "/packages/updated",
+ Icon: "fa fa-asterisk mr-1",
+ },
+ {
+ Name: "Newly Stable",
+ Link: "/packages/stable",
+ Icon: "fa fa-check-circle-o mr-1",
+ },
+ {
+ Name: "Keyworded",
+ Link: "/packages/keyworded",
+ Icon: "fa fa-circle-o mr-1",
+ },
}
-// renderIndexTemplate renders all templates used for the categories section
-func renderCategoryTemplate(page string, data interface{}, w http.ResponseWriter) {
- templates := template.Must(
- template.Must(
- template.New(page).
- Funcs(template.FuncMap{
- "add": func(a, b int) int {
- return a + b
- },
- }).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/categories/*.tmpl"))
-
- templates.ExecuteTemplate(w, page+".tmpl", data)
+func RenderPage(w http.ResponseWriter, r *http.Request, title string, currentTab string, content templ.Component) {
+ layout.TabbedLayout(title, "packages", "Packages", "fa fa-fw fa-cubes", "", categoriesViewTabs,
+ currentTab, content).Render(r.Context(), w)
}
diff --git a/pkg/app/handler/feeds/changes.go b/pkg/app/handler/feeds/changes.go
index 331d44f..a4adcfa 100644
--- a/pkg/app/handler/feeds/changes.go
+++ b/pkg/app/handler/feeds/changes.go
@@ -2,10 +2,12 @@ package feeds
import (
"fmt"
- "github.com/gorilla/feeds"
+ "html"
"net/http"
"soko/pkg/models"
"time"
+
+ "github.com/gorilla/feeds"
)
// Show renders a template to show a given package
@@ -19,17 +21,16 @@ func Changes(title string, description string, changedVersions []*models.Version
}
addFeedItems(feed, changedVersions)
feed.WriteAtom(w)
-
}
// addFeedItems is a helper to add items to a feed; most of the feeds use []*models.Version as the entity.
func addFeedItems(f *feeds.Feed, versions []*models.Version) {
for _, version := range versions {
- cpv := fmt.Sprintf("%s-%s", version.Atom, version.Version)
+ cpv := version.Atom + "-" + version.Version
item := &feeds.Item{
Title: cpv,
- Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", version.Atom)},
- Description: version.Description,
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + version.Atom},
+ Description: html.EscapeString(version.Description),
Author: &feeds.Author{Name: "unknown"},
Created: time.Now(),
}
diff --git a/pkg/app/handler/feeds/packages.go b/pkg/app/handler/feeds/packages.go
index bbfea46..2186401 100644
--- a/pkg/app/handler/feeds/packages.go
+++ b/pkg/app/handler/feeds/packages.go
@@ -2,10 +2,12 @@ package feeds
import (
"fmt"
- "github.com/gorilla/feeds"
+ "html"
"net/http"
"soko/pkg/models"
"time"
+
+ "github.com/gorilla/feeds"
)
// Show renders a template to show a given package
@@ -26,8 +28,8 @@ func addPackageFeedItems(f *feeds.Feed, gpackages []models.Package) {
for _, gpackage := range gpackages {
item := &feeds.Item{
Title: gpackage.Atom,
- Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", gpackage.Atom)},
- Description: gpackage.Longdescription,
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + gpackage.Atom},
+ Description: html.EscapeString(gpackage.Longdescription),
Author: &feeds.Author{Name: "unknown"},
Created: time.Now(),
}
@@ -54,7 +56,7 @@ func addAddedPackageFeedItems(f *feeds.Feed, packages []*models.Package) {
for _, gpackage := range packages {
item := &feeds.Item{
Title: gpackage.Atom,
- Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", gpackage.Atom)},
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + gpackage.Atom},
Description: gpackage.Description(),
Author: &feeds.Author{Name: "unknown"},
Created: time.Now(),
diff --git a/pkg/app/handler/index/index.go b/pkg/app/handler/index/index.go
deleted file mode 100644
index cd2f438..0000000
--- a/pkg/app/handler/index/index.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Used to show the landing page of the application
-
-package index
-
-import (
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-)
-
-// Show renders a template to show the landing page of the application
-func Show(w http.ResponseWriter, r *http.Request) {
- count, _ := database.DBCon.Model((*models.Package)(nil)).Count()
-
- var packagesList []models.Package
- if utils.GetUserPreferences(r).General.LandingPageLayout == "classic" {
- packagesList = getAddedPackages(10)
- } else {
- packagesList = getSearchHistoryPackages(r)
- }
-
- updatedVersions := getUpdatedVersions(10)
-
- renderIndexTemplate(w, createPageData(count, packagesList, updatedVersions, utils.GetUserPreferences(r)))
-}
diff --git a/pkg/app/handler/index/index.templ b/pkg/app/handler/index/index.templ
new file mode 100644
index 0000000..c3ddab1
--- /dev/null
+++ b/pkg/app/handler/index/index.templ
@@ -0,0 +1,113 @@
+package index
+
+import "net/http"
+import "soko/pkg/app/layout"
+import "soko/pkg/app/utils"
+import "soko/pkg/database"
+import "soko/pkg/models"
+
+templ header(packageCount int) {
+ <div class="col-12">
+ <div class="jumbotron mb-3" style="background: none!important;">
+ <h2 class="site-welcome stick-top">
+ Welcome to the Home
+ <br/>
+ of <span class="text-primary">{ formatPackageCount(packageCount) }</span> Gentoo Packages
+ </h2>
+ <form action="/packages/search" method="get">
+ <div class="typeahead__container px-5">
+ <div class="typeahead__field">
+ <span class="typeahead__query" style="font-size: 1.1em; height: 2.3em;">
+ <input class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus/>
+ </span>
+ <span class="typeahead__button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;">
+ <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit" title="Find" aria-label="Find">
+ <span class="typeahead__search-icon"></span><span class="sr-only">Find</span>
+ </button>
+ </span>
+ </div>
+ </div>
+ </form>
+ <br/>
+ <small class="mt-4 px-5 text-muted" style="font-size: 12px;">
+ This is the new packages.gentoo.org site. If anything isn't working as expected,
+ <a href="mailto:gpackages@gentoo.org">contact us</a>.
+ </small>
+ <br/>
+ <small class="px-5 text-muted" style="font-size: 12px;">
+ You can search by <a href="/packages/search?q=sys-kernel/gentoo-sources">atom</a>, <a href="/packages/search?q=sys-kernel">category</a>, <a href="/packages/search?q=gentoo-sources">name</a>, <a href="/packages/search?q=kernel@gentoo.org">maintainer</a> or <a href="/packages/search?q=x11-wm%20haskell@gentoo.org">combine</a> queries. Results similar to your query will be found as well.
+ </small>
+ </div>
+ </div>
+}
+
+templ packagesList(addedPackages []packageInfo, landingPage string) {
+ <div class="col-12">
+ <h3 class="mb-2">
+ <span class="fa fa-fw fa-history"></span>
+ if landingPage == "classic" {
+ <a class="text-dark" href="/packages/added">Added Packages</a>
+ } else {
+ <a class="text-dark">Search History</a>
+ }
+ </h3>
+ <div class="card border-top-0 mb-4">
+ <div class="table-responsive rounded">
+ <table class="table table-striped rounded mb-0">
+ <tbody>
+ for _, pkg := range addedPackages {
+ <tr>
+ <td>
+ <a href={ templ.URL("/packages/" + pkg.Category + "/" + pkg.Name) }>
+ <span class="text-muted">{ pkg.Category }</span>/<strong>{ pkg.Name }</strong>
+ </a>
+ </td>
+ <td>{ pkg.Description }</td>
+ </tr>
+ }
+ if landingPage == "full" && len(addedPackages) == 0 {
+ <tr><td class="text-center"><i>Visited packages will be displayed here in future</i></td></tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+}
+
+templ page(packageCount int, addedPackages []packageInfo, updatedVersions []*models.Version, userPreferences models.UserPreferences) {
+ <div class="container mb-5">
+ <div class="row">
+ @header(packageCount)
+ @packagesList(addedPackages, userPreferences.General.LandingPageLayout)
+ <div class="col-12">
+ <h3 class="pt-3 mb-2">
+ <span class="fa fa-fw fa-asterisk"></span>
+ <a class="text-dark" href="/packages/updated">Updated Packages</a>
+ </h3>
+ <ul class="list-group">
+ @utils.ChangedVersionsTable(updatedVersions)
+ </ul>
+ </div>
+ </div>
+ </div>
+ <script src="assets/index.js"></script>
+}
+
+// Show renders a template to show the landing page of the application
+func Show(w http.ResponseWriter, r *http.Request) {
+ count, _ := database.DBCon.Model((*models.Package)(nil)).Count()
+
+ var packagesList []packageInfo
+ if utils.GetUserPreferences(r).General.LandingPageLayout == "classic" {
+ packagesList = getAddedPackages(10)
+ } else {
+ packagesList = getSearchHistoryPackages(r)
+ }
+
+ updatedVersions := getUpdatedVersions(10)
+
+ layout.Layout("", "home", page(
+ count, packagesList, updatedVersions, utils.GetUserPreferences(r),
+ )).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/index/utils.go b/pkg/app/handler/index/utils.go
index 54adf76..f524058 100644
--- a/pkg/app/handler/index/utils.go
+++ b/pkg/app/handler/index/utils.go
@@ -4,73 +4,77 @@ package index
import (
b64 "encoding/base64"
- "github.com/go-pg/pg/v9/orm"
- "html/template"
"net/http"
- "reflect"
- "soko/pkg/app/handler/packages"
- "soko/pkg/app/utils"
+ "slices"
"soko/pkg/database"
"soko/pkg/models"
"strconv"
"strings"
+
+ "github.com/go-pg/pg/v10"
)
+type packageInfo struct {
+ Name string
+ Category string
+ Description string
+}
+
// getAddedPackages returns a list of a
// given number of recently added Versions
-func getAddedPackages(n int) []models.Package {
- var addedPackages []models.Package
- err := database.DBCon.Model(&addedPackages).
+func getAddedPackages(n int) (packages []packageInfo) {
+ descriptionQuery := database.DBCon.Model((*models.Version)(nil)).
+ Column("description").
+ Where("atom = package.atom").
+ Limit(1)
+ err := database.DBCon.Model((*models.Package)(nil)).
+ Column("name", "category").
+ ColumnExpr("(?) AS description", descriptionQuery).
Order("preceding_commits DESC").
Limit(n).
- Relation("Versions").
- Select()
+ Select(&packages)
if err != nil {
- return addedPackages
+ return nil
}
- return addedPackages
+ return
}
-func getSearchHistoryPackages(r *http.Request) []models.Package {
- var cookie, err = r.Cookie("search_history")
- var searchedPackages []models.Package
- if err == nil {
- packagesList := getSearchHistoryFromCookie(cookie)
- err := database.DBCon.Model(&searchedPackages).
- Where(getSearchHistoryQuery(packagesList)).
- Relation("Versions").
- Select()
- return getSortedSearchHistory(packagesList, searchedPackages)
- if err != nil {
- return searchedPackages
- }
+func getSearchHistoryPackages(r *http.Request) (packages []packageInfo) {
+ cookie, err := r.Cookie("search_history")
+ if err != nil {
+ return nil
}
- return searchedPackages
+ packagesList := getSearchHistoryFromCookie(cookie)
+
+ descriptionQuery := database.DBCon.Model((*models.Version)(nil)).
+ Column("description").
+ Where("atom = package.atom").
+ Limit(1)
+ err = database.DBCon.Model((*models.Package)(nil)).
+ Column("name", "category").
+ ColumnExpr("(?) AS description", descriptionQuery).
+ Where("atom in (?)", pg.In(packagesList)).
+ Select(&packages)
+ if err != nil {
+ return nil
+ }
+
+ return getSortedSearchHistory(packagesList, packages)
}
-func getSortedSearchHistory(sortedPackagesList []string, packagesList []models.Package) []models.Package {
- var result []models.Package
+func getSortedSearchHistory(sortedPackagesList []string, packagesList []packageInfo) (result []packageInfo) {
for _, gpackage := range sortedPackagesList {
for _, gpackageObject := range packagesList {
- if gpackageObject.Atom == gpackage {
+ if gpackageObject.Category+"/"+gpackageObject.Name == gpackage {
result = append(result, gpackageObject)
}
}
}
- reverse(result)
- return result
-}
-
-func reverse(s interface{}) {
- n := reflect.ValueOf(s).Len()
- swap := reflect.Swapper(s)
- for i, j := 0, n-1; i < j; i, j = i+1, j-1 {
- swap(i, j)
- }
+ slices.Reverse(result)
+ return
}
-func getSearchHistoryFromCookie(cookie *http.Cookie) []string {
- var packagesList []string
+func getSearchHistoryFromCookie(cookie *http.Cookie) (packagesList []string) {
cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value)
if err == nil {
packagesList = strings.Split(string(cookieValue), ",")
@@ -78,15 +82,7 @@ func getSearchHistoryFromCookie(cookie *http.Cookie) []string {
packagesList = packagesList[len(packagesList)-10:]
}
}
- return packagesList
-}
-
-func getSearchHistoryQuery(packagesList []string) string {
- var queryParts []string
- for _, gpackage := range packagesList {
- queryParts = append(queryParts, "atom = '"+gpackage+"'")
- }
- return strings.Join(queryParts, " OR ")
+ return
}
// getUpdatedVersions returns a list of a
@@ -97,10 +93,10 @@ func getUpdatedVersions(n int) []*models.Version {
err := database.DBCon.Model(&updates).
Order("preceding_commits DESC").
Limit(3*n).
- Relation("ChangedVersions", func(q *orm.Query) (*orm.Query, error) {
+ Relation("ChangedVersions", func(q *pg.Query) (*pg.Query, error) {
return q.Limit(30 * n), nil
}).
- Relation("ChangedVersions.Commits", func(q *orm.Query) (*orm.Query, error) {
+ Relation("ChangedVersions.Commits", func(q *pg.Query) (*pg.Query, error) {
return q.Order("preceding_commits DESC"), nil
}).
Select()
@@ -119,53 +115,11 @@ func getUpdatedVersions(n int) []*models.Version {
return updatedVersions
}
-// createPageData creates the data used in the template of the landing page
-func createPageData(packagecount int, addedPackages []models.Package, updatedVersions []*models.Version, userPreferences models.UserPreferences) interface{} {
- return struct {
- Header models.Header
- PackageCount string
- AddedPackages []models.Package
- UpdatedPackages []*models.Version
- Application models.Application
- UserPreferences models.UserPreferences
- }{
- Header: models.Header{Title: "", Tab: "home"},
- Application: utils.GetApplicationData(),
- PackageCount: formatPackageCount(packagecount),
- AddedPackages: addedPackages,
- UpdatedPackages: updatedVersions,
- UserPreferences: userPreferences,
- }
-}
-
-// renderIndexTemplate renders all templates used for the landing page
-func renderIndexTemplate(w http.ResponseWriter, pageData interface{}) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").
- Funcs(getFuncMap()).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/packages/changedVersionRow.tmpl")).
- ParseGlob("web/templates/index/*.tmpl"))
-
- templates.ExecuteTemplate(w, "show.tmpl", pageData)
-}
-
-// GetFuncMap returns the FuncMap used in templates
-func getFuncMap() template.FuncMap {
- return template.FuncMap{
- "contains": strings.Contains,
- "mkSlice": mkSlice,
- "formatRestricts": packages.FormatRestricts,
- }
-}
-
// formatPackageCount returns the formatted number of
// packages containing a thousands comma
func formatPackageCount(packageCount int) string {
packages := strconv.Itoa(packageCount)
- if len(string(packageCount)) == 6 {
+ if len(packages) == 6 {
return packages[:3] + "," + packages[3:]
} else if len(packages) == 5 {
return packages[:2] + "," + packages[2:]
@@ -175,8 +129,3 @@ func formatPackageCount(packageCount int) string {
return packages
}
}
-
-// mkSlice creates a slice based on the given arguments
-func mkSlice(args ...interface{}) []interface{} {
- return args
-}
diff --git a/pkg/app/handler/maintainer/browse.go b/pkg/app/handler/maintainer/browse.go
deleted file mode 100644
index e661d5f..0000000
--- a/pkg/app/handler/maintainer/browse.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package maintainer
-
-import (
- "net/http"
- "soko/pkg/database"
- "soko/pkg/models"
- "sort"
- "strings"
-)
-
-// Show renders a template to show a given maintainer page
-func Browse(w http.ResponseWriter, r *http.Request) {
-
- tabName := "projects"
- if strings.HasSuffix(r.URL.Path, "/gentoo-projects") {
- tabName = "projects"
- } else if strings.HasSuffix(r.URL.Path, "/gentoo-developers") {
- tabName = "gentoo-developers"
- } else if strings.HasSuffix(r.URL.Path, "/proxied-maintainers") {
- tabName = "proxied-maintainers"
- }
-
- var maintainers []*models.Maintainer
- database.DBCon.Model(&maintainers).Select()
-
- sort.Slice(maintainers, func(i, j int) bool {
- return maintainers[i].Name < maintainers[j].Name
- })
-
- renderBrowseTemplate(createBrowseData(tabName, maintainers), w)
-
-}
diff --git a/pkg/app/handler/maintainer/browse.templ b/pkg/app/handler/maintainer/browse.templ
new file mode 100644
index 0000000..f7bc8b6
--- /dev/null
+++ b/pkg/app/handler/maintainer/browse.templ
@@ -0,0 +1,94 @@
+package maintainer
+
+import "soko/pkg/models"
+import "soko/pkg/app/layout"
+import "net/http"
+import "soko/pkg/database"
+
+templ browsePage(maintainers []*models.Maintainer) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="row">
+ <div class="col-md-12">
+ <ul class="kk-col-list kk-6col-list kk-category-listing">
+ for i, maintainer := range maintainers {
+ if i == 0 || maintainer.Name[0] != maintainers[i-1].Name[0] {
+ <li class="kk-col-list-header">
+ <span class="kk-group-header">
+ if maintainer.Name != "" {
+ { maintainer.Name[0:1] }
+ } else {
+ #
+ }
+ </span>
+ </li>
+ }
+ <li>
+ <a
+ title={ maintainer.Name }
+ data-toggle="tooltip"
+ data-placement="right"
+ href={ templ.URL("/maintainer/" + maintainer.Email) }
+ >
+ if maintainer.Name != "" {
+ { maintainer.Name }
+ } else {
+ { maintainer.Email }
+ }
+ </a>
+ </li>
+ }
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+var browseViewTabs = []layout.SubTab{
+ {
+ Name: "Gentoo Projects",
+ Link: "/maintainers",
+ Icon: "fa fa-users mr-1",
+ },
+ {
+ Name: "Gentoo Developers",
+ Link: "/maintainers/gentoo-developers",
+ Icon: "fa fa-user mr-1",
+ },
+ {
+ Name: "Proxied Maintainers",
+ Link: "/maintainers/proxied-maintainers",
+ Icon: "fa fa-user-o mr-1",
+ },
+}
+
+func renderBrowsePage(w http.ResponseWriter, r *http.Request, title string, dbType string) {
+ var maintainers []*models.Maintainer
+ err := database.DBCon.Model(&maintainers).
+ Where("type = ?", dbType).
+ Order("name").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+
+ layout.TabbedLayout(title, "maintainers", "Maintainers", "fa fa-fw fa-users", "", browseViewTabs,
+ title, browsePage(maintainers)).Render(r.Context(), w)
+}
+
+func BrowseProjects(w http.ResponseWriter, r *http.Request) {
+ renderBrowsePage(w, r, "Gentoo Projects", "project")
+}
+
+func BrowseDevs(w http.ResponseWriter, r *http.Request) {
+ renderBrowsePage(w, r, "Gentoo Developers", "gentoo-developer")
+}
+
+func BrowseProxyDevs(w http.ResponseWriter, r *http.Request) {
+ renderBrowsePage(w, r, "Proxied Maintainers", "proxied-maintainer")
+}
diff --git a/pkg/app/handler/maintainer/show.go b/pkg/app/handler/maintainer/show.go
index fec48be..c6262b1 100644
--- a/pkg/app/handler/maintainer/show.go
+++ b/pkg/app/handler/maintainer/show.go
@@ -1,115 +1,348 @@
package maintainer
import (
- "github.com/go-pg/pg/v9/orm"
+ "encoding/json"
+ "html"
"net/http"
+ "soko/pkg/app/handler/packages/components"
+ "soko/pkg/app/layout"
"soko/pkg/app/utils"
"soko/pkg/database"
"soko/pkg/models"
- "sort"
"strings"
+ "time"
+
+ "github.com/go-pg/pg/v10"
+ "github.com/gorilla/feeds"
)
-// Show renders a template to show a given maintainer page
-func Show(w http.ResponseWriter, r *http.Request) {
- maintainerEmail := r.URL.Path[len("/maintainer/"):]
- maintainerEmail = strings.Split(maintainerEmail, "/")[0]
+func common(w http.ResponseWriter, r *http.Request) (maintainer models.Maintainer, packagesQuery *pg.Query, packagesCount int, err error) {
+ maintainerEmail := r.PathValue("email")
if !strings.Contains(maintainerEmail, "@") {
- maintainerEmail = maintainerEmail + "@gentoo.org"
+ maintainerEmail += "@gentoo.org"
}
- whereClause := "maintainers @> '[{\"Email\": \"" + maintainerEmail + "\"}]'"
+ packagesQuery = database.DBCon.Model((*models.Package)(nil)).Column("atom")
+
if maintainerEmail == "maintainer-needed@gentoo.org" {
- whereClause = "maintainers IS null"
+ packagesQuery = packagesQuery.Where("NULLIF(maintainers, '[]') IS null")
+ } else {
+ packagesQuery = packagesQuery.Where("maintainers @> ?", `[{"Email": "`+maintainerEmail+`"}]`)
}
- maintainer := models.Maintainer{
- Email: maintainerEmail,
+ maintainer = models.Maintainer{Email: maintainerEmail}
+ err = database.DBCon.Model(&maintainer).WherePK().Relation("Project").Relation("Projects").Select()
+ if err != nil {
+ http.NotFound(w, r)
+ return
}
- database.DBCon.Model(&maintainer).WherePK().Relation("Project").Relation("Projects").Select()
userPreferences := utils.GetUserPreferences(r)
if userPreferences.Maintainers.IncludeProjectPackages && maintainer.Projects != nil && len(maintainer.Projects) > 0 {
- whereParts := []string{"maintainers @> '[{\"Email\": \"" + maintainerEmail + "\"}]'"}
+ excludeList := strings.Join(userPreferences.Maintainers.ExcludedProjects, ",")
for _, proj := range maintainer.Projects {
- if !strings.Contains(strings.Join(userPreferences.Maintainers.ExcludedProjects, ","), proj.Email) {
- whereParts = append(whereParts, "maintainers @> '[{\"Email\": \""+proj.Email+"\"}]'")
+ if !strings.Contains(excludeList, proj.Email) {
+ packagesQuery = packagesQuery.WhereOr("maintainers @> ?", `[{"Email": "`+proj.Email+`"}]`)
}
}
- whereClause = strings.Join(whereParts, " OR ")
}
- var gpackages []*models.Package
- query := database.DBCon.Model(&gpackages).
- Where(whereClause)
-
- pageName := "packages"
- if strings.HasSuffix(r.URL.Path, "/changelog") {
- pageName = "changelog"
- query = query.
- Relation("Versions").
- Relation("Commits", func(q *orm.Query) (*orm.Query, error) {
- return q.Order("preceding_commits DESC").Limit(50), nil
- })
- } else if strings.HasSuffix(r.URL.Path, "/outdated") {
- pageName = "outdated"
- query = query.
- Relation("Versions").
- Relation("Outdated")
- } else if strings.HasSuffix(r.URL.Path, "/qa-report") {
- pageName = "qa-report"
- query = query.
- Relation("Versions").
- Relation("PkgCheckResults").
- Relation("Versions.PkgCheckResults")
- } else if strings.HasSuffix(r.URL.Path, "/pull-requests") {
- pageName = "pull-requests"
- query = query.
- Relation("Versions").
- Relation("PullRequests")
- } else if strings.HasSuffix(r.URL.Path, "/stabilization") {
- pageName = "stabilization"
- query = query.
- Relation("Versions").
- Relation("PkgCheckResults").
- Relation("Versions.PkgCheckResults").
- Relation("Bugs")
- } else if strings.HasSuffix(r.URL.Path, "/bugs") {
- pageName = "bugs"
- query = query.
- Relation("Versions").
- Relation("Versions.Bugs").
- Relation("Bugs")
- } else if strings.HasSuffix(r.URL.Path, "/security") {
- pageName = "security"
- query = query.
- Relation("Versions").
- Relation("Versions.Bugs").
- Relation("Bugs")
- } else {
- query = query.
- Relation("Versions").
- Relation("Versions.Masks")
+ packagesCount, err = packagesQuery.Clone().Count()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ return
+}
+
+func ShowChangelog(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var commits []*models.Commit
+ err = database.DBCon.Model(&commits).
+ Join("JOIN commit_to_packages").JoinOn("commit.id = commit_to_packages.commit_id").
+ Where("commit_to_packages.package_atom IN (?)", query).
+ Order("preceding_commits DESC").
+ Limit(50).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Changelog", components.Changelog("", commits)),
+ ).Render(r.Context(), w)
+}
+
+func ShowChangelogFeed(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, _, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var commits []*models.Commit
+ err = database.DBCon.Model(&commits).
+ Join("JOIN commit_to_packages").JoinOn("commit.id = commit_to_packages.commit_id").
+ Where("commit_to_packages.package_atom IN (?)", query).
+ Order("preceding_commits DESC").
+ Limit(100).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ feed := &feeds.Feed{
+ Title: "100 latest commits for " + maintainer.Name,
+ Description: "100 latest commits for " + maintainer.Name,
+ Author: &feeds.Author{Name: "Gentoo Packages Database"},
+ Created: time.Now(),
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/maintainer/" + maintainer.Email + "/changelog"},
+ }
+
+ for _, commit := range commits {
+ feed.Add(&feeds.Item{
+ Title: html.EscapeString(commit.Message),
+ Updated: commit.CommitterDate,
+ Created: commit.AuthorDate,
+ Author: &feeds.Author{Name: commit.CommitterName, Email: commit.CommitterEmail},
+ Link: &feeds.Link{Href: "https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id, Type: "text/html", Rel: "alternate"},
+ Id: commit.Id,
+ })
+ }
+ feed.WriteAtom(w)
+}
+
+func ShowOutdated(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var outdated []components.OutdatedItem
+ descriptionQuery := database.DBCon.Model((*models.Version)(nil)).
+ Column("description").
+ Where("atom = outdated_packages.atom").
+ Limit(1)
+ err = database.DBCon.Model((*models.OutdatedPackages)(nil)).
+ Column("atom").ColumnExpr("(?) AS description", descriptionQuery).
+ Where("atom IN (?)", query).
+ Order("atom").
+ Select(&outdated)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Outdated", components.Outdated(outdated)),
+ ).Render(r.Context(), w)
+}
+
+func ShowOutdatedFeed(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, _, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var outdated []models.OutdatedPackages
+ err = database.DBCon.Model(&outdated).
+ Where("atom IN (?)", query).
+ Order("atom").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ utils.OutdatedFeed(w, "https://packages.gentoo.org/maintainer/"+maintainer.Email+"/outdated", maintainer.Name+" <"+maintainer.Email+">", outdated)
+}
+
+func ShowPullRequests(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var pullRequests []*models.GithubPullRequest
+ err = database.DBCon.Model(&pullRequests).
+ DistinctOn("github_pull_request.id").
+ OrderExpr("github_pull_request.id DESC").
+ Join("JOIN package_to_github_pull_requests").JoinOn("github_pull_request.id = package_to_github_pull_requests.github_pull_request_id").
+ Where("package_atom IN (?)", query).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Pull requests", components.PullRequests(pullRequests)),
+ ).Render(r.Context(), w)
+}
+
+func ShowStabilization(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var results []*models.PkgCheckResult
+ err = database.DBCon.Model(&results).
+ Column("atom", "cpv", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom IN (?)", query).
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Stabilization", components.Stabilizations(results)),
+ ).Render(r.Context(), w)
+}
+
+func ShowBugs(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var bugs []*models.Bug
+ err = database.DBCon.Model(&bugs).
+ DistinctOn("id::INT").
+ Column("id", "summary", "component", "assignee").
+ OrderExpr("id::INT").
+ With("wanted", query).
+ Where("id IN (?)",
+ database.DBCon.Model((*models.PackageToBug)(nil)).
+ Column("bug_id").
+ Join("JOIN wanted").JoinOn("package_atom = wanted.atom")).
+ WhereOr("id IN (?)",
+ database.DBCon.Model((*models.VersionToBug)(nil)).
+ Column("bug_id").
+ Join("JOIN versions").JoinOn("version_id = versions.id").
+ Join("JOIN wanted").JoinOn("versions.atom = wanted.atom")).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ generalCount, stabilizationCount, keywordingCount := utils.CountBugsCategories(bugs)
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Bugs", components.Bugs("", generalCount, stabilizationCount, keywordingCount, bugs)),
+ ).Render(r.Context(), w)
+}
+
+func ShowSecurity(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var bugs []*models.Bug
+ err = database.DBCon.Model(&bugs).
+ DistinctOn("id::INT").
+ Column("id", "summary", "component", "assignee").
+ OrderExpr("id::INT").
+ With("wanted", query).
+ Where("component = ?", "Vulnerabilities").
+ Where("id IN (?)",
+ database.DBCon.Model((*models.PackageToBug)(nil)).
+ Column("bug_id").
+ Join("JOIN wanted").JoinOn("package_atom = wanted.atom")).
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Security", components.SecurityBugs("", bugs)),
+ ).Render(r.Context(), w)
+}
+
+func ShowStabilizationFile(w http.ResponseWriter, r *http.Request) {
+ _, query, _, err := common(w, r)
+ if err != nil {
+ return
+ }
+ pageName := r.URL.Path[strings.LastIndexByte(r.URL.Path, '/')+1:]
+
+ var results []*models.PkgCheckResult
+ err = database.DBCon.Model(&results).
+ Column("category", "package", "version", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom IN (?)", query).
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
}
+ utils.StabilizationExport(w, pageName, results)
+}
- err := query.Select()
+func ShowStabilizationFeed(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, _, err := common(w, r)
+ if err != nil {
+ return
+ }
- if err != nil || len(gpackages) == 0 {
+ var results []*models.PkgCheckResult
+ err = database.DBCon.Model(&results).
+ Column("atom", "cpv", "message").
+ Where("class = ?", "StableRequest").
+ Where("atom IN (?)", query).
+ OrderExpr("cpv").
+ Select()
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ utils.StabilizationFeed(w, "https://packages.gentoo.org/maintainer/"+maintainer.Email+"/stabilization", maintainer.Name+" <"+maintainer.Email+">", results)
+}
+
+func ShowPackages(w http.ResponseWriter, r *http.Request) {
+ maintainer, query, packagesCount, err := common(w, r)
+ if err != nil {
+ return
+ }
+ var gpackages []*models.Package
+ err = query.Model(&gpackages).
+ Column("category").
+ Order("category", "name").
+ Relation("Versions").Select()
+ if err != nil {
http.NotFound(w, r)
return
}
+ layout.Layout(maintainer.Name, "maintainers",
+ show(packagesCount, &maintainer, "Packages", showPackages(gpackages, &maintainer)),
+ ).Render(r.Context(), w)
+}
- sort.Slice(gpackages, func(i, j int) bool {
- if gpackages[i].Category != gpackages[j].Category {
- return gpackages[i].Category < gpackages[j].Category
- }
- return gpackages[i].Name < gpackages[j].Name
- })
+func ShowInfoJson(w http.ResponseWriter, r *http.Request) {
+ maintainer, _, _, err := common(w, r)
+ if err != nil {
+ return
+ }
- renderMaintainerTemplate("show",
- "*",
- GetFuncMap(),
- createMaintainerData(pageName, &maintainer, gpackages),
- w)
+ var reply struct {
+ Email string `json:"email"`
+ Name string `json:"name"`
+ IsProject bool `json:"is_project"`
+ Members []string `json:"members"`
+ MemberOf []string `json:"member_of"`
+ }
+ reply.Email = maintainer.Email
+ reply.Name = maintainer.Name
+ reply.IsProject = maintainer.Type == "project"
+
+ for _, member := range maintainer.Project.Members {
+ reply.Members = append(reply.Members, member.Email)
+ }
+ for _, project := range maintainer.Projects {
+ reply.MemberOf = append(reply.MemberOf, project.Email)
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ err = json.NewEncoder(w).Encode(reply)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ }
}
diff --git a/pkg/app/handler/maintainer/show.templ b/pkg/app/handler/maintainer/show.templ
new file mode 100644
index 0000000..317ce70
--- /dev/null
+++ b/pkg/app/handler/maintainer/show.templ
@@ -0,0 +1,256 @@
+package maintainer
+
+import "strconv"
+import "strings"
+import "soko/pkg/app/layout"
+import "soko/pkg/models"
+
+func showViewTabs(email string, packagesCount int, info *models.MaintainerPackagesInformation) []layout.SubTab {
+ return []layout.SubTab{
+ {
+ Name: "Packages",
+ Link: templ.URL("/maintainer/" + email),
+ Icon: "fa fa-info mr-1",
+ BadgeValue: strconv.Itoa(packagesCount),
+ },
+ {
+ Name: "Stabilization",
+ Link: templ.URL("/maintainer/" + email + "/stabilization"),
+ Icon: "fa fa-check-circle-o mr-1",
+ BadgeValue: strconv.Itoa(info.StableRequests),
+ },
+ {
+ Name: "Outdated",
+ Link: templ.URL("/maintainer/" + email + "/outdated"),
+ Icon: "fa fa-tag mr-1",
+ BadgeValue: strconv.Itoa(info.Outdated),
+ },
+ {
+ Name: "Pull requests",
+ Link: templ.URL("/maintainer/" + email + "/pull-requests"),
+ Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1",
+ BadgeValue: strconv.Itoa(info.PullRequests),
+ },
+ {
+ Name: "Bugs",
+ Link: templ.URL("/maintainer/" + email + "/bugs"),
+ Icon: "fa fa-bug",
+ BadgeValue: strconv.Itoa(info.Bugs),
+ },
+ {
+ Name: "Security",
+ Link: templ.URL("/maintainer/" + email + "/security"),
+ Icon: "fa fa-shield",
+ BadgeValue: strconv.Itoa(info.SecurityBugs),
+ },
+ {
+ Name: "Changelog",
+ Link: templ.URL("/maintainer/" + email + "/changelog"),
+ Icon: "fa fa-fw fa-history",
+ },
+ }
+}
+
+templ tabbedHeader(maintainer *models.Maintainer, packagesCount int, currentSubTab string) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title">
+ <small class="kk-package-cat">
+ if maintainer.Email == "maintainer-needed@gentoo.org" {
+ } else if maintainer.Type == "project" {
+ Gentoo Project
+ } else if strings.Contains(maintainer.Email, "@gentoo.org") {
+ Gentoo Developer
+ } else if maintainer.Email != "" {
+ Proxied Maintainer
+ }
+ </small>
+ <div>
+ <svg height="32" class="octicon octicon-person right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg>
+ <div class="kk-package-name">
+ if len(maintainer.Name) > 0 {
+ { maintainer.Name }
+ } else if len(maintainer.Email) > 0 {
+ { maintainer.Email }
+ } else {
+ Maintainer Needed
+ }
+ </div>
+ </div>
+ </h1>
+ </div>
+ <div class="col-md-7"></div>
+ <div class="col-md-12 pt-4 mt-1">
+ <nav class="nav kk-package-nav">
+ for _, tab := range showViewTabs(maintainer.Email, packagesCount, &maintainer.PackagesInformation) {
+ <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }>
+ <i class={ tab.Icon } aria-hidden="true"></i> { tab.Name }
+ if tab.BadgeValue != "" {
+ <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span>
+ }
+ </a>
+ }
+ </nav>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+templ show(packagesCount int, maintainer *models.Maintainer, currentSubTab string, component templ.Component) {
+ @tabbedHeader(maintainer, packagesCount, currentSubTab)
+ <div class="tab-content" id="myTabContent">
+ <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
+ @component
+ </div>
+ </div>
+}
+
+script filter() {
+ const value = document.querySelector("#filter").value.toLowerCase();
+ const groups = document.querySelectorAll("#pkglist .list-group");
+ for (let i = 0; i < groups.length; i++) {
+ let visible = false;
+ const rows = groups[i].querySelectorAll(".list-group-item");
+ for (let j = 0; j < rows.length; j++) {
+ const flag = rows[j].children[0].children[0].innerText.toLowerCase().includes(value);
+ rows[j].style.display = flag ? "" : "none";
+ visible ||= flag;
+ }
+ groups[i].style.display = visible ? "" : "none";
+ }
+}
+
+templ showPackages(packages []*models.Package, maintainer *models.Maintainer) {
+ <div class="row">
+ <div class="col-md-9" id="pkglist">
+ if len(packages) > 0 {
+ <p>
+ <input onKeyup={ filter() } id="filter" type="text" class="form-control form-control-xl" placeholder={ "Search packages maintained by " + maintainer.Email }/>
+ </p>
+ <ul class="list-group">
+ <h3 id={ packages[0].Category }>{ packages[0].Category }</h3>
+ for i, pkg := range packages {
+ if i != 0 && pkg.Category != packages[i-1].Category {
+ @templ.Raw("</ul>")
+ <h3 class="mt-4" id={ pkg.Category }>{ pkg.Category }</h3>
+ @templ.Raw(`<ul class="list-group">`)
+ }
+ <li class="list-group-item">
+ <div class="row">
+ <div class="col-md-4">
+ <a href={ templ.URL("/packages/" + pkg.Atom) } class="text-dark"><b>{ pkg.Atom }</b></a>
+ </div>
+ <div class="col-md-8 text-muted">
+ { pkg.Description() }
+ </div>
+ </div>
+ </li>
+ }
+ </ul>
+ @filter()
+ } else {
+ <div class="row">
+ <div class="col-md-8"></div>
+ <div class="col-md-4">
+ <img
+ style="width: 100%;"
+ src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"
+ />
+ </div>
+ </div>
+ }
+ </div>
+ <div class="col-md-3 pt-4">
+ if maintainer.Project.Description != "" {
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <dl>
+ <dd class="ml-3 mb-0 text-muted">
+ { maintainer.Project.Description }
+ </dd>
+ </dl>
+ </div>
+ }
+ <h4 class={ templ.KV("mt-4", maintainer.Project.Description != "") }>
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ External Resources
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseExternalResources">
+ <dl class="ml-3">
+ <dd>
+ <span class="fa fa-fw fa-chain-broken"></span>
+ <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;maintainer=" + maintainer.Email) } title="CI report" target="_blank">CI Report</a>
+ (<a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;maintainer=" + maintainer.Email) } title="Verbose CI report" target="_blank">verbose</a>)
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-book"></span>
+ <a href={ templ.URL(maintainer.Project.Url) } target="_blank">Documentation</a>
+ </dd>
+ </dl>
+ </div>
+ if maintainer.Project.Description != "" {
+ <h4 class="mt-4">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseMembers" role="button" aria-expanded="false" aria-controls="collapseMembers">
+ Members
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseMembers">
+ <dl>
+ for _, member := range maintainer.Project.Members {
+ <dd class="ml-3 mb-0">
+ <a href={ templ.URL("/maintainer/" + member.Email) }>{ member.Name }</a>
+ if member.IsLead {
+ (Lead)
+ }
+ </dd>
+ }
+ </dl>
+ </div>
+ }
+ if len(maintainer.Projects) > 0 {
+ <h4>
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseProjects" role="button" aria-expanded="false" aria-controls="collapseProjects">
+ Projects
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseProjects">
+ <dl>
+ for _, project := range maintainer.Projects {
+ <dd class="ml-3 mb-0"><a href={ templ.URL("/maintainer/" + project.Email) }>{ project.Name }</a></dd>
+ }
+ </dl>
+ </div>
+ }
+ if len(packages) > 0 {
+ <h4 class="mt-4">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts">
+ Shortcuts
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseShortcuts">
+ <dl>
+ for i, pkg := range packages {
+ if i == 0 || pkg.Category != packages[i-1].Category {
+ <dd class="ml-3 mb-0">
+ <a href={ templ.URL("#" + pkg.Category) }>{ pkg.Category }</a>
+ </dd>
+ }
+ }
+ </dl>
+ </div>
+ }
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/maintainer/utils.go b/pkg/app/handler/maintainer/utils.go
deleted file mode 100644
index c59a19f..0000000
--- a/pkg/app/handler/maintainer/utils.go
+++ /dev/null
@@ -1,142 +0,0 @@
-package maintainer
-
-import (
- "crypto/md5"
- "encoding/hex"
- "html/template"
- "net/http"
- "soko/pkg/app/handler/packages"
- "soko/pkg/app/utils"
- "soko/pkg/models"
- "sort"
- "strings"
-)
-
-// RenderPackageTemplates renders the given templates using the given data
-// One pattern can be used to specify templates
-func renderMaintainerTemplate(page string, templatepattern string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.New(page).
- Funcs(funcMap).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/maintainer/components/*.tmpl")).
- ParseGlob("web/templates/maintainer/" + templatepattern + ".tmpl"))
- templates.ExecuteTemplate(w, page+".tmpl", data)
-}
-
-// renderIndexTemplate renders all templates used for the categories section
-func renderBrowseTemplate(data interface{}, w http.ResponseWriter) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("browse").
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/maintainer/maintainersbrowseheader.tmpl")).
- ParseGlob("web/templates/maintainer/browse.tmpl"))
-
- templates.ExecuteTemplate(w, "browse.tmpl", data)
-}
-
-// createPackageData creates the data used in the show package template
-func createMaintainerData(pageName string, maintainer *models.Maintainer, gpackages []*models.Package) interface{} {
- return struct {
- PageName string
- Maintainer *models.Maintainer
- Header models.Header
- Packages []*models.Package
- Application models.Application
- }{
- PageName: pageName,
- Maintainer: maintainer,
- Header: models.Header{Title: maintainer.Name + " – ", Tab: "maintainers"},
- Packages: gpackages,
- Application: utils.GetApplicationData(),
- }
-}
-
-// createCategoriesData creates the data used in
-// the template to display a specific category
-func createBrowseData(tabName string, data interface{}) interface{} {
- return struct {
- Header models.Header
- TabName string
- Maintainers interface{}
- Application models.Application
- }{
- Header: models.Header{Title: "Maintainers – ", Tab: "maintainers"},
- TabName: tabName,
- Maintainers: data,
- Application: utils.GetApplicationData(),
- }
-}
-
-func getAllBugs(packages []*models.Package) []*models.Bug {
- allBugs := make(map[string]*models.Bug)
-
- for _, gpackage := range packages {
- for _, bug := range gpackage.AllBugs() {
- allBugs[bug.Id] = bug
- }
- }
-
- var allBugsList []*models.Bug
- for _, bug := range allBugs {
- allBugsList = append(allBugsList, bug)
- }
-
- sort.Slice(allBugsList, func(i, j int) bool {
- return allBugsList[i].Id < allBugsList[j].Id
- })
-
- return allBugsList
-}
-
-// GetFuncMap returns the FuncMap used in templates
-func GetFuncMap() template.FuncMap {
- return template.FuncMap{
- "contains": strings.Contains,
- "replaceall": strings.ReplaceAll,
- "tolower": strings.ToLower,
- "getAllBugs": getAllBugs,
- "formatRestricts": packages.FormatRestricts,
- "appendCommits": func(a []*models.Commit, b []*models.Commit) []*models.Commit {
- return append(a, b...)
- },
- "gravatar": func(email string) string {
- hasher := md5.Sum([]byte(email))
- hash := hex.EncodeToString(hasher[:])
- return "https://www.gravatar.com/avatar/" + hash + "?s=13&amp;d=retro"
- },
- "getReverse": func(index int, versions []*models.Version) *models.Version {
- return versions[len(versions)-1-index]
- },
- "mkSlice": func(args ...interface{}) []interface{} {
- return args
- },
- "add": func(a, b int) int {
- return a + b
- },
- "sortCommits": func(commits []*models.Commit) []*models.Commit {
- sort.Slice(commits, func(i, j int) bool {
- return commits[i].PrecedingCommits > commits[j].PrecedingCommits
- })
- return commits
- },
- "getPullRequests": func(packages []*models.Package) []*models.GithubPullRequest {
- pullrequestsMap := map[string]*models.GithubPullRequest{}
- for _, gpackage := range packages {
- for _, pr := range gpackage.PullRequests {
- pullrequestsMap[pr.Id] = pr
- }
- }
-
- var pullrequests []*models.GithubPullRequest
- for _, pr := range pullrequestsMap {
- pullrequests = append(pullrequests, pr)
- }
- return pullrequests
- },
- }
-}
diff --git a/pkg/app/handler/packages/added.go b/pkg/app/handler/packages/added.go
deleted file mode 100644
index 11102b4..0000000
--- a/pkg/app/handler/packages/added.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Used to show recently added versions
-
-package packages
-
-import (
- "net/http"
- "soko/pkg/app/handler/feeds"
-)
-
-// Added renders a template containing a list of 50 recently added versions.
-func Added(w http.ResponseWriter, r *http.Request) {
- addedVersions := GetAddedVersions(50)
- RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Added", addedVersions), w)
-}
-
-func AddedFeed(w http.ResponseWriter, r *http.Request) {
- addedPackages := GetAddedPackages(250)
- feeds.AddedPackages("Added packages in Gentoo.", "Added packages in Gentoo.", addedPackages, w)
-}
diff --git a/pkg/app/handler/packages/changed_versions.templ b/pkg/app/handler/packages/changed_versions.templ
new file mode 100644
index 0000000..3b268ad
--- /dev/null
+++ b/pkg/app/handler/packages/changed_versions.templ
@@ -0,0 +1,76 @@
+package packages
+
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+import "net/http"
+import "soko/pkg/app/handler/categories"
+import "soko/pkg/app/handler/feeds"
+
+templ changedVersionsPage(pageType string, versions []*models.Version) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <h3 class="mb-2" style="text-transform: capitalize;">
+ { pageType } Packages
+ <a
+ title="Atom feed"
+ class="kk-feed-icon"
+ href={ templ.URL("/packages/" + pageType + ".atom") }
+ >
+ <span class="fa fa-fw fa-rss-square"></span>
+ </a>
+ </h3>
+ <li class="list-group rounded">
+ @utils.ChangedVersionsTable(versions)
+ </li>
+ </div>
+ </div>
+ </div>
+}
+
+// Added renders a template containing a list of 50 recently added versions.
+func Added(w http.ResponseWriter, r *http.Request) {
+ addedVersions := GetAddedVersions(50)
+ categories.RenderPage(w, r, "Added Packages", "Added", changedVersionsPage("added", addedVersions))
+}
+
+func AddedFeed(w http.ResponseWriter, r *http.Request) {
+ addedPackages := GetAddedPackages(250)
+ feeds.AddedPackages("Added packages in Gentoo.", "Added packages in Gentoo.", addedPackages, w)
+}
+
+// Updated renders a template containing
+// a list of 50 recently updated versions
+func Updated(w http.ResponseWriter, r *http.Request) {
+ updatedVersions := GetUpdatedVersions(50)
+ categories.RenderPage(w, r, "Updated Packages", "Updated", changedVersionsPage("updated", updatedVersions))
+}
+
+func UpdatedFeed(w http.ResponseWriter, r *http.Request) {
+ updatedVersions := GetUpdatedVersions(250)
+ feeds.Changes("Added packages in Gentoo.", "Added packages in Gentoo.", updatedVersions, w)
+}
+
+// Stabilized renders a template containing
+// a list of 50 recently stabilized versions
+func Stabilized(w http.ResponseWriter, r *http.Request) {
+ stabilizedVersions := GetStabilizedVersions(50)
+ categories.RenderPage(w, r, "Stabilized Packages", "Newly Stable", changedVersionsPage("stabilized", stabilizedVersions))
+}
+
+func StabilizedFeed(w http.ResponseWriter, r *http.Request) {
+ stabilizedVersions := GetStabilizedVersions(250)
+ feeds.Changes("Stabilized packages in Gentoo.", "Stabilized packages in Gentoo.", stabilizedVersions, w)
+}
+
+// Keyworded renders a template containing
+// a list of 50 recently keyworded versions
+func Keyworded(w http.ResponseWriter, r *http.Request) {
+ keywordedVersions := GetKeywordedVersions(50)
+ categories.RenderPage(w, r, "Keyworded Packages", "Keyworded", changedVersionsPage("keyworded", keywordedVersions))
+}
+
+func KeywordedFeed(w http.ResponseWriter, r *http.Request) {
+ keywordedVersions := GetKeywordedVersions(250)
+ feeds.Changes("Keyworded packages in Gentoo.", "Keyworded packages in Gentoo.", keywordedVersions, w)
+}
diff --git a/pkg/app/handler/packages/components/bugs.templ b/pkg/app/handler/packages/components/bugs.templ
new file mode 100644
index 0000000..ee49df2
--- /dev/null
+++ b/pkg/app/handler/packages/components/bugs.templ
@@ -0,0 +1,152 @@
+package components
+
+import "soko/pkg/models"
+import "strconv"
+
+templ bugsList(title, component string, bugs []*models.Bug, titleClass, id string) {
+ <h3 id={ id } class={ titleClass }>{ title }</h3>
+ <ul class="list-group">
+ for _, bug := range bugs {
+ if bug.Component == component {
+ <li class="list-group-item">
+ <div class="row">
+ <div class="col-md-12">
+ <i class="fa fa-bug" aria-hidden="true"></i>
+ <a href={ templ.URL("https://bugs.gentoo.org/" + bug.Id) } class="text-dark"><b>{ bug.Summary }</b></a>
+ </div>
+ <div class="col-md-12 text-muted">
+ { bug.Id } - Assigned to { bug.Assignee }
+ </div>
+ </div>
+ </li>
+ }
+ }
+ </ul>
+}
+
+func bugAtomLink(atom string) templ.SafeURL {
+ if atom == "" {
+ return templ.URL("https://bugs.gentoo.org/")
+ }
+ return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Linux&component=Current packages&short_desc=" + atom + ": <ADD SUMMARY HERE>")
+}
+
+templ Bugs(atom string, generalCount, stabilizationCount, keywordingCount int, bugs []*models.Bug) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(bugs) > 0 {
+ if generalCount > 0 {
+ @bugsList("Bug Reports", "Current packages", bugs, "mb-4", "packages")
+ }
+ if stabilizationCount > 0 {
+ @bugsList("Stabilization Bug Reports", "Stabilization", bugs, "my-4", "stabilization")
+ }
+ if keywordingCount > 0 {
+ @bugsList("Keywording Bug Reports", "Keywording", bugs, "my-4", "keywording")
+ }
+ } else {
+ <div class="row pt-5">
+ <div class="col-md-4">
+ <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
+ </div>
+ <div class="col-md-8 pt-3">
+ <h2>Good job! There are no bugs.</h2>
+ <span>You think something is missing here? <br/> Start with filling a <a href={ bugAtomLink(atom) }>new bug</a>.</span>
+ </div>
+ </div>
+ }
+ </div>
+ <div class="col-md-3 pt-5">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs:
+ <ul>
+ <li><a href={ bugAtomLink(atom) }>File a new Bug</a></li>
+ <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li>
+ <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li>
+ </ul>
+ </span>
+ </div>
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts">
+ Shortcuts
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseShortcuts">
+ <ul>
+ <li>
+ <a
+ if generalCount > 0 {
+ href="#packages"
+ }
+ >
+ Packages Bugs ({ strconv.Itoa(generalCount) })
+ </a>
+ </li>
+ <li>
+ <a
+ if stabilizationCount > 0 {
+ href="#stabilization"
+ }
+ >
+ Stabilization Bugs ({ strconv.Itoa(stabilizationCount) })
+ </a>
+ </li>
+ <li>
+ <a
+ if keywordingCount > 0 {
+ href="#keywording"
+ }
+ >
+ Keywording Bugs ({ strconv.Itoa(keywordingCount) })
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+}
+
+func securityBugAtomLink(atom string) templ.SafeURL {
+ if atom == "" {
+ return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Security&component=Vulnerabilities")
+ }
+ return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Security&component=Vulnerabilities&short_desc=" + atom + ": <ADD SUMMARY HERE>")
+}
+
+templ SecurityBugs(atom string, bugs []*models.Bug) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(bugs) > 0 {
+ @bugsList("Security Bug Reports", "Vulnerabilities", bugs, "mb-4", "security")
+ } else {
+ <div class="row pt-5">
+ <div class="col-md-4">
+ <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
+ </div>
+ <div class="col-md-8 pt-3">
+ <h2>There are no open security bugs.</h2>
+ <span>You think something is missing here? <br/> Start with filling a <a href={ securityBugAtomLink(atom) }>new security bug</a>.</span>
+ </div>
+ </div>
+ }
+ </div>
+ <div class="col-md-3 pt-5">
+ <h4>
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Contact Information
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ Please file new vulnerability reports on <a href={ securityBugAtomLink(atom) }>Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component.
+ </span>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/components/changelog.templ b/pkg/app/handler/packages/components/changelog.templ
new file mode 100644
index 0000000..9e86328
--- /dev/null
+++ b/pkg/app/handler/packages/components/changelog.templ
@@ -0,0 +1,121 @@
+package components
+
+import "crypto/md5"
+import "encoding/hex"
+import "time"
+import "soko/pkg/models"
+
+func gravatar(email string) string {
+ hasher := md5.Sum([]byte(email))
+ hash := hex.EncodeToString(hasher[:])
+ return "https://www.gravatar.com/avatar/" + hash + "?s=13&amp;d=retro"
+}
+
+templ chagedPaths(commitId string, badgeClass string, files []*models.ChangedFile) {
+ for idx, value := range files {
+ if idx < 20 {
+ <span class={ "badge badge-pill badge-light", badgeClass }>
+ <a class="text-muted" href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/diff/" + value.Path + "?id=" + commitId) }>{ value.Path }</a>
+ </span>
+ }
+ }
+}
+
+templ Changelog(atom string, commits []*models.Commit) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(commits) > 0 {
+ <span class="d-flex justify-content-between">
+ <h3>Latest Commits</h3>
+ <span>
+ <a
+ if atom != "" {
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + atom + "?h=master") }
+ } else {
+ href="./changelog.atom"
+ }
+ target="_blank"
+ >
+ <span class="fa fa-fw fa-rss text-dark"></span> Atom feed
+ </a>
+ </span>
+ </span>
+ <style>
+ .kk-added-file-badge {
+ background-color: #dff0d8;
+ font-weight: normal;
+ }
+ .kk-added-file-badge > a {
+ color: #424242!important;
+ }
+ .kk-modified-file-badge {
+ background-color: #fcf8e3;
+ font-weight: normal;
+ }
+ .kk-modified-file-badge > a {
+ color: #424242!important;
+ }
+ .kk-deleted-file-badge {
+ background-color: #f2dede;
+ font-weight: normal;
+ }
+ .kk-deleted-file-badge > a {
+ color: #424242!important;
+ }
+ </style>
+ <ul class="timeline">
+ <li>
+ <span class="text-muted">Commits on { commits[0].CommitterDate.Format(time.DateOnly) }</span>
+ <ul class="list-group">
+ for i, commit := range commits {
+ if currentDate := commit.CommitterDate.Format(time.DateOnly); i > 0 && currentDate != commits[i-1].CommitterDate.Format(time.DateOnly) {
+ @templ.Raw("</ul></li><li>")
+ <span class="text-muted">Commits on { currentDate }</span>
+ @templ.Raw(`<ul class="list-group">`)
+ }
+ <li class="list-group-item">
+ <div class="row">
+ <div class="col-md-8">
+ <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) }><b style="color:#424242!important;">{ commit.Message }</b></a>
+ </div>
+ <div class="col-md-4 text-right text-muted">
+ <a title={ commit.Id } class="kk-commit" href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) }>{ commit.Id[:7] }</a>
+ </div>
+ <div class="col-md-12" style="color:#424242!important;">
+ if commit.AuthorName != commit.CommitterName {
+ <span data-toggle="tooltip" title={ "authored on " + commit.AuthorDate.Format(time.DateTime) + " UTC" }>
+ <img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src={ gravatar(commit.AuthorEmail) }/>
+ <a href={ templ.URL("mailto:" + commit.AuthorEmail) }>{ commit.AuthorName }</a> authored
+ </span> and&nbsp;
+ }
+ <img class="rounded-sm inline" src={ gravatar(commit.CommitterEmail) }/>
+ <a href={ templ.URL("mailto:" + commit.CommitterEmail) }>{ commit.CommitterName }</a> committed on { commit.CommitterDate.Format(time.DateTime) } UTC
+ </div>
+ <div class="col-md-12">
+ @chagedPaths(commit.Id, "kk-added-file-badge", commit.ChangedFiles.Added)
+ @chagedPaths(commit.Id, "kk-modified-file-badge", commit.ChangedFiles.Modified)
+ @chagedPaths(commit.Id, "kk-deleted-file-badge", commit.ChangedFiles.Deleted)
+ if len(commit.ChangedFiles.Added)> 20 || len(commit.ChangedFiles.Modified) > 20 || len(commit.ChangedFiles.Deleted) > 20 {
+ <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) } class="text-muted">...</a>
+ }
+ </div>
+ </div>
+ </li>
+ }
+ </ul>
+ </li>
+ </ul>
+ } else if atom != "" {
+ <li class="list-group-item kk-panel-content-sorry">
+ This package has not been changed since our repository has moved to Git.
+ <br/>
+ <br/>
+ <a href={ templ.URL("https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/" + atom + "/ChangeLog?view=markup") } class="btn btn-default">
+ <span class="fa fa-fw fa-history"></span>
+ View old CVS Changelog
+ </a>
+ </li>
+ }
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/components/outdated.templ b/pkg/app/handler/packages/components/outdated.templ
new file mode 100644
index 0000000..30a7ce1
--- /dev/null
+++ b/pkg/app/handler/packages/components/outdated.templ
@@ -0,0 +1,66 @@
+package components
+
+type OutdatedItem struct {
+ Atom string
+ Description string
+}
+
+templ Outdated(outdated []OutdatedItem) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(outdated) > 0 {
+ <span class="d-flex justify-content-between">
+ <h3 class="mb-4">Outdated Packages</h3>
+ <span>
+ <a href="./outdated.atom">
+ <span class="fa fa-fw fa-rss text-dark"></span> Atom feed
+ </a>
+ </span>
+ </span>
+ <ul class="list-group">
+ for _, pkg := range outdated {
+ <li class="list-group-item">
+ <div class="row">
+ <div class="col-md-4">
+ <a href={ templ.URL("/packages/" + pkg.Atom) } class="text-dark"><b>{ pkg.Atom }</b></a>
+ </div>
+ <div class="col-md-8 text-muted">{ pkg.Description }</div>
+ </div>
+ </li>
+ }
+ </ul>
+ } else {
+ <div class="row pt-5">
+ <div class="col-md-4">
+ <img
+ style="width: 100%;"
+ src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"
+ />
+ </div>
+ <div class="col-md-8 pt-3">
+ <h2>Good job!</h2>
+ <span>
+ According to repology.org there are no outdated packages here.
+ <br/>
+ Please use this information with care though. The repology data might not be accurate.
+ </span>
+ </div>
+ </div>
+ }
+ </div>
+ <div class="col-md-3 pt-4">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ Based on the data of <a href="https://repology.org/">repology.org</a>, there might be a new version available for these packages.
+ <br/>
+ Please don't solely rely on this information, as the repology data might not be accurate.
+ </span>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/components/pullrequests.templ b/pkg/app/handler/packages/components/pullrequests.templ
new file mode 100644
index 0000000..0f2cc2a
--- /dev/null
+++ b/pkg/app/handler/packages/components/pullrequests.templ
@@ -0,0 +1,91 @@
+package components
+
+import "soko/pkg/models"
+import "strconv"
+
+css badgeColor(color string) {
+ font-weight: normal;
+ background-color: { "#" + color + "!important" };
+}
+
+func isDarkBadgeColor(color string) bool {
+ return color == "5319e7" || color == "0052cc" || color == "b60205"
+}
+
+templ PullRequests(pullRequests []*models.GithubPullRequest) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(pullRequests) > 0 {
+ <h3 class="mb-4">Pull Requests</h3>
+ <ul class="list-group">
+ for _, pr := range pullRequests {
+ <li class="list-group-item">
+ <div class="row">
+ <div class="col-md-11">
+ <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span>
+ <a href={ templ.URL("https://github.com/gentoo/gentoo/pull/" + pr.Id) } class="text-dark">
+ <b>{ pr.Title }</b>
+ </a>
+ <a href={ templ.URL(pr.CiStateLink) }>
+ if pr.CiState == "SUCCESS" {
+ <i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i>
+ } else {
+ <i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i>
+ }
+ </a>
+ for _, label := range pr.Labels {
+ <span
+ class={
+ "badge badge-pill p-1",
+ badgeColor(label.Color),
+ templ.KV("badge-light", !isDarkBadgeColor(label.Color)),
+ templ.KV("badge-dark", isDarkBadgeColor(label.Color)),
+ }
+ >
+ { label.Name }
+ </span>
+ }
+ </div>
+ <div class="col-md-1 text-right">
+ <a href={ templ.URL("https://github.com/gentoo/gentoo/pull/" + pr.Id) } class="text-muted">
+ <i class="fa fa-comment-o" aria-hidden="true"></i>
+ { strconv.Itoa(pr.Comments) }
+ </a>
+ </div>
+ <div class="col-md-12 text-muted">
+ <span style="font-size: 90%;">
+ #{ pr.Id } opened { pr.CreatedAt } by { pr.Author }
+ </span>
+ </div>
+ </div>
+ </li>
+ }
+ </ul>
+ } else {
+ <div class="row pt-5">
+ <div class="col-md-4">
+ <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
+ </div>
+ <div class="col-md-8 pt-3">
+ <h2>There are no pull requests</h2>
+ <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span>
+ </div>
+ </div>
+ }
+ </div>
+ <div class="col-md-3 pt-4">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub.
+ <br/>
+ Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>.
+ </span>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/components/stabilization.templ b/pkg/app/handler/packages/components/stabilization.templ
new file mode 100644
index 0000000..1bdd1c2
--- /dev/null
+++ b/pkg/app/handler/packages/components/stabilization.templ
@@ -0,0 +1,58 @@
+package components
+
+import "soko/pkg/models"
+
+templ Stabilizations(results []*models.PkgCheckResult) {
+ <div class="row">
+ <div class="col-md-9">
+ <span class="d-flex justify-content-between">
+ <h3>Stable Requests</h3>
+ <span>
+ <a href="./stabilization.atom">
+ <span class="fa fa-fw fa-rss text-dark"></span> Atom feed
+ </a>
+ &nbsp;
+ <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <span class="fa fa-fw fa-download"></span>
+ </button>
+ <span class="dropdown-menu dropdown-menu-right">
+ <a class="dropdown-item" href="./stabilization.list" target="_blank">Plain Text</a>
+ <a class="dropdown-item" href="./stabilization.json" target="_blank">JSON file</a>
+ <a class="dropdown-item" href="./stabilization.xml" target="_blank">XML file</a>
+ </span>
+ </span>
+ </span>
+ if len(results) > 0 {
+ <ul class="timeline">
+ for _, res := range results {
+ <li>
+ <ul class="list-group">
+ <li class="list-group-item">
+ <a href={ templ.URL("/packages/" + res.Atom) } class="text-dark">
+ <strong>{ res.CPV }</strong>
+ </a>
+ <br/>
+ <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span>
+ </li>
+ </ul>
+ </li>
+ }
+ </ul>
+ } else {
+ <div class="text-center w-100"><i>- No Stable Requests found -</i></div>
+ }
+ </div>
+ <div class="col-md-3 pt-4">
+ <h4>
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ This page lists potential stabilization candidates. Please have a look at the <a href="https://wiki.gentoo.org/wiki/Stable_request">wiki page</a> { "for" } more information.
+ </span>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/dependencies.templ b/pkg/app/handler/packages/dependencies.templ
new file mode 100644
index 0000000..ea4e00b
--- /dev/null
+++ b/pkg/app/handler/packages/dependencies.templ
@@ -0,0 +1,139 @@
+package packages
+
+import "soko/pkg/models"
+
+var dependenciesInnerTypes = []string{"rindex", "dindex", "bindex", "iindex", "pindex"}
+
+templ dependencies(pkg *models.Package) {
+ <div class="row">
+ <div class="col-md-9">
+ <h3>
+ <a class="text-dark">
+ <i class="fa fa-level-down" aria-hidden="true"></i> Dependencies
+ </a>
+ <a href={ templ.URL("/packages/" + pkg.Atom + "/reverse-dependencies") } class="ml-3 text-muted">
+ <i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies
+ </a>
+ </h3>
+ <ul class="timeline">
+ for _, version := range pkg.Versions {
+ <li>
+ <span class="text-muted">{ version.Version }</span>
+ if depMap := version.BuildDepMap(); len(depMap) != 0 {
+ <div class="card mt-4">
+ <div class="table-responsive border-0">
+ <table class="table mb-0">
+ <thead>
+ <tr>
+ <th scope="col">Version</th>
+ <th scope="col">RDEPEND</th>
+ <th scope="col">DEPEND</th>
+ <th scope="col">BDEPEND</th>
+ <th scope="col">IDEPEND</th>
+ <th scope="col">PDEPEND</th>
+ </tr>
+ </thead>
+ <tbody>
+ for _, atomMap := range depMap {
+ <tr>
+ <th scope="row"><a class="text-dark" href={ templ.URL("/packages/" + atomMap.Atom) }>{ atomMap.Atom }</a></th>
+ for _, key := range dependenciesInnerTypes {
+ <td>
+ if _, found := atomMap.Map[key]; found {
+ <i class="fa fa-check" style="color:green;" aria-hidden="true"></i>
+ } else {
+ <i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>
+ }
+ </td>
+ }
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ }
+ </li>
+ }
+ </ul>
+ </div>
+ <div class="col-md-3 pt-5">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ The dependencies are regularly computed based on the <a href="https://qa-reports.gentoo.org/">qa-reports</a>.
+ </span>
+ </div>
+ </div>
+ </div>
+}
+
+templ reverseDependencies(pkg *models.Package) {
+ <div class="row">
+ <div class="col-md-9">
+ <h3>
+ <a class="text-muted" href={ templ.URL("/packages/" + pkg.Atom + "/dependencies") }>
+ <i class="fa fa-level-down" aria-hidden="true"></i> Dependencies
+ </a>
+ <a class="ml-3 text-dark">
+ <i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies
+ </a>
+ </h3>
+ <div class="card mt-4">
+ <div class="table-responsive border-0">
+ <table class="table mb-0">
+ <thead>
+ <tr>
+ <th scope="col">Version</th>
+ <th scope="col">RDEPEND</th>
+ <th scope="col">DEPEND</th>
+ <th scope="col">BDEPEND</th>
+ <th scope="col">IDEPEND</th>
+ <th scope="col">PDEPEND</th>
+ </tr>
+ </thead>
+ <tbody>
+ for _, dep := range pkg.BuildRevDepMap() {
+ <tr>
+ <th scope="row"><a class="text-dark" href={ templ.URL("/packages/" + dep.Atom) }>{ dep.Version }</a></th>
+ for _, key := range dependenciesInnerTypes {
+ <td>
+ if _, found := dep.Map[key]; found {
+ <i class="fa fa-check" style="color:green;" aria-hidden="true"></i>
+ } else {
+ <i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>
+ }
+ </td>
+ }
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-3 pt-5">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ The reverse dependencies are regularly parsed from the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. The sources can be found at:
+ <ul>
+ <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/rindex/" + pkg.Atom) }>rdepend</a></li>
+ <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/dindex/" + pkg.Atom) }>depend</a></li>
+ <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/bindex/" + pkg.Atom) }>bdepend</a></li>
+ <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/iindex/" + pkg.Atom) }>idepend</a></li>
+ <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/pindex/" + pkg.Atom) }>pdepend</a></li>
+ </ul>
+ </span>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/json.go b/pkg/app/handler/packages/json.go
index 24cb2e7..8621736 100644
--- a/pkg/app/handler/packages/json.go
+++ b/pkg/app/handler/packages/json.go
@@ -2,13 +2,13 @@ package packages
import (
"encoding/json"
- "github.com/go-pg/pg"
- "github.com/go-pg/pg/v9/orm"
"net/http"
"soko/pkg/database"
"soko/pkg/models"
"strings"
"time"
+
+ "github.com/go-pg/pg/v10"
)
// build the json for the package
@@ -20,12 +20,15 @@ func buildJson(w http.ResponseWriter, r *http.Request) {
Where("atom = ?", atom).
Relation("Versions").
Relation("Versions.Masks").
- Relation("Commits", func(q *orm.Query) (*orm.Query, error) {
+ Relation("Commits", func(q *pg.Query) (*pg.Query, error) {
return q.Order("preceding_commits DESC").Limit(1), nil
}).
Select()
- if err != nil && err != pg.ErrNoRows {
+ if err == pg.ErrNoRows {
+ http.NotFound(w, r)
+ return
+ } else if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
@@ -33,6 +36,11 @@ func buildJson(w http.ResponseWriter, r *http.Request) {
sortVersionsDesc(gpackage.Versions)
+ if len(gpackage.Versions) == 0 || len(gpackage.Commits) == 0 {
+ http.NotFound(w, r)
+ return
+ }
+
versions := getJSONVersions(gpackage)
maintainers := getJSONMaintainers(gpackage)
useflags := getJSONUseflag(gpackage)
diff --git a/pkg/app/handler/packages/keyworded.go b/pkg/app/handler/packages/keyworded.go
deleted file mode 100644
index 27e2a15..0000000
--- a/pkg/app/handler/packages/keyworded.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Used to show recently keyworded versions
-
-package packages
-
-import (
- "net/http"
- "soko/pkg/app/handler/feeds"
-)
-
-// Keyworded renders a template containing
-// a list of 50 recently keyworded versions
-func Keyworded(w http.ResponseWriter, r *http.Request) {
- keywordedVersions := GetKeywordedVersions(50)
- RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Keyworded", keywordedVersions), w)
-}
-
-func KeywordedFeed(w http.ResponseWriter, r *http.Request) {
- keywordedVersions := GetKeywordedVersions(250)
- feeds.Changes("Keyworded packages in Gentoo.", "Keyworded packages in Gentoo.", keywordedVersions, w)
-}
diff --git a/pkg/app/handler/packages/overview.templ b/pkg/app/handler/packages/overview.templ
new file mode 100644
index 0000000..7bf34d2
--- /dev/null
+++ b/pkg/app/handler/packages/overview.templ
@@ -0,0 +1,467 @@
+package packages
+
+import "slices"
+import "strings"
+import "time"
+import "soko/pkg/app/handler/packages/components"
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+
+func overviewSlotText(version *models.Version) string {
+ if version.Subslot != "" {
+ return version.Slot + "/" + version.Subslot
+ }
+ return version.Slot
+}
+
+templ overviewVersionRow(version *models.Version, userPreferences *models.UserPreferences) {
+ <tr>
+ <td class="kk-version ">
+ <strong>
+ <a
+ class="kk-ebuild-link"
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + version.Atom + "/" + version.Package + "-" + version.Version + ".ebuild") }
+ >
+ { version.Version }
+ </a>
+ </strong>
+ <span class="kk-slot"> : { overviewSlotText(version) }</span>
+ if len(version.Restricts) > 0 {
+ <span
+ class="badge badge-danger kk-restrict-label"
+ title={ "The following features are restricted: " + strings.Join(version.Restricts, " ") }
+ >
+ { utils.FormatRestricts(version.Restricts) }
+ </span>
+ }
+ if userPreferences.Packages.Overview.EAPI == "inline" {
+ <span style="background-color: white;border:1px solid grey;color: grey;" class="badge badge-danger kk-restrict-label" title="The following features are restricted:">EAPI { version.EAPI }</span>
+ }
+ </td>
+ if userPreferences.Packages.Overview.EAPI == "column" {
+ <td class="text-center">
+ { version.EAPI }
+ </td>
+ }
+ for _, arch := range models.ArchesToShow {
+ if keywords := strings.Fields(version.Keywords); slices.Contains(keywords, "~"+arch) {
+ if len(version.Masks) > 0 {
+ <td class="kk-keyword kk-keyword-masked" title={ version.Version + " is masked (testing) on " + arch }>
+ <svg height="16" class="octicon octicon-diff-modified" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-mask" xlink:href="#svg-ver-mask"></use></svg>
+ <span class="sr-only">~{ arch }</span>
+ </td>
+ } else {
+ <td class="kk-keyword kk-keyword-testing" title={ version.Version + " is testing on " + arch }>
+ <svg height="16" class="octicon octicon-diff-modified" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-testing" xlink:href="#svg-ver-testing"></use></svg>
+ <span class="sr-only">~{ arch }</span>
+ </td>
+ }
+ } else if slices.Contains(keywords, "-"+arch) {
+ <td class="kk-keyword kk-keyword-unavailable" title={ version.Version + " is unavailable on " + arch }>
+ <svg height="16" class="octicon octicon-diff-removed" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-unavailable" xlink:href="#svg-ver-unavailable"></use></svg>
+ <span class="sr-only">-{ arch }</span>
+ </td>
+ } else if slices.Contains(keywords, arch) {
+ if len(version.Masks) > 0 {
+ <td class="kk-keyword kk-keyword-masked" title={ version.Version + " is masked (stable) on " + arch }>
+ <svg height="16" class="octicon octicon-diff-added" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-mask" xlink:href="#svg-ver-mask"></use></svg>
+ <span class="sr-only">{ arch }</span>
+ </td>
+ } else {
+ <td class="kk-keyword kk-keyword-stable" title={ version.Version + " is stable on " + arch }>
+ <svg height="16" class="octicon octicon-diff-added" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-stable" xlink:href="#svg-ver-stable"></use></svg>
+ <span class="sr-only">{ arch }</span>
+ </td>
+ }
+ } else if slices.Contains(keywords, "-*") {
+ <td class="kk-keyword kk-keyword-unavailable" title={ version.Version + " is unavailable on " + arch }>
+ <svg height="16" class="octicon octicon-diff-removed" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-unavailable" xlink:href="#svg-ver-unavailable"></use></svg>
+ <span class="sr-only">-{ arch }</span>
+ </td>
+ } else {
+ <td class="kk-keyword kk-keyword-unkown" title={ version.Version + " is unknown on " + arch }>
+ <span class="sr-only">?{ arch }</span>
+ </td>
+ }
+ }
+ </tr>
+}
+
+templ overviewVersions(pkg *models.Package, userPreferences *models.UserPreferences) {
+ <h3 class="mb-2">Available Versions</h3>
+ <div class="card mb-4 rounded">
+ <svg style="display: none" version="1.1">
+ <defs>
+ <symbol id="svg-ver-mask" viewBox="0 0 14 16">
+ <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path>
+ </symbol>
+ <symbol id="svg-ver-testing" viewBox="0 0 14 16">
+ <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path>
+ </symbol>
+ <symbol id="svg-ver-unavailable" viewBox="0 0 14 16">
+ <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path>
+ </symbol>
+ <symbol id="svg-ver-stable" viewBox="0 0 14 16">
+ <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path>
+ </symbol>
+ </defs>
+ </svg>
+ <div class="table-responsive border-0">
+ <table class="table table-bordered kk-versions-table mb-0 overflow-hidden border-0">
+ <thead class="border-0">
+ <tr class="border-0">
+ <th class="kk-version border-left-0 border-top-0">Version</th>
+ if userPreferences.Packages.Overview.EAPI == "column" {
+ <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">EAPI</th>
+ }
+ for _, arch := range models.ArchesToShow {
+ <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">{ arch }</th>
+ }
+ </tr>
+ </thead>
+ <tbody>
+ for _, version := range pkg.Versions {
+ @overviewVersionRow(version, userPreferences)
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+}
+
+templ overview(pkg *models.Package, userPreferences *models.UserPreferences) {
+ <div class="row">
+ <div class="col-md-9">
+ if len(pkg.Outdated) > 0 {
+ if !pkg.HasVersion(pkg.Outdated[0].NewestVersion) {
+ <div class="alert alert-info">
+ <strong><span class="fa fa-fw fa-lightbulb-o"></span> Version { pkg.Outdated[0].NewestVersion } is available upstream. Please consider updating!</strong>
+ <br/>
+ It seems that version { pkg.Outdated[0].NewestVersion } is available upstream, while the latest version in the Gentoo tree is { pkg.Outdated[0].GentooVersion }.
+ <br/>
+ <small><i>You think this warning is false? Read more about it <a href="https://archives.gentoo.org/gentoo-dev/message/b793f4da5a5b5e20a063ea431500a820">here</a>.</i></small>
+ </div>
+ }
+ }
+ @overviewVersions(pkg, userPreferences)
+ if mask := getMask(pkg.Versions); mask != nil {
+ <h3 class="pt-3 mb-2">Masks</h3>
+ <div class="card kk-mask mb-3">
+ <ul class="list-group list-group-flush kk-mask">
+ <li class="list-group-item kk-mask">
+ if showRemovalNotice(pkg.Versions) {
+ <p style="color:#721c24;">
+ <strong><span class="fa fa-fw fa-warning"></span> This package is masked and could be removed soon!</strong>
+ <br/>
+ The mask comment indicates that this package is scheduled for removal from our package repository.
+ <br/>
+ Please review the mask information below for more details.
+ </p>
+ }
+ <strong class="kk-mask-reason">
+ @templ.Raw(mask.Reason)
+ </strong>
+ <div class="kk-mask-details">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ Affected packages
+ </div>
+ <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden">
+ { mask.Versions }
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ Author/Date
+ </div>
+ <div class="col-xs-12 col-md-9">
+ { mask.Author } &lt;{ mask.AuthorEmail }&gt; <span class="text-muted">({ mask.Date.Format(time.DateOnly) })</span>
+ </div>
+ </div>
+ </div>
+ </li>
+ </ul>
+ </div>
+ } else if deprecation := getDeprecation(pkg.Versions); deprecation != nil {
+ <h3 class="pt-3 mb-2">Deprecation Warning</h3>
+ <div class="card bg-warning mb-3">
+ <ul class="list-group list-group-flush bg-warning">
+ <li class="list-group-item bg-warning">
+ <strong class="kk-mask-reason">
+ @templ.Raw(deprecation.Reason)
+ </strong>
+ <div class="kk-mask-details">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ Affected packages
+ </div>
+ <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden">
+ { deprecation.Versions }
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ Author/Date
+ </div>
+ <div class="col-xs-12 col-md-9">
+ { deprecation.Author } &lt;{ deprecation.AuthorEmail }&gt; <span class="text-muted">({ deprecation.Date.Format(time.DateOnly) })</span>
+ </div>
+ </div>
+ </div>
+ </li>
+ </ul>
+ </div>
+ }
+ if len(pkg.Maintainers) == 0 {
+ <div class="alert alert-info">
+ <strong><span class="fa fa-fw fa-wrench"></span> This package needs a new maintainer!</strong>
+ <br/>
+ If you are interested in helping with the maintenance of { pkg.Name }, please get in touch with our
+ <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers" class="alert-link">Proxy Maintainers team</a>.
+ </div>
+ }
+ <h3 class="pt-3 mb-2">Package Metadata</h3>
+ <div class="card border-0 mb-3">
+ <ul class="list-group kk-metadata-list">
+ if len(pkg.Versions[0].Homepage) > 1 {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-home"></span>
+ Other homepage(s)
+ </div>
+ <div class="col-xs-12 col-md-9">
+ for i, url := range pkg.Versions[0].Homepage[1:] {
+ if i > 0 {
+ <br/>
+ }
+ <a href={ templ.URL(url) }>{ url }</a>
+ }
+ </div>
+ </div>
+ </li>
+ }
+ if len(pkg.Upstream.Doc) > 0 || len(pkg.Upstream.Changelog) > 0 || len(pkg.Upstream.BugsTo) > 0 || len(pkg.Upstream.RemoteIds) > 0 {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-code-fork"></span>
+ Upstream
+ </div>
+ <div class="col-xs-12 col-md-9">
+ <table>
+ for i, url := range pkg.Upstream.Doc {
+ <tr>
+ <td>
+ if i == 0 {
+ <span class="kk-useflag-group float-right mr-2">Documentation</span>
+ }
+ </td>
+ <td><a href={ templ.URL(url) }>{ url }</a></td>
+ </tr>
+ }
+ for i, url := range pkg.Upstream.Changelog {
+ <tr>
+ <td>
+ if i == 0 {
+ <span class="kk-useflag-group float-right mr-2">Changelog</span>
+ }
+ </td>
+ <td><a href={ templ.URL(url) }>{ url }</a></td>
+ </tr>
+ }
+ for i, url := range pkg.Upstream.BugsTo {
+ <tr>
+ <td>
+ if i == 0 {
+ <span class="kk-useflag-group float-right mr-2">Bugs-To</span>
+ }
+ </td>
+ <td><a href={ templ.URL(url) }>{ url }</a></td>
+ </tr>
+ }
+ for i, remote := range pkg.Upstream.RemoteIds {
+ <tr>
+ <td>
+ if i == 0 {
+ <span class="kk-useflag-group float-right mr-2">Remote-Id</span>
+ }
+ </td>
+ <td>
+ if url := remoteIdLink(remote); url != "" {
+ <a href={ templ.URL(url) }>{ url }</a>
+ } else {
+ <a>({ remote.Type }) { remote.Id }</a>
+ }
+ </td>
+ </tr>
+ }
+ </table>
+ </div>
+ </div>
+ </li>
+ }
+ if pkg.Longdescription != "" {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-info"></span>Full description
+ </div>
+ <div class="col-xs-12 col-md-9">
+ { pkg.Longdescription }
+ </div>
+ </div>
+ </li>
+ }
+ if localUseflags, globalUseflags, useExpands := getPackageUseflags(pkg); len(localUseflags) > 0 || len(globalUseflags) > 0 || len(useExpands) > 0 {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-sliders"></span>
+ USE flags
+ </div>
+ <div class="col-xs-12 col-md-9">
+ if len(localUseflags) > 0 {
+ <span class="kk-useflag-group">Local Use Flags</span>
+ <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }>
+ for _, use := range localUseflags {
+ <li class="kk-useflag">
+ <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a>
+ </li>
+ }
+ </ul>
+ }
+ if len(globalUseflags) > 0 {
+ <span class="kk-useflag-group">Global Use Flags</span>
+ <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }>
+ for _, use := range globalUseflags {
+ <li class="kk-useflag">
+ <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a>
+ </li>
+ }
+ </ul>
+ }
+ if len(useExpands) > 0 {
+ for groupName, flags := range useExpands {
+ <span class="kk-useflag-group">{ groupName } (Use Expand)</span>
+ <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }>
+ for _, use := range flags {
+ <li class="kk-useflag">
+ <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ strings.TrimPrefix(use.Name, use.UseExpand + "_") }</a>
+ </li>
+ }
+ </ul>
+ }
+ }
+ </div>
+ </div>
+ </li>
+ }
+ if pkg.Versions[0].License != "" {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-legal"></span>
+ License
+ </div>
+ <div class="col-xs-12 col-md-9">
+ { pkg.Versions[0].License }
+ </div>
+ </div>
+ </li>
+ }
+ if len(pkg.Maintainers) > 0 {
+ <li class="kk-metadata-item list-group-item">
+ <div class="row">
+ <div class="col-xs-12 col-md-3 kk-metadata-key">
+ <span class="fa fa-fw fa-user"></span>
+ Maintainer(s)
+ </div>
+ <div class="col-xs-12 col-md-9">
+ for i, maintainer := range pkg.Maintainers {
+ if i > 0 {
+ ,&nbsp;
+ }
+ <a title={ maintainer.PrintName() } href={ templ.URL("/maintainer/" + maintainer.Email) }>
+ { maintainer.PrintName() }
+ </a>
+ <a href={ templ.URL("mailto:" + maintainer.Email) }>
+ <i class="fa fa-envelope-o" style="font-size: .925em;" aria-hidden="true"></i>
+ </a>
+ }
+ </div>
+ </div>
+ </li>
+ }
+ </ul>
+ </div>
+ if userPreferences.Packages.Overview.Layout == "full" {
+ <div class="mt-4 pt-4"></div>
+ @components.Changelog(pkg.Atom, pkg.Commits)
+ }
+ </div>
+ <div class="col-md-3 pl-4 pt-4 mt-2">
+ <h4 class="mb-2 ml-1">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources">
+ External Resources
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseExternalResources">
+ <dl class="ml-3">
+ <dd>
+ <span class="fa fa-fw fa-bug"></span>
+ <a href={ templ.URL("https://bugs.gentoo.org/buglist.cgi?quicksearch=" + pkg.Atom) } class="" target="_blank">
+ Related bugs
+ </a>
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-chain-broken"></span>
+ <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg=" + pkg.Category + ":" + pkg.Name) } title="CI report" target="_blank">CI Report</a>
+ (<a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg=" + pkg.Category + ":" + pkg.Name) } title="Verbose CI report" target="_blank">verbose</a>)
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-sort-numeric-desc"></span>
+ <a href={ templ.URL("https://repology.org/tools/project-by?repo=gentoo&name_type=srcname&target_page=project_versions&name=" + pkg.Atom) } target="_blank">
+ Repology
+ </a>
+ </dd>
+ <dd>
+ <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span>
+ <a href={ templ.URL("https://github.com/gentoo/gentoo/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+" + pkg.Atom) } target="_blank">
+ Open Pull Requests
+ </a>
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-book"></span>
+ <a href={ templ.URL("https://wiki.gentoo.org/wiki/Special:Search/" + pkg.Name) } target="_blank">
+ Documentation
+ </a>
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-comments-o"></span>
+ <a href={ templ.URL("https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords=" + pkg.Name + "&mode=results") } target="_blank">
+ Forums posts
+ </a>
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-code-fork"></span>
+ <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + pkg.Atom) } target="_blank">
+ Git repository browser
+ </a>
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-history"></span>
+ <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + pkg.Atom + "?showmsg=1") } title="Git log" target="_blank">Git log</a>
+ (<a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + pkg.Atom) } title="Short git log" target="_blank">short</a>)
+ </dd>
+ <dd>
+ <span class="fa fa-fw fa-rss"></span>
+ <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + pkg.Atom + "?h=master") } target="_blank">
+ Changes Feed
+ </a>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/qareport.templ b/pkg/app/handler/packages/qareport.templ
new file mode 100644
index 0000000..619b7f5
--- /dev/null
+++ b/pkg/app/handler/packages/qareport.templ
@@ -0,0 +1,70 @@
+package packages
+
+import "soko/pkg/models"
+
+templ qaReport(pkg *models.Package) {
+ <div class="row">
+ <div class="col-md-9">
+ <h3>Pkgcheck Warnings</h3>
+ <ul class="timeline">
+ <li>
+ <span class="text-muted">All Versions</span>
+ <ul class="list-group">
+ for _, res := range pkg.PkgCheckResults {
+ <li class="list-group-item">
+ <strong>{ res.Class }</strong>
+ <br/>
+ <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span>
+ </li>
+ }
+ </ul>
+ </li>
+ for _, ver := range pkg.Versions {
+ <li>
+ <span class="text-muted">{ ver.Version }</span>
+ <ul class="list-group">
+ for _, res := range ver.PkgCheckResults {
+ <li class="list-group-item">
+ <strong>{ res.Class }</strong>
+ <br/>
+ <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span>
+ </li>
+ }
+ </ul>
+ </li>
+ }
+ </ul>
+ </div>
+ <div class="col-md-3 pt-5">
+ <h4 class="">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
+ Description
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseDescription">
+ <span class="text-muted">
+ Pkgcheck is used regularly to generate QA reports. Pkgcheck is a pkgcore-based QA utility for ebuild repos.
+ </span>
+ </div>
+ <h4 class="mt-4">
+ <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources">
+ External Resources
+ </a>
+ </h4>
+ <div class="collapse show" id="collapseExternalResources">
+ <ul>
+ <li>
+ <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg=" + pkg.Category + ":" + pkg.Name) } target="_blank">
+ CI Report
+ </a>
+ </li>
+ <li>
+ <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg=" + pkg.Category + ":" + pkg.Name) } target="_blank">
+ CI Report (verbose)
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/resolve.go b/pkg/app/handler/packages/resolve.go
index f3027db..8939bea 100644
--- a/pkg/app/handler/packages/resolve.go
+++ b/pkg/app/handler/packages/resolve.go
@@ -2,11 +2,11 @@ package packages
import (
"encoding/json"
- "github.com/go-pg/pg"
- "github.com/go-pg/pg/v9/orm"
"net/http"
"soko/pkg/database"
"soko/pkg/models"
+
+ "github.com/go-pg/pg/v10"
)
// Show renders a template to show a given package
@@ -18,7 +18,7 @@ func Resolve(w http.ResponseWriter, r *http.Request) {
Where("atom LIKE ?", "%"+atom).
Relation("Versions").
Relation("Versions.Masks").
- Relation("Commits", func(q *orm.Query) (*orm.Query, error) {
+ Relation("Commits", func(q *pg.Query) (*pg.Query, error) {
return q.Order("preceding_commits DESC").Limit(1), nil
}).
Limit(1).
diff --git a/pkg/app/handler/packages/search.go b/pkg/app/handler/packages/search.go
index 69cda9f..ade3982 100644
--- a/pkg/app/handler/packages/search.go
+++ b/pkg/app/handler/packages/search.go
@@ -3,62 +3,70 @@
package packages
import (
- "github.com/go-pg/pg"
+ "encoding/json"
"net/http"
"soko/pkg/app/handler/feeds"
+ "soko/pkg/app/layout"
"soko/pkg/database"
"soko/pkg/models"
"strings"
+
+ "github.com/go-pg/pg/v10"
)
// Search renders a template containing a list of search results
// for a given query of packages
func Search(w http.ResponseWriter, r *http.Request) {
-
searchTerm := getParameterValue("q", r)
- var packages []models.Package
- var err error
- if strings.Contains(searchTerm, "@") {
+ if searchTerm == "" {
+ http.Redirect(w, r, "/", http.StatusMovedPermanently)
+ return
+ } else if strings.Contains(searchTerm, "@") {
var maintainers []models.Maintainer
database.DBCon.Model(&maintainers).Where("email = ?", searchTerm).Select()
if len(maintainers) > 0 {
- http.Redirect(w, r, "/maintainer/"+searchTerm, 301)
+ http.Redirect(w, r, "/maintainer/"+searchTerm, http.StatusMovedPermanently)
+ return
+ }
+ } else if strings.Contains(searchTerm, "/") {
+ var packages []models.Package
+ database.DBCon.Model(&packages).Where("atom = ?", searchTerm).Select()
+ if len(packages) > 0 {
+ http.Redirect(w, r, "/packages/"+searchTerm, http.StatusMovedPermanently)
return
}
}
+ var packages []models.Package
+ query := database.DBCon.Model(&packages).
+ Relation("Versions")
+
if strings.Contains(searchTerm, "*") {
// if the query contains wildcards
wildcardSearchTerm := strings.ReplaceAll(searchTerm, "*", "%")
- err = database.DBCon.Model(&packages).
- WhereOr("atom LIKE ? ", wildcardSearchTerm).
- WhereOr("name LIKE ? ", wildcardSearchTerm).
- Relation("Versions").
- OrderExpr("name <-> '" + searchTerm + "'").
- Select()
+ query = query.
+ WhereOr("atom LIKE ?", wildcardSearchTerm).
+ WhereOr("name LIKE ?", wildcardSearchTerm)
} else {
// if the query contains no wildcards do a fuzzy search
- searchQuery := BuildSearchQuery(searchTerm)
- err = database.DBCon.Model(&packages).
- Where(searchQuery).
- WhereOr("atom LIKE ? ", ("%" + searchTerm + "%")).
- Relation("Versions").
- OrderExpr("name <-> '" + searchTerm + "'").
- Select()
+ query = BuildSearchQuery(query, searchTerm).
+ WhereOr("atom LIKE ?", "%"+searchTerm+"%")
}
+ err := query.OrderExpr("name <-> ?", searchTerm).
+ Select()
if err != nil && err != pg.ErrNoRows {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
+ if len(packages) == 1 {
+ http.Redirect(w, r, "/packages/"+packages[0].Atom, http.StatusMovedPermanently)
+ return
+ }
- renderPackageTemplate("search",
- "search",
- GetFuncMap(),
- getSearchData(packages, searchTerm),
- w)
+ layout.Layout(searchTerm, "packages", search(searchTerm, packages)).Render(r.Context(), w)
}
// Search renders a template containing a list of search results
@@ -67,13 +75,11 @@ func SearchFeed(w http.ResponseWriter, r *http.Request) {
searchTerm := getParameterValue("q", r)
searchTerm = strings.ReplaceAll(searchTerm, "*", "")
- searchQuery := BuildSearchQuery(searchTerm)
var packages []models.Package
- err := database.DBCon.Model(&packages).
- Where(searchQuery).
+ err := BuildSearchQuery(database.DBCon.Model(&packages), searchTerm).
Relation("Versions").
- OrderExpr("name <-> '" + searchTerm + "'").
+ OrderExpr("name <-> ?", searchTerm).
Select()
if err != nil && err != pg.ErrNoRows {
http.Error(w, http.StatusText(http.StatusInternalServerError),
@@ -84,13 +90,21 @@ func SearchFeed(w http.ResponseWriter, r *http.Request) {
feeds.Packages(searchTerm, packages, w)
}
-func BuildSearchQuery(searchString string) string {
- var searchClauses []string
+func BuildSearchQuery(query *pg.Query, searchString string) *pg.Query {
for _, searchTerm := range strings.Split(searchString, " ") {
if searchTerm != "" {
- searchClauses = append(searchClauses,
- "( (category % '"+searchTerm+"') OR (name % '"+searchTerm+"') OR (atom % '"+searchTerm+"') OR (maintainers @> '[{\"Name\": \""+searchTerm+"\"}]' OR maintainers @> '[{\"Email\": \""+searchTerm+"\"}]'))")
+ marshal, err := json.Marshal(searchTerm)
+ if err != nil {
+ continue
+ }
+ query = query.WhereGroup(func(q *pg.Query) (*pg.Query, error) {
+ return q.WhereOr("category % ?", searchTerm).
+ WhereOr("name % ?", searchTerm).
+ WhereOr("atom % ?", searchTerm).
+ WhereOr("maintainers @> ?", `[{"Name": `+string(marshal)+`}]`).
+ WhereOr("maintainers @> ?", `[{"Email": `+string(marshal)+`}]`), nil
+ })
}
}
- return strings.Join(searchClauses, " AND ")
+ return query
}
diff --git a/pkg/app/handler/packages/search.templ b/pkg/app/handler/packages/search.templ
new file mode 100644
index 0000000..6fb168f
--- /dev/null
+++ b/pkg/app/handler/packages/search.templ
@@ -0,0 +1,61 @@
+package packages
+
+import "strconv"
+import "soko/pkg/models"
+
+templ search(query string, packages []models.Package) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <h1 class="first-header">
+ Search Results <small>{ "for " + query }</small>
+ <a title="Atom feed" href={ templ.URL("/packages/search.atom?q=" + query) } class="kk-feed-icon">
+ <span class="fa fa-fw fa-rss-square"></span>
+ </a>
+ </h1>
+ if len(packages) > 0 {
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ Results 1—{ strconv.Itoa(len(packages)) } of { strconv.Itoa(len(packages)) }
+ </div>
+ <div class="list-group">
+ for _, pkg := range packages {
+ <a class="list-group-item list-group-item-action" href={ templ.URL("/packages/" + pkg.Atom) }>
+ <h3 class="kk-search-result-header"><span class="text-muted">{ pkg.Category }/</span>{ pkg.Name }</h3>
+ { pkg.Versions[0].Description }
+ </a>
+ }
+ </div>
+ // TODO paging
+ // <div class="panel-footer">
+ // <div class="btn-group" role="group" aria-label="Result navigation">
+ // <%= link_to '< Prev', search_packages_path(q: params[:q], o: [@offset - PackageRepository.default_search_size, 0].max), class: 'btn btn-default' + (@offset > 0 ? '' : ' disabled') %>
+ // <%= link_to 'Next >', search_packages_path(q: params[:q], o: @offset + PackageRepository.default_search_size), class: 'btn btn-default ' + ((@offset + PackageRepository.default_search_size) > @packages.total ? 'disabled' : '') %>
+ // </div>
+ // </div>
+ </div>
+ // TODO in head: alternate_feed_link(search_packages_url(format: :atom, params: request.query_parameters), t(:atom_feed))
+ } else {
+ <div class="jumbotron">
+ <h2 class="site-welcome stick-top">Nothing found. :( Try again?</h2>
+ <form action="/packages/search" method="get">
+ <div class="typeahead__container">
+ <div class="typeahead__field">
+ <span class="typeahead__query">
+ <input id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus/>
+ </span>
+ <span class="typeahead__button">
+ <button type="submit" title="Find" aria-label="Find">
+ <span class="typeahead__search-icon"></span><span class="sr-only">Find</span>
+ </button>
+ </span>
+ </div>
+ </div>
+ </form>
+ </div>
+ <script src="/assets/index.js"></script>
+ }
+ </div>
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/show.go b/pkg/app/handler/packages/show.go
index 75ca8ea..27d8b29 100644
--- a/pkg/app/handler/packages/show.go
+++ b/pkg/app/handler/packages/show.go
@@ -5,101 +5,124 @@ package packages
import (
b64 "encoding/base64"
"encoding/json"
- "github.com/go-pg/pg"
- "github.com/go-pg/pg/v9/orm"
+ "fmt"
"net/http"
+ "soko/pkg/app/layout"
"soko/pkg/app/utils"
"soko/pkg/database"
"soko/pkg/models"
"strings"
"time"
+
+ "github.com/go-pg/pg/v10"
)
// Show renders a template to show a given package
func Show(w http.ResponseWriter, r *http.Request) {
+ category := r.PathValue("category")
+ packageName := r.PathValue("package")
+ pageName := r.PathValue("pageName")
+ atom := category + "/" + packageName
- if strings.HasSuffix(r.URL.Path, "/changelog.json") {
- changelogJSON(w, r)
- return
- } else if strings.HasSuffix(r.URL.Path, ".json") {
+ if pageName == "" && strings.HasSuffix(packageName, ".json") {
buildJson(w, r)
return
}
- atom := r.URL.Path[len("/packages/"):]
- pageName := "overview"
- userPreferences := utils.GetUserPreferences(r)
+ var currentSubTab string
+ userPreferences := utils.GetUserPreferences(r)
if userPreferences.General.LandingPageLayout == "full" {
updateSearchHistory(atom, w, r)
}
- if strings.HasSuffix(r.URL.Path, "/changelog") {
- atom = strings.ReplaceAll(atom, "/changelog", "")
- pageName = "changelog"
- } else if strings.HasSuffix(r.URL.Path, "/qa-report") {
- atom = strings.ReplaceAll(atom, "/qa-report", "")
- pageName = "qa-report"
- } else if strings.HasSuffix(r.URL.Path, "/pull-requests") {
+ var gpackage models.Package
+ query := database.DBCon.Model(&gpackage).
+ Relation("Bugs").
+ Relation("PullRequests").
+ Relation("Versions", func(q *pg.Query) (*pg.Query, error) {
+ // performs mostly correct ordering of versions, which is perfected by sortVersionsDesc
+ return q.Order("version DESC"), nil
+ }).
+ Relation("Versions.Bugs")
+
+ switch pageName {
+ case "changelog":
+ currentSubTab = "Changelog"
+ query = query.Relation("Commits", func(q *pg.Query) (*pg.Query, error) {
+ // here be dragons
+ const template = (`'%[1]s', (SELECT ARRAY_AGG("%[1]s") ` +
+ `FROM jsonb_array_elements(COALESCE(NULLIF(changed_files -> '%[1]s', 'null'), '[]')) AS "%[1]s" ` +
+ `WHERE "%[1]s" ->> 'Path' LIKE ?)`)
+ return q.Column("commit_to_package.*",
+ "commit.id", "preceding_commits", "message",
+ "author_name", "author_email", "author_date",
+ "committer_name", "committer_email", "committer_date").
+ ColumnExpr(("json_build_object(" +
+ fmt.Sprintf(template, "Modified") + "," +
+ fmt.Sprintf(template, "Added") + "," +
+ fmt.Sprintf(template, "Deleted") +
+ ") AS changed_files"), atom+"/%", atom+"/%", atom+"/%").
+ Order("preceding_commits DESC").
+ Limit(50), nil
+ })
+ case "changelog.json":
+ changelogJSON(w, r)
+ return
+ case "qa-report":
+ currentSubTab = "QA report"
+ query = query.
+ Relation("PkgCheckResults").
+ Relation("Versions.PkgCheckResults")
+ case "pull-requests":
atom = strings.ReplaceAll(atom, "/pull-requests", "")
- pageName = "pull-requests"
- } else if strings.HasSuffix(r.URL.Path, "/bugs") {
+ currentSubTab = "Pull requests"
+ case "bugs":
atom = strings.ReplaceAll(atom, "/bugs", "")
- pageName = "bugs"
- } else if strings.HasSuffix(r.URL.Path, "/security") {
+ currentSubTab = "Bugs"
+ case "security":
atom = strings.ReplaceAll(atom, "/security", "")
- pageName = "security"
- } else if strings.HasSuffix(r.URL.Path, "/dependencies") {
+ currentSubTab = "Security"
+ case "dependencies":
atom = strings.ReplaceAll(atom, "/dependencies", "")
- pageName = "dependencies"
- } else if strings.HasSuffix(r.URL.Path, "/reverse-dependencies") {
+ currentSubTab = "Dependencies"
+ query = query.Relation("Versions.Dependencies")
+ case "reverse-dependencies":
atom = strings.ReplaceAll(atom, "/reverse-dependencies", "")
- pageName = "reverse-dependencies"
+ currentSubTab = "Reverse Dependencies"
+ query = query.Relation("ReverseDependencies")
+ case "", "overview":
+ query = query.Relation("Outdated").
+ Relation("Versions.Masks").
+ Relation("Versions.Deprecates")
+ currentSubTab = "Overview"
+ default:
+ http.NotFound(w, r)
+ return
}
- gpackage := new(models.Package)
- err := database.DBCon.Model(gpackage).
- Where("atom = ?", atom).
- Relation("Outdated").
- Relation("PkgCheckResults").
- Relation("Bugs").
- Relation("PullRequests").
- Relation("Versions").
- Relation("Versions.Bugs").
- Relation("Versions.Masks").
- Relation("Versions.PkgCheckResults").
- Relation("Versions.Dependencies").
- Relation("ReverseDependencies").
- Relation("Commits", func(q *orm.Query) (*orm.Query, error) {
- return q.Order("preceding_commits DESC").Limit(userPreferences.Packages.Overview.ChangelogLength), nil
- }).
- Select()
-
- if err != nil {
+ err := query.Where("atom = ?", atom).Select()
+ if err != nil || len(gpackage.Versions) == 0 {
http.NotFound(w, r)
return
}
sortVersionsDesc(gpackage.Versions)
- localUseflags, globalUseflags, useExpands := getPackageUseflags(gpackage)
-
- renderPackageTemplate("show",
- "*",
- GetFuncMap(),
- createPackageData(pageName, gpackage, localUseflags, globalUseflags, useExpands, userPreferences),
- w)
+ layout.Layout(gpackage.Atom, "packages",
+ show(&gpackage, currentSubTab, utils.GetUserPreferences(r)),
+ ).Render(r.Context(), w)
}
func updateSearchHistory(atom string, w http.ResponseWriter, r *http.Request) {
- var cookie, err = r.Cookie("search_history")
+ cookie, err := r.Cookie("search_history")
var packages string
if err == nil {
cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value)
if err == nil {
packagesList := strings.Split(string(cookieValue), ",")
if strings.Contains(string(cookieValue), atom) {
- newPackagesList := []string{}
+ newPackagesList := make([]string, 0, len(packagesList)-1)
for _, gpackage := range packagesList {
if gpackage != atom {
newPackagesList = append(newPackagesList, gpackage)
@@ -135,7 +158,7 @@ func changelogJSON(w http.ResponseWriter, r *http.Request) {
gpackage := new(models.Package)
err := database.DBCon.Model(gpackage).
Where("atom = ?", atom).
- Relation("Commits", func(q *orm.Query) (*orm.Query, error) {
+ Relation("Commits", func(q *pg.Query) (*pg.Query, error) {
return q.Order("preceding_commits DESC").Limit(5), nil
}).
Select()
@@ -191,6 +214,17 @@ func changelogJSON(w http.ResponseWriter, r *http.Request) {
w.Write(b)
}
+func countBugs(gpackage *models.Package) (securityBugs, nonSecurityBugs int) {
+ for _, bug := range gpackage.Bugs {
+ if bug.Component == "Vulnerabilities" {
+ securityBugs++
+ } else {
+ nonSecurityBugs++
+ }
+ }
+ return
+}
+
type Changes struct {
Changes []Change `json:"changes"`
}
diff --git a/pkg/app/handler/packages/show.templ b/pkg/app/handler/packages/show.templ
new file mode 100644
index 0000000..fa3b33f
--- /dev/null
+++ b/pkg/app/handler/packages/show.templ
@@ -0,0 +1,163 @@
+package packages
+
+import "strconv"
+import "soko/pkg/app/handler/packages/components"
+import "soko/pkg/app/layout"
+import "soko/pkg/models"
+
+func showViewTabs(pkg *models.Package) []layout.SubTab {
+ securityBugs, nonSecurityBugs := countBugs(pkg)
+ return []layout.SubTab{
+ {
+ Name: "Overview",
+ Link: templ.URL("/packages/" + pkg.Atom),
+ Icon: "fa fa-info mr-1",
+ },
+ {
+ Name: "Dependencies",
+ Link: templ.URL("/packages/" + pkg.Atom + "/dependencies"),
+ Icon: "fa fa-link",
+ },
+ {
+ Name: "QA report",
+ Link: templ.URL("/packages/" + pkg.Atom + "/qa-report"),
+ Icon: "fa fa-fw fa-chain-broken",
+ },
+ {
+ Name: "Pull requests",
+ Link: templ.URL("/packages/" + pkg.Atom + "/pull-requests"),
+ Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1",
+ BadgeValue: strconv.Itoa(len(pkg.PullRequests)),
+ },
+ {
+ Name: "Bugs",
+ Link: templ.URL("/packages/" + pkg.Atom + "/bugs"),
+ Icon: "fa fa-bug",
+ BadgeValue: strconv.Itoa(nonSecurityBugs),
+ },
+ {
+ Name: "Security",
+ Link: templ.URL("/packages/" + pkg.Atom + "/security"),
+ Icon: "fa fa-shield",
+ BadgeValue: strconv.Itoa(securityBugs),
+ },
+ {
+ Name: "Changelog",
+ Link: templ.URL("/packages/" + pkg.Atom + "/changelog"),
+ Icon: "fa fa-fw fa-history",
+ },
+ }
+}
+
+templ tabbedHeader(pkg *models.Package, currentSubTab string) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title" data-atom={ pkg.Atom } data-category={ pkg.Category } data-name={ pkg.Name }>
+ <small class="kk-package-cat">
+ <a href={ templ.URL("/categories/" + pkg.Category) } class="text-dark">{ pkg.Category }</a>/
+ </small>
+ <div>
+ <svg height="32" class="octicon octicon-package right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"></path></svg>
+ <div class="kk-package-name">{ pkg.Name }</div>
+ </div>
+ </h1>
+ </div>
+ <div class="col-md-7">
+ <p class="lead kk-package-maindesc">{ pkg.Description() }</p>
+ if len(pkg.Versions[0].Homepage) > 0 {
+ <p class="kk-package-homepage">
+ <a href={ templ.URL(pkg.Versions[0].Homepage[0]) }>{ pkg.Versions[0].Homepage[0] }</a>
+ </p>
+ }
+ </div>
+ <div class="col-md-12 pt-4 mt-1">
+ <nav class="nav kk-package-nav">
+ for _, tab := range showViewTabs(pkg) {
+ <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }>
+ <i class={ tab.Icon } aria-hidden="true"></i> { tab.Name }
+ if tab.BadgeValue != "" {
+ <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span>
+ }
+ </a>
+ }
+ </nav>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+func collectAllBugs(pkg *models.Package) (atom string, generalCount, stabilizationCount, keywordingCount int, bugs []*models.Bug) {
+ atom = pkg.Atom
+ bugs = make([]*models.Bug, 0, len(pkg.Bugs))
+ handled := make(map[string]struct{}, len(pkg.Bugs))
+ for _, bug := range pkg.Bugs {
+ if bug.Component == "Current packages" {
+ generalCount++
+ bugs = append(bugs, bug)
+ handled[bug.Id] = struct{}{}
+ }
+ }
+ for _, ver := range pkg.Versions {
+ for _, bug := range ver.Bugs {
+ if _, found := handled[bug.Id]; found {
+ continue
+ }
+ if bug.Component == "Stabilization" {
+ stabilizationCount++
+ bugs = append(bugs, bug)
+ } else if bug.Component == "Keywording" {
+ keywordingCount++
+ bugs = append(bugs, bug)
+ }
+ handled[bug.Id] = struct{}{}
+ }
+ }
+ return
+}
+
+func collectSecurityBugs(pkg *models.Package) (string, []*models.Bug) {
+ bugs := make([]*models.Bug, 0, len(pkg.Bugs))
+ for _, bug := range pkg.Bugs {
+ if bug.Component == "Vulnerabilities" {
+ bugs = append(bugs, bug)
+ }
+ }
+ return pkg.Atom, bugs
+}
+
+templ show(pkg *models.Package, currentSubTab string, userPreferences models.UserPreferences) {
+ if currentSubTab == "Reverse Dependencies" {
+ @tabbedHeader(pkg, "Dependencies")
+ } else {
+ @tabbedHeader(pkg, currentSubTab)
+ }
+ <div class="tab-content" id="myTabContent">
+ <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
+ switch currentSubTab {
+ case "QA report":
+ @qaReport(pkg)
+ case "Pull requests":
+ @components.PullRequests(pkg.PullRequests)
+ case "Bugs":
+ @components.Bugs(collectAllBugs(pkg))
+ case "Security":
+ @components.SecurityBugs(collectSecurityBugs(pkg))
+ case "Changelog":
+ @components.Changelog(pkg.Atom, pkg.Commits)
+ case "Dependencies":
+ @dependencies(pkg)
+ case "Reverse Dependencies":
+ @reverseDependencies(pkg)
+ default:
+ @overview(pkg, &userPreferences)
+ }
+ </div>
+ </div>
+}
diff --git a/pkg/app/handler/packages/stabilized.go b/pkg/app/handler/packages/stabilized.go
deleted file mode 100644
index 79e80b0..0000000
--- a/pkg/app/handler/packages/stabilized.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Used to show recently stabilized versions
-
-package packages
-
-import (
- "net/http"
- "soko/pkg/app/handler/feeds"
-)
-
-// Stabilized renders a template containing
-// a list of 50 recently stabilized versions
-func Stabilized(w http.ResponseWriter, r *http.Request) {
- stabilizedVersions := GetStabilizedVersions(50)
- RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Stabilized", stabilizedVersions), w)
-}
-
-func StabilizedFeed(w http.ResponseWriter, r *http.Request) {
- stabilizedVersions := GetStabilizedVersions(250)
- feeds.Changes("Stabilized packages in Gentoo.", "Stabilized packages in Gentoo.", stabilizedVersions, w)
-}
diff --git a/pkg/app/handler/packages/suggest.go b/pkg/app/handler/packages/suggest.go
index 9c2d082..2d9759b 100644
--- a/pkg/app/handler/packages/suggest.go
+++ b/pkg/app/handler/packages/suggest.go
@@ -4,55 +4,44 @@ package packages
import (
"encoding/json"
- "github.com/go-pg/pg"
"net/http"
"soko/pkg/database"
"soko/pkg/models"
+
+ "github.com/go-pg/pg"
)
// Suggest returns json encoded suggestions of
// packages based on the given query
func Suggest(w http.ResponseWriter, r *http.Request) {
-
searchTerm := getParameterValue("q", r)
- var packages []models.Package
- err := database.DBCon.Model(&packages).
- Where("atom LIKE ? ", ("%" + searchTerm + "%")).
- Relation("Versions").
- Select()
+ var suggestions struct {
+ Results []struct {
+ Name string `json:"name"`
+ Category string `json:"category"`
+ Description string `json:"description"`
+ } `json:"results"`
+ }
+
+ descriptionQuery := database.DBCon.Model((*models.Version)(nil)).
+ Column("description").
+ Where("atom = package.atom").
+ Limit(1)
+ err := database.DBCon.Model((*models.Package)(nil)).
+ Column("name", "category").
+ ColumnExpr("(?) AS description", descriptionQuery).
+ Where("atom LIKE ? ", "%"+searchTerm+"%").
+ OrderExpr("name <-> ?", searchTerm).
+ Limit(10).
+ Select(&suggestions.Results)
if err != nil && err != pg.ErrNoRows {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
- type Result struct {
- Name string `json:"name"`
- Category string `json:"category"`
- description string `json:"description"`
- }
-
- type Results struct {
- Results []*Result `json:"results"`
- }
-
- var results []*Result
-
- for _, gpackage := range packages {
- results = append(results, &Result{
- Name: gpackage.Name,
- Category: gpackage.Category,
- description: gpackage.Versions[0].Description,
- })
- }
-
- result := Results{
- Results: results,
- }
-
- b, err := json.Marshal(result)
-
+ b, err := json.Marshal(suggestions)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
diff --git a/pkg/app/handler/packages/updated.go b/pkg/app/handler/packages/updated.go
deleted file mode 100644
index f94e9b4..0000000
--- a/pkg/app/handler/packages/updated.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Used to show recently updated versions
-
-package packages
-
-import (
- "net/http"
- "soko/pkg/app/handler/feeds"
-)
-
-// Updated renders a template containing
-// a list of 50 recently updated versions
-func Updated(w http.ResponseWriter, r *http.Request) {
- updatedVersions := GetUpdatedVersions(50)
- RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Updated", updatedVersions), w)
-}
-
-func UpdatedFeed(w http.ResponseWriter, r *http.Request) {
- updatedVersions := GetUpdatedVersions(250)
- feeds.Changes("Added packages in Gentoo.", "Added packages in Gentoo.", updatedVersions, w)
-}
diff --git a/pkg/app/handler/packages/utils.go b/pkg/app/handler/packages/utils.go
index ccc03c3..423f937 100644
--- a/pkg/app/handler/packages/utils.go
+++ b/pkg/app/handler/packages/utils.go
@@ -3,26 +3,19 @@
package packages
import (
- "crypto/md5"
- "encoding/hex"
- "github.com/go-pg/pg"
- "github.com/go-pg/pg/v9/orm"
- "html/template"
+ "log/slog"
"net/http"
- "soko/pkg/app/utils"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
- utils2 "soko/pkg/utils"
"sort"
"strings"
- textTemplate "text/template"
+
+ "github.com/go-pg/pg/v10"
)
// GetAddedPackages returns a list of recently added
// packages containing a given number of packages
-func GetAddedPackages(n int) []*models.Package {
- var addedPackages []*models.Package
+func GetAddedPackages(n int) (addedPackages []*models.Package) {
err := database.DBCon.Model(&addedPackages).
Order("preceding_commits DESC").
Limit(n).
@@ -30,40 +23,37 @@ func GetAddedPackages(n int) []*models.Package {
Relation("Versions.Commits").
Select()
if err != nil && err != pg.ErrNoRows {
- logger.Error.Println("Error during fetching added packages from database")
- logger.Error.Println(err)
+ slog.Error("Failed fetching added packages from database", slog.Any("err", err))
}
- return addedPackages
+ return
}
// GetAddedVersions returns a list of recently added
// versions containing a given number of versions
-func GetAddedVersions(n int) []*models.Version {
+func GetAddedVersions(n int) (addedVersions []*models.Version) {
addedPackages := GetAddedPackages(n)
- var addedVersions []*models.Version
for _, addedPackage := range addedPackages {
addedVersions = append(addedVersions, addedPackage.Versions...)
}
- return addedVersions
+ return
}
// GetUpdatedVersions returns a list of recently updated
// versions containing a given number of versions
-func GetUpdatedVersions(n int) []*models.Version {
- var updatedVersions []*models.Version
+func GetUpdatedVersions(n int) (updatedVersions []*models.Version) {
var updates []models.Commit
err := database.DBCon.Model(&updates).
Order("preceding_commits DESC").
Limit(n).
- Relation("ChangedVersions", func(q *orm.Query) (*orm.Query, error) {
+ Relation("ChangedVersions", func(q *pg.Query) (*pg.Query, error) {
return q.Limit(10 * n), nil
}).
- Relation("ChangedVersions.Commits", func(q *orm.Query) (*orm.Query, error) {
+ Relation("ChangedVersions.Commits", func(q *pg.Query) (*pg.Query, error) {
return q.Order("preceding_commits DESC"), nil
}).
Select()
if err != nil {
- return updatedVersions
+ return
}
for _, commit := range updates {
for _, changedVersion := range commit.ChangedVersions {
@@ -72,87 +62,57 @@ func GetUpdatedVersions(n int) []*models.Version {
updatedVersions = append(updatedVersions, commit.ChangedVersions...)
}
if len(updatedVersions) > n {
- updatedVersions = updatedVersions[:10]
+ updatedVersions = updatedVersions[:n]
}
- return updatedVersions
+ return
}
// GetStabilizedVersions returns a list of recently stabilized
// versions containing a given number of versions
-func GetStabilizedVersions(n int) []*models.Version {
- var stabilizedVersions []*models.Version
+func GetStabilizedVersions(n int) (stabilizedVersions []*models.Version) {
var updates []models.KeywordChange
err := database.DBCon.Model(&updates).
Relation("Version").
Relation("Commit").
Order("commit.preceding_commits DESC").
Where("stabilized IS NOT NULL").
+ Where("version.id IS NOT NULL").
Limit(n).
Select()
if err != nil {
- return stabilizedVersions
+ return
}
- for _, update := range updates {
- if update.Version != nil {
- update.Version.Commits = []*models.Commit{update.Commit}
- stabilizedVersions = append(stabilizedVersions, update.Version)
- }
+
+ stabilizedVersions = make([]*models.Version, len(updates))
+ for i, update := range updates {
+ update.Version.Commits = []*models.Commit{update.Commit}
+ stabilizedVersions[i] = update.Version
}
- return stabilizedVersions
+ return
}
// GetKeywordedVersions returns a list of recently keyworded
// versions containing a given number of versions
-func GetKeywordedVersions(n int) []*models.Version {
- var keywordedVersions []*models.Version
+func GetKeywordedVersions(n int) (keywordedVersions []*models.Version) {
var updates []models.KeywordChange
err := database.DBCon.Model(&updates).
Relation("Version").
Relation("Commit").
Order("commit.preceding_commits DESC").
Where("added IS NOT NULL").
+ Where("version.id IS NOT NULL").
Limit(n).
Select()
if err != nil {
- return keywordedVersions
+ return
}
- for _, update := range updates {
- if update.Version != nil {
- update.Version.Commits = []*models.Commit{update.Commit}
- keywordedVersions = append(keywordedVersions, update.Version)
- }
- }
- return keywordedVersions
-}
-// RenderPackageTemplates renders the given templates using the given data
-// One pattern can be used to specify templates
-func renderPackageTemplate(page string, templatepattern string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.New(page).
- Funcs(funcMap).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/packages/components/*.tmpl")).
- ParseGlob("web/templates/packages/" + templatepattern + ".tmpl"))
- templates.ExecuteTemplate(w, page+".tmpl", data)
-}
-
-// RenderPackageTemplates renders the given templates using the given data
-// Two patterns can be used to specify templates
-func RenderPackageTemplates(page string, templatepattern1 string, templatepattern2 string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.Must(
- template.New(page).
- Funcs(funcMap).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/packages/browsepackagesheader.tmpl")).
- ParseGlob("web/templates/packages/" + templatepattern1 + ".tmpl")).
- ParseGlob("web/templates/packages/" + templatepattern2 + ".tmpl"))
- templates.ExecuteTemplate(w, page+".tmpl", data)
+ keywordedVersions = make([]*models.Version, len(updates))
+ for i, update := range updates {
+ update.Version.Commits = []*models.Commit{update.Commit}
+ keywordedVersions[i] = update.Version
+ }
+ return
}
// getAtom returns the atom of the package from the given url
@@ -164,92 +124,6 @@ func getAtom(r *http.Request) string {
return atom
}
-// getSearchData returns the data used in search templates
-func getSearchData(packages []models.Package, search string) interface{} {
- return struct {
- Header models.Header
- Search string
- Packages []models.Package
- Application models.Application
- }{
- Header: models.Header{Title: search + " – ", Tab: "packages"},
- Search: search,
- Packages: packages,
- Application: utils.GetApplicationData(),
- }
-}
-
-// getChangelogData returns the data used in changelog templates
-func getChangelogData(commits []*models.Commit, atom string) interface{} {
- return struct {
- Commits []*models.Commit
- Atom string
- }{
- Commits: commits,
- Atom: atom,
- }
-}
-
-// GetFuncMap returns the FuncMap used in templates
-func GetFuncMap() template.FuncMap {
- return template.FuncMap{
- "contains": strings.Contains,
- "listContains": listContains,
- "replaceall": strings.ReplaceAll,
- "gravatar": gravatar,
- "mkSlice": mkSlice,
- "getReverse": getReverse,
- "tolower": strings.ToLower,
- "formatRestricts": FormatRestricts,
- "RemoteIdLink": RemoteIdLink,
- "isMasked": isMasked,
- "getMask": getMask,
- "showRemovalNotice": showRemovalNotice,
- "add": func(a, b int) int {
- return a + b
- },
- }
-}
-
-// GetFuncMap returns the FuncMap used in templates
-func GetTextFuncMap() textTemplate.FuncMap {
- return textTemplate.FuncMap{
- "contains": strings.Contains,
- "replaceall": strings.ReplaceAll,
- "gravatar": gravatar,
- "mkSlice": mkSlice,
- "getReverse": getReverse,
- "tolower": strings.ToLower,
- "formatRestricts": FormatRestricts,
- "isMasked": isMasked,
- "getMask": getMask,
- "showRemovalNotice": showRemovalNotice,
- }
-}
-
-func listContains(list []string, item string) bool {
- return strings.Contains(" "+strings.Join(list, " ")+" ", " "+item+" ")
-}
-
-// gravatar creates a link to the gravatar
-// based on the email
-func gravatar(email string) string {
- hasher := md5.Sum([]byte(email))
- hash := hex.EncodeToString(hasher[:])
- return "https://www.gravatar.com/avatar/" + hash + "?s=13&amp;d=retro"
-}
-
-// mkSlice creates a slice of the given arguments
-func mkSlice(args ...interface{}) []interface{} {
- return args
-}
-
-// getReverse returns the element of a slice in
-// reverse direction based on the index
-func getReverse(index int, versions []*models.Version) *models.Version {
- return versions[len(versions)-1-index]
-}
-
// getParameterValue returns the value of a given parameter
func getParameterValue(parameterName string, r *http.Request) string {
results, ok := r.URL.Query()[parameterName]
@@ -264,36 +138,38 @@ func getParameterValue(parameterName string, r *http.Request) string {
// getPackageUseflags retrieves all local USE flags, global USE
// flags and use expands for a given package
-func getPackageUseflags(gpackage *models.Package) ([]models.Useflag, []models.Useflag, map[string][]models.Useflag) {
- var localUseflags, allGlobalUseflags, filteredGlobalUseflags []models.Useflag
- useExpands := make(map[string][]models.Useflag)
- for _, rawUseflag := range gpackage.Versions[0].Useflags {
-
- var tmp_useflags []models.Useflag
- err := database.DBCon.Model(&tmp_useflags).
- Where("Name = ?", strings.Replace(rawUseflag, "+", "", 1)).
- Select()
+func getPackageUseflags(gpackage *models.Package) (localUseflags []models.Useflag, filteredGlobalUseflags []models.Useflag, useExpands map[string][]models.Useflag) {
+ rawUseFlags := gpackage.AllUseflags()
+ if len(rawUseFlags) == 0 {
+ return
+ }
- if err != nil && err != pg.ErrNoRows {
- logger.Error.Println("Error during fetching added packages from database")
- logger.Error.Println(err)
- continue
- }
+ var tmp_useflags []models.Useflag
+ err := database.DBCon.Model(&tmp_useflags).
+ WhereGroup(func(q *pg.Query) (*pg.Query, error) {
+ return q.Where("scope = ?", "local").Where("package = ?", gpackage.Atom), nil
+ }).
+ WhereOrGroup(func(q *pg.Query) (*pg.Query, error) {
+ return q.Where("scope != ?", "local").Where("name in (?)", pg.In(rawUseFlags)), nil
+ }).
+ Order("name ASC").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ slog.Error("Failed fetching use flags", slog.Any("err", err))
+ return
+ }
- for _, useflag := range tmp_useflags {
- if useflag.Scope == "global" {
- allGlobalUseflags = append(allGlobalUseflags, useflag)
- } else if useflag.Scope == "local" {
- if useflag.Package == gpackage.Atom {
- localUseflags = append(localUseflags, useflag)
- }
- } else {
- if _, ok := useExpands[useflag.UseExpand]; !ok {
- useExpands[useflag.UseExpand] = []models.Useflag{useflag}
- } else {
- useExpands[useflag.UseExpand] = append(useExpands[useflag.UseExpand], useflag)
- }
+ var allGlobalUseflags []models.Useflag
+ useExpands = make(map[string][]models.Useflag)
+ for _, useflag := range tmp_useflags {
+ if useflag.Scope == "global" {
+ allGlobalUseflags = append(allGlobalUseflags, useflag)
+ } else if useflag.Scope == "local" {
+ if useflag.Package == gpackage.Atom {
+ localUseflags = append(localUseflags, useflag)
}
+ } else {
+ useExpands[useflag.UseExpand] = append(useExpands[useflag.UseExpand], useflag)
}
}
@@ -307,107 +183,66 @@ func getPackageUseflags(gpackage *models.Package) ([]models.Useflag, []models.Us
return localUseflags, filteredGlobalUseflags, useExpands
}
-// createPackageData creates the data used in the show package template
-func createPackageData(pageName string, gpackage *models.Package, localUseflags []models.Useflag, globalUseflags []models.Useflag, useExpands map[string][]models.Useflag, userPreferences models.UserPreferences) interface{} {
- return struct {
- PageName string
- Header models.Header
- Package models.Package
- Versions []*models.Version
- Masks []models.Mask
- LocalUseflags []models.Useflag
- GlobalUseflags []models.Useflag
- UseExpands map[string][]models.Useflag
- Application models.Application
- UserPreferences models.UserPreferences
- }{
- PageName: pageName,
- Header: models.Header{Title: gpackage.Atom + " – ", Tab: "packages"},
- Package: *gpackage,
- Versions: gpackage.Versions,
- LocalUseflags: localUseflags,
- GlobalUseflags: globalUseflags,
- UseExpands: useExpands,
- Masks: nil,
- Application: utils.GetApplicationData(),
- UserPreferences: userPreferences,
- }
-}
-
-// CreateFeedData creates the data used in changedVersions template
-func CreateFeedData(name string, versions []*models.Version) interface{} {
- return struct {
- Header models.Header
- Name string
- Versions []*models.Version
- Application models.Application
- }{
- Header: models.Header{Title: "Packages – ", Tab: "packages"},
- Name: name,
- Versions: versions,
- Application: utils.GetApplicationData(),
- }
-}
-
-// FormatRestricts returns a string containing a comma separated
-// list of capitalized first letters of the package restricts
-func FormatRestricts(restricts []string) string {
- var result []string
- for _, restrict := range restricts {
- if restrict != "" && restrict != "(" && restrict != ")" && !strings.HasSuffix(restrict, "?") {
- result = append(result, strings.ToUpper(string(restrict[0])))
- }
- }
- result = utils2.Deduplicate(result)
- return strings.Join(result, ", ")
-}
-
-// RemoteIdLink returns a link to the homepage of a given remote id
-func RemoteIdLink(remoteId models.RemoteId) string {
+// remoteIdLink returns a link to the homepage of a given remote id
+func remoteIdLink(remoteId models.RemoteId) string {
switch remoteId.Type {
+ case "bitbucket":
+ return "https://bitbucket.org/" + remoteId.Id
+ case "codeberg":
+ return "https://codeberg.org/" + remoteId.Id
+ case "cpan":
+ return "https://metacpan.org/dist/" + remoteId.Id
case "cpan-module":
return "https://metacpan.org/pod/" + remoteId.Id
- case "cpan":
- return "https://metacpan.org/release/" + remoteId.Id
+ case "cran":
+ return "https://cran.r-project.org/web/packages/" + remoteId.Id + "/"
+ case "ctan":
+ return "https://ctan.org/pkg/" + remoteId.Id
+ case "freedesktop-gitlab":
+ return "https://gitlab.freedesktop.org/" + remoteId.Id + ".git/"
+ case "gentoo":
+ return "https://gitweb.gentoo.org/" + remoteId.Id + ".git/"
case "github":
return "https://github.com/" + remoteId.Id
- case "sourceforge":
- return "https://sourceforge.net/projects/" + remoteId.Id + "/"
+ case "gitlab":
+ return "https://gitlab.com/" + remoteId.Id
+ case "gnome-gitlab":
+ return "https://gitlab.gnome.org/" + remoteId.Id + ".git/"
case "google-code":
return "https://code.google.com/archive/p/" + remoteId.Id + "/"
- case "bitbucket":
- return "https://bitbucket.org/" + remoteId.Id
- case "pypi":
- return "https://pypi.org/project/" + remoteId.Id + "/"
+ case "hackage":
+ return "https://hackage.haskell.org/package/" + remoteId.Id
+ case "heptapod":
+ return "https://foss.heptapod.net/" + remoteId.Id
+ case "kde-invent":
+ return "https://invent.kde.org/" + remoteId.Id
case "launchpad":
return "https://launchpad.net/" + remoteId.Id
- case "sourceforge-jp":
- return "https://sourceforge.net/projects/" + remoteId.Id + "/"
- case "rubygems":
- return "https://rubygems.org/gems/" + remoteId.Id + "/"
+ case "osdn":
+ return "https://osdn.net/projects/" + remoteId.Id + "/"
case "pear":
return "https://pear.php.net/package/" + remoteId.Id
- case "freshmeat":
- return "http://freshmeat.sourceforge.net/projects/" + remoteId.Id
- case "gitlab":
- return "https://gitlab.com/" + remoteId.Id
- case "heptapod":
- return "https://foss.heptapod.net/" + remoteId.Id
+ case "pecl":
+ return "https://pecl.php.net/package/" + remoteId.Id
+ case "pypi":
+ return "https://pypi.org/project/" + remoteId.Id + "/"
+ case "rubygems":
+ return "https://rubygems.org/gems/" + remoteId.Id + "/"
+ case "savannah":
+ return "https://savannah.gnu.org/projects/" + remoteId.Id
+ case "savannah-nongnu":
+ return "https://savannah.nongnu.org/projects/" + remoteId.Id
+ case "sourceforge":
+ return "https://sourceforge.net/projects/" + remoteId.Id + "/"
+ case "sourcehut":
+ return "https://sr.ht/" + remoteId.Id + "/"
+ case "vim":
+ return "https://vim.org/scripts/script.php?script_id=" + remoteId.Id
default:
return ""
}
}
-// isMasked returns true if any version is masked
-func isMasked(versions []*models.Version) bool {
- for _, version := range versions {
- if len(version.Masks) > 0 {
- return true
- }
- }
- return false
-}
-
// getMask returns the mask entry of the first version that is masked
func getMask(versions []*models.Version) *models.Mask {
for _, version := range versions {
@@ -420,20 +255,22 @@ func getMask(versions []*models.Version) *models.Mask {
// showRemovalNotice if all versions of the package are masked
func showRemovalNotice(versions []*models.Version) bool {
- showNotice := false
for _, version := range versions {
if len(version.Masks) > 0 && version.Masks[0].Versions == version.Atom {
- showNotice = true
+ return true
}
}
- return showNotice
+ return false
}
-// sort the versions in ascending order
-func sortVersionsAsc(versions []*models.Version) {
- sort.Slice(versions, func(i, j int) bool {
- return versions[i].SmallerThan(*versions[j])
- })
+// getDeprecation returns the deprecation entry of the first version that is deprecated
+func getDeprecation(versions []*models.Version) *models.DeprecatedPackage {
+ for _, version := range versions {
+ if len(version.Deprecates) > 0 {
+ return version.Deprecates[0]
+ }
+ }
+ return nil
}
// sort the versions in descending order
diff --git a/pkg/app/handler/useflags/expand.templ b/pkg/app/handler/useflags/expand.templ
new file mode 100644
index 0000000..c73d95b
--- /dev/null
+++ b/pkg/app/handler/useflags/expand.templ
@@ -0,0 +1,60 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ expand(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-md-9">
+ <div class="card border-0">
+ <div class="list-group">
+ for i, use := range useflags {
+ if i == 0 || use.UseExpand != useflags[i-1].UseExpand {
+ @templ.Raw("</div></div>")
+ <h3 class={ templ.KV("mt-4", i > 0) } id={ use.UseExpand }>{ use.UseExpand }</h3>
+ @templ.Raw(`<div class="card border-0"><div class="list-group">`)
+ }
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ <div class="col-md-3">
+ <dl>
+ <dd class="ml-3 mb-0">
+ for i, use := range useflags {
+ if i == 0 || use.UseExpand != useflags[i-1].UseExpand {
+ <a href={ templ.URL("#" + use.UseExpand) } class="text-muted">{ use.UseExpand }</a>
+ <br/>
+ }
+ }
+ </dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+}
+
+func Expand(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'use_expand'").
+ Order("use_expand", "name").
+ Column("use_expand", "name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "USE Expand", "USE Expand", expand(useflags))
+}
diff --git a/pkg/app/handler/useflags/global.go b/pkg/app/handler/useflags/global.go
deleted file mode 100644
index 45a9e06..0000000
--- a/pkg/app/handler/useflags/global.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Used to search for USE flags
-
-package useflags
-
-import (
- "github.com/go-pg/pg"
- "html/template"
- "net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-)
-
-// Search renders a template containing a list of search results
-// for a given query of USE flags
-func Global(w http.ResponseWriter, r *http.Request) {
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).Where("scope = 'global'").Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: "Global" + " – ", Tab: "useflags"},
- Page: "global",
- Useflags: useflags,
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/list.tmpl"))
-
- templates.ExecuteTemplate(w, "list.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/global.templ b/pkg/app/handler/useflags/global.templ
new file mode 100644
index 0000000..edfcda2
--- /dev/null
+++ b/pkg/app/handler/useflags/global.templ
@@ -0,0 +1,44 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ global(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <h3><span class="text-capitalize">Global</span> USE flags</h3>
+ <div class="card border-0">
+ <div class="list-group">
+ for _, use := range useflags {
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+func Global(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'global'").
+ Order("name").
+ Column("name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "Global", "Global", global(useflags))
+}
diff --git a/pkg/app/handler/useflags/index.go b/pkg/app/handler/useflags/index.go
deleted file mode 100644
index c14161e..0000000
--- a/pkg/app/handler/useflags/index.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Used to display the landing page of the USE flag section
-
-package useflags
-
-import (
- "html/template"
- "net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/models"
-)
-
-// Index renders a template to show the index page of the USE flags
-// section containing a bubble chart of popular USE flags
-func Index(w http.ResponseWriter, r *http.Request) {
-
- data := struct {
- Header models.Header
- Page string
- Application models.Application
- }{
- Header: models.Header{Title: "Useflags – ", Tab: "useflags"},
- Page: "browse",
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/index.tmpl"))
-
- templates.ExecuteTemplate(w, "index.tmpl", data)
-}
-
-// Index renders a template to show the index page of the USE flags
-// section containing a bubble chart of popular USE flags
-func Default(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils2.GetUserPreferences(r)
- if userPreferences.Useflags.Layout == "bubble" {
- http.Redirect(w, r, "/useflags/popular", http.StatusSeeOther)
- } else {
- http.Redirect(w, r, "/useflags/search", http.StatusSeeOther)
- }
-}
diff --git a/pkg/app/handler/useflags/local.go b/pkg/app/handler/useflags/local.go
deleted file mode 100644
index 23d1403..0000000
--- a/pkg/app/handler/useflags/local.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Used to search for USE flags
-
-package useflags
-
-import (
- "github.com/go-pg/pg"
- "html/template"
- "net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
- "sort"
-)
-
-// Search renders a template containing a list of search results
-// for a given query of USE flags
-func Local(w http.ResponseWriter, r *http.Request) {
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).Where("scope = 'local'").Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- sort.Slice(useflags, func(i, j int) bool {
- if useflags[i].Package != useflags[j].Package {
- return useflags[i].Package < useflags[j].Package
- } else {
- return useflags[i].Name < useflags[j].Name
- }
- })
-
- data := struct {
- Header models.Header
- Page string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: "Local" + " – ", Tab: "useflags"},
- Page: "local",
- Useflags: useflags,
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/listlocal.tmpl"))
-
- templates.ExecuteTemplate(w, "listlocal.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/local.templ b/pkg/app/handler/useflags/local.templ
new file mode 100644
index 0000000..cdc4a53
--- /dev/null
+++ b/pkg/app/handler/useflags/local.templ
@@ -0,0 +1,48 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ local(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="card border-0">
+ <div class="list-group">
+ for i, use := range useflags {
+ if i == 0 || use.Package != useflags[i-1].Package {
+ @templ.Raw("</div></div>")
+ <h3 class={ templ.KV("mt-4", i > 0) }>{ use.Package }</h3>
+ @templ.Raw(`<div class="card border-0"><div class="list-group">`)
+ }
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+func Local(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'local'").
+ Order("package", "name").
+ Column("package", "name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "Local", "Local", local(useflags))
+}
diff --git a/pkg/app/handler/useflags/popular.go b/pkg/app/handler/useflags/popular.go
index 2c1773d..7443bd1 100644
--- a/pkg/app/handler/useflags/popular.go
+++ b/pkg/app/handler/useflags/popular.go
@@ -8,57 +8,43 @@ import (
"net/http"
"soko/pkg/database"
"soko/pkg/models"
- "sort"
- "strings"
+
+ "github.com/go-pg/pg/v10"
)
+var excludePopularUseflags = []string{"test", "doc", "debug"}
+
// Popular shows a json encoded list of popular USE flags
func Popular(w http.ResponseWriter, r *http.Request) {
+ popular := struct {
+ Name string `json:"name"`
+ Useflags []struct {
+ Useflag string `pg:"useflag" json:"name"`
+ Count int `pg:"count" json:"size"`
+ Children types.Object `pg:"-" json:"children"`
+ } `json:"children"`
+ }{
+ Name: "flags",
+ }
- var versions []models.Version
- err := database.DBCon.Model(&versions).Column("useflags").Select()
+ err := database.DBCon.Model((*models.Version)(nil)).
+ Column("useflag").
+ ColumnExpr("COUNT(useflag) AS count").
+ TableExpr("jsonb_array_elements_text(useflags) AS raw_useflag").
+ TableExpr("REPLACE(raw_useflag,'+','') AS useflag").
+ Where(`useflag NOT LIKE '%\_%'`).
+ Where("useflag NOT IN (?)", pg.In(excludePopularUseflags)).
+ Group("useflag").
+ Order("count DESC").
+ Limit(66).
+ Select(&popular.Useflags)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
- dict := make(map[string]int)
- for _, version := range versions {
- for _, useflag := range version.Useflags {
- if useflag != "test" && useflag != "doc" && useflag != "debug" && len(strings.Split(useflag, "_")) < 2 {
- dict[strings.ReplaceAll(useflag, "+", "")] = dict[strings.ReplaceAll(useflag, "+", "")] + 1
- }
- }
- }
-
- type kv struct {
- Key string `json:"name"`
- Value int `json:"size"`
- Children types.Object `json:"children"`
- }
-
- type p struct {
- Name string `json:"name"`
- Children []kv `json:"children"`
- }
-
- var ss []kv
- for k, v := range dict {
- ss = append(ss, kv{k, v, nil})
- }
-
- sort.Slice(ss, func(i, j int) bool {
- return ss[i].Value > ss[j].Value
- })
-
- popular := p{
- Name: "flags",
- Children: ss[0:66],
- }
-
b, err := json.Marshal(popular)
-
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
diff --git a/pkg/app/handler/useflags/popular.templ b/pkg/app/handler/useflags/popular.templ
new file mode 100644
index 0000000..716a73a
--- /dev/null
+++ b/pkg/app/handler/useflags/popular.templ
@@ -0,0 +1,31 @@
+package useflags
+
+import "net/http"
+
+templ popular() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="card" style="background: none;border: none;">
+ <noscript>
+ <div class="panel-body kk-panel-content-sorry">
+ This feature requires JavaScript to work.
+ </div>
+ </noscript>
+ <div
+ class="panel-body kk-useflag-bubble-container"
+ id="bubble-placeholder"
+ style="overflow: hidden!important; display: none;"
+ ></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <script src="/assets/useflags.js"></script>
+}
+
+// PopularPage renders a template to show the index page of the USE flags
+// section containing a bubble chart of popular USE flags
+func PopularPage(w http.ResponseWriter, r *http.Request) {
+ RenderPage(w, r, "Useflags", "Widely used", popular())
+}
diff --git a/pkg/app/handler/useflags/search.go b/pkg/app/handler/useflags/search.go
deleted file mode 100644
index 2523834..0000000
--- a/pkg/app/handler/useflags/search.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Used to search for USE flags
-
-package useflags
-
-import (
- "github.com/go-pg/pg"
- "html/template"
- "net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-)
-
-// Search renders a template containing a list of search results
-// for a given query of USE flags
-func Search(w http.ResponseWriter, r *http.Request) {
-
- results, _ := r.URL.Query()["q"]
-
- param := ""
- var useflags []models.Useflag
- if len(results) != 0 {
- param = results[0]
- err := database.DBCon.Model(&useflags).Where("name LIKE ? ", (param + "%")).Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
- }
-
- data := struct {
- Header models.Header
- Page string
- Search string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: param + " – ", Tab: "useflags"},
- Page: "search",
- Search: param,
- Useflags: useflags,
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/search.tmpl"))
-
- templates.ExecuteTemplate(w, "search.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/search.templ b/pkg/app/handler/useflags/search.templ
new file mode 100644
index 0000000..bcfa88a
--- /dev/null
+++ b/pkg/app/handler/useflags/search.templ
@@ -0,0 +1,92 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+css searchButton() {
+ border-top-right-radius: 0.25rem !important;
+ border-bottom-right-radius: 0.25rem !important;
+ font-size: 1.1em !important;
+ height: 2.3em !important;
+ border-left: 0px;
+ box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) !important;
+}
+
+templ search(query string, useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class={ "col-12", templ.KV("mt-5", len(useflags) == 0), templ.KV("pt-5", len(useflags) == 0) }>
+ <div class="col-12 mt-3 text-center">
+ <h2>Find USE flags</h2>
+ </div>
+ <div class="col-12">
+ <form action="/useflags/search" method="get" class="useflag-search mt-3 mb-5 mx-5 px-5">
+ <div class="typeahead__container mx-5 px-5">
+ <div class="typeahead__field">
+ <span class="typeahead__query" style="font-size: 1.1em; height: 2.3em;">
+ <input id="q" name="q" class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" type="search" autocomplete="off" placeholder="Find USE flags"/>
+ </span>
+ <span class="typeahead__button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;">
+ <button class={ searchButton() } type="submit">
+ <span class="typeahead__search-icon"></span>
+ </button>
+ </span>
+ </div>
+ </div>
+ </form>
+ </div>
+ if query != "" {
+ if len(useflags) > 0 {
+ <h2>USE Flag Search Results <small>{ "for" } { query }</small></h2>
+ <div class="card border-0">
+ <div class="list-group">
+ for _, use := range useflags {
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.URL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">
+ { use.Name }
+ if use.Scope == "local" {
+ <span class="text-secondary">({ use.Package })</span>
+ }
+ </h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ } else {
+ <h2>No results found <small>{ "for" } { query }</small></h2>
+ }
+ }
+ </div>
+ </div>
+ </div>
+ <script src="/assets/useflags.js"></script>
+}
+
+// Search renders a template containing a list of search results
+// for a given query of USE flags
+func Search(w http.ResponseWriter, r *http.Request) {
+ results := r.URL.Query()["q"]
+
+ param := ""
+ var useflags []models.Useflag
+ if len(results) != 0 {
+ param = results[0]
+ err := database.DBCon.Model(&useflags).
+ Column("name", "description", "scope", "package").
+ Where("name LIKE ?", param+"%").
+ OrderExpr("scope, name <-> ?", param).
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ }
+ RenderPage(w, r, param, "Search", search(param, useflags))
+}
diff --git a/pkg/app/handler/useflags/show.go b/pkg/app/handler/useflags/show.go
deleted file mode 100644
index bcea074..0000000
--- a/pkg/app/handler/useflags/show.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Used to show a specific package
-
-package useflags
-
-import (
- "github.com/go-pg/pg/v9"
- "html/template"
- "net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
- "soko/pkg/utils"
- "strings"
-)
-
-// Show renders a template to show a given USE flag
-func Show(w http.ResponseWriter, r *http.Request) {
-
- useflagName := r.URL.Path[len("/useflags/"):]
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).Where("name = ? ", useflagName).Select()
- if err != nil || len(useflags) < 1 {
- http.NotFound(w, r)
- return
- }
-
- useflag := useflags[0]
- var localuseflags []models.Useflag
-
- for _, use := range useflags {
- if use.Scope == "global" {
- useflag = use
- } else if use.Scope == "local" {
- localuseflags = append(localuseflags, use)
- } else if use.Scope == "use_expand" {
- ShowUseExpand(w, r, use)
- return
- }
- }
-
- var versions []models.Version
- err = database.DBCon.Model(&versions).Column("atom").Where("useflags::jsonb @> ?", "\""+useflagName+"\"").Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- var packages []string
- for _, version := range versions {
- packages = append(packages, version.Atom)
- }
-
- packages = utils.Deduplicate(packages)
-
- data := struct {
- Header models.Header
- Page string
- Useflag models.Useflag
- LocalUseflags []models.Useflag
- Packages []string
- Application models.Application
- }{
- Header: models.Header{Title: useflag.Name + " – ", Tab: "useflags"},
- Page: "show",
- Useflag: useflag,
- LocalUseflags: localuseflags,
- Packages: packages,
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").Funcs(template.FuncMap{
- "replaceall": strings.ReplaceAll,
- }).ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/useflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/show.tmpl"))
-
- templates.ExecuteTemplate(w, "show.tmpl", data)
-}
-
-// ShowUseExpand renders a template to show a given use_expand
-func ShowUseExpand(w http.ResponseWriter, r *http.Request, useExpand models.Useflag) {
-
- funcMap := template.FuncMap{
- "replaceall": strings.ReplaceAll,
- }
-
- var otheruseexpands []models.Useflag
- err := database.DBCon.Model(&otheruseexpands).Where("use_expand = ? ", useExpand.UseExpand).Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- var versions []models.Version
- err = database.DBCon.Model(&versions).Column("atom").Where("useflags::jsonb @> ?", "\""+useExpand.Name+"\"").Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- var packages []string
- for _, version := range versions {
- packages = append(packages, version.Atom)
- }
-
- packages = utils.Deduplicate(packages)
-
- data := struct {
- Header models.Header
- Page string
- Useflag models.Useflag
- OtherUseExpands []models.Useflag
- Packages []string
- Application models.Application
- }{
- Header: models.Header{Title: useExpand.Name + " – ", Tab: "useflags"},
- Page: "show",
- Useflag: useExpand,
- OtherUseExpands: otheruseexpands,
- Packages: packages,
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").Funcs(funcMap).ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/useflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/showexpand.tmpl"))
-
- templates.ExecuteTemplate(w, "showexpand.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/show.templ b/pkg/app/handler/useflags/show.templ
new file mode 100644
index 0000000..2beb499
--- /dev/null
+++ b/pkg/app/handler/useflags/show.templ
@@ -0,0 +1,175 @@
+package useflags
+
+import "net/http"
+import "strconv"
+import "strings"
+import "soko/pkg/app/layout"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ showUseflagHeader(useflag models.Useflag) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3 pt-2">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title">
+ <small class="kk-package-cat">
+ <a href="/useflags" class={ "text-dark", "ml-1", templ.KV("text-capitalize", useflag.UseExpand == "") }>
+ if useflag.UseExpand != "" {
+ { useflag.UseExpand }
+ } else {
+ { useflag.Scope } USE flag
+ }
+ </a>
+ </small>
+ <div>
+ <div class="kk-package-name" style="margin-left: 0px!important;">
+ <span class="fa fa-fw fa-sliders"></span>
+ <span class="ml-2">
+ if useflag.UseExpand != "" {
+ { strings.TrimPrefix(useflag.Name, useflag.UseExpand + "_") }
+ } else {
+ { useflag.Name }
+ }
+ </span>
+ </div>
+ </div>
+ </h1>
+ </div>
+ if useflag.Scope != "local" {
+ <div class="col-md-7">
+ <p class="lead kk-package-maindesc">
+ { useflag.Description }
+ </p>
+ </div>
+ }
+ <div class="col-md-12 pt-4 mt-1"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+templ show(useflag models.Useflag, localUseflags, otherUseExpands []models.Useflag, Packages []string) {
+ @showUseflagHeader(useflag)
+ <div class="tab-content" id="myTabContent">
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ if len(otherUseExpands) != 0 {
+ <h3 class="mb-2">Other “{ useflag.UseExpand }” USE_EXPAND flag values</h3>
+ <div class="card">
+ <div class="table-responsive">
+ <table class="table">
+ <thead>
+ <th>Use Flag</th>
+ <th>Description</th>
+ </thead>
+ <tbody>
+ for _, use := range otherUseExpands {
+ <tr>
+ <th class="kk-nobreak-cell">
+ <a href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a>
+ </th>
+ <td>{ use.Description }</td>
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ }
+ if len(localUseflags) != 0 {
+ <h3 class="mb-2">Packages describing “{ useflag.Name }” as local USE flag</h3>
+ <div class="card mb-4 border-top-0">
+ <div class="table-responsive">
+ <table class="table mb-0">
+ <thead>
+ <th>Package</th>
+ <th>“{ useflag.Name }” Flag Description</th>
+ </thead>
+ <tbody>
+ for _, use := range localUseflags {
+ <tr>
+ <th class="kk-nobreak-cell">
+ <a href={ templ.URL("/packages/" + use.Package) }>{ use.Package }</a>
+ </th>
+ <td>{ use.Description }</td>
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ }
+ if len(Packages) != 0 {
+ <h3 class="mb-2 pt-2">All packages providing a “{ useflag.Name }” USE flag ({ strconv.Itoa(len(Packages)) })</h3>
+ <div class="card">
+ <div class="card-body">
+ <ul class="kk-col-list kk-3col-list kk-useflag-listing mb-0">
+ for _, pkg := range Packages {
+ <li><a href={ templ.URL("/packages/" + pkg) }>{ pkg }</a></li>
+ }
+ </ul>
+ </div>
+ </div>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+// Show renders a template to show a given USE flag
+func Show(w http.ResponseWriter, r *http.Request) {
+ useFlagName := r.PathValue("useflag")
+
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("name = ?", useFlagName).
+ Order("scope", "package").
+ Select()
+ if err != nil || len(useflags) < 1 {
+ http.NotFound(w, r)
+ return
+ }
+
+ var packages []string
+ err = database.DBCon.Model((*models.Version)(nil)).
+ Column("atom").Distinct().
+ Where("useflags::jsonb @> ?", "\""+useFlagName+"\"").
+ Order("atom").
+ Select(&packages)
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+
+ useflag := useflags[0]
+
+ var localUseFlags, otherUseExpands []models.Useflag
+ if use := useflags[len(useflags)-1]; use.Scope == "use_expand" {
+ err := database.DBCon.Model(&otherUseExpands).
+ Column("name", "description").
+ Where("use_expand = ?", useflag.UseExpand).
+ Order("name").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ } else if useflag.Scope == "global" {
+ localUseFlags = useflags[1:]
+ } else {
+ localUseFlags = useflags
+ }
+
+ layout.Layout(useFlagName, "useflags",
+ show(useflag, localUseFlags, otherUseExpands, packages)).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/useflags/suggest.go b/pkg/app/handler/useflags/suggest.go
index 710ac15..2093a3b 100644
--- a/pkg/app/handler/useflags/suggest.go
+++ b/pkg/app/handler/useflags/suggest.go
@@ -4,54 +4,43 @@ package useflags
import (
"encoding/json"
- "github.com/go-pg/pg/v9"
"net/http"
"soko/pkg/database"
"soko/pkg/models"
+
+ "github.com/go-pg/pg/v10"
)
// Suggest returns a json encoded suggestions of
// USE flags based on the given query
func Suggest(w http.ResponseWriter, r *http.Request) {
-
- results, _ := r.URL.Query()["q"]
-
+ results, found := r.URL.Query()["q"]
+ if !found || len(results[0]) < 1 {
+ http.Error(w, http.StatusText(http.StatusBadRequest),
+ http.StatusBadRequest)
+ return
+ }
param := results[0]
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).Where("name LIKE ? ", (param + "%")).Select()
+ var suggestions struct {
+ Results []struct {
+ Id string `json:"id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ } `json:"results"`
+ }
+
+ err := database.DBCon.Model((*models.Useflag)(nil)).
+ Column("id", "name", "description").
+ Where("name LIKE ?", param+"%").
+ Select(&suggestions.Results)
if err != nil && err != pg.ErrNoRows {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
- type Suggest struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Description string `json:"description"`
- }
-
- type Suggestions struct {
- Results []Suggest `json:"results"`
- }
-
- var suggests []Suggest
-
- for _, useflag := range useflags {
- suggests = append(suggests, Suggest{
- Id: useflag.Id,
- Name: useflag.Name,
- Description: useflag.Description,
- })
- }
-
- suggestions := Suggestions{
- Results: suggests,
- }
-
jsondata, err := json.Marshal(suggestions)
-
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
diff --git a/pkg/app/handler/useflags/utils.go b/pkg/app/handler/useflags/utils.go
new file mode 100644
index 0000000..5056792
--- /dev/null
+++ b/pkg/app/handler/useflags/utils.go
@@ -0,0 +1,20 @@
+package useflags
+
+import (
+ "net/http"
+ "soko/pkg/app/layout"
+
+ "github.com/a-h/templ"
+)
+
+var tabs = []layout.SubTab{
+ {Name: "Widely used", Link: templ.URL("/useflags"), Icon: "fa fa-line-chart mr-1"},
+ {Name: "Search", Link: templ.URL("/useflags/search"), Icon: "fa fa-search mr-1"},
+ {Name: "Global", Link: templ.URL("/useflags/global"), Icon: "fa fa-globe mr-1"},
+ {Name: "Local", Link: templ.URL("/useflags/local"), Icon: "fa fa-map-marker mr-1"},
+ {Name: "USE Expand", Link: templ.URL("/useflags/expand"), Icon: "fa fa-list mr-1"},
+}
+
+func RenderPage(w http.ResponseWriter, r *http.Request, title string, currentTab string, content templ.Component) {
+ layout.TabbedLayout(title, "useflags", "USE flags", "fa fa-fw fa-sliders", "", tabs, currentTab, content).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/user/general.templ b/pkg/app/handler/user/general.templ
new file mode 100644
index 0000000..c908295
--- /dev/null
+++ b/pkg/app/handler/user/general.templ
@@ -0,0 +1,89 @@
+package user
+
+import "encoding/base64"
+import "encoding/json"
+import "net/http"
+import "time"
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+
+templ general(preferences models.GeneralPreferences) {
+ <form method="post" action="/user/preferences/general/layout">
+ <div class="row">
+ <div class="col-5 offset-1 mt-1">
+ <div class="card" style="background: transparent;">
+ <div class="card-body">
+ <img id="img1" alt="Recently Added Packages (default)" src="/assets/pgo3.png" style="width: 100%;cursor: pointer;"/>
+ </div>
+ </div>
+ <div class="text-center mt-2">
+ <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
+ <input
+ type="radio"
+ id="classicLandingpageLayout"
+ name="landingpage-layout"
+ value="classic"
+ checked?={ preferences.LandingPageLayout == "classic" }
+ />
+ <label class="form-check-label ml-1" for="classicLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Added Packages (default)">Recently Added Packages <i>(default)</i></label>
+ </div>
+ </div>
+ </div>
+ <div class="col-5 mt-1">
+ <div class="card" style="background: transparent;">
+ <div class="card-body">
+ <img id="img2" alt="Recently Visited Packages" src="/assets/pgo4.png" style="width: 100%;cursor: pointer;"/>
+ </div>
+ </div>
+ <div class="text-center mt-2">
+ <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
+ <input
+ type="radio"
+ id="fullLandingpageLayout"
+ name="landingpage-layout"
+ value="full"
+ checked?={ preferences.LandingPageLayout == "full" }
+ />
+ <label class="form-check-label ml-1" for="fullLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Visited Packages">Recently Visited Packages</label>
+ </div>
+ </div>
+ </div>
+ <div class="col-10 offset-1 mt-4">
+ <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
+ <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/general/reset">Reset to Defaults</a>
+ </div>
+ </div>
+ </form>
+ <div id="myModal" class="modal">
+ <span class="close">&times;</span>
+ <img class="modal-content" id="img01"/>
+ <div id="caption"></div>
+ </div>
+}
+
+func General(w http.ResponseWriter, r *http.Request) {
+ userPreferences := utils.GetUserPreferences(r)
+ r.ParseForm()
+ // landing page layout
+ layout := r.Form.Get("landingpage-layout")
+ if layout == "classic" || layout == "full" {
+ userPreferences.General.LandingPageLayout = layout
+ }
+ // store cookie
+ encodedUserPreferences, err := json.Marshal(&userPreferences.General)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther)
+}
+
+func ResetGeneral(w http.ResponseWriter, r *http.Request) {
+ userPreferences := utils.GetDefaultUserPreferences()
+ encodedUserPreferences, err := json.Marshal(&userPreferences.General)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther)
+}
diff --git a/pkg/app/handler/user/maintainers.templ b/pkg/app/handler/user/maintainers.templ
new file mode 100644
index 0000000..a12c913
--- /dev/null
+++ b/pkg/app/handler/user/maintainers.templ
@@ -0,0 +1,91 @@
+package user
+
+import "encoding/base64"
+import "encoding/json"
+import "net/http"
+import "time"
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+import "slices"
+import "soko/pkg/database"
+
+func splitAllProjects() [][]models.Project {
+ var projects []models.Project
+ database.DBCon.Model(&projects).Column("name", "email").Select()
+ split := (3 + len(projects)) / 4
+ return [][]models.Project{projects[:split], projects[split : 2*split], projects[2*split : 3*split], projects[3*split:]}
+}
+
+templ maintainers(preferences models.MaintainersPreferences) {
+ <form method="post" action="/user/preferences/maintainers/edit">
+ <div class="row">
+ <div class="col-12">
+ <h3 class="mt-0" id="qa-report">Include Project Packages</h3>
+ <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
+ <input
+ type="checkbox"
+ id="include-packages"
+ name="include-packages"
+ value="true"
+ checked?={ preferences.IncludeProjectPackages }
+ />
+ <label class="form-check-label ml-1" for="include-packages" style="overflow:hidden;text-overflow: ellipsis;" title="">Include packages of projects the maintainer is part of</label>
+ </div>
+ <i>If this option is enabled, all packages, QA reports, pull requests and bugs of projects a maintainer is part of will be displayed as well on the maintainer page. That is, if <i>Larry</i> is part of the <i>Python</i> project, all packages, QA reports, pull requests and bugs of the Python project will be displayed as well on the maintainer page of <i>Larry</i>.<br/>Below you can furthermore specify projects that will be excluded on the maintainer page. E.g. if Larry is furthermore part of the proxy-maintainers project, and the project is marked below, packages of the proxy maintainers project won't be shown on Larry's maintainer page.</i>
+ </div>
+ <div class="col-12">
+ <h3 class="mt-4 pt-3" id="qa-report">Excluded Projects</h3>
+ </div>
+ for _, projects := range splitAllProjects() {
+ <div class="col-3">
+ for _, project := range projects {
+ <li class="list-group-item">
+ <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;height:21px;">
+ <input
+ type="checkbox"
+ id={ "excluded-projects-" + project.Email }
+ name="excluded-projects"
+ value={ project.Email }
+ checked?={ slices.Contains(preferences.ExcludedProjects, project.Email) }
+ />
+ <label class="form-check-label ml-1" for={ "excluded-projects-" + project.Email } style="overflow:hidden;text-overflow: ellipsis;height:21px;" title={ project.Name }>{ project.Name }</label>
+ </div>
+ </li>
+ }
+ </div>
+ }
+ <div class="col-12 mt-4">
+ <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
+ <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/maintainers/reset">Reset to Defaults</a>
+ </div>
+ </div>
+ </form>
+}
+
+func Maintainers(w http.ResponseWriter, r *http.Request) {
+ userPreferences := utils.GetUserPreferences(r)
+ r.ParseForm()
+ // excluded projects
+ excludedProjects := r.Form["excluded-projects"]
+ userPreferences.Maintainers.ExcludedProjects = excludedProjects
+ // include projects?
+ includePackages := r.Form.Get("include-packages")
+ userPreferences.Maintainers.IncludeProjectPackages = includePackages == "true"
+ // store cookie
+ encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther)
+}
+
+func ResetMaintainers(w http.ResponseWriter, r *http.Request) {
+ userPreferences := utils.GetDefaultUserPreferences()
+ encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther)
+}
diff --git a/pkg/app/handler/user/packages.templ b/pkg/app/handler/user/packages.templ
new file mode 100644
index 0000000..0bf4cbd
--- /dev/null
+++ b/pkg/app/handler/user/packages.templ
@@ -0,0 +1,126 @@
+package user
+
+import "encoding/base64"
+import "encoding/json"
+import "net/http"
+import "time"
+import "soko/pkg/app/utils"
+import "soko/pkg/models"
+
+templ packages(preferences models.PackagesPreferences) {
+ <div class="row">
+ <form method="post" action="/user/preferences/packages/edit">
+ <h4 class="mb-1">Layout</h4>
+ <div class="row">
+ <div class="col-6 mt-1">
+ <div class="card" style="background: transparent;">
+ <div class="card-body">
+ <img id="img1" alt="Versions + Metadata (default)" src="/assets/pgo2.png" style="width: 100%;cursor: pointer;"/>
+ </div>
+ </div>
+ <div class="text-center mt-2">
+ <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
+ <input
+ type="radio"
+ id="minimalOverviewLayout"
+ name="overview-layout"
+ value="minimal"
+ checked?={ preferences.Overview.Layout == "minimal" }
+ />
+ <label class="form-check-label ml-1" for="minimalOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata (default)">Versions + Metadata <i>(default)</i></label>
+ </div>
+ </div>
+ </div>
+ <div class="col-6 mt-1">
+ <div class="card" style="background: transparent;">
+ <div class="card-body">
+ <img id="img2" alt="Versions + Metadata + Changelog" src="/assets/pgo1.png" onclick="document.getElementById('fullOverviewLayout').checked = true;" style="width: 100%;cursor: pointer;"/>
+ </div>
+ </div>
+ <div class="text-center mt-2">
+ <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
+ <input
+ type="radio"
+ id="fullOverviewLayout"
+ name="overview-layout"
+ value="full"
+ checked?={ preferences.Overview.Layout == "full" }
+ />
+ <label class="form-check-label ml-1" for="fullOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata + Changelog">Versions + Metadata + Changelog</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <h4 class="mt-4 mb-1">EAPI version</h4>
+ <div class="card">
+ <div class="card-body">
+ Show
+ <select class="form-control form-control-sm ml-2" style="max-width: 100px;display: inline;" name="overview-eapi" id="overview-eapi">
+ <option
+ value="none"
+ selected?={ preferences.Overview.EAPI == "none" }
+ >none</option>
+ <option
+ value="column"
+ selected?={ preferences.Overview.EAPI == "column" }
+ >in column</option>
+ <option
+ value="inline"
+ selected?={ preferences.Overview.EAPI == "inline" }
+ >inline</option>
+ </select>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-12 mt-4">
+ <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
+ <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/packages/reset">Reset to Defaults</a>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div id="myModal" class="modal">
+ <span class="close">&times;</span>
+ <img class="modal-content" id="img01"/>
+ <div id="caption"></div>
+ </div>
+}
+
+func EditPackagesPreferences(w http.ResponseWriter, r *http.Request) {
+
+ userPreferences := utils.GetUserPreferences(r)
+
+ r.ParseForm()
+
+ // Overview: Layout
+ overviewLayout := r.Form.Get("overview-layout")
+ if overviewLayout == "minimal" || overviewLayout == "full" {
+ userPreferences.Packages.Overview.Layout = overviewLayout
+ }
+
+ // EAPI
+ showEAPI := r.Form.Get("overview-eapi")
+ if showEAPI == "none" || showEAPI == "column" || showEAPI == "inline" {
+ userPreferences.Packages.Overview.EAPI = showEAPI
+ }
+
+ //
+ // Store cookie
+ //
+ encodedUserPreferences, err := json.Marshal(&userPreferences.Packages)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther)
+}
+
+func ResetPackages(w http.ResponseWriter, r *http.Request) {
+ userPreferences := utils.GetDefaultUserPreferences()
+ encodedUserPreferences, err := json.Marshal(&userPreferences.Packages)
+ if err == nil {
+ sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences)
+ addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour)
+ }
+ http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther)
+}
diff --git a/pkg/app/handler/user/preferences.go b/pkg/app/handler/user/preferences.go
deleted file mode 100644
index 8c5deec..0000000
--- a/pkg/app/handler/user/preferences.go
+++ /dev/null
@@ -1,245 +0,0 @@
-package user
-
-import (
- b64 "encoding/base64"
- "encoding/json"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/config"
- "soko/pkg/database"
- "soko/pkg/models"
- "strconv"
- "strings"
- "time"
-)
-
-// Preferences renders a template to show the user preferences page
-func Preferences(w http.ResponseWriter, r *http.Request) {
-
- pageName := "general"
-
- if strings.HasSuffix(r.URL.Path, "/general") {
- pageName = "general"
- } else if strings.HasSuffix(r.URL.Path, "/packages") {
- pageName = "packages"
- } else if strings.HasSuffix(r.URL.Path, "/maintainers") {
- pageName = "maintainers"
- } else if strings.HasSuffix(r.URL.Path, "/useflags") {
- pageName = "useflags"
- } else if strings.HasSuffix(r.URL.Path, "/arches") {
- pageName = "arches"
- }
-
- var allProjects []*models.Project
- database.DBCon.Model(&allProjects).Select()
-
- renderUserTemplate(w, r, allProjects, pageName, "preferences")
-}
-
-func EditPackagesPreferences(w http.ResponseWriter, r *http.Request) {
-
- userPreferences := utils.GetUserPreferences(r)
-
- r.ParseForm()
-
- // Overview: Layout
- overviewLayout := r.Form.Get("overview-layout")
- if overviewLayout == "minimal" || overviewLayout == "full" {
- userPreferences.Packages.Overview.Layout = overviewLayout
- }
-
- // Overview: Keywords
- overviewKeywords := r.Form["overview-keywords"]
- userPreferences.Packages.Overview.Keywords = overviewKeywords
-
- // EAPI
- showEAPI := r.Form.Get("overview-eapi")
- if showEAPI == "none" || showEAPI == "column" || showEAPI == "inline" {
- userPreferences.Packages.Overview.EAPI = showEAPI
- }
-
- // Overview: Show Outdated
- userPreferences.Packages.Overview.ShowOutdated = r.Form.Get("overview-showOutdated") == "true"
-
- // Overview: Metadata fields
- overviewMetadataFields := r.Form["overview-metadata-fields"]
- userPreferences.Packages.Overview.MetadataFields = overviewMetadataFields
-
- // Overview: Changelog
- changelogSize, err := strconv.Atoi(r.Form.Get("overview-changelog-size"))
- if err == nil {
- if changelogSize < 100 {
- userPreferences.Packages.Overview.ChangelogLength = changelogSize
- } else {
- userPreferences.Packages.Overview.ChangelogLength = 100
- }
- }
-
- // Dependencies
- defaultDependenciesPage := r.Form.Get("dependencies-default-page")
- if defaultDependenciesPage == "dependencies" || defaultDependenciesPage == "reverse-dependencies" {
- userPreferences.Packages.Dependencies.Default = defaultDependenciesPage
- }
-
- // QA Report
- qaReportClasses := r.Form["qareport-classes"]
- excludedQAReportClasses := []int{}
- for i := 0; i <= 190; i++ {
- if !contains(qaReportClasses, strconv.Itoa(i)) {
- excludedQAReportClasses = append(excludedQAReportClasses, i)
- }
- }
- userPreferences.Packages.QAReport.ExcludedWarningClasses = excludedQAReportClasses
-
- // Tabs
- visibleTabs := r.Form["visible-tabs"]
- userPreferences.Packages.Tabs.Visible = visibleTabs
-
- //
- // Store cookie
- //
- encodedUserPreferences, err := json.Marshal(&userPreferences.Packages)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther)
-}
-
-func ResetPackages(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetDefaultUserPreferences()
- encodedUserPreferences, err := json.Marshal(&userPreferences.Packages)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther)
-}
-
-func General(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetUserPreferences(r)
- r.ParseForm()
- // landing page layout
- layout := r.Form.Get("landingpage-layout")
- if layout == "classic" || layout == "full" {
- userPreferences.General.LandingPageLayout = layout
- }
- // store cookie
- encodedUserPreferences, err := json.Marshal(&userPreferences.General)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther)
-}
-
-func ResetGeneral(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetDefaultUserPreferences()
- encodedUserPreferences, err := json.Marshal(&userPreferences.General)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther)
-}
-
-func Useflags(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetUserPreferences(r)
- r.ParseForm()
- // default use flag page
- layout := r.Form.Get("useflag-default-page")
- if layout == "bubble" || layout == "search" {
- userPreferences.Useflags.Layout = layout
- }
- // store cookie
- encodedUserPreferences, err := json.Marshal(&userPreferences.Useflags)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_useflags", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/useflags", http.StatusSeeOther)
-}
-
-func ResetUseflags(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetDefaultUserPreferences()
- encodedUserPreferences, err := json.Marshal(&userPreferences.Useflags)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_useflags", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/useflags", http.StatusSeeOther)
-}
-
-func Arches(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetUserPreferences(r)
- r.ParseForm()
- // visible arches
- visibleArches := r.Form["visible-arches"]
- userPreferences.Arches.Visible = visibleArches
- // default arch
- defaultArch := r.Form.Get("arches-default-arch")
- userPreferences.Arches.DefaultArch = defaultArch
- // default arches page
- defaultPage := r.Form.Get("arches-default-page")
- userPreferences.Arches.DefaultPage = defaultPage
- // store cookie
- encodedUserPreferences, err := json.Marshal(&userPreferences.Arches)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_arches", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/arches", http.StatusSeeOther)
-}
-
-func ResetArches(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetDefaultUserPreferences()
- encodedUserPreferences, err := json.Marshal(&userPreferences.Arches)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_arches", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/arches", http.StatusSeeOther)
-}
-
-func Maintainers(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetUserPreferences(r)
- r.ParseForm()
- // excluded projects
- excludedProjects := r.Form["excluded-projects"]
- userPreferences.Maintainers.ExcludedProjects = excludedProjects
- // include projects?
- includePackages := r.Form.Get("include-packages")
- userPreferences.Maintainers.IncludeProjectPackages = includePackages == "true"
- // store cookie
- encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther)
-}
-
-func ResetMaintainers(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils.GetDefaultUserPreferences()
- encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers)
- if err == nil {
- sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences)
- addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour)
- }
- http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther)
-}
-
-// addCookie will apply a new cookie to the response of a http request
-// with the key/value specified.
-func addCookie(w http.ResponseWriter, name, path, value string, ttl time.Duration) {
- expire := time.Now().Add(ttl)
- cookie := http.Cookie{
- Name: name,
- Path: path,
- Value: value,
- Expires: expire,
- HttpOnly: true,
- Secure: config.DevMode() == "false",
- }
- http.SetCookie(w, &cookie)
-}
diff --git a/pkg/app/handler/user/preferences.templ b/pkg/app/handler/user/preferences.templ
new file mode 100644
index 0000000..5119635
--- /dev/null
+++ b/pkg/app/handler/user/preferences.templ
@@ -0,0 +1,80 @@
+package user
+
+import "net/http"
+import "time"
+import "soko/pkg/app/layout"
+import "soko/pkg/app/utils"
+import "soko/pkg/config"
+import "soko/pkg/models"
+
+var viewTabs = []layout.SubTab{
+ {
+ Name: "General",
+ Link: "/user/preferences/general",
+ Icon: "fa fa-globe mr-1",
+ },
+ {
+ Name: "Packages",
+ Link: "/user/preferences/packages",
+ Icon: "fa fa-cube mr-1",
+ },
+ {
+ Name: "Maintainers",
+ Link: "/user/preferences/maintainers",
+ Icon: "fa fa-users mr-1",
+ },
+}
+
+templ show(currentSubTab string, preferences models.UserPreferences) {
+ <div class="container mb-5">
+ switch currentSubTab {
+ case "General":
+ @general(preferences.General)
+ case "Packages":
+ @packages(preferences.Packages)
+ case "Maintainers":
+ @maintainers(preferences.Maintainers)
+ }
+ </div>
+ <script src="/assets/userpref.js"></script>
+}
+
+templ sortableScript() {
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
+ <script>
+ if(document.getElementById("example1") != null && document.getElementById("example2") != null) {
+ new Sortable(example1, {
+ group: 'shared',
+ animation: 150,
+ ghostClass: 'bg-info'
+ });
+ new Sortable(example2, {
+ group: 'shared',
+ animation: 150,
+ ghostClass: 'bg-info'
+ });
+ }
+ </script>
+}
+
+func Preferences(currentSubTab string) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ layout.TabbedLayout("User", "preferences", "Preferences", "fa fa-fw fa-cog", "You can customize the page contents to your needs here", viewTabs,
+ currentSubTab, show(currentSubTab, utils.GetUserPreferences(r))).Render(r.Context(), w)
+ }
+}
+
+// addCookie will apply a new cookie to the response of a http request
+// with the key/value specified.
+func addCookie(w http.ResponseWriter, name, path, value string, ttl time.Duration) {
+ expire := time.Now().Add(ttl)
+ cookie := http.Cookie{
+ Name: name,
+ Path: path,
+ Value: value,
+ Expires: expire,
+ HttpOnly: true,
+ Secure: config.DevMode() == "false",
+ }
+ http.SetCookie(w, &cookie)
+}
diff --git a/pkg/app/handler/user/utils.go b/pkg/app/handler/user/utils.go
deleted file mode 100644
index 0372ef8..0000000
--- a/pkg/app/handler/user/utils.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package user
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/models"
- "strings"
-)
-
-// renderAboutTemplate renders a specific about template
-func renderUserTemplate(w http.ResponseWriter, r *http.Request, allProjects []*models.Project, pageName, page string) {
- templates := template.Must(
- template.Must(
- template.Must(
- template.Must(
- template.New(page).Funcs(template.FuncMap{
- "Contains": contains,
- "ContainsInt": containsInt,
- "CreateSlice": createSlice,
- "GetPkgcheckClass": models.GetPkgcheckClass,
- "add": func(a, b int) int {
- return a + b
- },
- }).
- ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/user/preferences/*.tmpl")).
- ParseGlob("web/templates/user/userheader.tmpl")).
- ParseGlob("web/templates/user/" + page + ".tmpl"))
-
- templates.ExecuteTemplate(w, page+".tmpl", getPageData(pageName, allProjects, utils.GetUserPreferences(r)))
-}
-
-func contains(list []string, item string) bool {
- return strings.Contains(" "+strings.Join(list, " ")+" ", " "+item+" ")
-}
-
-func containsInt(list []int, item int) bool {
- for _, v := range list {
- if v == item {
- return true
- }
- }
- return false
-}
-
-func createSlice(n int) []int {
- slice := []int{}
- for i := 0; i <= n; i++ {
- slice = append(slice, i)
- }
- return slice
-}
-
-// getPageData returns the data used
-// in all about templates
-func getPageData(pageName string, allProjects []*models.Project, preferences models.UserPreferences) interface{} {
- return struct {
- Header models.Header
- Application models.Application
- PageName string
- Projects []*models.Project
- UserPreferences models.UserPreferences
- }{
- Header: models.Header{Title: "User – ", Tab: "user"},
- Application: utils.GetApplicationData(),
- PageName: pageName,
- Projects: allProjects,
- UserPreferences: preferences,
- }
-}
diff --git a/pkg/app/layout/page.templ b/pkg/app/layout/page.templ
new file mode 100644
index 0000000..ebfe060
--- /dev/null
+++ b/pkg/app/layout/page.templ
@@ -0,0 +1,188 @@
+package layout
+
+import "soko/pkg/config"
+
+templ head(title string) {
+ <head>
+ <title>
+ if title != "" {
+ { title } – Gentoo Packages
+ } else {
+ Gentoo Packages
+ }
+ </title>
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+ <meta name="theme-color" content="#54487a"/>
+ <meta name="description" content="Gentoo Packages Database"/>
+ <script src="/assets/application.js"></script>
+ <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"/>
+ <link rel="stylesheet" href="/assets/stylesheets.css"/>
+ </head>
+}
+
+templ siteTitle() {
+ <div class="site-title">
+ <div class="container">
+ <div class="row justify-content-between">
+ <div class="logo">
+ <a href="/" title="Back to the homepage" class="site-logo">
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/site-logo.svg"/>
+ </a>
+ <span class="site-label">Packages</span>
+ </div>
+ <div class="site-title-buttons">
+ <div class="btn-group btn-group-sm">
+ <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a>
+ <div class="btn-group btn-group-sm">
+ <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
+ <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span>
+ </a>
+ <div class="dropdown-menu dropdown-menu-right">
+ <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a>
+ <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a>
+ <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a>
+ <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a>
+ <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a>
+ <div class="dropdown-divider"></div>
+ <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a>
+ <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a>
+ <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a>
+ <div class="dropdown-divider"></div>
+ <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+templ navigationBar(tab string) {
+ <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation">
+ <div class="container">
+ <div class="navbar-header">
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse">
+ <ul class="navbar-nav mr-auto">
+ <li class={ "nav-item", templ.KV("active", tab == "home") }><a class="nav-link" href="/">Home</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "packages") }><a class="nav-link" href="/categories">Packages</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "maintainers") }><a class="nav-link" href="/maintainers">Maintainers</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "useflags") }><a class="nav-link" href="/useflags">USE flags</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "arches") }><a class="nav-link" href="/arches">Architectures</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "about") }><a class="nav-link" href="/about">About</a></li>
+ </ul>
+ if tab != "home" {
+ <form class="form-inline inlinesearch" role="search" action="/packages/search" method="get">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text" id="basic-addon1"><i class="fa fa-search" aria-hidden="true"></i></span>
+ </div>
+ <input class="form-control" name="q" type="text" placeholder="Find Packages" aria-label="Find Packages"/>
+ </div>
+ </form>
+ }
+ </div>
+ </div>
+ </nav>
+}
+
+templ footer() {
+ <footer style="background-color: #fafafa; box-shadow:none!important;">
+ <div class="container pt-4" style="border-top: 1px solid #dddddd;">
+ <div class="row">
+ <div class="col-2 col-sm-2 col-md-2">
+ <ul class="footerlinks three-icons">
+ <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li>
+ <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li>
+ <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li>
+ </ul>
+ </div>
+ <div class="col-8 col-sm-8 col-md-8">
+ <strong>&copy; 2001&ndash;2024 Gentoo Authors</strong>
+ <br/>
+ <small>
+ Gentoo is a trademark of the Gentoo Foundation, Inc. and of Förderverein Gentoo e.V.
+ The contents of this document, unless otherwise expressly stated, are licensed under the
+ <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license.
+ The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply.
+ </small>
+ </div>
+ <div class="col-2 col-sm-2 col-md-2 text-right">
+ <strong><a class="text-dark" href="https://www.gentoo.org/inside-gentoo/contact/">Contact</a></strong>
+ <br/>
+ <small>{ config.Version() }</small>
+ </div>
+ </div>
+ </div>
+ </footer>
+}
+
+templ Layout(title string, tab string, contents templ.Component) {
+ <!DOCTYPE html>
+ <html lang="en">
+ @head(title)
+ <body>
+ <header>
+ @siteTitle()
+ @navigationBar(tab)
+ </header>
+ @contents
+ @footer()
+ </body>
+ </html>
+}
+
+type SubTab struct {
+ Name string
+ Link templ.SafeURL
+ Icon string
+ BadgeValue string
+}
+
+templ tabbedHeader(subTitle string, icon string, description string, tabs []SubTab, currentSubTab string, contents templ.Component) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3 pt-2">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title">
+ <div>
+ <div class="kk-package-name" style="margin-left: 0px!important;"><span class={ icon }></span><span class="ml-2">{ subTitle }</span></div>
+ </div>
+ </h1>
+ </div>
+ <div class="col-md-7">{ description }</div>
+ <div class="col-md-12 pt-4 mt-1">
+ <nav class="nav kk-package-nav">
+ for _, tab := range tabs {
+ <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }>
+ if tab.Icon != "" {
+ <i class={ tab.Icon } aria-hidden="true"></i>
+ }
+ { tab.Name }
+ if tab.BadgeValue != "" {
+ <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span>
+ }
+ </a>
+ }
+ </nav>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="tab-content" id="myTabContent">
+ @contents
+ </div>
+}
+
+templ TabbedLayout(title string, tab string, subTitle string, icon string, description string, tabs []SubTab, currentSubTab string, contents templ.Component) {
+ @Layout(title, tab, tabbedHeader(subTitle, icon, description, tabs, currentSubTab, contents))
+}
diff --git a/pkg/app/serve.go b/pkg/app/serve.go
index ce4d8bb..b54d4f2 100644
--- a/pkg/app/serve.go
+++ b/pkg/app/serve.go
@@ -3,11 +3,10 @@
package app
import (
- "github.com/99designs/gqlgen/graphql/handler"
- "github.com/99designs/gqlgen/graphql/handler/extension"
- "log"
+ "log/slog"
"net/http"
_ "net/http/pprof"
+ "os"
"soko/pkg/api/graphql/generated"
"soko/pkg/api/graphql/graphiql"
"soko/pkg/api/graphql/resolvers"
@@ -21,75 +20,103 @@ import (
"soko/pkg/app/handler/user"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
+
+ "github.com/99designs/gqlgen/graphql/handler"
+ "github.com/99designs/gqlgen/graphql/handler/extension"
)
// Serve is used to serve the web application
func Serve() {
-
database.Connect()
defer database.DBCon.Close()
- setRoute("/categories", categories.Index)
- setRoute("/categories.json", categories.JSONCategories)
- setRoute("/categories/", categories.Show)
-
- setRoute("/useflags/popular.json", useflags.Popular)
- setRoute("/useflags/suggest.json", useflags.Suggest)
- setRoute("/useflags/search", useflags.Search)
- setRoute("/useflags/global", useflags.Global)
- setRoute("/useflags/local", useflags.Local)
- setRoute("/useflags/popular", useflags.Index)
- setRoute("/useflags", useflags.Default)
- setRoute("/useflags/", useflags.Show)
-
- setRoute("/arches", arches.Index)
- setRoute("/arches/", arches.Show)
-
- setRoute("/about", about.Index)
- setRoute("/about/help", about.Help)
- setRoute("/about/feedback", about.Feedback)
- setRoute("/about/feeds", about.Feeds)
- setRoute("/about/status", about.Status)
-
- setRoute("/maintainers", maintainer.Browse)
- setRoute("/maintainers/", maintainer.Browse)
- setRoute("/maintainer/", maintainer.Show)
-
- setRoute("/packages/search", packages.Search)
- setRoute("/packages/suggest.json", packages.Suggest)
- setRoute("/packages/resolve.json", packages.Resolve)
- setRoute("/packages/added", packages.Added)
- setRoute("/packages/updated", packages.Updated)
- setRoute("/packages/stable", packages.Stabilized)
- setRoute("/packages/keyworded", packages.Keyworded)
- setRoute("/packages/", packages.Show)
- setRoute("/", index.Show)
-
- setRoute("/packages/added.atom", packages.AddedFeed)
- setRoute("/packages/updated.atom", packages.UpdatedFeed)
- setRoute("/packages/keyworded.atom", packages.KeywordedFeed)
- setRoute("/packages/stable.atom", packages.StabilizedFeed)
- // Added for backwards compability
- redirect("/packages/stabilized.atom", "/packages/stable.atom")
- setRoute("/packages/search.atom", packages.SearchFeed)
-
- setRoute("/user", user.Preferences)
- setRoute("/user/preferences", user.Preferences)
- setRoute("/user/preferences/", user.Preferences)
+ setRoute("GET /categories", categories.Index)
+ setRoute("GET /categories.json", categories.JSONCategories)
+ setRoute("GET /categories/{category}", categories.ShowPackages)
+ setRoute("GET /categories/{category}/bugs", categories.ShowBugs)
+ setRoute("GET /categories/{category}/outdated", categories.ShowOutdated)
+ setRoute("GET /categories/{category}/outdated.atom", categories.OutdatedFeed)
+ setRoute("GET /categories/{category}/pull-requests", categories.ShowPullRequests)
+ setRoute("GET /categories/{category}/security", categories.ShowSecurity)
+ setRoute("GET /categories/{category}/stabilization", categories.ShowStabilizations)
+ setRoute("GET /categories/{category}/stabilization.atom", categories.StabilizationFeed)
+ setRoute("GET /categories/{category}/stabilization.json", categories.ShowStabilizationFile)
+ setRoute("GET /categories/{category}/stabilization.list", categories.ShowStabilizationFile)
+ setRoute("GET /categories/{category}/stabilization.xml", categories.ShowStabilizationFile)
+
+ redirect("GET /useflags", "/useflags/popular")
+ setRoute("GET /useflags/popular.json", useflags.Popular)
+ setRoute("GET /useflags/suggest.json", useflags.Suggest)
+ setRoute("GET /useflags/search", useflags.Search)
+ setRoute("GET /useflags/global", useflags.Global)
+ setRoute("GET /useflags/local", useflags.Local)
+ setRoute("GET /useflags/expand", useflags.Expand)
+ setRoute("GET /useflags/popular", useflags.PopularPage)
+ setRoute("GET /useflags/{useflag}", useflags.Show)
+
+ redirect("GET /arches", "/arches/amd64/keyworded")
+ setRoute("GET /arches/{arch}/stable", arches.ShowStable)
+ setRoute("GET /arches/{arch}/stable.atom", arches.ShowStableFeed)
+ setRoute("GET /arches/{arch}/keyworded", arches.ShowKeyworded)
+ setRoute("GET /arches/{arch}/keyworded.atom", arches.ShowKeywordedFeed)
+ setRoute("GET /arches/{arch}/leaf-packages", arches.ShowLeafPackages)
+
+ setRoute("GET /about", about.Index)
+ setRoute("GET /about/help", about.Help)
+ setRoute("GET /about/feedback", about.Feedback)
+ setRoute("GET /about/feeds", about.Feeds)
+ setRoute("GET /about/status", about.Status)
+
+ setRoute("GET /maintainers", maintainer.BrowseProjects)
+ redirect("GET /maintainers/gentoo-projects", "/maintainers")
+ setRoute("GET /maintainers/gentoo-developers", maintainer.BrowseDevs)
+ setRoute("GET /maintainers/proxied-maintainers", maintainer.BrowseProxyDevs)
+ setRoute("GET /maintainer/{email}", maintainer.ShowPackages)
+ setRoute("GET /maintainer/{email}/bugs", maintainer.ShowBugs)
+ setRoute("GET /maintainer/{email}/changelog", maintainer.ShowChangelog)
+ setRoute("GET /maintainer/{email}/changelog.atom", maintainer.ShowChangelogFeed)
+ setRoute("GET /maintainer/{email}/info.json", maintainer.ShowInfoJson)
+ setRoute("GET /maintainer/{email}/outdated", maintainer.ShowOutdated)
+ setRoute("GET /maintainer/{email}/outdated.atom", maintainer.ShowOutdatedFeed)
+ setRoute("GET /maintainer/{email}/pull-requests", maintainer.ShowPullRequests)
+ setRoute("GET /maintainer/{email}/security", maintainer.ShowSecurity)
+ setRoute("GET /maintainer/{email}/stabilization", maintainer.ShowStabilization)
+ setRoute("GET /maintainer/{email}/stabilization.json", maintainer.ShowStabilizationFile)
+ setRoute("GET /maintainer/{email}/stabilization.list", maintainer.ShowStabilizationFile)
+ setRoute("GET /maintainer/{email}/stabilization.xml", maintainer.ShowStabilizationFile)
+ setRoute("GET /maintainer/{email}/stabilization.atom", maintainer.ShowStabilizationFeed)
+
+ setRoute("GET /packages/search", packages.Search)
+ setRoute("GET /packages/suggest.json", packages.Suggest)
+ setRoute("GET /packages/resolve.json", packages.Resolve)
+ setRoute("GET /packages/added", packages.Added)
+ setRoute("GET /packages/updated", packages.Updated)
+ setRoute("GET /packages/stable", packages.Stabilized)
+ setRoute("GET /packages/keyworded", packages.Keyworded)
+ setRoute("GET /packages/{category}/{package}", packages.Show)
+ setRoute("GET /packages/{category}/{package}/{pageName}", packages.Show)
+ setRoute("GET /{$}", index.Show)
+
+ setRoute("GET /packages/added.atom", packages.AddedFeed)
+ setRoute("GET /packages/updated.atom", packages.UpdatedFeed)
+ setRoute("GET /packages/keyworded.atom", packages.KeywordedFeed)
+ setRoute("GET /packages/stable.atom", packages.StabilizedFeed)
+ // Added for backwards compatibility
+ redirect("GET /packages/stabilized.atom", "/packages/stable.atom")
+ setRoute("GET /packages/search.atom", packages.SearchFeed)
+
+ redirect("GET /user", "/user/preferences/general")
+ redirect("GET /user/preferences", "/user/preferences/general")
+ setRoute("GET /user/preferences/general", user.Preferences("General"))
+ setRoute("GET /user/preferences/packages", user.Preferences("Packages"))
+ setRoute("GET /user/preferences/maintainers", user.Preferences("Maintainers"))
setRoute("/user/preferences/general/layout", user.General)
setRoute("/user/preferences/general/reset", user.ResetGeneral)
- setRoute("/user/preferences/arches/visible", user.Arches)
- setRoute("/user/preferences/arches/reset", user.ResetArches)
-
setRoute("/user/preferences/packages/edit", user.EditPackagesPreferences)
setRoute("/user/preferences/packages/reset", user.ResetPackages)
- setRoute("/user/preferences/useflags/edit", user.Useflags)
- setRoute("/user/preferences/useflags/reset", user.ResetUseflags)
-
setRoute("/user/preferences/maintainers/edit", user.Maintainers)
setRoute("/user/preferences/maintainers/reset", user.ResetMaintainers)
@@ -109,9 +136,11 @@ func Serve() {
// graphiql: api explorer
setRoute("/api/explore/", graphiql.Show)
- logger.Info.Println("Serving on port: " + config.Port())
- log.Fatal(http.ListenAndServe(":"+config.Port(), nil))
-
+ address := ":" + config.Port()
+ slog.Info("Serving HTTP", "address", address)
+ err := http.ListenAndServe(address, nil)
+ slog.Error("exited server", "err", err)
+ os.Exit(1)
}
// define a route using the default middleware and the given handler
@@ -121,7 +150,7 @@ func setRoute(path string, handler http.HandlerFunc) {
func redirect(from, to string) {
http.HandleFunc(from, func(w http.ResponseWriter, r *http.Request) {
- http.Redirect(w, r, to, 301)
+ http.Redirect(w, r, to, http.StatusMovedPermanently)
})
}
diff --git a/pkg/app/utils/applicationdata.go b/pkg/app/utils/applicationdata.go
index d22e5c9..db27f63 100644
--- a/pkg/app/utils/applicationdata.go
+++ b/pkg/app/utils/applicationdata.go
@@ -3,8 +3,8 @@
package utils
import (
+ "log/slog"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"time"
)
@@ -14,9 +14,9 @@ import (
func GetApplicationData() models.Application {
// Select user by primary key.
applicationData := &models.Application{Id: "latest"}
- err := database.DBCon.Select(applicationData)
+ err := database.DBCon.Model(applicationData).WherePK().Select()
if err != nil {
- logger.Error.Println("Error fetching application data")
+ slog.Error("Failed fetching application data", slog.Any("err", err))
return models.Application{
Id: "latest",
LastUpdate: time.Now(),
diff --git a/pkg/app/utils/bugs.go b/pkg/app/utils/bugs.go
new file mode 100644
index 0000000..d840541
--- /dev/null
+++ b/pkg/app/utils/bugs.go
@@ -0,0 +1,21 @@
+package utils
+
+import (
+ "soko/pkg/models"
+)
+
+func CountBugsCategories(bugs []*models.Bug) (generalCount, stabilizationCount, keywordingCount int) {
+ for _, bug := range bugs {
+ switch bug.Component {
+ case "Current packages":
+ generalCount++
+ case "Stabilization":
+ stabilizationCount++
+ case "Keywording":
+ keywordingCount++
+ default:
+ continue
+ }
+ }
+ return
+}
diff --git a/pkg/app/utils/changedVersion.templ b/pkg/app/utils/changedVersion.templ
new file mode 100644
index 0000000..b23269d
--- /dev/null
+++ b/pkg/app/utils/changedVersion.templ
@@ -0,0 +1,130 @@
+package utils
+
+import "slices"
+import "soko/pkg/models"
+import "strings"
+import "time"
+
+templ ChangedVersionsTable(versions []*models.Version) {
+ for _, version := range versions {
+ <li class="list-group-item kk-package-detailed">
+ <div class="row">
+ <div class="col-xs-12 col-md-6">
+ <h4 class="stick-top"><a href={ templ.URL("/packages/" + version.Atom) }>{ version.Atom }</a></h4>
+ <div class="kk-package-detailed-toolbox">
+ <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <span class="fa fa-fw fa-navicon"></span>
+ </button>
+ <div class="dropdown-menu dropdown-menu-right">
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://bugs.gentoo.org/buglist.cgi?quicksearch=" + version.Atom) }
+ >
+ <span class="fa fa-fw fa-bug"></span>
+ Related bugs
+ </a>
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://wiki.gentoo.org/index.php?title=Special:Search&fulltext=Search&search=" + version.Package) }
+ >
+ <span class="fa fa-fw fa-book"></span>
+ Documentation
+ </a>
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords=" + version.Package + "&mode=results") }
+ >
+ <span class="fa fa-fw fa-comments-o"></span>
+ Forums posts
+ </a>
+ <div class="dropdown-divider"></div>
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + version.Atom) }
+ >
+ <span class="fa fa-fw fa-code-fork"></span>
+ Git repository browser
+ </a>
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + version.Atom + "?showmsg=1") }
+ >
+ <span class="fa fa-fw fa-history"></span>
+ Git log
+ </a>
+ <a
+ class="dropdown-item"
+ target="_blank"
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + version.Atom + "?h=master") }
+ >
+ <span class="fa fa-fw fa-rss"></span>
+ Changes feed
+ </a>
+ </div>
+ </div>
+ { version.Description }
+ <br/>
+ <small class="text-muted"></small>
+ if len(version.Commits) > 0 {
+ <div class="kk-inline-changelog-entry">
+ <a
+ href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + version.Commits[0].Id) }
+ title="Git commit"
+ >
+ <span class="octicon octicon-git-pull-request"></span>
+ <span class="kk-commit-message">{ version.Commits[0].Message }</span>
+ </a>
+ </div>
+ }
+ </div>
+ <div class="col-xs-12 col-md-6">
+ <small class="text-muted pull-right">
+ if len(version.Commits) > 0 {
+ <span title={ version.Commits[0].CommitterDate.Format(time.DateTime) + " UTC" }>
+ { version.Commits[0].CommitterDate.Format(time.DateTime) } UTC
+ </span>
+ } else {
+ <span title="unknown">unknown</span>
+ }
+ </small>
+ <div class="kk-version-card">
+ <p class="mb-2">
+ <strong>{ version.Version }</strong>
+ <span class="kk-slot"> : { version.Slot }</span>
+ if len(version.Restricts) > 0 {
+ <span
+ class="badge badge-danger kk-restrict-label"
+ title={ "The following features are restricted: " + strings.Join(version.Restricts, " ") }
+ >
+ { FormatRestricts(version.Restricts) }
+ </span>
+ }
+ </p>
+ <p>
+ for _, arch := range models.ArchesToShow {
+ if slices.Contains(strings.Fields(version.Keywords), arch) {
+ <span style="margin-right: 4px;" class="label kk-keyword-stable" title={ version.Version + " is stable on " + arch }>
+ { arch }
+ </span>
+ } else if slices.Contains(strings.Fields(version.Keywords), "~"+arch) {
+ <span style="margin-right: 4px;" class="label kk-keyword-testing" title={ version.Version + " is testing on " + arch }>
+ ~{ arch }
+ </span>
+ } else {
+ <span style="margin-right: 4px;" class="label kk-keyword-unknown" title={ version.Version + " is unknown on " + arch }>
+ ?{ arch }
+ </span>
+ }
+ }
+ </p>
+ </div>
+ </div>
+ </div>
+ </li>
+ }
+}
diff --git a/pkg/app/utils/outdated.go b/pkg/app/utils/outdated.go
new file mode 100644
index 0000000..317c82b
--- /dev/null
+++ b/pkg/app/utils/outdated.go
@@ -0,0 +1,29 @@
+package utils
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gorilla/feeds"
+
+ "soko/pkg/models"
+)
+
+func OutdatedFeed(w http.ResponseWriter, link, title string, outdated []models.OutdatedPackages) {
+ feed := &feeds.Feed{
+ Title: "Outdated Packages for " + title,
+ Author: &feeds.Author{Name: "Gentoo Packages Database"},
+ Created: time.Now(),
+ Link: &feeds.Link{Href: link},
+ }
+
+ for _, entry := range outdated {
+ feed.Add(&feeds.Item{
+ Id: entry.Atom,
+ Title: entry.Atom,
+ Description: "Version " + entry.NewestVersion + " is available, while the latest version in the Gentoo tree is " + entry.GentooVersion + ".",
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/packages/" + entry.Atom, Type: "text/html", Rel: "alternate"},
+ })
+ }
+ feed.WriteAtom(w)
+}
diff --git a/pkg/app/utils/stabilization.go b/pkg/app/utils/stabilization.go
new file mode 100644
index 0000000..8757440
--- /dev/null
+++ b/pkg/app/utils/stabilization.go
@@ -0,0 +1,86 @@
+package utils
+
+import (
+ "encoding/json"
+ "encoding/xml"
+ "html"
+ "net/http"
+ "soko/pkg/models"
+ "strings"
+ "time"
+
+ "github.com/gorilla/feeds"
+)
+
+type stabilization struct {
+ XMLName xml.Name `xml:"stabilization" json:"-"`
+ Category string `xml:"category" json:"category"`
+ Package string `xml:"package" json:"package"`
+ Version string `xml:"version" json:"version"`
+ Message string `xml:"message" json:"message"`
+}
+
+func (s stabilization) String() string {
+ return s.Category + "/" + s.Package + "-" + s.Version + " # " + s.Message
+}
+
+func StabilizationExport(w http.ResponseWriter, pageUrl string, results []*models.PkgCheckResult) {
+ result := make([]stabilization, len(results))
+ for i, pkgcheck := range results {
+ result[i] = stabilization{
+ Category: pkgcheck.Category,
+ Package: pkgcheck.Package,
+ Version: pkgcheck.Version,
+ Message: pkgcheck.Message,
+ }
+ }
+
+ _, extension, _ := strings.Cut(pageUrl, ".")
+ switch extension {
+ case "json":
+ b, err := json.Marshal(result)
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.Write(b)
+ case "xml":
+ b, err := xml.Marshal(struct {
+ XMLName xml.Name `xml:"xml"`
+ Packages []stabilization
+ }{Packages: result})
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ w.Header().Set("Content-Type", "application/xml")
+ w.Write(b)
+ case "list":
+ var lines string
+ for _, pkg := range result {
+ lines += pkg.String() + "\n"
+ }
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte(lines))
+ }
+}
+
+func StabilizationFeed(w http.ResponseWriter, link, title string, results []*models.PkgCheckResult) {
+ feed := &feeds.Feed{
+ Title: "Stabilization candidates for " + title,
+ Author: &feeds.Author{Name: "Gentoo Packages Database"},
+ Created: time.Now(),
+ Link: &feeds.Link{Href: link},
+ }
+
+ for _, pkgcheck := range results {
+ feed.Add(&feeds.Item{
+ Title: pkgcheck.CPV,
+ Description: html.EscapeString(pkgcheck.Message),
+ Link: &feeds.Link{Href: "https://packages.gentoo.org/packages/" + pkgcheck.Atom, Type: "text/html", Rel: "alternate"},
+ Id: pkgcheck.CPV,
+ })
+ }
+ feed.WriteAtom(w)
+}
diff --git a/pkg/app/utils/userdata.go b/pkg/app/utils/userdata.go
index baaba7f..dc4258b 100644
--- a/pkg/app/utils/userdata.go
+++ b/pkg/app/utils/userdata.go
@@ -38,21 +38,8 @@ func GetUserPreferences(r *http.Request) models.UserPreferences {
}
}
- cookie, err = r.Cookie("userpref_useflags")
- if err == nil {
- cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value)
- if err == nil {
- json.Unmarshal(cookieValue, &userPreferences.Useflags)
- }
- }
-
- cookie, err = r.Cookie("userpref_arches")
- if err == nil {
- cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value)
- if err == nil {
- json.Unmarshal(cookieValue, &userPreferences.Arches)
- }
- }
+ // old cookie: userpref_useflags
+ // old cookie: userpref_arches
userPreferences.Sanitize()
diff --git a/pkg/app/utils/version.go b/pkg/app/utils/version.go
new file mode 100644
index 0000000..5609404
--- /dev/null
+++ b/pkg/app/utils/version.go
@@ -0,0 +1,19 @@
+package utils
+
+import (
+ "soko/pkg/utils"
+ "strings"
+)
+
+// FormatRestricts returns a string containing a comma separated
+// list of capitalized first letters of the package restricts
+func FormatRestricts(restricts []string) string {
+ var result []string
+ for _, restrict := range restricts {
+ if restrict != "" && restrict != "(" && restrict != ")" && !strings.HasSuffix(restrict, "?") {
+ result = append(result, strings.ToUpper(string(restrict[0])))
+ }
+ }
+ result = utils.Deduplicate(result)
+ return strings.Join(result, ", ")
+}
diff --git a/pkg/config/config.go b/pkg/config/config.go
index b291555..3bd651f 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -1,6 +1,9 @@
package config
-import "os"
+import (
+ "fmt"
+ "os"
+)
func PortDir() string {
return getEnv("SOKO_PORT_DIR", "/mnt/packages-tree/gentoo")
@@ -34,12 +37,12 @@ func DevMode() string {
return getEnv("SOKO_DEVMODE", "false")
}
-func Debug() string {
- return getEnv("SOKO_DEBUG", "false")
+func Debug() bool {
+ return getEnv("SOKO_DEBUG", "false") == "true"
}
-func Quiet() string {
- return getEnv("SOKO_QUIET", "false")
+func Quiet() bool {
+ return getEnv("SOKO_QUIET", "false") == "true"
}
func LogFile() string {
@@ -47,7 +50,7 @@ func LogFile() string {
}
func Version() string {
- return getEnv("SOKO_VERSION", "v1.0.0")
+ return getEnv("SOKO_VERSION", "v1.0.3")
}
func Port() string {
@@ -66,6 +69,10 @@ func CacheControl() string {
return getEnv("SOKO_CACHE_CONTROL", "max-age=300")
}
+func UserAgent() string {
+ return fmt.Sprintf("Gentoo Soko %s/packages.gentoo.org/gpackages@gentoo.org", Version())
+}
+
func getEnv(key string, fallback string) string {
if os.Getenv(key) != "" {
return os.Getenv(key)
diff --git a/pkg/database/connection.go b/pkg/database/connection.go
index 33325e6..77a6b50 100644
--- a/pkg/database/connection.go
+++ b/pkg/database/connection.go
@@ -4,11 +4,14 @@ package database
import (
"context"
- "github.com/go-pg/pg/v9"
- "github.com/go-pg/pg/v9/orm"
- "log"
+ "log/slog"
+ "os"
+ "time"
+
+ "github.com/go-pg/pg/v10"
+ "github.com/go-pg/pg/v10/orm"
+
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/models"
)
@@ -19,39 +22,50 @@ var (
)
// CreateSchema creates the tables in the database
-// in case they don't alreay exist
+// in case they don't already exist
func CreateSchema() error {
- for _, model := range []interface{}{(*models.Package)(nil),
+ for _, model := range []interface{}{
+ (*models.CommitToPackage)(nil),
+ (*models.CommitToVersion)(nil),
+ (*models.PackageToBug)(nil),
+ (*models.VersionToBug)(nil),
+ (*models.PackageToGithubPullRequest)(nil),
+ (*models.MaskToVersion)(nil),
+ (*models.DeprecatedToVersion)(nil),
+ (*models.Package)(nil),
+ (*models.CategoryPackagesInformation)(nil),
(*models.Category)(nil),
(*models.Version)(nil),
(*models.Commit)(nil),
(*models.KeywordChange)(nil),
- (*models.CommitToPackage)(nil),
- (*models.CommitToVersion)(nil),
(*models.Useflag)(nil),
(*models.Mask)(nil),
- (*models.MaskToVersion)(nil),
+ (*models.DeprecatedPackage)(nil),
(*models.OutdatedPackages)(nil),
(*models.Project)(nil),
(*models.MaintainerToProject)(nil),
(*models.PkgCheckResult)(nil),
(*models.GithubPullRequest)(nil),
- (*models.PackageToGithubPullRequest)(nil),
(*models.Bug)(nil),
- (*models.PackageToBug)(nil),
- (*models.VersionToBug)(nil),
(*models.ReverseDependency)(nil),
(*models.Maintainer)(nil),
- (*models.Application)(nil)} {
-
- err := DBCon.CreateTable(model, &orm.CreateTableOptions{
+ (*models.Application)(nil),
+ } {
+ err := DBCon.Model(model).CreateTable(&orm.CreateTableOptions{
IfNotExists: true,
})
if err != nil {
+ tableName := string(DBCon.Model(model).TableModel().Table().TypeName)
+ slog.Error("Failed creating table", slog.String("table", tableName), slog.Any("err", err))
return err
}
-
}
+ _, err := DBCon.Exec("CREATE EXTENSION IF NOT EXISTS pg_trgm")
+ if err != nil {
+ slog.Error("Failed creating extension 'pg_trgm'", slog.Any("err", err))
+ return err
+ }
+
return nil
}
@@ -63,7 +77,10 @@ func (d dbLogger) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Cont
// AfterQuery is used to log SQL queries
func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) error {
- logger.Debug.Println(q.FormattedQuery())
+ query, err := q.FormattedQuery()
+ if err == nil {
+ slog.Debug(string(query), slog.Duration("duration", time.Since(q.StartTime)))
+ }
return nil
}
@@ -71,19 +88,30 @@ func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) error {
// and turn on logging if desired
func Connect() {
DBCon = pg.Connect(&pg.Options{
- User: config.PostgresUser(),
- Password: config.PostgresPass(),
- Database: config.PostgresDb(),
- Addr: config.PostgresHost() + ":" + config.PostgresPort(),
+ User: config.PostgresUser(),
+ Password: config.PostgresPass(),
+ Database: config.PostgresDb(),
+ Addr: config.PostgresHost() + ":" + config.PostgresPort(),
+ DialTimeout: 10 * time.Second,
})
- DBCon.AddQueryHook(dbLogger{})
+ if !config.Quiet() {
+ DBCon.AddQueryHook(dbLogger{})
+ }
- err := CreateSchema()
- if err != nil {
- logger.Error.Println("ERROR: Could not create database schema")
- logger.Error.Println(err)
- log.Fatalln(err)
+ if err := CreateSchema(); err != nil {
+ slog.Error("Failed creating database schema", slog.Any("err", err))
+ os.Exit(1)
}
+}
+func TruncateTable(model any) {
+ query := DBCon.Model(model)
+ tableName := string(query.TableModel().Table().TypeName)
+ _, err := query.Exec("TRUNCATE TABLE ?TableName")
+ if err != nil {
+ slog.Error("Failed truncating table", slog.String("table", tableName), slog.Any("err", err))
+ } else {
+ slog.Info("Truncated table", slog.String("table", tableName))
+ }
}
diff --git a/pkg/logger/loggers.go b/pkg/logger/loggers.go
deleted file mode 100644
index 0ef51e9..0000000
--- a/pkg/logger/loggers.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package logger
-
-import (
- "io"
- "log"
- "os"
-)
-
-var (
- Debug *log.Logger
- Info *log.Logger
- Error *log.Logger
-)
-
-func Init(
- debugHandle io.Writer,
- infoHandle io.Writer,
- errorHandle io.Writer) {
-
- Debug = log.New(debugHandle,
- "DEBUG: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-
- Info = log.New(infoHandle,
- "INFO: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-
- Error = log.New(errorHandle,
- "ERROR: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-}
-
-func CreateLogFile(path string) *os.File {
- f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
- if err != nil {
- log.Println(err)
- }
- return f
-}
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
index 9e48a02..2d6a878 100644
--- a/pkg/metrics/metrics.go
+++ b/pkg/metrics/metrics.go
@@ -1,44 +1,45 @@
package metrics
import (
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promauto"
"soko/pkg/app/utils"
"soko/pkg/database"
"soko/pkg/models"
"time"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
)
var (
- UpdateAges = map[string]prometheus.Gauge {
+ UpdateAges = map[string]prometheus.Gauge{
"dependencies": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "dependencies"},
}),
"pkgcheck": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "pkgcheck"},
}),
"pullrequests": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "pullrequests"},
}),
"bugs": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "bugs"},
}),
"projects": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "projects"},
}),
"maintainers": promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_update_age",
- Help: "The age of the last update",
+ Name: "pgo_update_age",
+ Help: "The age of the last update",
ConstLabels: prometheus.Labels{"type": "maintainers"},
}),
}
@@ -49,8 +50,7 @@ var (
})
)
-
-func Update(){
+func Update() {
database.Connect()
defer database.DBCon.Close()
@@ -65,10 +65,9 @@ func Update(){
}
lastCommit := &models.Commit{Id: utils.GetApplicationData().LastCommit}
- err := database.DBCon.Select(lastCommit)
+ err := database.DBCon.Model(lastCommit).WherePK().Select()
if err == nil {
LastCommitAge.Set(time.Since(lastCommit.CommitterDate).Seconds())
}
-
}
diff --git a/pkg/models/category.go b/pkg/models/category.go
index a1a073c..fcf13b0 100644
--- a/pkg/models/category.go
+++ b/pkg/models/category.go
@@ -3,7 +3,17 @@
package models
type Category struct {
- Name string `pg:",pk"`
- Description string
- Packages []*Package `pg:",fk:category"`
+ Name string `pg:",pk"`
+ Description string
+ Packages []*Package `pg:",fk:category"`
+ PackagesInformation CategoryPackagesInformation `pg:",fk:name,rel:has-one"`
+}
+
+type CategoryPackagesInformation struct {
+ Name string `pg:",pk"`
+ Outdated int
+ PullRequests int
+ Bugs int
+ SecurityBugs int
+ StableRequests int
}
diff --git a/pkg/models/commit.go b/pkg/models/commit.go
index d6fa710..7e6cd07 100644
--- a/pkg/models/commit.go
+++ b/pkg/models/commit.go
@@ -15,8 +15,8 @@ type Commit struct {
CommitterDate time.Time
Message string
ChangedFiles *ChangedFiles
- ChangedPackages []*Package `pg:"many2many:commit_to_packages,joinFK:package_atom"`
- ChangedVersions []*Version `pg:"many2many:commit_to_versions,joinFK:version_id"`
+ ChangedPackages []*Package `pg:"many2many:commit_to_packages,join_fk:package_atom"`
+ ChangedVersions []*Version `pg:"many2many:commit_to_versions,join_fk:version_id"`
KeywordChanges []*KeywordChange `pg:",fk:commit_id"`
}
@@ -34,11 +34,11 @@ type ChangedFile struct {
type KeywordChange struct {
Id string `pg:",pk"`
CommitId string
- Commit *Commit `pg:",fk:commit_id"`
+ Commit *Commit `pg:",fk:commit_id,rel:has-one"`
VersionId string
- Version *Version `pg:",fk:version_id"`
+ Version *Version `pg:",fk:version_id,rel:has-one"`
PackageId string
- Package *Package `pg:",fk:package_id"`
+ Package *Package `pg:",fk:package_id,rel:has-one"`
Added []string
Stabilized []string
All []string
diff --git a/pkg/models/deprecated.go b/pkg/models/deprecated.go
new file mode 100644
index 0000000..1c1b1cb
--- /dev/null
+++ b/pkg/models/deprecated.go
@@ -0,0 +1,19 @@
+// Contains the model of a package deprecated entry
+
+package models
+
+import "time"
+
+type DeprecatedPackage struct {
+ Versions string `pg:",pk"`
+ Author string
+ AuthorEmail string
+ Date time.Time
+ Reason string
+}
+
+type DeprecatedToVersion struct {
+ Id string `pg:",pk"`
+ DeprecatedVersions string
+ VersionId string
+}
diff --git a/pkg/models/github.go b/pkg/models/github.go
index bbd9dd5..aca52e9 100644
--- a/pkg/models/github.go
+++ b/pkg/models/github.go
@@ -31,62 +31,59 @@ type GitHubPullRequestQueryResult struct {
Data GitHubPullRequestQueryResultData `json:"data"`
}
-func (res GitHubPullRequestQueryResult) HasNextPage() bool {
+func (res *GitHubPullRequestQueryResult) HasNextPage() bool {
return res.Data.Search.PageInfo.HasNextPage
}
-func (res GitHubPullRequestQueryResult) CreatePullRequest() []GithubPullRequest {
- var pullrequests []GithubPullRequest
+func (res *GitHubPullRequestQueryResult) EndCursor() string {
+ return res.Data.Search.PageInfo.EndCursor
+}
+
+func (res *GitHubPullRequestQueryResult) AppendPullRequest(pullRequests map[int]*GithubPullRequest) {
for _, rawObject := range res.Data.Search.Edges {
- pullrequest := rawObject.Node
- cistate := ""
- cistatelink := ""
- if pullrequest.Commits.Nodes != nil && len(pullrequest.Commits.Nodes) > 0 {
- cistate = pullrequest.Commits.Nodes[0].Commit.Status.State
-
- if pullrequest.Commits.Nodes[0].Commit.Status.Contexts != nil && len(pullrequest.Commits.Nodes[0].Commit.Status.Contexts) > 0 {
- cistatelink = pullrequest.Commits.Nodes[0].Commit.Status.Contexts[0].TargetUrl
+ pullRequest := rawObject.Node
+ var ciState, ciStateLink string
+ if pullRequest.Commits.Nodes != nil && len(pullRequest.Commits.Nodes) > 0 {
+ ciState = pullRequest.Commits.Nodes[0].Commit.Status.State
+
+ if pullRequest.Commits.Nodes[0].Commit.Status.Contexts != nil && len(pullRequest.Commits.Nodes[0].Commit.Status.Contexts) > 0 {
+ ciStateLink = pullRequest.Commits.Nodes[0].Commit.Status.Contexts[0].TargetUrl
}
}
- pullrequests = append(pullrequests, GithubPullRequest{
- Id: strconv.Itoa(pullrequest.Number),
- Closed: pullrequest.Closed,
- Url: pullrequest.Url,
- Title: pullrequest.Title,
- CreatedAt: pullrequest.CreatedAt,
- UpdatedAt: pullrequest.UpdatedAt,
- CiState: cistate,
- CiStateLink: cistatelink,
- Labels: pullrequest.CreateLabelsArray(),
- Comments: pullrequest.Comments.TotalCount,
- Files: pullrequest.CreateFilesArray(),
- Author: pullrequest.Author.Login,
- })
+ pullRequests[pullRequest.Number] = &GithubPullRequest{
+ Id: strconv.Itoa(pullRequest.Number),
+ Closed: pullRequest.Closed,
+ Url: pullRequest.Url,
+ Title: pullRequest.Title,
+ CreatedAt: pullRequest.CreatedAt,
+ UpdatedAt: pullRequest.UpdatedAt,
+ CiState: ciState,
+ CiStateLink: ciStateLink,
+ Labels: pullRequest.CreateLabelsArray(),
+ Comments: pullRequest.Comments.TotalCount,
+ Files: pullRequest.CreateFilesArray(),
+ Author: pullRequest.Author.Login,
+ }
}
- return pullrequests
}
-func (node GitHubPullRequestSearchNode) CreateLabelsArray() []GitHubPullRequestLabelNode {
- var labels []GitHubPullRequestLabelNode
- for _, label := range node.Labels.Edges {
- labels = append(labels, label.Node)
+func (node *GitHubPullRequestSearchNode) CreateLabelsArray() []GitHubPullRequestLabelNode {
+ labels := make([]GitHubPullRequestLabelNode, len(node.Labels.Edges))
+ for i, label := range node.Labels.Edges {
+ labels[i] = label.Node
}
return labels
}
-func (node GitHubPullRequestSearchNode) CreateFilesArray() []GitHubPullRequestFileNode {
- var labels []GitHubPullRequestFileNode
- for _, label := range node.Files.Edges {
- labels = append(labels, label.Node)
+func (node *GitHubPullRequestSearchNode) CreateFilesArray() []GitHubPullRequestFileNode {
+ labels := make([]GitHubPullRequestFileNode, len(node.Files.Edges))
+ for i, label := range node.Files.Edges {
+ labels[i] = label.Node
}
return labels
}
-func (res GitHubPullRequestQueryResult) EndCursor() string {
- return res.Data.Search.PageInfo.EndCursor
-}
-
type GitHubPullRequestQueryResultData struct {
Search GitHubPullRequestSearchResult `json:"search"`
}
diff --git a/pkg/models/package.go b/pkg/models/package.go
index 439480a..f543891 100644
--- a/pkg/models/package.go
+++ b/pkg/models/package.go
@@ -2,23 +2,26 @@
package models
-import "sort"
+import (
+ "sort"
+ "strings"
+)
type Package struct {
Atom string `pg:",pk"`
Category string
Name string
- Versions []*Version `pg:",fk:atom"`
+ Versions []*Version `pg:",fk:atom,rel:has-many"`
Longdescription string
Maintainers []*Maintainer
Upstream Upstream
- Commits []*Commit `pg:"many2many:commit_to_packages,joinFK:commit_id"`
+ Commits []*Commit `pg:"many2many:commit_to_packages,join_fk:commit_id"`
PrecedingCommits int `pg:",use_zero"`
- PkgCheckResults []*PkgCheckResult `pg:",fk:atom"`
- Outdated []*OutdatedPackages `pg:",fk:atom"`
- Bugs []*Bug `pg:"many2many:package_to_bugs,joinFK:bug_id"`
- PullRequests []*GithubPullRequest `pg:"many2many:package_to_github_pull_requests,joinFK:github_pull_request_id"`
- ReverseDependencies []*ReverseDependency `pg:",fk:atom"`
+ PkgCheckResults []*PkgCheckResult `pg:",fk:atom,rel:has-many"`
+ Outdated []*OutdatedPackages `pg:",fk:atom,rel:has-many"`
+ Bugs []*Bug `pg:"many2many:package_to_bugs,join_fk:bug_id"`
+ PullRequests []*GithubPullRequest `pg:"many2many:package_to_github_pull_requests,join_fk:github_pull_request_id"`
+ ReverseDependencies []*ReverseDependency `pg:",fk:atom,rel:has-many"`
}
type Maintainer struct {
@@ -28,9 +31,16 @@ type Maintainer struct {
Restrict string
PackagesInformation MaintainerPackagesInformation
// In case the maintainer type is "project", Project will point to the project
- Project Project `pg:",fk:email"`
+ Project Project `pg:",fk:email,rel:has-one"`
// In case the maintainer type is not "project", Projects will point to the projects the maintainer is member of
- Projects []*Project `pg:"many2many:maintainer_to_projects,joinFK:project_email"`
+ Projects []*Project `pg:"many2many:maintainer_to_projects,join_fk:project_email"`
+}
+
+func (m *Maintainer) PrintName() string {
+ if m.Name != "" {
+ return m.Name
+ }
+ return m.Email
}
type MaintainerPackagesInformation struct {
@@ -53,18 +63,36 @@ type RemoteId struct {
Id string
}
-func (p Package) BuildRevDepMap() map[string]map[string]string {
- var data = map[string]map[string]string{}
+type packageDepMap struct {
+ Version string
+ Atom string
+ Map map[string]struct{}
+}
+
+func (p Package) BuildRevDepMap() []packageDepMap {
+ var data = map[string]packageDepMap{}
for _, dep := range p.ReverseDependencies {
- if data[dep.ReverseDependencyVersion] == nil {
- data[dep.ReverseDependencyVersion] = map[string]string{}
- data[dep.ReverseDependencyVersion]["Atom"] = dep.ReverseDependencyAtom
+ if _, found := data[dep.ReverseDependencyVersion]; !found {
+ data[dep.ReverseDependencyVersion] = packageDepMap{
+ Version: dep.ReverseDependencyVersion,
+ Atom: strings.ReplaceAll(dep.ReverseDependencyAtom, "[B]", ""),
+ Map: map[string]struct{}{},
+ }
}
- data[dep.ReverseDependencyVersion][dep.Type] = "true"
+ data[dep.ReverseDependencyVersion].Map[dep.Type] = struct{}{}
}
- return data
+ result := make([]packageDepMap, 0, len(data))
+ for _, v := range data {
+ result = append(result, v)
+ }
+
+ sort.Slice(result, func(i, j int) bool {
+ return result[i].Version < result[j].Version
+ })
+
+ return result
}
func (p Package) Description() string {
@@ -76,6 +104,15 @@ func (p Package) Description() string {
return p.Longdescription
}
+func (p *Package) HasVersion(version string) bool {
+ for _, v := range p.Versions {
+ if v.Version == version {
+ return true
+ }
+ }
+ return false
+}
+
func (p Package) AllBugs() []*Bug {
allBugs := make(map[string]*Bug)
@@ -101,3 +138,18 @@ func (p Package) AllBugs() []*Bug {
return allBugsList
}
+
+func (p *Package) AllUseflags() []string {
+ useflags := make(map[string]struct{})
+ for _, version := range p.Versions {
+ for _, useflag := range version.Useflags {
+ useflags[strings.TrimPrefix(useflag, "+")] = struct{}{}
+ }
+ }
+
+ useflagsList := make([]string, 0, len(useflags))
+ for useflag := range useflags {
+ useflagsList = append(useflagsList, useflag)
+ }
+ return useflagsList
+}
diff --git a/pkg/models/userpreferences.go b/pkg/models/userpreferences.go
index 0e6cd19..91d95ee 100644
--- a/pkg/models/userpreferences.go
+++ b/pkg/models/userpreferences.go
@@ -2,14 +2,10 @@
package models
-import "strings"
-
type UserPreferences struct {
General GeneralPreferences
Packages PackagesPreferences
Maintainers MaintainersPreferences
- Useflags UseflagsPreferences
- Arches ArchesPreferences
}
type GeneralPreferences struct {
@@ -17,55 +13,12 @@ type GeneralPreferences struct {
}
type PackagesPreferences struct {
- Overview PackagesOverviewPreferences
- Dependencies PackagesDependenciesPreferences
- QAReport PackagesQAReportPreferences
- PullRequests PackagesPullRequestsPreferences
- Bugs PackagesBugsPreferences
- Security PackagesSecurityPreferences
- Changelog PackagesChangelogPreferences
- Tabs PackagesTabsPreferences
+ Overview PackagesOverviewPreferences
}
type PackagesOverviewPreferences struct {
- Layout string
- Keywords []string
- EAPI string
- ShowOutdated bool
- MetadataFields []string
- ChangelogType string
- ChangelogLength int
-}
-
-type PackagesDependenciesPreferences struct {
- Default string
-}
-
-type PackagesQAReportPreferences struct {
- ExcludedWarningClasses []int
- ShowAll bool
-}
-
-type PackagesPullRequestsPreferences struct {
- Layout string
-}
-
-type PackagesBugsPreferences struct {
Layout string
-}
-
-type PackagesSecurityPreferences struct {
- Layout string
- ShowGLSAs bool
-}
-
-type PackagesChangelogPreferences struct {
- Layout string
- Size int
-}
-
-type PackagesTabsPreferences struct {
- Visible []string
+ EAPI string
}
type MaintainersPreferences struct {
@@ -73,64 +26,20 @@ type MaintainersPreferences struct {
ExcludedProjects []string
}
-type UseflagsPreferences struct {
- Layout string
-}
-
-type ArchesPreferences struct {
- Visible []string
- DefaultArch string
- DefaultPage string
-}
+var ArchesToShow = [...]string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "riscv", "sparc"}
+var AllArches = [...]string{"alpha", "amd64", "arm", "arm64", "hppa", "ia64", "mips", "ppc", "ppc64", "riscv", "s390", "sparc", "x86"}
func GetDefaultUserPreferences() UserPreferences {
userPreferences := UserPreferences{}
userPreferences.General = GeneralPreferences{}
userPreferences.Packages = PackagesPreferences{}
userPreferences.Packages.Overview = PackagesOverviewPreferences{}
- userPreferences.Packages.Dependencies = PackagesDependenciesPreferences{}
- userPreferences.Packages.QAReport = PackagesQAReportPreferences{}
- userPreferences.Packages.PullRequests = PackagesPullRequestsPreferences{}
- userPreferences.Packages.Bugs = PackagesBugsPreferences{}
- userPreferences.Packages.Security = PackagesSecurityPreferences{}
- userPreferences.Packages.Changelog = PackagesChangelogPreferences{}
- userPreferences.Packages.Tabs = PackagesTabsPreferences{}
userPreferences.Maintainers = MaintainersPreferences{}
- userPreferences.Useflags = UseflagsPreferences{}
- userPreferences.Arches = ArchesPreferences{}
userPreferences.General.LandingPageLayout = "classic"
userPreferences.Packages.Overview.Layout = "minimal"
- userPreferences.Packages.Overview.Keywords = []string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "sparc"}
userPreferences.Packages.Overview.EAPI = "none"
- userPreferences.Packages.Overview.ShowOutdated = true
- userPreferences.Packages.Overview.MetadataFields = []string{"homepage", "upstream", "longdescription", "useflags", "license", "maintainers"}
- userPreferences.Packages.Overview.ChangelogType = "compact"
- userPreferences.Packages.Overview.ChangelogLength = 5
-
- userPreferences.Packages.Dependencies.Default = "dependencies"
-
- userPreferences.Packages.QAReport.ExcludedWarningClasses = []int{}
- userPreferences.Packages.QAReport.ShowAll = true
-
- userPreferences.Packages.PullRequests.Layout = "default"
-
- userPreferences.Packages.Bugs.Layout = "default"
-
- userPreferences.Packages.Security.Layout = "default"
- userPreferences.Packages.Security.ShowGLSAs = false
-
- userPreferences.Packages.Changelog.Layout = "compact"
- userPreferences.Packages.Changelog.Size = 15
-
- userPreferences.Packages.Tabs.Visible = []string{"Overview", "Dependencies", "QA report", "Pull requests", "Bugs", "Security", "Changelog"}
-
- userPreferences.Arches.Visible = []string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "sparc"}
- userPreferences.Arches.DefaultArch = "amd64"
- userPreferences.Arches.DefaultPage = "keyworded"
-
- userPreferences.Useflags.Layout = "bubble"
userPreferences.Maintainers.IncludeProjectPackages = false
userPreferences.Maintainers.ExcludedProjects = []string{}
@@ -141,127 +50,15 @@ func GetDefaultUserPreferences() UserPreferences {
func (u *UserPreferences) Sanitize() {
defaultUserPreferences := GetDefaultUserPreferences()
- if !(u.General.LandingPageLayout == "classic" || u.General.LandingPageLayout == "full"){
+ if !(u.General.LandingPageLayout == "classic" || u.General.LandingPageLayout == "full") {
u.General.LandingPageLayout = defaultUserPreferences.General.LandingPageLayout
}
- if !(u.Packages.Overview.Layout == "minimal" || u.Packages.Overview.Layout == "full"){
+ if !(u.Packages.Overview.Layout == "minimal" || u.Packages.Overview.Layout == "full") {
u.Packages.Overview.Layout = defaultUserPreferences.Packages.Overview.Layout
}
- sanitizedKeywords := []string{}
- for _, keyword := range u.Packages.Overview.Keywords {
- if strings.Contains(strings.Join(u.GetAllKeywords(), ","), keyword){
- sanitizedKeywords = append(sanitizedKeywords, keyword)
- }
- }
- u.Packages.Overview.Keywords = sanitizedKeywords
-
- if !(u.Packages.Overview.EAPI == "none" || u.Packages.Overview.EAPI == "column" || u.Packages.Overview.EAPI == "inline"){
+ if !(u.Packages.Overview.EAPI == "none" || u.Packages.Overview.EAPI == "column" || u.Packages.Overview.EAPI == "inline") {
u.Packages.Overview.EAPI = defaultUserPreferences.Packages.Overview.EAPI
}
-
- sanitizedMetadataFields := []string{}
- for _, metadataField := range u.Packages.Overview.MetadataFields {
- if strings.Contains(strings.Join(defaultUserPreferences.Packages.Overview.MetadataFields, ","), metadataField){
- sanitizedMetadataFields = append(sanitizedMetadataFields, metadataField)
- }
- }
- u.Packages.Overview.MetadataFields = sanitizedMetadataFields
-
- if !(u.Packages.Overview.ChangelogType == "compact"){
- u.Packages.Overview.ChangelogType = defaultUserPreferences.Packages.Overview.ChangelogType
- }
-
- if !(u.Packages.Overview.ChangelogLength >= 100){
- u.Packages.Overview.ChangelogLength = 100
- }
-
- if !(u.Packages.Dependencies.Default == "dependencies" || u.Packages.Dependencies.Default == "reverse-dependencies"){
- u.Packages.Dependencies.Default = defaultUserPreferences.Packages.Dependencies.Default
- }
-
- if !(u.Packages.PullRequests.Layout == "default"){
- u.Packages.PullRequests.Layout = defaultUserPreferences.Packages.PullRequests.Layout
- }
-
- if !(u.Packages.Bugs.Layout == "default"){
- u.Packages.Bugs.Layout = defaultUserPreferences.Packages.Bugs.Layout
- }
-
- if !(u.Packages.Security.Layout == "default"){
- u.Packages.Security.Layout = defaultUserPreferences.Packages.Security.Layout
- }
-
- if !(u.Packages.Changelog.Layout == "default"){
- u.Packages.Changelog.Layout = defaultUserPreferences.Packages.Changelog.Layout
- }
-
- if !(u.Packages.Changelog.Size >= 100){
- u.Packages.Changelog.Size = 100
- }
-
- sanitizedTabs := []string{}
- for _, tab := range u.Packages.Tabs.Visible {
- if strings.Contains(strings.Join(defaultUserPreferences.Packages.Tabs.Visible, ","), tab){
- sanitizedTabs = append(sanitizedTabs, tab)
- }
- }
- u.Packages.Tabs.Visible = sanitizedTabs
-
- sanitizedVisibleArches := []string{}
- for _, keyword := range u.Arches.Visible {
- if strings.Contains(strings.Join(u.GetAllKeywords(), ","), keyword){
- sanitizedVisibleArches = append(sanitizedVisibleArches, keyword)
- }
- }
- u.Arches.Visible = sanitizedVisibleArches
-
- if !strings.Contains(strings.Join(u.GetAllKeywords(), ","), u.Arches.DefaultArch){
- u.Arches.DefaultArch = defaultUserPreferences.Arches.DefaultArch
- }
-
- if !(u.Arches.DefaultPage == "keyworded" || u.Arches.DefaultPage == "stable"){
- u.Arches.DefaultPage = defaultUserPreferences.Arches.DefaultPage
- }
-
- if !(u.Useflags.Layout == "bubble" || u.Useflags.Layout == "search"){
- u.Useflags.Layout = defaultUserPreferences.Useflags.Layout
- }
-}
-
-func (u UserPreferences) ContainsPkgcheckClass(class string) bool {
- for _, v := range u.Packages.QAReport.ExcludedWarningClasses {
- if GetPkgcheckClass(v) == class {
- return false
- }
- }
- return true
-}
-
-func (u UserPreferences) GetAllKeywords() []string {
- return []string{"alpha", "amd64", "arm", "arm64", "hppa", "ia64", "m68k", "mips", "ppc", "ppc64", "riscv", "s390", "sparc", "x86", "ppc-aix", "amd64-linux", "arm-linux", "arm64-linux", "ppc64-linux", "x86-linux", "ppc-macos", "x86-macos", "x64-macos", "m68k-mint", "sparc-solaris", "sparc64-solaris", "x64-solaris", "x86-solaris", "x64-winnt", "x86-winnt", "x64-cygwin", "x86-cygwin"}
-}
-
-func GetPkgcheckClass(number int) string {
- pkgcheckClasses := []string{"AbsoluteSymlink", "ArchesWithoutProfiles", "BadCommitSummary", "BadDependency", "BadDescription", "BadFilename", "BadHomepage", "BadKeywords", "BadPackageUpdate", "BadProtocol", "BadWhitespaceCharacter", "BannedCharacter", "BannedEapi", "BannedEapiCommand", "BinaryFile", "CatBadlyFormedXml", "CatInvalidXml", "CatMetadataXmlEmptyElement", "CatMetadataXmlIndentation", "CatMetadataXmlInvalidCatRef", "CatMetadataXmlInvalidPkgRef", "CatMissingMetadataXml", "ConflictingAccountIdentifiers", "ConflictingChksums", "DeadUrl", "DeprecatedChksum", "DeprecatedDep", "DeprecatedEapi", "DeprecatedEapiCommand", "DeprecatedEclass", "DeprecatedInsinto", "DirectNoMaintainer", "DirectStableKeywords", "DoubleEmptyLine", "DoublePrefixInPath", "DroppedKeywords", "DroppedStableKeywords", "DroppedUnstableKeywords", "DuplicateEclassInherits", "DuplicateFiles", "DuplicateKeywords", "EbuildIncorrectCopyright", "EbuildInvalidCopyright", "EbuildInvalidLicenseHeader", "EbuildNonGentooAuthorsCopyright", "EbuildOldGentooCopyright", "EclassBashSyntaxError", "EclassIncorrectCopyright", "EclassInvalidCopyright", "EclassInvalidLicenseHeader", "EclassNonGentooAuthorsCopyright", "EclassOldGentooCopyright", "EmptyCategoryDir", "EmptyFile", "EmptyMaintainer", "EmptyPackageDir", "EmptyProject", "EqualVersions", "ExecutableFile", "HomepageInSrcUri", "HttpsUrlAvailable", "IncorrectCopyright", "InvalidBdepend", "InvalidCommitMessage", "InvalidCommitTag", "InvalidCopyright", "InvalidDepend", "InvalidEapi", "InvalidLicense", "InvalidLicenseHeader", "InvalidPN", "InvalidPdepend", "InvalidProperties", "InvalidRdepend", "InvalidRequiredUse", "InvalidRestrict", "InvalidSlot", "InvalidSrcUri", "InvalidUTF8", "InvalidUseFlags", "LaggingProfileEapi", "LaggingStable", "MaintainerWithoutProxy", "MatchingChksums", "MatchingGlobalUse", "MismatchedPN", "MismatchedPerlVersion", "MissingAccountIdentifier", "MissingChksum", "MissingLicense", "MissingLicenseFile", "MissingLicenseRestricts", "MissingManifest", "MissingPackageRevision", "MissingPythonEclass", "MissingSignOff", "MissingSlash", "MissingSlotDep", "MissingTestRestrict", "MissingUnpackerDep", "MissingUri", "MissingUseDepDefault", "MissingVirtualKeywords", "MovedPackageUpdate", "MultiMovePackageUpdate", "NoFinalNewline", "NonGentooAuthorsCopyright", "NonexistentBlocker", "NonexistentDeps", "NonexistentProfilePath", "NonexistentProjectMaintainer", "NonsolvableDepsInDev", "NonsolvableDepsInExp", "NonsolvableDepsInStable", "ObsoleteUri", "OldGentooCopyright", "OldMultiMovePackageUpdate", "OldPackageUpdate", "OutdatedBlocker", "OutsideRangeAccountIdentifier", "OverlappingKeywords", "PkgBadlyFormedXml", "PkgInvalidXml", "PkgMetadataXmlEmptyElement", "PkgMetadataXmlIndentation", "PkgMetadataXmlInvalidCatRef", "PkgMetadataXmlInvalidPkgRef", "PkgMissingMetadataXml", "PotentialGlobalUse", "PotentialLocalUse", "PotentialStable", "ProbableGlobalUse", "ProbableUseExpand", "ProfileError", "ProfileWarning", "PythonEclassError", "PythonMissingDeps", "PythonMissingRequiredUse", "PythonRuntimeDepInAnyR1", "RdependChange", "RedirectedUrl", "RedundantDodir", "RedundantLongDescription", "RedundantUriRename", "RedundantVersion", "RequiredUseDefaults", "SSLCertificateError", "SizeViolation", "SourcingError", "StableRequest", "StaleProxyMaintProject", "StaticSrcUri", "TarballAvailable", "TrailingEmptyLine", "UncheckableDep", "UnderscoreInUseFlag", "UnknownCategories", "UnknownKeywords", "UnknownLicenses", "UnknownManifest", "UnknownMirror", "UnknownPkgDirEntry", "UnknownProfilePackageKeywords", "UnknownProfilePackageUse", "UnknownProfilePackages", "UnknownProfileUse", "UnknownProperties", "UnknownRestrict", "UnknownUseFlags", "UnnecessaryLicense", "UnnecessaryManifest", "UnnecessarySlashStrip", "UnsortedKeywords", "UnstableOnly", "UnstatedIuse", "UnusedEclasses", "UnusedGlobalUse", "UnusedInMastersEclasses", "UnusedInMastersGlobalUse", "UnusedInMastersLicenses", "UnusedInMastersMirrors", "UnusedLicenses", "UnusedLocalUse", "UnusedMirrors", "UnusedProfileDirs", "VariableInHomepage", "VisibleVcsPkg", "VulnerablePackage", "WhitespaceFound", "WrongIndentFound", "WrongMaintainerType"}
- return pkgcheckClasses[number]
-}
-
-func GetPkgcheckClassIndex(class string) int {
- pkgcheckClasses := []string{"AbsoluteSymlink", "ArchesWithoutProfiles", "BadCommitSummary", "BadDependency", "BadDescription", "BadFilename", "BadHomepage", "BadKeywords", "BadPackageUpdate", "BadProtocol", "BadWhitespaceCharacter", "BannedCharacter", "BannedEapi", "BannedEapiCommand", "BinaryFile", "CatBadlyFormedXml", "CatInvalidXml", "CatMetadataXmlEmptyElement", "CatMetadataXmlIndentation", "CatMetadataXmlInvalidCatRef", "CatMetadataXmlInvalidPkgRef", "CatMissingMetadataXml", "ConflictingAccountIdentifiers", "ConflictingChksums", "DeadUrl", "DeprecatedChksum", "DeprecatedDep", "DeprecatedEapi", "DeprecatedEapiCommand", "DeprecatedEclass", "DeprecatedInsinto", "DirectNoMaintainer", "DirectStableKeywords", "DoubleEmptyLine", "DoublePrefixInPath", "DroppedKeywords", "DroppedStableKeywords", "DroppedUnstableKeywords", "DuplicateEclassInherits", "DuplicateFiles", "DuplicateKeywords", "EbuildIncorrectCopyright", "EbuildInvalidCopyright", "EbuildInvalidLicenseHeader", "EbuildNonGentooAuthorsCopyright", "EbuildOldGentooCopyright", "EclassBashSyntaxError", "EclassIncorrectCopyright", "EclassInvalidCopyright", "EclassInvalidLicenseHeader", "EclassNonGentooAuthorsCopyright", "EclassOldGentooCopyright", "EmptyCategoryDir", "EmptyFile", "EmptyMaintainer", "EmptyPackageDir", "EmptyProject", "EqualVersions", "ExecutableFile", "HomepageInSrcUri", "HttpsUrlAvailable", "IncorrectCopyright", "InvalidBdepend", "InvalidCommitMessage", "InvalidCommitTag", "InvalidCopyright", "InvalidDepend", "InvalidEapi", "InvalidLicense", "InvalidLicenseHeader", "InvalidPN", "InvalidPdepend", "InvalidProperties", "InvalidRdepend", "InvalidRequiredUse", "InvalidRestrict", "InvalidSlot", "InvalidSrcUri", "InvalidUTF8", "InvalidUseFlags", "LaggingProfileEapi", "LaggingStable", "MaintainerWithoutProxy", "MatchingChksums", "MatchingGlobalUse", "MismatchedPN", "MismatchedPerlVersion", "MissingAccountIdentifier", "MissingChksum", "MissingLicense", "MissingLicenseFile", "MissingLicenseRestricts", "MissingManifest", "MissingPackageRevision", "MissingPythonEclass", "MissingSignOff", "MissingSlash", "MissingSlotDep", "MissingTestRestrict", "MissingUnpackerDep", "MissingUri", "MissingUseDepDefault", "MissingVirtualKeywords", "MovedPackageUpdate", "MultiMovePackageUpdate", "NoFinalNewline", "NonGentooAuthorsCopyright", "NonexistentBlocker", "NonexistentDeps", "NonexistentProfilePath", "NonexistentProjectMaintainer", "NonsolvableDepsInDev", "NonsolvableDepsInExp", "NonsolvableDepsInStable", "ObsoleteUri", "OldGentooCopyright", "OldMultiMovePackageUpdate", "OldPackageUpdate", "OutdatedBlocker", "OutsideRangeAccountIdentifier", "OverlappingKeywords", "PkgBadlyFormedXml", "PkgInvalidXml", "PkgMetadataXmlEmptyElement", "PkgMetadataXmlIndentation", "PkgMetadataXmlInvalidCatRef", "PkgMetadataXmlInvalidPkgRef", "PkgMissingMetadataXml", "PotentialGlobalUse", "PotentialLocalUse", "PotentialStable", "ProbableGlobalUse", "ProbableUseExpand", "ProfileError", "ProfileWarning", "PythonEclassError", "PythonMissingDeps", "PythonMissingRequiredUse", "PythonRuntimeDepInAnyR1", "RdependChange", "RedirectedUrl", "RedundantDodir", "RedundantLongDescription", "RedundantUriRename", "RedundantVersion", "RequiredUseDefaults", "SSLCertificateError", "SizeViolation", "SourcingError", "StableRequest", "StaleProxyMaintProject", "StaticSrcUri", "TarballAvailable", "TrailingEmptyLine", "UncheckableDep", "UnderscoreInUseFlag", "UnknownCategories", "UnknownKeywords", "UnknownLicenses", "UnknownManifest", "UnknownMirror", "UnknownPkgDirEntry", "UnknownProfilePackageKeywords", "UnknownProfilePackageUse", "UnknownProfilePackages", "UnknownProfileUse", "UnknownProperties", "UnknownRestrict", "UnknownUseFlags", "UnnecessaryLicense", "UnnecessaryManifest", "UnnecessarySlashStrip", "UnsortedKeywords", "UnstableOnly", "UnstatedIuse", "UnusedEclasses", "UnusedGlobalUse", "UnusedInMastersEclasses", "UnusedInMastersGlobalUse", "UnusedInMastersLicenses", "UnusedInMastersMirrors", "UnusedLicenses", "UnusedLocalUse", "UnusedMirrors", "UnusedProfileDirs", "VariableInHomepage", "VisibleVcsPkg", "VulnerablePackage", "WhitespaceFound", "WrongIndentFound", "WrongMaintainerType"}
- for k, v := range pkgcheckClasses {
- if v == class {
- return k
- }
- }
- return -1
-}
-
-func createSlice(n int) []int {
- slice := []int{}
- for i := 0; i <= n; i++ {
- slice = append(slice, i)
- }
- return slice
}
diff --git a/pkg/models/version.go b/pkg/models/version.go
index eb40a59..f36eb52 100644
--- a/pkg/models/version.go
+++ b/pkg/models/version.go
@@ -6,6 +6,7 @@ import (
"fmt"
"math/big"
"regexp"
+ "sort"
"strconv"
"strings"
"unicode"
@@ -27,25 +28,39 @@ type Version struct {
Homepage []string
License string
Description string
- Commits []*Commit `pg:"many2many:commit_to_versions,joinFK:commit_id"`
- Masks []*Mask `pg:"many2many:mask_to_versions,joinFK:mask_versions"`
+ Commits []*Commit `pg:"many2many:commit_to_versions,join_fk:commit_id"`
+ Masks []*Mask `pg:"many2many:mask_to_versions,join_fk:mask_versions"`
+ Deprecates []*DeprecatedPackage `pg:"many2many:deprecated_to_versions,join_fk:deprecated_versions"`
PkgCheckResults []*PkgCheckResult `pg:",fk:cpv"`
Dependencies []*ReverseDependency `pg:",fk:reverse_dependency_version"`
- Bugs []*Bug `pg:"many2many:version_to_bugs,joinFK:bug_id"`
+ Bugs []*Bug `pg:"many2many:version_to_bugs,join_fk:bug_id"`
}
-func (v Version) BuildDepMap() map[string]map[string]string {
- var data = map[string]map[string]string{}
+type versionDepMap struct {
+ Atom string
+ Map map[string]struct{}
+}
+
+func (v Version) BuildDepMap() []versionDepMap {
+ var data = map[string]map[string]struct{}{}
for _, dep := range v.Dependencies {
if data[dep.Atom] == nil {
- data[dep.Atom] = map[string]string{}
- data[dep.Atom]["Atom"] = dep.Atom
+ data[dep.Atom] = map[string]struct{}{}
}
- data[dep.Atom][dep.Type] = "true"
+ data[dep.Atom][dep.Type] = struct{}{}
+ }
+
+ result := make([]versionDepMap, 0, len(data))
+ for k, v := range data {
+ result = append(result, versionDepMap{k, v})
}
- return data
+ sort.Slice(result, func(i, j int) bool {
+ return result[i].Atom < result[j].Atom
+ })
+
+ return result
}
// GreaterThan returns true if the version is greater than the given version
@@ -54,15 +69,13 @@ func (v *Version) GreaterThan(other Version) bool {
versionIdentifierA := v.computeVersionIdentifier()
versionIdentifierB := other.computeVersionIdentifier()
- if(v.Version == "0.7.8_p0-r100"){
+ if v.Version == "0.7.8_p0-r100" {
fmt.Println("versionIdentifierA")
fmt.Println(versionIdentifierA)
fmt.Println("versionIdentifierB")
fmt.Println(versionIdentifierB)
}
-
-
// compare the numeric part
numericPartsA := strings.Split(versionIdentifierA.NumericPart, ".")
numericPartsB := strings.Split(versionIdentifierB.NumericPart, ".")
@@ -214,9 +227,13 @@ func (v *Version) computeVersionIdentifier() VersionIdentifier {
}
// getNumericPart returns the numeric part of the version, that is:
-// version, letter
+//
+// version, letter
+//
// i.e. 10.3.18a becomes
-// 10.3.18, a
+//
+// 10.3.18, a
+//
// The first returned string is the version and the second if the (optional) letter
func getNumericPart(str string) (string, string) {
if unicode.IsLetter(rune(str[len(str)-1])) {
@@ -227,14 +244,23 @@ func getNumericPart(str string) (string, string) {
// getSuffix creates a VersionSuffix based on the given string.
// The given string is expected to be look like
-// pre20190518
+//
+// pre20190518
+//
// for instance. The suffix named as well as the following number
// will be parsed and returned as VersionSuffix
func getSuffix(str string) *VersionSuffix {
allowedSuffixes := []string{"alpha", "beta", "pre", "rc", "p"}
for _, allowedSuffix := range allowedSuffixes {
- if regexp.MustCompile(allowedSuffix + `\d+`).MatchString(str) {
- parsedSuffix, err := strconv.Atoi(strings.ReplaceAll(str, allowedSuffix, ""))
+ if regexp.MustCompile(allowedSuffix + `\d*`).MatchString(str) {
+ trimmed := strings.TrimPrefix(str, allowedSuffix)
+ if len(trimmed) == 0 {
+ return &VersionSuffix{
+ Name: allowedSuffix,
+ Number: 0,
+ }
+ }
+ parsedSuffix, err := strconv.Atoi(trimmed)
if err == nil {
return &VersionSuffix{
Name: allowedSuffix,
@@ -255,7 +281,9 @@ func isRevision(str string) bool {
// getSuffixOrder returns an int for the given suffix,
// based on the following:
-// _alpha < _beta < _pre < _rc < _p < none
+//
+// _alpha < _beta < _pre < _rc < _p < none
+//
// as defined in the Package Manager Specification (PMS)
func getSuffixOrder(suffix string) int {
if suffix == "p" {
diff --git a/pkg/portage/bugs/bugs.go b/pkg/portage/bugs/bugs.go
new file mode 100644
index 0000000..3e803b8
--- /dev/null
+++ b/pkg/portage/bugs/bugs.go
@@ -0,0 +1,334 @@
+package bugs
+
+import (
+ "encoding/json"
+ "log/slog"
+ "net/http"
+ "net/url"
+ "regexp"
+ "soko/pkg/config"
+ "soko/pkg/database"
+ "soko/pkg/models"
+ "soko/pkg/portage/utils"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/go-pg/pg/v10"
+)
+
+type restAPIBug struct {
+ Id int `json:"id"`
+ Product string `json:"product"`
+ Status string `json:"status"`
+ Summary string `json:"summary"`
+ Component string `json:"component"`
+ StabilizationAtoms string `json:"cf_stabilisation_atoms"`
+ AssigneeDetails struct {
+ RealName string `json:"real_name"`
+ } `json:"assigned_to_detail"`
+}
+
+func (b *restAPIBug) BugId() string {
+ return strconv.Itoa(b.Id)
+}
+
+func (b *restAPIBug) ToDBType() *models.Bug {
+ return &models.Bug{
+ Id: b.BugId(),
+ Product: b.Product,
+ Status: b.Status,
+ Summary: b.Summary,
+ Component: b.Component,
+ Assignee: b.AssigneeDetails.RealName,
+ }
+}
+
+func UpdateBugs() {
+ database.Connect()
+ defer database.DBCon.Close()
+
+ update := models.Application{
+ Id: "bugs",
+ }
+ err := database.DBCon.Model(&update).WherePK().Select()
+ if err != nil && err != pg.ErrNoRows {
+ slog.Error("Failed to fetch last update time for bugs", slog.Any("err", err))
+ return
+ }
+ if update.LastCommit != "" {
+ importAllOpenBugs()
+ } else {
+ lastUpdate := update.LastUpdate
+ if err != nil {
+ importAllOpenBugs()
+ } else {
+ if time.Now().Before(lastUpdate) {
+ lastUpdate = time.Now()
+ }
+ changedSince := lastUpdate.AddDate(0, 0, -2)
+ updateChangedBugs(changedSince)
+ }
+ }
+
+ updateCategoriesInfo()
+
+ updateStatus()
+}
+
+func fetchBugs(changedSince *time.Time, bugStatus []string) (bugs []restAPIBug, err error) {
+ const limit = 5000
+
+ params := url.Values{
+ "include_fields": []string{"id,product,status,summary,component,assigned_to,cf_stabilisation_atoms"},
+ "bug_status": bugStatus,
+ "order": []string{"changeddate DESC"},
+ "product": []string{"Gentoo Linux", "Gentoo Security"},
+ "limit": []string{strconv.Itoa(limit)},
+ }
+
+ if changedSince != nil {
+ params.Set("chfieldfrom", changedSince.Format("2006-01-02"))
+ }
+
+ for offset := 0; ; offset += limit {
+ slog.Info("Importing bugs from bugs.gentoo.org", slog.Int("start", offset), slog.Int("end", offset+limit))
+ params.Set("offset", strconv.Itoa(offset))
+ resp, err := http.Get("https://bugs.gentoo.org/rest/bug?" + params.Encode())
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ slog.Error("Failed to fetch bugs", slog.Int("status", resp.StatusCode))
+ return bugs, nil
+ }
+
+ var response struct {
+ Bugs []restAPIBug `json:"bugs"`
+ }
+ err = json.NewDecoder(resp.Body).Decode(&response)
+ if err != nil {
+ slog.Error("Failed to decode bugs", slog.Any("err", err))
+ return bugs, nil
+ }
+
+ bugs = append(bugs, response.Bugs...)
+
+ if len(response.Bugs) < limit {
+ break
+ }
+ }
+ slog.Info("Collected bugs", slog.Int("count", len(bugs)))
+ return
+}
+
+func importAllOpenBugs() {
+ bugs, err := fetchBugs(nil, []string{"UNCONFIRMED", "CONFIRMED", "IN_PROGRESS"})
+ if err != nil {
+ slog.Error("Failed to fetch bugs",
+ slog.String("status", "UNCONFIRMED, CONFIRMED, IN_PROGRESS"),
+ slog.Any("err", err))
+ return
+ }
+
+ database.TruncateTable((*models.Bug)(nil))
+ database.TruncateTable((*models.PackageToBug)(nil))
+ database.TruncateTable((*models.VersionToBug)(nil))
+
+ processApiBugs(bugs)
+}
+
+func updateChangedBugs(changedSince time.Time) {
+ bugs, err := fetchBugs(&changedSince, []string{"UNCONFIRMED", "CONFIRMED", "IN_PROGRESS", "RESOLVED"})
+ if err != nil {
+ slog.Error("Failed to fetch bugs",
+ slog.String("status", "UNCONFIRMED, CONFIRMED, IN_PROGRESS, RESOLVED"),
+ slog.Time("changed_since", changedSince),
+ slog.Any("err", err))
+ return
+ }
+ processApiBugs(bugs)
+}
+
+func processApiBugs(bugs []restAPIBug) {
+ var resolvedBugs []string
+ var dbBugs []*models.Bug
+ var verBugs []*models.VersionToBug
+ var pkgsBugs []*models.PackageToBug
+ processedBugs := make(map[int]struct{}, len(bugs))
+
+ for _, bug := range bugs {
+ if bug.Status == "RESOLVED" {
+ resolvedBugs = append(resolvedBugs, bug.BugId())
+ } else if _, found := processedBugs[bug.Id]; !found {
+ dbBugs = append(dbBugs, bug.ToDBType())
+ processedBugs[bug.Id] = struct{}{}
+ bugId := bug.BugId()
+ if strings.TrimSpace(bug.StabilizationAtoms) != "" {
+ versions := make(map[string]struct{})
+ for _, gpackage := range strings.Split(bug.StabilizationAtoms, "\n") {
+ affectedVersions, _, _ := strings.Cut(strings.TrimSpace(gpackage), " ")
+ if strings.TrimSpace(affectedVersions) != "" {
+ for _, version := range calculateAffectedVersions(affectedVersions) {
+ versions[version.Id] = struct{}{}
+ }
+ }
+ }
+ for version := range versions {
+ verBugs = append(verBugs, &models.VersionToBug{
+ Id: version + "-" + bugId,
+ VersionId: version,
+ BugId: bugId,
+ })
+ }
+ } else {
+ summary, _, _ := strings.Cut(strings.TrimSpace(bug.Summary), " ")
+ affectedPackage := versionSpecifierToPackageAtom(summary)
+
+ pkgsBugs = append(pkgsBugs, &models.PackageToBug{
+ Id: affectedPackage + "-" + bugId,
+ PackageAtom: affectedPackage,
+ BugId: bugId,
+ })
+ }
+ }
+ }
+
+ res1, err := database.DBCon.Model(&dbBugs).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed to insert bugs", slog.Any("err", err))
+ return
+ }
+
+ res2, err := database.DBCon.Model(&verBugs).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed to insert version bugs", slog.Any("err", err))
+ return
+ }
+
+ res3, err := database.DBCon.Model(&pkgsBugs).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed to insert package bugs", slog.Any("err", err))
+ return
+ }
+
+ slog.Info("Inserted",
+ slog.Int("bugs", res1.RowsAffected()),
+ slog.Int("version_bugs", res2.RowsAffected()),
+ slog.Int("package_bugs", res3.RowsAffected()))
+
+ if len(resolvedBugs) > 0 {
+ res1, err := database.DBCon.Model((*models.Bug)(nil)).WhereIn("id IN (?)", resolvedBugs).Delete()
+ if err != nil {
+ slog.Error("Failed to delete bugs", slog.Any("err", err))
+ return
+ }
+
+ res2, err := database.DBCon.Model((*models.PackageToBug)(nil)).WhereIn("bug_id IN (?)", resolvedBugs).Delete()
+ if err != nil {
+ slog.Error("Failed to delete package bugs", slog.Any("err", err))
+ return
+ }
+
+ res3, err := database.DBCon.Model((*models.VersionToBug)(nil)).WhereIn("bug_id IN (?)", resolvedBugs).Delete()
+ if err != nil {
+ slog.Error("Failed to delete version bugs", slog.Any("err", err))
+ return
+ }
+
+ slog.Info("Deleted",
+ slog.Int("bugs", res1.RowsAffected()),
+ slog.Int("package_bugs", res2.RowsAffected()),
+ slog.Int("version_bugs", res3.RowsAffected()))
+ }
+}
+
+func calculateAffectedVersions(versionSpecifier string) []*models.Version {
+ packageAtom := versionSpecifierToPackageAtom(versionSpecifier)
+ return utils.CalculateAffectedVersions(versionSpecifier, packageAtom)
+}
+
+var versionNumber = regexp.MustCompile(`-[0-9]`)
+
+// versionSpecifierToPackageAtom returns the package atom from a given version specifier
+func versionSpecifierToPackageAtom(versionSpecifier string) string {
+ gpackage := strings.ReplaceAll(versionSpecifier, ">", "")
+ gpackage = strings.ReplaceAll(gpackage, "<", "")
+ gpackage = strings.ReplaceAll(gpackage, "=", "")
+ gpackage = strings.ReplaceAll(gpackage, "~", "")
+
+ gpackage, _, _ = strings.Cut(gpackage, ":")
+
+ gpackage = versionNumber.Split(gpackage, 2)[0]
+
+ return gpackage
+}
+
+func updateCategoriesInfo() {
+ var categoriesInfoArr []*models.CategoryPackagesInformation
+ err := database.DBCon.Model((*models.PackageToBug)(nil)).
+ ColumnExpr("SPLIT_PART(package_atom, '/', 1) as name").
+ ColumnExpr("COUNT(DISTINCT bug_id) as bugs").
+ ColumnExpr("COUNT(DISTINCT bug_id) FILTER(WHERE component = ?) as security_bugs", "Vulnerabilities").
+ Join("JOIN bugs").JoinOn("package_to_bug.bug_id = bugs.id").
+ Where("NULLIF(package_atom, '') IS NOT NULL").
+ Where(`package_atom LIKE '%/%'`).
+ GroupExpr("SPLIT_PART(package_atom, '/', 1)").
+ Select(&categoriesInfoArr)
+ if err != nil {
+ slog.Error("Failed collecting bugs stats", slog.Any("err", err))
+ return
+ }
+ categoriesInfo := make(map[string]*models.CategoryPackagesInformation, len(categoriesInfoArr))
+ for _, categoryInfo := range categoriesInfoArr {
+ if categoryInfo.Name != "" {
+ categoriesInfo[categoryInfo.Name] = categoryInfo
+ }
+ }
+
+ var categories []*models.CategoryPackagesInformation
+ err = database.DBCon.Model(&categories).Column("name").Select()
+ if err != nil {
+ slog.Error("Failed fetching categories packages information", slog.Any("err", err))
+ return
+ } else if len(categories) > 0 {
+ for _, category := range categories {
+ if info, found := categoriesInfo[category.Name]; found {
+ category.Bugs = info.Bugs
+ category.SecurityBugs = info.SecurityBugs
+ } else {
+ category.Bugs = 0
+ category.SecurityBugs = 0
+ }
+ delete(categoriesInfo, category.Name)
+ }
+ _, err = database.DBCon.Model(&categories).
+ Set("bugs = ?bugs").
+ Set("security_bugs = ?security_bugs").
+ Update()
+ if err != nil {
+ slog.Error("Failed updating categories packages information", slog.Any("err", err))
+ }
+ categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesInfo))
+ }
+
+ for _, catInfo := range categoriesInfo {
+ categories = append(categories, catInfo)
+ }
+ if len(categories) > 0 {
+ _, err = database.DBCon.Model(&categories).Insert()
+ if err != nil {
+ slog.Error("Failed inserting categories packages information", slog.Any("err", err))
+ }
+ }
+}
+
+func updateStatus() {
+ database.DBCon.Model(&models.Application{
+ Id: "bugs",
+ LastUpdate: time.Now(),
+ Version: config.Version(),
+ }).OnConflict("(id) DO UPDATE").Insert()
+}
diff --git a/pkg/portage/bugs/security.go b/pkg/portage/bugs/security.go
deleted file mode 100644
index 5b4c053..0000000
--- a/pkg/portage/bugs/security.go
+++ /dev/null
@@ -1,332 +0,0 @@
-package bugs
-
-import (
- "encoding/csv"
- "net/http"
- "regexp"
- "soko/pkg/config"
- "soko/pkg/database"
- "soko/pkg/logger"
- "soko/pkg/models"
- "strings"
- "time"
-)
-
-func UpdateBugs(init bool) {
- UpdateSecurityBugs()
- UpdatePackagesBugs(init)
-
- UpdateClosedBugs()
-
- updateStatus()
-}
-
-func UpdateSecurityBugs() {
- importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&component=Vulnerabilities&list_id=4688108&product=Gentoo%20Security&query_format=advanced&resolution=---&ctype=csv&human=1")
-}
-
-func UpdatePackagesBugs(init bool) {
- //
- // Keywording
- //
- importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&component=Keywording&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1")
-
- //
- // Stabilization
- //
- importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&component=Stabilization&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1")
-
- //
- // Current Packages
- //
- if init {
- importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&chfield=%5BBug%20creation%5D&chfieldfrom=2000-01-01&chfieldto=2020-01-01&component=Current%20packages&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1")
- }
- importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&chfield=%5BBug%20creation%5D&chfieldfrom=2020-01-01&chfieldto=2021-01-01&component=Current%20packages&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1")
-}
-
-func UpdateClosedBugs() {
- logger.Error.Println("UpdateClosedBugs")
- //
- // Security
- //
- deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Vulnerabilities&list_id=4694466&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Security&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&ctype=csv&human=1")
-
- //
- // Keywording
- //
- deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Keywording&list_id=4694472&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1")
-
- //
- // Stabilization
- //
- deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Stabilization&list_id=4694456&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1")
-
- //
- // Current Packages
- //
- deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Current%20packages&list_id=4773158&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1")
-}
-
-func deleteBugs(source string) {
- database.Connect()
- defer database.DBCon.Close()
-
- data, err := readCSVFromUrl(source)
- if err != nil {
- logger.Error.Println(err)
- }
-
- for idx, row := range data {
- // skip header
- if idx == 0 || len(row) < 7 {
- continue
- }
-
- bug := models.Bug{
- Id: row[0],
- }
-
- //
- // Delete bug
- //
- _, err = database.DBCon.Model(&bug).WherePK().Delete()
- if err != nil {
- logger.Error.Println(err)
- }
-
- //
- // Delete Package To Bug
- //
- bugId := row[0]
- summary := row[6]
- summary = strings.Split(summary, " ")[0]
- affectedPackage := versionSpecifierToPackageAtom(summary)
-
- _, err = database.DBCon.Model(&models.PackageToBug{
- Id: affectedPackage + "-" + bugId,
- PackageAtom: affectedPackage,
- BugId: bugId,
- }).Where("bug_id = ?bug_id").Delete()
- if err != nil {
- logger.Error.Println(err)
- }
- }
-}
-
-func importBugs(source string) {
-
- database.Connect()
- defer database.DBCon.Close()
-
- data, err := readCSVFromUrl(source)
- if err != nil {
- logger.Error.Println(err)
- }
-
- for idx, row := range data {
- // skip header
- if idx == 0 || len(row) < 7 {
- continue
- }
-
- bug := models.Bug{
- Id: row[0],
- Product: row[1],
- Component: row[2],
- Assignee: row[3],
- Status: row[4],
- Summary: row[6],
- }
-
- database.DBCon.Model(&bug).WherePK().OnConflict("(id) DO UPDATE").Insert()
-
- //
- // Insert Package To Bug
- //
- bugId := row[0]
- summary := row[6]
- if strings.TrimSpace(row[8]) != "" {
- for _, gpackage := range strings.Split(row[8], "\n") {
- affectedVersions := strings.Split(gpackage, " ")[0]
- if strings.TrimSpace(affectedVersions) != "" {
- CalculateAffectedVersions(bugId, affectedVersions)
- }
- }
- } else {
- summary = strings.Split(summary, " ")[0]
- affectedPackage := versionSpecifierToPackageAtom(summary)
-
- database.DBCon.Model(&models.PackageToBug{
- Id: affectedPackage + "-" + bugId,
- PackageAtom: affectedPackage,
- BugId: bugId,
- }).WherePK().OnConflict("(id) DO UPDATE").Insert()
- }
-
- }
-
-}
-
-func CalculateAffectedVersions(bugId, versionSpecifier string) {
-
- packageAtom := versionSpecifierToPackageAtom(versionSpecifier)
- var versions []*models.Version
-
- if strings.HasPrefix(versionSpecifier, "=") {
- versions = exaktVersion(versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "<=") {
- versions = comparedVersions("<=", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "<") {
- versions = comparedVersions("<", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, ">=") {
- versions = comparedVersions(">=", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, ">") {
- versions = comparedVersions(">", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "~") {
- versions = allRevisions(versionSpecifier, packageAtom)
- } else if strings.Contains(versionSpecifier, ":") {
- versions = versionsWithSlot(versionSpecifier, packageAtom)
- } else {
- versions = allVersions(versionSpecifier, packageAtom)
- }
-
- for _, version := range versions {
- versionToBug := &models.VersionToBug{
- Id: version.Id + "-" + bugId,
- VersionId: version.Id,
- BugId: bugId,
- }
-
- _, err := database.DBCon.Model(versionToBug).OnConflict("(id) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Printf("Error while inserting version to bug entry: %v", err)
- }
- }
-}
-
-// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version
-func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version {
- var results []*models.Version
- var versions []*models.Version
- versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "")
- versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "")
- versionSpecifier = strings.Split(versionSpecifier, ":")[0]
-
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Select()
-
- for _, v := range versions {
- givenVersion := models.Version{Version: versionSpecifier}
- if operator == ">" {
- if v.GreaterThan(givenVersion) {
- results = append(results, v)
- }
- } else if operator == ">=" {
- if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) {
- results = append(results, v)
- }
- } else if operator == "<" {
- if v.SmallerThan(givenVersion) {
- results = append(results, v)
- }
- } else if operator == "<=" {
- if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) {
- results = append(results, v)
- }
- }
- }
- return results
-}
-
-// allRevisions returns all revisions of the given version
-func allRevisions(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- revision := regexp.MustCompile(`-r[0-9]*$`)
- versionWithoutRevision := revision.Split(versionSpecifier, 1)[0]
- versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "")
- database.DBCon.Model(&versions).
- Where("id LIKE ?", versionWithoutRevision+"%").
- Select()
-
- return versions
-}
-
-// exaktVersion returns the exact version specified in the versionSpecifier
-func exaktVersion(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- database.DBCon.Model(&versions).
- Where("id = ?", versionSpecifier).
- Select()
-
- return versions
-}
-
-// TODO include subslot
-// versionsWithSlot returns all versions with the given slot
-func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- slot := strings.Split(versionSpecifier, ":")[1]
-
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Where("slot = ?", slot).
- Select()
-
- return versions
-}
-
-// allVersions returns all versions of the given package
-func allVersions(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Select()
- return versions
-}
-
-func readCSVFromUrl(url string) ([][]string, error) {
- resp, err := http.Get(url)
- if err != nil {
- return nil, err
- }
-
- defer resp.Body.Close()
- reader := csv.NewReader(resp.Body)
- reader.Comma = ','
- data, err := reader.ReadAll()
- if err != nil {
- return nil, err
- }
-
- return data, nil
-}
-
-// versionSpecifierToPackageAtom returns the package atom from a given version specifier
-func versionSpecifierToPackageAtom(versionSpecifier string) string {
- gpackage := strings.ReplaceAll(versionSpecifier, ">", "")
- gpackage = strings.ReplaceAll(gpackage, "<", "")
- gpackage = strings.ReplaceAll(gpackage, "=", "")
- gpackage = strings.ReplaceAll(gpackage, "~", "")
-
- gpackage = strings.Split(gpackage, ":")[0]
-
- versionnumber := regexp.MustCompile(`-[0-9]`)
- gpackage = versionnumber.Split(gpackage, 2)[0]
-
- return gpackage
-}
-
-func updateStatus() {
-
- database.Connect()
- defer database.DBCon.Close()
-
- database.DBCon.Model(&models.Application{
- Id: "bugs",
- LastUpdate: time.Now(),
- Version: config.Version(),
- }).OnConflict("(id) DO UPDATE").Insert()
-}
diff --git a/pkg/portage/dependencies/dependency.go b/pkg/portage/dependencies/dependency.go
index 3ded5eb..e6e4358 100644
--- a/pkg/portage/dependencies/dependency.go
+++ b/pkg/portage/dependencies/dependency.go
@@ -1,158 +1,99 @@
package dependencies
import (
+ "archive/tar"
"fmt"
- "io/ioutil"
+ "io"
+ "log/slog"
"net/http"
"regexp"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
- "strconv"
"strings"
- "sync"
"time"
-)
-
-// TODO
-var WaitGroup sync.WaitGroup
-
-var Dependencies []*models.ReverseDependency
-
-var PackageCounter int
-var DependencyCounter int
-var ErrCounter int
-var NewCounter int
-var (
- mu sync.RWMutex
+ "github.com/ulikunitz/xz"
)
-func AddDependency(dependency *models.ReverseDependency) {
- mu.Lock()
- defer mu.Unlock()
- Dependencies = append(Dependencies, dependency)
-}
-
-func AddtoErrorCounter(amount int) {
- mu.Lock()
- defer mu.Unlock()
- ErrCounter = ErrCounter + amount
-}
-
-func GetErrorCounter() int {
- mu.RLock() // readers lock
- defer mu.RUnlock()
- return ErrCounter
-}
+var Dependencies []*models.ReverseDependency
func FullPackageDependenciesUpdate() {
-
database.Connect()
defer database.DBCon.Close()
- var packages []models.Package
- database.DBCon.Model(&packages).Select()
-
- PackageCounter = 0
- NewCounter = 0
-
- cc := 0
-
- for _, gpackage := range packages {
-
- if cc%100 == 0 {
- logger.Info.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(cc))
- WaitGroup.Wait()
- }
-
- WaitGroup.Add(1)
- go UpdatePackageDependencies(gpackage.Atom)
-
- cc++
+ dependencyCounter, err := UpdateDependencies()
+ if err != nil {
+ return
}
- logger.Info.Println("Waiting for go routines to finish")
-
- WaitGroup.Wait()
-
- logger.Info.Println()
- logger.Info.Println("Processed " + strconv.Itoa(PackageCounter) + " packages.")
- logger.Info.Println("Got " + strconv.Itoa(DependencyCounter) + " dependencies.")
- logger.Info.Println("Start inserting dependencies into the database")
- logger.Info.Println("Errors: " + strconv.Itoa(GetErrorCounter()))
+ slog.Info("collected dependencies", slog.Int("count", dependencyCounter))
- logger.Info.Println("---")
-
- // finally delete all outdated dependencies
- // TODO in future we want a better incremental update here
- deleteAllDependencies()
-
- counter := 0
- length := len(Dependencies)
- for _, dependency := range Dependencies {
-
- if counter%1000 == 0 {
- logger.Info.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(counter) + " / " + strconv.Itoa(length))
- }
-
- database.DBCon.Model(dependency).WherePK().OnConflict("(id) DO UPDATE").Insert()
- counter++
+ database.TruncateTable((*models.ReverseDependency)(nil))
+ // because we removed all previous rows in table, we aren't concerned about
+ // duplicates, so we can use bulk insert
+ res, err := database.DBCon.Model(&Dependencies).Insert()
+ if err != nil {
+ slog.Error("Error during inserting dependencies", slog.Any("err", err))
+ } else {
+ slog.Info("Inserted dependencies", slog.Int("rows", res.RowsAffected()))
}
updateStatus()
}
-func UpdatePackageDependencies(atom string) {
-
- // reverse dependeny urls
- rdepend := "https://qa-reports.gentoo.org/output/genrdeps/rindex/" + atom
- parseDependencies(atom, rdepend, "rdepend")
-
- depend := "https://qa-reports.gentoo.org/output/genrdeps/dindex/" + atom
- parseDependencies(atom, depend, "depend")
-
- pdepend := "https://qa-reports.gentoo.org/output/genrdeps/pindex/" + atom
- parseDependencies(atom, pdepend, "pdepend")
-
- bdepend := "https://qa-reports.gentoo.org/output/genrdeps/bindex/" + atom
- parseDependencies(atom, bdepend, "bdepend")
-
- WaitGroup.Done()
-}
-
-func parseDependencies(atom, url, kind string) {
-
+func UpdateDependencies() (int, error) {
client := http.Client{
Timeout: 600 * time.Second,
}
- resp, err := client.Get(url)
-
+ resp, err := client.Get("https://qa-reports.gentoo.org/output/genrdeps/rdeps.tar.xz")
if err != nil {
- logger.Error.Println(err)
- return
+ slog.Error("Failed fetching dependencies", slog.Any("err", err))
+ return 0, err
}
-
defer resp.Body.Close()
if resp.StatusCode != 200 {
- return
+ slog.Error("Got bad status code", slog.Int("code", resp.StatusCode))
+ return 0, fmt.Errorf("status code: %d", resp.StatusCode)
}
- PackageCounter++
-
- rawResponse, err := ioutil.ReadAll(resp.Body)
-
+ xz, err := xz.NewReader(resp.Body)
if err != nil {
- return
+ slog.Error("Failed decompressing dependencies", slog.Any("err", err))
+ return 0, err
}
- rawDependencies := strings.Split(string(rawResponse), "\n")
-
- for _, rawDependency := range rawDependencies {
+ var dependencyCounter int
+ tr := tar.NewReader(xz)
+ for {
+ hdr, err := tr.Next()
+ if err == io.EOF {
+ break // end of tar archive
+ }
+ if err != nil {
+ slog.Error("Failed reading dependencies tar", slog.Any("err", err))
+ return 0, err
+ }
+ switch hdr.Typeflag {
+ case tar.TypeReg:
+ nameParts := strings.SplitN(hdr.Name, "/", 2)
+
+ rawResponse, err := io.ReadAll(tr)
+ if err != nil {
+ slog.Error("Failed reading file from tar", slog.Any("err", err))
+ return 0, err
+ }
+ parseDependencies(string(rawResponse), nameParts[1], nameParts[0])
+ dependencyCounter++
+ }
+ }
+ return dependencyCounter, nil
+}
+func parseDependencies(rawResponse, atom, kind string) {
+ for _, rawDependency := range strings.Split(rawResponse, "\n") {
dependencyParts := strings.Split(rawDependency, ":")
if strings.TrimSpace(dependencyParts[0]) == "" {
@@ -164,7 +105,7 @@ func parseDependencies(atom, url, kind string) {
condition = dependencyParts[1]
}
- AddDependency(&models.ReverseDependency{
+ Dependencies = append(Dependencies, &models.ReverseDependency{
Id: atom + "-" + kind + "-" + rawDependency,
Atom: atom,
Type: kind,
@@ -172,9 +113,7 @@ func parseDependencies(atom, url, kind string) {
ReverseDependencyVersion: dependencyParts[0],
Condition: condition,
})
-
}
-
}
func versionSpecifierToPackageAtom(versionSpecifier string) string {
@@ -191,40 +130,6 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string {
return gpackage
}
-// deleteAllPullrequests deletes all entries in the pullrequests and package to pull request table
-func deleteAllDependencies() {
- var reverseDependencies []*models.ReverseDependency
- database.DBCon.Model(&reverseDependencies).Select()
- for _, reverseDependency := range reverseDependencies {
- database.DBCon.Model(reverseDependency).WherePK().Delete()
- }
-}
-
-func deleteOutdatedDependencies(newDependencies []*models.ReverseDependency) {
- var oldDependencies []*models.ReverseDependency
- database.DBCon.Model(&oldDependencies).Select()
-
- for index, oldDependency := range oldDependencies {
-
- if index%10000 == 0 {
- fmt.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(index) + " / " + strconv.Itoa(len(oldDependencies)))
- }
-
- found := false
- for _, newDependency := range newDependencies {
- if oldDependency.Id == newDependency.Id {
- found = true
- }
- }
-
- if !found {
- database.DBCon.Model(oldDependency).WherePK().Delete()
- }
-
- }
-
-}
-
func updateStatus() {
database.DBCon.Model(&models.Application{
Id: "dependencies",
diff --git a/pkg/portage/github/pullrequests.go b/pkg/portage/github/pullrequests.go
index ea70cd0..9399a06 100644
--- a/pkg/portage/github/pullrequests.go
+++ b/pkg/portage/github/pullrequests.go
@@ -3,32 +3,28 @@ package github
import (
"bytes"
"encoding/json"
- "io/ioutil"
+ "log/slog"
"net/http"
- appUtils "soko/pkg/app/utils"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
- "soko/pkg/utils"
"strconv"
"strings"
"time"
)
func buildQuery(limit int, isOpen bool, lastUpdated, after string) map[string]string {
-
- lastUpdatedQuery := ""
+ var lastUpdatedQuery string
if lastUpdated != "" {
lastUpdatedQuery = `updated:>` + lastUpdated
}
- afterQuery := ""
+ var afterQuery string
if after != "" {
afterQuery = `after: "` + after + `",`
}
- isOpenQuery := ""
+ var isOpenQuery string
if isOpen {
isOpenQuery = `is:open`
}
@@ -109,102 +105,139 @@ func buildQuery(limit int, isOpen bool, lastUpdated, after string) map[string]st
}
func FullUpdatePullRequests() {
-
database.Connect()
defer database.DBCon.Close()
- deleteAllPullrequests()
+ database.TruncateTable((*models.GithubPullRequest)(nil))
+ database.TruncateTable((*models.PackageToGithubPullRequest)(nil))
// year of the git migration
- UpdatePullRequestsAfter(true, "2015-01-01", "")
+ updatePullRequestsAfter(true, "2015-01-01", "")
updateStatus()
}
-func IncrementalUpdatePullRequests() {
-
- database.Connect()
- defer database.DBCon.Close()
+func updatePullRequestsAfter(isOpen bool, lastUpdated, after string) {
+ pullRequests := make(map[int]*models.GithubPullRequest)
+ client := &http.Client{Timeout: time.Second * 30}
- lastUpdate := appUtils.GetApplicationData().LastUpdate.UTC().Format(time.RFC3339)
- lastUpdate = strings.Split(lastUpdate, "Z")[0] + "Z"
- UpdatePullRequestsAfter(false, lastUpdate, "")
- // TODO --> we need to update old ent
- // TODO --> delete closed pull requests
+ for {
+ slog.Info("Requesting pull requests", slog.Int("index", len(pullRequests)))
+ jsonData := buildQuery(100, isOpen, lastUpdated, after)
+ jsonValue, _ := json.Marshal(jsonData)
- updateStatus()
-}
+ request, err := http.NewRequest(http.MethodPost, "https://api.github.com/graphql", bytes.NewBuffer(jsonValue))
+ if err != nil {
+ slog.Error("Failed querying github graphql", slog.Any("err", err))
+ return
+ }
-func UpdatePullRequestsAfter(isOpen bool, lastUpdated, after string) {
- jsonData := buildQuery(100, isOpen, lastUpdated, after)
+ request.Header.Set("Authorization", "bearer "+config.GithubAPIToken())
+ response, err := client.Do(request)
+ if err != nil {
+ slog.Error("The HTTP request failed", slog.Any("err", err))
+ return
+ }
+ defer response.Body.Close()
- jsonValue, _ := json.Marshal(jsonData)
- request, err := http.NewRequest("POST", "https://api.github.com/graphql", bytes.NewBuffer(jsonValue))
- request.Header.Set("Authorization", "bearer "+config.GithubAPIToken())
- client := &http.Client{Timeout: time.Second * 30}
- response, err := client.Do(request)
- if err != nil {
- logger.Error.Println("The HTTP request failed with error")
- logger.Error.Println(err)
+ var prData models.GitHubPullRequestQueryResult
+ err = json.NewDecoder(response.Body).Decode(&prData)
+ if err != nil {
+ slog.Error("Failed to parse JSON", slog.Any("err", err))
+ return
+ }
+ prData.AppendPullRequest(pullRequests)
+
+ // If there is a next page, import it as well
+ if prData.HasNextPage() {
+ time.Sleep(2 * time.Second)
+ after = prData.EndCursor()
+ } else {
+ break
+ }
}
- defer response.Body.Close()
- data, _ := ioutil.ReadAll(response.Body)
- var prData models.GitHubPullRequestQueryResult
- err = json.Unmarshal([]byte(data), &prData)
-
- pullrequests := prData.CreatePullRequest()
-
- for _, pullrequest := range pullrequests {
- //
- // Create Pullrequest
- //
- database.DBCon.Model(&pullrequest).WherePK().OnConflict("(id) DO UPDATE").Insert()
+ if len(pullRequests) == 0 {
+ slog.Info("No pull requests to insert")
+ return
+ }
- //
- // Create Package To Pullrequest
- //
- var affectedPackages []string
+ categoriesPullRequests := make(map[string]map[string]struct{})
+ var pkgsPullRequests []*models.PackageToGithubPullRequest
+ for _, pullrequest := range pullRequests {
+ affectedPackages := make(map[string]struct{})
for _, file := range pullrequest.Files {
pathParts := strings.Split(file.Path, "/")
if len(pathParts) >= 2 && strings.Contains(pathParts[0], "-") {
- affectedPackages = append(affectedPackages, pathParts[0]+"/"+pathParts[1])
+ affectedPackages[pathParts[0]+"/"+pathParts[1]] = struct{}{}
+
+ prs, ok := categoriesPullRequests[pathParts[0]]
+ if !ok {
+ prs = make(map[string]struct{})
+ }
+ prs[pullrequest.Id] = struct{}{}
+ categoriesPullRequests[pathParts[0]] = prs
}
}
- affectedPackages = utils.Deduplicate(affectedPackages)
- for _, affectedPackage := range affectedPackages {
- database.DBCon.Model(&models.PackageToGithubPullRequest{
+ for affectedPackage := range affectedPackages {
+ pkgsPullRequests = append(pkgsPullRequests, &models.PackageToGithubPullRequest{
Id: affectedPackage + "-" + pullrequest.Id,
PackageAtom: affectedPackage,
GithubPullRequestId: pullrequest.Id,
- }).WherePK().OnConflict("(id) DO UPDATE").Insert()
+ })
}
}
- //
- // If there is a next page, import it as well
- //
+ rows := make([]*models.GithubPullRequest, 0, len(pullRequests))
+ for _, row := range pullRequests {
+ rows = append(rows, row)
+ }
+ result, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed to insert pull requests", slog.Any("err", err))
+ return
+ }
+ slog.Info("Inserted pull requests", slog.Int("rows", result.RowsAffected()))
- if prData.HasNextPage() {
- // Wait for some time, as Github will block the request otherwise
- time.Sleep(2 * time.Second)
- UpdatePullRequestsAfter(isOpen, lastUpdated, prData.EndCursor())
+ result, err = database.DBCon.Model(&pkgsPullRequests).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed to insert packages to pull requests", slog.Any("err", err))
+ return
}
+ slog.Info("Inserted packages to pull requests", slog.Int("rows", result.RowsAffected()))
+ updateCategoriesPullRequests(categoriesPullRequests)
}
-// deleteAllPullrequests deletes all entries in the pullrequests and package to pull request table
-func deleteAllPullrequests() {
- var pullrequests []*models.GithubPullRequest
- database.DBCon.Model(&pullrequests).Select()
- for _, pullrequest := range pullrequests {
- database.DBCon.Model(pullrequest).WherePK().Delete()
+func updateCategoriesPullRequests(categoriesPullRequests map[string]map[string]struct{}) {
+ var categories []*models.CategoryPackagesInformation
+ err := database.DBCon.Model(&categories).Column("name").Select()
+ if err != nil {
+ slog.Error("Failed fetching categories packages information", slog.Any("err", err))
+ return
+ } else if len(categories) > 0 {
+ for _, category := range categories {
+ category.PullRequests = len(categoriesPullRequests[category.Name])
+ delete(categoriesPullRequests, category.Name)
+ }
+ _, err = database.DBCon.Model(&categories).Set("pull_requests = ?pull_requests").Update()
+ if err != nil {
+ slog.Error("Failed updating categories packages information", slog.Any("err", err))
+ }
+ categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesPullRequests))
}
- var packagesToGithubPullRequest []*models.PackageToGithubPullRequest
- database.DBCon.Model(&packagesToGithubPullRequest).Select()
- for _, packageToGithubPullRequest := range packagesToGithubPullRequest {
- database.DBCon.Model(packageToGithubPullRequest).WherePK().Delete()
+ for category, prs := range categoriesPullRequests {
+ categories = append(categories, &models.CategoryPackagesInformation{
+ Name: category,
+ PullRequests: len(prs),
+ })
+ }
+ if len(categories) > 0 {
+ _, err = database.DBCon.Model(&categories).Insert()
+ if err != nil {
+ slog.Error("Failed inserting categories packages information", slog.Any("err", err))
+ }
}
}
diff --git a/pkg/portage/maintainers/update.go b/pkg/portage/maintainers/update.go
index e42a8e6..306d9d8 100644
--- a/pkg/portage/maintainers/update.go
+++ b/pkg/portage/maintainers/update.go
@@ -1,24 +1,30 @@
package maintainers
import (
+ "log/slog"
"soko/pkg/config"
"soko/pkg/database"
"soko/pkg/models"
- "soko/pkg/utils"
- "sort"
"strings"
"time"
)
+const maintainerNeededEmail = "maintainer-needed@gentoo.org"
+
func FullImport() {
database.Connect()
defer database.DBCon.Close()
+ slog.Info("Loading all raw maintainers from the database")
var allMaintainerInformation []*models.Maintainer
database.DBCon.Model((*models.Package)(nil)).ColumnExpr("jsonb_array_elements(maintainers)->>'Name' as name, jsonb_array_elements(maintainers) ->> 'Email' as email, jsonb_array_elements(maintainers) ->> 'Type' as type").Select(&allMaintainerInformation)
- maintainers := map[string]*models.Maintainer{}
+ maintainers := map[string]*models.Maintainer{
+ maintainerNeededEmail: {
+ Email: maintainerNeededEmail,
+ },
+ }
for _, rawMaintainer := range allMaintainerInformation {
_, ok := maintainers[rawMaintainer.Email]
@@ -31,6 +37,7 @@ func FullImport() {
}
}
+ slog.Info("Loading all packages from the database")
var gpackages []*models.Package
database.DBCon.Model(&gpackages).
Relation("Outdated").
@@ -41,24 +48,20 @@ func FullImport() {
Relation("Versions.PkgCheckResults").
Select()
- // TODO in future we want an incremental update here
- // but for now we delete everything and insert it again
- // this is currently acceptable as it takes less than 2 seconds
- deleteAllMaintainers()
-
for _, maintainer := range maintainers {
- outdated := 0
- securityBugs := 0
- pullrequestIds := []string{}
- nonSecurityBugs := 0
- stableRequests := 0
+ var outdated, stableRequests int
+ pullRequestIds := make(map[string]struct{})
maintainerPackages := []*models.Package{}
for _, gpackage := range gpackages {
found := false
- for _, packageMaintainer := range gpackage.Maintainers {
- if packageMaintainer.Email == maintainer.Email {
- found = true
+ if len(gpackage.Maintainers) == 0 && maintainer.Email == maintainerNeededEmail {
+ found = true
+ } else {
+ for _, packageMaintainer := range gpackage.Maintainers {
+ if packageMaintainer.Email == maintainer.Email {
+ found = true
+ }
}
}
@@ -68,7 +71,7 @@ func FullImport() {
outdated = outdated + len(gpackage.Outdated)
for _, pullRequest := range gpackage.PullRequests {
- pullrequestIds = append(pullrequestIds, string(pullRequest.Id))
+ pullRequestIds[pullRequest.Id] = struct{}{}
}
// Find Stable Requests
@@ -82,31 +85,26 @@ func FullImport() {
}
}
- for _, bug := range getAllBugs(maintainerPackages) {
- if bug.Component == "Vulnerabilities" {
- securityBugs++
- } else {
- nonSecurityBugs++
- }
- }
+ securityBugs, nonSecurityBugs := countBugs(maintainerPackages)
maintainer.PackagesInformation = models.MaintainerPackagesInformation{
Outdated: outdated,
- PullRequests: len(utils.Deduplicate(pullrequestIds)),
+ PullRequests: len(pullRequestIds),
Bugs: nonSecurityBugs,
SecurityBugs: securityBugs,
StableRequests: stableRequests,
}
+ maintainer.Name = strings.TrimSpace(maintainer.Name)
+
if maintainer.Name == "" {
- maintainer.Name = strings.Title(strings.Split(maintainer.Email, "@")[0])
+ name, _, _ := strings.Cut(maintainer.Email, "@")
+ maintainer.Name = strings.Title(name)
}
if maintainer.Type == "project" && strings.HasPrefix(maintainer.Name, "Gentoo ") {
- maintainer.Name = strings.Replace(maintainer.Name, "Gentoo ", "", 1)
- }
-
- if maintainer.Type == "person" {
+ maintainer.Name = strings.TrimPrefix(maintainer.Name, "Gentoo ")
+ } else if maintainer.Type == "person" {
if strings.HasSuffix(maintainer.Email, "@gentoo.org") {
maintainer.Type = "gentoo-developer"
} else {
@@ -114,49 +112,44 @@ func FullImport() {
}
}
- database.DBCon.Model(maintainer).WherePK().OnConflict("(email) DO UPDATE").Insert()
}
+ // TODO in future we want an incremental update here
+ // but for now we delete everything and insert it again
+ // this is currently acceptable as it takes less than 2 seconds
+ database.TruncateTable((*models.Maintainer)(nil))
+
+ rows := make([]*models.Maintainer, 0, len(maintainers))
+ for _, row := range maintainers {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(email) DO NOTHING").Insert()
+ if err != nil {
+ slog.Error("Failed inserting maintainers", slog.Any("err", err))
+ return
+ }
+ slog.Info("Inserted maintainers", slog.Int("rows", res.RowsAffected()))
+
updateStatus()
}
-func getAllBugs(packages []*models.Package) []*models.Bug {
+func countBugs(packages []*models.Package) (securityBugs, nonSecurityBugs int) {
allBugs := make(map[string]*models.Bug)
-
for _, gpackage := range packages {
for _, bug := range gpackage.AllBugs() {
allBugs[bug.Id] = bug
}
}
- var allBugsList []*models.Bug
for _, bug := range allBugs {
- allBugsList = append(allBugsList, bug)
- }
-
- sort.Slice(allBugsList, func(i, j int) bool {
- return allBugsList[i].Id < allBugsList[j].Id
- })
-
- return allBugsList
-}
-
-// deleteAllMaintainers deletes all entries in the maintainers table
-func deleteAllMaintainers() {
- var maintainers []*models.Maintainer
- database.DBCon.Model(&maintainers).Select()
- for _, maintainer := range maintainers {
- database.DBCon.Model(maintainer).WherePK().Delete()
- }
-}
-
-func contains(element string, elements []string) bool {
- for _, el := range elements {
- if element == el {
- return true
+ if bug.Component == "Vulnerabilities" {
+ securityBugs++
+ } else {
+ nonSecurityBugs++
}
}
- return false
+
+ return
}
func updateStatus() {
diff --git a/pkg/portage/pkgcheck/parse.go b/pkg/portage/pkgcheck/parse.go
index 36e80ad..6eab781 100644
--- a/pkg/portage/pkgcheck/parse.go
+++ b/pkg/portage/pkgcheck/parse.go
@@ -2,12 +2,10 @@ package pkgcheck
import (
"encoding/xml"
- "io/ioutil"
- "log"
+ "log/slog"
"net/http"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"time"
)
@@ -30,62 +28,111 @@ type PkgCheckResult struct {
// UpdatePkgCheckResults will update the database table that contains all pkgcheck results
func UpdatePkgCheckResults() {
-
database.Connect()
defer database.DBCon.Close()
- if config.Quiet() == "true" {
- log.SetOutput(ioutil.Discard)
- }
-
// get the pkg check results from qa-reports.gentoo.org
pkgCheckResults, err := parseQAReport()
if err != nil {
- logger.Error.Println("Error while parsing qa-reports data. Aborting...")
+ slog.Error("Failed parsing qa-reports data", slog.Any("err", err))
+ return
}
- // clean up the database
- deleteAllPkgCheckResults()
-
- // update the database with the new results
- for _, pkgCheckResult := range pkgCheckResults.Results {
- database.DBCon.Insert(&models.PkgCheckResult{
- Id: pkgCheckResult.Category + "/" + pkgCheckResult.Package + "-" + pkgCheckResult.Version + "-" + pkgCheckResult.Class + "-" + pkgCheckResult.Message,
- Atom: pkgCheckResult.Category + "/" + pkgCheckResult.Package,
+ collected := make(map[string]*models.PkgCheckResult, len(pkgCheckResults))
+ for _, pkgCheckResult := range pkgCheckResults {
+ catpkg := pkgCheckResult.Category + "/" + pkgCheckResult.Package
+ catpkgver := catpkg + "-" + pkgCheckResult.Version
+ id := catpkgver + "-" + pkgCheckResult.Class + "-" + pkgCheckResult.Message
+ collected[id] = &models.PkgCheckResult{
+ Id: id,
+ Atom: catpkg,
Category: pkgCheckResult.Category,
Package: pkgCheckResult.Package,
Version: pkgCheckResult.Version,
- CPV: pkgCheckResult.Category + "/" + pkgCheckResult.Package + "-" + pkgCheckResult.Version,
+ CPV: catpkgver,
Class: pkgCheckResult.Class,
Message: pkgCheckResult.Message,
- })
+ }
+ }
+
+ // clean up the database
+ database.TruncateTable((*models.PkgCheckResult)(nil))
+
+ // update the database with the new results
+ rows := make([]*models.PkgCheckResult, 0, len(collected))
+ for _, row := range collected {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(id) DO NOTHING").Insert()
+ if err != nil {
+ slog.Error("Failed inserting pkgcheck results", slog.Any("err", err))
+ return
}
+ slog.Info("Inserted pkgcheck results", slog.Int("rows", res.RowsAffected()))
+
+ updateCategoriesInfo()
updateStatus()
}
// parseQAReport gets the xml from qa-reports.gentoo.org and parses it
-func parseQAReport() (PkgCheckResults, error) {
+func parseQAReport() ([]PkgCheckResult, error) {
resp, err := http.Get("https://qa-reports.gentoo.org/output/gentoo-ci/output.xml")
if err != nil {
- return PkgCheckResults{}, err
+ return nil, err
}
defer resp.Body.Close()
- xmlData, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return PkgCheckResults{}, err
- }
var pkgCheckResults PkgCheckResults
- xml.Unmarshal(xmlData, &pkgCheckResults)
- return pkgCheckResults, err
+ err = xml.NewDecoder(resp.Body).Decode(&pkgCheckResults)
+ return pkgCheckResults.Results, err
}
-// deleteAllOutdated deletes all entries in the outdated table
-func deleteAllPkgCheckResults() {
- var allPkgCheckResults []*models.PkgCheckResult
- database.DBCon.Model(&allPkgCheckResults).Select()
- for _, pkgCheckResult := range allPkgCheckResults {
- database.DBCon.Model(pkgCheckResult).WherePK().Delete()
+func updateCategoriesInfo() {
+ var categoriesInfoArr []*models.CategoryPackagesInformation
+ err := database.DBCon.Model((*models.PkgCheckResult)(nil)).
+ ColumnExpr("SPLIT_PART(atom, '/', 1) as name").
+ ColumnExpr("COUNT(id) as stable_requests").
+ Where("NULLIF(atom, '') IS NOT NULL").
+ Where("class = 'StableRequest'").
+ GroupExpr("SPLIT_PART(atom, '/', 1)").
+ Select(&categoriesInfoArr)
+ if err != nil {
+ slog.Error("Failed collecting pkgcheck results stats", slog.Any("err", err))
+ return
+ }
+ categoriesInfo := make(map[string]int, len(categoriesInfoArr))
+ for _, categoryInfo := range categoriesInfoArr {
+ categoriesInfo[categoryInfo.Name] = categoryInfo.StableRequests
+ }
+
+ var categories []*models.CategoryPackagesInformation
+ err = database.DBCon.Model(&categories).Column("name").Select()
+ if err != nil {
+ slog.Error("Failed fetching categories packages information", slog.Any("err", err))
+ return
+ } else if len(categories) > 0 {
+ for _, category := range categories {
+ category.StableRequests = categoriesInfo[category.Name]
+ delete(categoriesInfo, category.Name)
+ }
+ _, err = database.DBCon.Model(&categories).Set("stable_requests = ?stable_requests").Update()
+ if err != nil {
+ slog.Error("Failed updating categories packages information", slog.Any("err", err))
+ }
+ categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesInfo))
+ }
+
+ for category, stableRequests := range categoriesInfo {
+ categories = append(categories, &models.CategoryPackagesInformation{
+ Name: category,
+ StableRequests: stableRequests,
+ })
+ }
+ if len(categories) > 0 {
+ _, err = database.DBCon.Model(&categories).Insert()
+ if err != nil {
+ slog.Error("Error while inserting categories packages information", slog.Any("err", err))
+ }
}
}
diff --git a/pkg/portage/projects/update.go b/pkg/portage/projects/update.go
index d9a47a0..d463862 100644
--- a/pkg/portage/projects/update.go
+++ b/pkg/portage/projects/update.go
@@ -2,40 +2,36 @@ package projects
import (
"encoding/xml"
- "io/ioutil"
- "log"
+ "log/slog"
"net/http"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"time"
)
-// UpdatePkgCheckResults will update the database table that contains all pkgcheck results
+// UpdateProjects will update the database table that contains all projects
func UpdateProjects() {
-
database.Connect()
defer database.DBCon.Close()
- if config.Quiet() == "true" {
- log.SetOutput(ioutil.Discard)
- }
-
- // get the pkg check results from qa-reports.gentoo.org
+ // get projects from api.gentoo.org
projectList, err := parseProjectList()
if err != nil {
- logger.Error.Println("Error while parsing project list. Aborting...")
+ slog.Error("Error while parsing project list", slog.Any("err", err))
+ return
}
- // clean up the database
- deleteAllProjects()
-
- // insert new project list
- for _, project := range projectList.Projects {
- database.DBCon.Insert(&project)
+ var members []*models.MaintainerToProject
+ membersMap := make(map[string]struct{})
+ for _, project := range projectList {
for _, member := range project.Members {
- database.DBCon.Insert(&models.MaintainerToProject{
+ id := member.Email + "|" + project.Email
+ if _, ok := membersMap[id]; ok {
+ continue
+ }
+ membersMap[id] = struct{}{}
+ members = append(members, &models.MaintainerToProject{
Id: member.Email + "-" + project.Email,
MaintainerEmail: member.Email,
ProjectEmail: project.Email,
@@ -43,38 +39,48 @@ func UpdateProjects() {
}
}
+ // clean up the database
+ database.TruncateTable((*models.Project)(nil))
+ database.TruncateTable((*models.MaintainerToProject)(nil))
+
+ // insert new project list
+ _, err = database.DBCon.Model(&projectList).Insert()
+ if err != nil {
+ slog.Error("Error while inserting project list", slog.Any("err", err))
+ return
+ }
+ _, err = database.DBCon.Model(&members).Insert()
+ if err != nil {
+ slog.Error("Error while inserting project members", slog.Any("err", err))
+ return
+ }
+
updateStatus()
}
-// parseQAReport gets the xml from qa-reports.gentoo.org and parses it
-func parseProjectList() (models.ProjectList, error) {
+// parseProjectList gets the xml from api.gentoo.org and parses it
+func parseProjectList() ([]models.Project, error) {
resp, err := http.Get("https://api.gentoo.org/metastructure/projects.xml")
if err != nil {
- return models.ProjectList{}, err
+ return nil, err
}
defer resp.Body.Close()
- xmlData, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return models.ProjectList{}, err
- }
- var projectList models.ProjectList
- xml.Unmarshal(xmlData, &projectList)
- return projectList, err
-}
-// deleteAllOutdated deletes all entries in the outdated table
-func deleteAllProjects() {
- var allProjects []*models.Project
- database.DBCon.Model(&allProjects).Select()
- for _, project := range allProjects {
- database.DBCon.Model(project).WherePK().Delete()
+ var projectList models.ProjectList
+ err = xml.NewDecoder(resp.Body).Decode(&projectList)
+ if err != nil {
+ return nil, err
}
- var allMaintainerToProjects []*models.MaintainerToProject
- database.DBCon.Model(&allMaintainerToProjects).Select()
- for _, maintainerToProject := range allMaintainerToProjects {
- database.DBCon.Model(maintainerToProject).WherePK().Delete()
+ uniqueProjects := make([]models.Project, 0, len(projectList.Projects))
+ seen := make(map[string]struct{}, len(projectList.Projects))
+ for _, project := range projectList.Projects {
+ if _, ok := seen[project.Email]; !ok {
+ seen[project.Email] = struct{}{}
+ uniqueProjects = append(uniqueProjects, project)
+ }
}
+ return uniqueProjects, nil
}
func updateStatus() {
diff --git a/pkg/portage/repology/outdated.go b/pkg/portage/repology/outdated.go
index e836ab0..93f9008 100644
--- a/pkg/portage/repology/outdated.go
+++ b/pkg/portage/repology/outdated.go
@@ -1,17 +1,20 @@
package repology
import (
- "bytes"
+ "bufio"
+ "context"
"encoding/json"
- "io/ioutil"
- "log"
+ "fmt"
+ "log/slog"
"net/http"
+ "regexp"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"strings"
"time"
+
+ "golang.org/x/time/rate"
)
type Package struct {
@@ -22,158 +25,298 @@ type Package struct {
Status string `json:"status"`
}
-type Packages map[string][]Package
+type Packages = map[string][]Package
+
+var client = http.Client{Timeout: 1 * time.Minute}
+var clientRateLimiter = rate.NewLimiter(rate.Every(2*time.Second), 1)
// UpdateOutdated will update the database table that contains all outdated gentoo versions
func UpdateOutdated() {
-
database.Connect()
defer database.DBCon.Close()
- if config.Quiet() == "true" {
- log.SetOutput(ioutil.Discard)
+ // Get all outdated Versions
+ outdated := newOutdatedCheck()
+ for letter := 'a'; letter <= 'z'; letter++ {
+ outdated.getOutdatedStartingWith(letter)
}
- // Get all outdated Versions
- var outdatedVersions []*models.OutdatedPackages
- letters := "abcdefghijklmnopqrstuvwxyz"
- for _, letter := range letters {
- outdatedVersions = append(outdatedVersions, getOutdatedStartingWith(letter)...)
+ // Update the database
+ if len(outdated.outdatedVersions) > 0 {
+ database.TruncateTable((*models.OutdatedPackages)(nil))
+
+ res, err := database.DBCon.Model(&outdated.outdatedVersions).Insert()
+ if err != nil {
+ slog.Error("Error while inserting outdated packages", slog.Any("err", err))
+ } else {
+ slog.Info("Inserted outdated packages", slog.Int("res", res.RowsAffected()))
+ }
}
- // Clean up the database
- deleteAllOutdated()
+ // Updated the outdated status of categories
+ var categories []*models.CategoryPackagesInformation
+ err := database.DBCon.Model(&categories).Column("name").Select()
+ if err != nil {
+ slog.Error("Failed fetching categories packages information", slog.Any("err", err))
+ return
+ } else if len(categories) > 0 {
+ for _, category := range categories {
+ category.Outdated = outdated.outdatedCategories[category.Name]
+ delete(outdated.outdatedCategories, category.Name)
+ }
+ _, err = database.DBCon.Model(&categories).Set("outdated = ?outdated").Update()
+ if err != nil {
+ slog.Error("Failed updating categories packages information", slog.Any("err", err))
+ }
+ categories = make([]*models.CategoryPackagesInformation, 0, len(outdated.outdatedCategories))
+ }
- // Update the database
- for _, outdated := range outdatedVersions {
- database.DBCon.Insert(outdated)
+ for category, count := range outdated.outdatedCategories {
+ categories = append(categories, &models.CategoryPackagesInformation{
+ Name: category,
+ Outdated: count,
+ })
+ }
+ if len(categories) > 0 {
+ _, err = database.DBCon.Model(&categories).Insert()
+ if err != nil {
+ slog.Error("Error while inserting categories packages information", slog.Any("err", err))
+ }
}
updateStatus()
}
-// getOutdatedStartingWith gets all outdated packages starting with the given letter
-func getOutdatedStartingWith(letter rune) []*models.OutdatedPackages {
- repoPackages, err := parseRepologyData("https://repology.org/api/v1/projects/" + string(letter) + "/?inrepo=gentoo&outdated=1")
+type atomOutdatedRules struct {
+ ignore bool
+ ignoreVersions []string
+ ignoreRepos []string
+ selectedRepos []string
+}
+
+func (a *atomOutdatedRules) isIgnored(version string, repo string) bool {
+ if a == nil {
+ return false
+ } else if a.ignore {
+ return true
+ }
+
+ for _, v := range a.ignoreVersions {
+ if strings.HasPrefix(version, v) {
+ return true
+ }
+ }
+ for _, r := range a.ignoreRepos {
+ if strings.HasPrefix(repo, r) {
+ return true
+ }
+ }
+ if len(a.selectedRepos) > 0 {
+ found := false
+ for _, r := range a.selectedRepos {
+ if strings.HasPrefix(repo, r) {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return true
+ }
+ }
+ return false
+}
+
+type outdatedCheck struct {
+ blockedRepos map[string]struct{}
+ blockedCategories map[string]struct{}
+ atomRules map[string]*atomOutdatedRules
+
+ outdatedCategories map[string]int
+ outdatedVersions []*models.OutdatedPackages
+}
+
+func newOutdatedCheck() outdatedCheck {
+ return outdatedCheck{
+ blockedRepos: readBlockList("ignored-repositories"),
+ blockedCategories: readBlockList("ignored-categories"),
+ atomRules: buildAtomRules(),
+
+ outdatedCategories: make(map[string]int),
+ }
+}
+// getOutdatedStartingWith gets all outdated packages starting with the given letter
+func (o *outdatedCheck) getOutdatedStartingWith(letter rune) {
+ repoPackages, err := parseRepologyData(letter)
if err != nil {
- logger.Error.Println("Error while fetching repology data")
- return []*models.OutdatedPackages{}
+ slog.Error("Error while fetching repology data", slog.String("letter", string(letter)), slog.Any("err", err))
}
- blockedRepos := readBlocklist("ignored-repositories")
- blockedCategories := readBlocklist("ignored-categories")
- blockedPackages := readBlocklist("ignored-packages")
+ for packagename := range repoPackages {
+ outdated := make(map[string]bool)
+ currentVersion := make(map[string]string)
+ var newestVersion string
- var outdatedVersions []*models.OutdatedPackages
- for packagename, _ := range repoPackages {
- atom := ""
- newest := ""
- version := ""
- outdated := false
// get the gentoo atom name first
+ gentooPackages := make(map[string]struct{})
for _, v := range repoPackages[packagename] {
if v.Repo == "gentoo" {
- atom = v.VisibleName
+ gentooPackages[v.VisibleName] = struct{}{}
}
}
+ mainLoop:
for _, v := range repoPackages[packagename] {
- if v.Status == "newest" &&
- !contains(blockedRepos, v.Repo) &&
- !contains(blockedPackages, atom+"::"+v.Repo) {
- newest = v.Version
- }
- if v.Repo == "gentoo" && v.Status == "newest" {
- outdated = false
- break
- }
- if v.Repo == "gentoo" &&
- v.Status == "outdated" &&
- !containsPrefix(blockedCategories, strings.Split(v.VisibleName, "/")[0]) &&
- !containsPrefix(blockedPackages, v.VisibleName) {
-
- atom = v.VisibleName
- outdated = true
- version = v.Version
+ category, _, _ := strings.Cut(v.VisibleName, "/")
+ if v.Repo == "gentoo" {
+ if v.Status == "newest" {
+ outdated[v.VisibleName] = false
+ } else if v.Status == "outdated" {
+ if contains(o.blockedCategories, category) || o.atomRules[v.VisibleName].isIgnored(v.Version, v.Repo) {
+ continue
+ }
+ if _, found := outdated[v.VisibleName]; !found {
+ outdated[v.VisibleName] = true
+ }
+ if latest, found := currentVersion[v.VisibleName]; found {
+ current := models.Version{Version: v.Version}
+ if current.GreaterThan(models.Version{Version: latest}) {
+ currentVersion[v.VisibleName] = v.Version
+ }
+ } else {
+ currentVersion[v.VisibleName] = v.Version
+ }
+ }
+ } else if len(newestVersion) == 0 && v.Status == "newest" && !contains(o.blockedRepos, v.Repo) {
+ for atom := range gentooPackages {
+ if o.atomRules[atom].isIgnored(v.Version, v.Repo) {
+ continue mainLoop
+ }
+ }
+ newestVersion = v.Version
}
}
- if outdated && newest != "" && strings.HasPrefix(packagename, string(letter)) {
- outdatedVersions = append(outdatedVersions, &models.OutdatedPackages{
- Atom: atom,
- GentooVersion: version,
- NewestVersion: newest,
- })
+ if len(newestVersion) == 0 {
+ continue
}
- }
- return outdatedVersions
+ for atom, outdated := range outdated {
+ if outdated && packagename[0] == byte(letter) {
+ o.outdatedVersions = append(o.outdatedVersions, &models.OutdatedPackages{
+ Atom: atom,
+ GentooVersion: currentVersion[atom],
+ NewestVersion: newestVersion,
+ })
+
+ category, _, found := strings.Cut(atom, "/")
+ if found {
+ o.outdatedCategories[category]++
+ }
+ }
+ }
+ }
}
// parseRepologyData gets the json from given url and parses it
-func parseRepologyData(url string) (Packages, error) {
- resp, err := http.Get(url)
+func parseRepologyData(letter rune) (Packages, error) {
+ err := clientRateLimiter.Wait(context.Background())
+ if err != nil {
+ return Packages{}, fmt.Errorf("rate limiter failed: %w", err)
+ }
+
+ url := "https://repology.org/api/v1/projects/" + string(letter) + "/?inrepo=gentoo&outdated=1"
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return Packages{}, fmt.Errorf("new request: %w", err)
+ }
+ req.Header.Set("User-Agent", config.UserAgent())
+
+ resp, err := client.Do(req)
if err != nil {
- return Packages{}, err
+ return Packages{}, fmt.Errorf("do http: %w", err)
}
defer resp.Body.Close()
- var repoPackages Packages
- dec := json.NewDecoder(resp.Body)
- err = dec.Decode(&repoPackages)
- return repoPackages, err
-}
-// deleteAllOutdated deletes all entries in the outdated table
-func deleteAllOutdated() {
- var allOutdated []*models.OutdatedPackages
- database.DBCon.Model(&allOutdated).Select()
- for _, outdated := range allOutdated {
- database.DBCon.Model(outdated).WherePK().Delete()
+ if resp.StatusCode != http.StatusOK {
+ return Packages{}, fmt.Errorf("error while fetching repology data: %s", resp.Status)
}
+
+ var repoPackages Packages
+ err = json.NewDecoder(resp.Body).Decode(&repoPackages)
+ return repoPackages, err
}
-// readBlocklist parses a block list and returns a list of
+// readBlockList parses a block list and returns a list of
// lines whereas comments as well as empty lines are ignored
-func readBlocklist(file string) []string {
- var blocklist []string
- resp, err := http.Get("https://gitweb.gentoo.org/sites/soko-metadata.git/plain/repology/" + file)
+func readBlockList(file string) map[string]struct{} {
+ blocklist := make(map[string]struct{})
+ resp, err := client.Get("https://gitweb.gentoo.org/sites/soko-metadata.git/plain/repology/" + file)
if err != nil {
- return []string{}
+ slog.Error("Failed to fetch blacklist", slog.String("file", file), slog.Any("err", err))
+ return blocklist
}
defer resp.Body.Close()
- buf := new(bytes.Buffer)
- buf.ReadFrom(resp.Body)
- rawBlocklist := buf.String()
+ if resp.StatusCode != http.StatusOK {
+ slog.Error("Failed to fetch blacklist", slog.String("file", file), slog.String("status", resp.Status))
+ return blocklist
+ }
- for _, line := range strings.Split(rawBlocklist, "\n") {
+ scanner := bufio.NewScanner(resp.Body)
+ for scanner.Scan() {
+ line := scanner.Text()
if !strings.HasPrefix(line, "#") && strings.TrimSpace(line) != "" {
- blocklist = append(blocklist, line)
+ blocklist[line] = struct{}{}
}
}
return blocklist
}
-// contains returns true if the given list includes
-// the given string. Otherwise false is returned.
-func contains(list []string, item string) bool {
- for _, i := range list {
- if i == item {
- return true
+func buildAtomRules() map[string]*atomOutdatedRules {
+ var versionNumber = regexp.MustCompile(`-[0-9]`)
+
+ blacklist := readBlockList("ignored-packages")
+ whitelist := readBlockList("selected-packages")
+
+ atomRules := make(map[string]*atomOutdatedRules, len(blacklist)+len(whitelist))
+ for line := range blacklist {
+ cpv, repo, hasRepo := strings.Cut(line, "::")
+ atom := versionNumber.Split(cpv, 2)[0]
+ rule, found := atomRules[atom]
+ if !found {
+ rule = &atomOutdatedRules{}
+ atomRules[atom] = rule
+ }
+ if hasRepo && repo != "" {
+ rule.ignoreRepos = append(rule.ignoreRepos, repo)
+ } else if atom != cpv {
+ rule.ignoreVersions = append(rule.ignoreVersions, strings.TrimPrefix(cpv, atom+"-"))
+ } else {
+ rule.ignore = true
}
}
- return false
-}
-// contains returns true if the given string is a prefix
-// of an item in the given list. Otherwise false is returned.
-func containsPrefix(list []string, item string) bool {
- for _, i := range list {
- if strings.HasPrefix(i, item) {
- return true
+ for line := range whitelist {
+ cpv, repo, hasRepo := strings.Cut(line, "::")
+ atom := versionNumber.Split(cpv, 2)[0]
+ rule, found := atomRules[atom]
+ if !found {
+ rule = &atomOutdatedRules{}
+ atomRules[atom] = rule
+ }
+ if hasRepo && repo != "" {
+ rule.selectedRepos = append(rule.selectedRepos, repo)
}
}
- return false
+
+ return atomRules
+}
+
+// contains returns true if the given list includes
+// the given string. Otherwise false is returned.
+func contains(list map[string]struct{}, item string) bool {
+ _, found := list[item]
+ return found
}
func updateStatus() {
diff --git a/pkg/portage/repository/category.go b/pkg/portage/repository/category.go
index 8ea9413..b0dfe18 100644
--- a/pkg/portage/repository/category.go
+++ b/pkg/portage/repository/category.go
@@ -4,12 +4,11 @@ package repository
import (
"encoding/xml"
- "io/ioutil"
+ "log/slog"
"os"
"regexp"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"strings"
)
@@ -17,99 +16,116 @@ import (
// isCategory checks whether the path points to a category
// descriptions that is an metadata.xml file
func isCategory(path string) bool {
- isCategory, _ := regexp.MatchString(`[^/]*\/metadata\.xml`, path)
+ isCategory, _ := regexp.MatchString(`^[^/]*\/metadata\.xml$`, path)
return isCategory
}
-// UpdateCategory updates the category in the database in case
-// the given path points to a category description
-func UpdateCategory(path string) {
-
- splittedLine := strings.Split(path, "\t")
+// UpdateCategories updates the categories in the database for each
+// given path that points to a category description
+func UpdateCategories(paths []string) {
+ deleted := map[string]*models.Category{}
+ modified := map[string]*models.Category{}
+
+ for _, path := range paths {
+ splittedLine := strings.Split(path, "\t")
+
+ if len(splittedLine) != 2 {
+ if len(splittedLine) == 1 && isCategory(path) {
+ if cat := updateModifiedCategory(path); cat != nil {
+ modified[cat.Name] = cat
+ }
+ }
+ continue
+ }
- if len(splittedLine) != 2 {
- if len(splittedLine) == 1 && isCategory(path) {
- updateModifiedCategory(path)
+ status := splittedLine[0]
+ changedFile := splittedLine[1]
+
+ if !isCategory(changedFile) {
+ continue
+ } else if status == "D" {
+ cat := updateDeletedCategory(changedFile)
+ deleted[cat.Name] = cat
+ } else if status == "A" || status == "M" {
+ if cat := updateModifiedCategory(changedFile); cat != nil {
+ modified[cat.Name] = cat
+ }
}
- return
}
- status := splittedLine[0]
- changedFile := splittedLine[1]
+ if len(deleted) > 0 {
+ rows := make([]*models.Category, 0, len(deleted))
+ for _, row := range deleted {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).Delete()
+ if err != nil {
+ slog.Error("Failed deleting categories", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted categories", slog.Int("rows", res.RowsAffected()))
+ }
+ }
- if isCategory(changedFile) && status == "D" {
- updateDeletedCategory(changedFile)
- } else if isCategory(changedFile) && (status == "A" || status == "M") {
- updateModifiedCategory(changedFile)
+ if len(modified) > 0 {
+ rows := make([]*models.Category, 0, len(modified))
+ for _, row := range modified {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(name) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed updating categories", slog.Any("err", err))
+ } else {
+ slog.Info("Updated categories", slog.Int("rows", res.RowsAffected()))
+ }
}
}
// updateDeletedCategory deletes a category from the database
-func updateDeletedCategory(changedFile string) {
- splitted := strings.Split(changedFile, "/")
- id := splitted[0]
-
- category := &models.Category{Name: id}
- _, err := database.DBCon.Model(category).WherePK().Delete()
-
- if err != nil {
- logger.Error.Println("Error during deleting category " + id)
- logger.Error.Println(err)
- }
-
+func updateDeletedCategory(changedFile string) *models.Category {
+ name, _, _ := strings.Cut(changedFile, "/")
+ return &models.Category{Name: name}
}
// updateModifiedCategory adds a category to the database or
// updates it. To do so, it parses the metadata from metadata.xml
-func updateModifiedCategory(changedFile string) {
- splitted := strings.Split(changedFile, "/")
- id := splitted[0]
-
- catmetadata := GetCatMetadata(config.PortDir() + "/" + changedFile)
- description := ""
+func updateModifiedCategory(changedFile string) *models.Category {
+ name, _, _ := strings.Cut(changedFile, "/")
- for _, longdescription := range catmetadata.Longdescriptions {
- if longdescription.Lang == "en" {
- description = strings.TrimSpace(longdescription.Content)
- }
+ xmlFile, err := os.Open(config.PortDir() + "/" + changedFile)
+ if err != nil {
+ slog.Error("Failed reading category metadata", slog.String("category", changedFile), slog.Any("err", err))
+ return nil
}
+ defer xmlFile.Close()
- category := &models.Category{
- Name: id,
- Description: description,
+ var catMetadata CatMetadata
+ err = xml.NewDecoder(xmlFile).Decode(&catMetadata)
+ if err != nil {
+ slog.Error("Error decoding category", slog.String("category", changedFile), slog.Any("err", err))
+ return nil
}
- _, err := database.DBCon.Model(category).OnConflict("(name) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating category " + id)
- logger.Error.Println(err)
+ var description string
+ for _, longDescription := range catMetadata.LongDescriptions {
+ if longDescription.Lang == "en" || longDescription.Lang == "" {
+ description = strings.TrimSpace(longDescription.Content)
+ }
}
-}
-// GetCatMetadata reads and parses the category
-// metadata from the metadata.xml file
-func GetCatMetadata(path string) Catmetadata {
- xmlFile, err := os.Open(path)
- if err != nil {
- logger.Error.Println("Error during reading category metadata")
- logger.Error.Println(err)
+ return &models.Category{
+ Name: name,
+ Description: description,
}
- defer xmlFile.Close()
- byteValue, _ := ioutil.ReadAll(xmlFile)
- var catmetadata Catmetadata
- xml.Unmarshal(byteValue, &catmetadata)
- return catmetadata
}
// Descriptions of the category metadata.xml format
-type Catmetadata struct {
+type CatMetadata struct {
XMLName xml.Name `xml:"catmetadata"`
- Longdescriptions []Longdescription `xml:"longdescription"`
+ LongDescriptions []LongDescription `xml:"longdescription"`
}
-type Longdescription struct {
+type LongDescription struct {
XMLName xml.Name `xml:"longdescription"`
Lang string `xml:"lang,attr"`
Content string `xml:",chardata"`
diff --git a/pkg/portage/repository/commit.go b/pkg/portage/repository/commit.go
index f9ccc7f..17a3371 100644
--- a/pkg/portage/repository/commit.go
+++ b/pkg/portage/repository/commit.go
@@ -3,44 +3,57 @@
package repository
import (
+ "log/slog"
"os/exec"
+ "slices"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
- "strconv"
"strings"
"time"
)
+var (
+ // arrays for collecting date for batch dump into database
+ commits []*models.Commit
+ packages []*models.Package
+ keywordChanges = map[string]*models.KeywordChange{}
+ packagesCommit []*models.CommitToPackage
+ versionsCommits []*models.CommitToVersion
+)
+
// UpdateCommits incrementally imports all new commits. New commits are
// determined by retrieving the last commit in the database (if present)
// and parsing all following commits. In case no last commit is present
// a full import starting with the first commit in the tree is done.
func UpdateCommits() string {
- logger.Info.Println("Start updating commits")
+ slog.Info("Start updating commits")
- latestCommit, PrecedingCommitsOffset := utils.GetLatestCommitAndPreceeding()
+ latestCommit, precedingCommitsOffset := utils.GetLatestCommitAndPreceding()
- for PrecedingCommits, rawCommit := range utils.GetCommits(latestCommit, "HEAD") {
- latestCommit = processCommit(PrecedingCommits, PrecedingCommitsOffset, rawCommit)
+ for precedingCommits, rawCommit := range utils.GetCommits(latestCommit, "HEAD") {
+ latestCommit = processCommit(precedingCommits, precedingCommitsOffset, rawCommit)
+
+ if len(commits) > 10000 {
+ dumpToDatabase()
+ }
}
- logger.Info.Println("Finished updating commits")
+ dumpToDatabase()
+ slog.Info("Finished updating commits")
return latestCommit
}
// processCommit parses a single commit log output and updates it into the database
-func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit string) string {
-
+func processCommit(PrecedingCommits, PrecedingCommitsOffset int, rawCommit string) string {
commitLines := strings.Split(rawCommit, "\n")
if len(commitLines) < 8 {
return ""
}
- logProgess(PrecedingCommits)
+ logProgress(PrecedingCommits)
id := strings.TrimSpace(strings.ReplaceAll(commitLines[0], "commit ", ""))
authorName := strings.TrimSpace(strings.Split(strings.ReplaceAll(commitLines[1], "Author: ", ""), "<")[0])
@@ -59,7 +72,7 @@ func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit s
changedFiles := processChangedFiles(PrecedingCommits, PrecedingCommitsOffset, commitLines, id)
- commit := &models.Commit{
+ commits = append(commits, &models.Commit{
Id: id,
PrecedingCommits: PrecedingCommitsOffset + PrecedingCommits + 1,
AuthorName: authorName,
@@ -70,26 +83,16 @@ func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit s
CommitterDate: committerDate,
Message: message,
ChangedFiles: changedFiles,
- }
-
- _, err := database.DBCon.Model(commit).OnConflict("(id) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating commit: " + id)
- logger.Error.Println(err)
- }
+ })
return id
}
// processChangedFiles parses files that have changed in the commit and links the
// commit to packages and package versions
-func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commitLines []string, id string) *models.ChangedFiles {
- var addedFiles []*models.ChangedFile
- var modifiedFiles []*models.ChangedFile
- var deletedFiles []*models.ChangedFile
+func processChangedFiles(PrecedingCommits, PrecedingCommitsOffset int, commitLines []string, id string) *models.ChangedFiles {
+ var addedFiles, modifiedFiles, deletedFiles []*models.ChangedFile
for _, commitLine := range commitLines {
-
line := strings.Split(commitLine, "\t")
if len(line) < 2 {
continue
@@ -99,25 +102,18 @@ func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commi
path := strings.TrimSpace(line[1])
if strings.HasPrefix(status, "M") {
-
- modifiedFiles = addChangedFile(modifiedFiles, path, "M")
+ modifiedFiles = append(modifiedFiles, &models.ChangedFile{Path: path, ChangeType: "M"})
createKeywordChange(id, path, commitLine)
-
} else if strings.HasPrefix(commitLine, "D") {
-
- deletedFiles = addChangedFile(deletedFiles, path, "D")
-
+ deletedFiles = append(deletedFiles, &models.ChangedFile{Path: path, ChangeType: "D"})
} else if strings.HasPrefix(commitLine, "A") {
-
- addedFiles = addChangedFile(addedFiles, path, "A")
+ addedFiles = append(addedFiles, &models.ChangedFile{Path: path, ChangeType: "A"})
updateFirstCommitOfPackage(path, commitLine, PrecedingCommitsOffset+PrecedingCommits+1)
createAddedKeywords(id, path, commitLine)
-
}
linkCommitToPackage(commitLine, path, id)
linkCommitToVersion(commitLine, path, id)
-
}
return &models.ChangedFiles{
@@ -127,116 +123,91 @@ func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commi
}
}
-// logProgess logs the progress of a loop
-func logProgess(counter int) {
+// logProgress logs the progress of a loop
+func logProgress(counter int) {
if counter%1000 == 0 {
- logger.Info.Println("Processed commits: " + strconv.Itoa(counter))
+ slog.Info("Processed commits", slog.Int("commits", counter))
} else if counter == 1 {
// The initial commit is *huge* that's why we log it as well
- logger.Info.Println("Processed first commit.")
+ slog.Info("Processed first commit.")
}
}
-func linkCommitToPackage(commitLine string, path string, id string) {
- var commitToPackage *models.CommitToPackage
+func linkCommitToPackage(commitLine, path, id string) {
if (len(strings.Split(commitLine, "/")) >= 3) &&
(strings.HasPrefix(commitLine, "M") ||
strings.HasPrefix(commitLine, "D") ||
strings.HasPrefix(commitLine, "A")) {
- pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")
+ pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")
- commitToPackageId := id + "-" + pathParts[0] + "/" + strings.Split(commitLine, "/")[1]
- commitToPackage = &models.CommitToPackage{
- Id: commitToPackageId,
+ packageAtom := pathParts[0] + "/" + strings.Split(commitLine, "/")[1]
+ packagesCommit = append(packagesCommit, &models.CommitToPackage{
+ Id: id + "-" + packageAtom,
CommitId: id,
- PackageAtom: pathParts[0] + "/" + strings.Split(commitLine, "/")[1],
- }
-
- _, err := database.DBCon.Model(commitToPackage).OnConflict("(id) DO NOTHING").Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating CommitToPackage: " + commitToPackageId)
- logger.Error.Println(err)
- }
-
+ PackageAtom: packageAtom,
+ })
}
}
-func linkCommitToVersion(commitLine string, path string, id string) {
- var commitToVersion *models.CommitToVersion
+func linkCommitToVersion(commitLine, path, id string) {
if (strings.HasPrefix(commitLine, "M") ||
strings.HasPrefix(commitLine, "D") ||
strings.HasPrefix(commitLine, "A")) &&
- len(strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")) == 3 &&
+ len(strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")) == 3 &&
strings.HasSuffix(strings.TrimSpace(strings.Split(commitLine, "\t")[1]), ".ebuild") {
- pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")
+ pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")
- commitToVersionId := id + "-" + pathParts[0] + "/" + pathParts[2]
- commitToVersion = &models.CommitToVersion{
- Id: commitToVersionId,
+ versionId := pathParts[0] + "/" + pathParts[2]
+ versionsCommits = append(versionsCommits, &models.CommitToVersion{
+ Id: id + "-" + versionId,
CommitId: id,
- VersionId: pathParts[0] + "/" + pathParts[2],
- }
-
- _, err := database.DBCon.Model(commitToVersion).OnConflict("(id) DO NOTHING").Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating CommitToVersion: " + commitToVersionId)
- logger.Error.Println(err)
- }
-
+ VersionId: versionId,
+ })
}
}
-func createKeywordChange(id string, path string, commitLine string) {
-
- if !strings.HasSuffix(path, ".ebuild") || !(len(strings.Split(commitLine, "/")) >= 3) {
+func createKeywordChange(id, path, commitLine string) {
+ if !strings.HasSuffix(path, ".ebuild") || !(strings.Count(commitLine, "/") >= 2) {
return
}
- var change *models.KeywordChange
-
raw_lines, err := utils.Exec(config.PortDir(), "git", "show", id, "--", path)
if err != nil {
if exitError, ok := err.(*exec.ExitError); !ok || exitError.ExitCode() != 1 {
- logger.Error.Println("Problem parsing file")
+ slog.Error("Failed running git show", slog.String("id", id), slog.String("path", path), slog.Any("err", err))
return
}
}
- var keywords_old []string
- var keywords_new []string
+ var keywords_old, keywords_new []string
for _, line := range raw_lines {
if strings.HasPrefix(line, "-KEYWORDS=") {
- keywords_old = strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "-KEYWORDS=", ""), "\"", ""), " ")
-
+ keywords_old = strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "-KEYWORDS="), "\"", ""), " ")
} else if strings.HasPrefix(line, "+KEYWORDS") {
- keywords_new = strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "+KEYWORDS=", ""), "\"", ""), " ")
+ keywords_new = strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "+KEYWORDS="), "\"", ""), " ")
}
}
- var added_keywords []string
- var stabilized_keywords []string
+ var added_keywords, stabilized_keywords []string
if keywords_old != nil && keywords_new != nil {
-
for _, keyword := range keywords_new {
- if !utils.Contains(keywords_old, keyword) {
+ if !slices.Contains(keywords_old, keyword) {
added_keywords = append(added_keywords, keyword)
}
- if !strings.HasPrefix(keyword, "~") && utils.Contains(keywords_old, ("~"+keyword)) {
+ if !strings.HasPrefix(keyword, "~") && slices.Contains(keywords_old, "~"+keyword) {
stabilized_keywords = append(stabilized_keywords, keyword)
}
}
- pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")
+ pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")
keywordChangeId := id + "-" + strings.TrimSpace(strings.Split(commitLine, "\t")[1])
- change = &models.KeywordChange{
+ keywordChanges[keywordChangeId] = &models.KeywordChange{
Id: keywordChangeId,
CommitId: id,
VersionId: pathParts[0] + "/" + pathParts[2],
@@ -245,39 +216,28 @@ func createKeywordChange(id string, path string, commitLine string) {
Stabilized: stabilized_keywords,
All: keywords_new,
}
-
- _, err := database.DBCon.Model(change).OnConflict("(id) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Println("Error updating Keyword change: " + keywordChangeId)
- logger.Error.Println(err)
- }
-
}
}
func createAddedKeywords(id string, path string, commitLine string) {
- var change *models.KeywordChange
if strings.HasSuffix(strings.TrimSpace(strings.Split(commitLine, "\t")[1]), ".ebuild") &&
- (len(strings.Split(commitLine, "/")) >= 3) {
+ (strings.Count(commitLine, "/") >= 2) {
raw_lines, err := utils.Exec(config.PortDir(), "git", "show", id, "--", path)
if err != nil {
if exitError, ok := err.(*exec.ExitError); !ok || exitError.ExitCode() != 1 {
- logger.Error.Println("Problem parsing file")
- logger.Error.Println(exitError)
+ slog.Error("Failed running git show", slog.String("id", id), slog.String("path", path), slog.Any("err", err))
return
}
}
for _, line := range raw_lines {
if strings.HasPrefix(line, "+KEYWORDS=") {
-
- pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")
- keywords := strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "+KEYWORDS=", ""), "\"", ""), " ")
+ pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")
+ keywords := strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "+KEYWORDS="), "\"", ""), " ")
keywordChangeId := id + "-" + strings.TrimSpace(strings.Split(commitLine, "\t")[1])
- change = &models.KeywordChange{
+ keywordChanges[keywordChangeId] = &models.KeywordChange{
Id: keywordChangeId,
CommitId: id,
VersionId: pathParts[0] + "/" + pathParts[2],
@@ -285,14 +245,6 @@ func createAddedKeywords(id string, path string, commitLine string) {
Added: keywords,
All: keywords,
}
-
- _, err := database.DBCon.Model(change).OnConflict("(id) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Println("Error updating Keyword change: " + keywordChangeId)
- logger.Error.Println(err)
- }
-
}
}
@@ -301,26 +253,64 @@ func createAddedKeywords(id string, path string, commitLine string) {
func updateFirstCommitOfPackage(path string, commitLine string, precedingCommits int) {
// Added Package
- if strings.HasSuffix(path, "metadata.xml") && len(strings.Split(path, "/")) == 3 {
-
+ if strings.HasSuffix(path, "metadata.xml") && strings.Count(commitLine, "/") == 2 {
atom := strings.Split(path, "/")[0] + "/" + strings.Split(path, "/")[1]
- addedpackage := &models.Package{
+ packages = append(packages, &models.Package{
Atom: atom,
PrecedingCommits: precedingCommits,
+ })
+ }
+}
+
+func dumpToDatabase() {
+ slog.Info("Writing to database",
+ slog.Int("KeywordChange", len(keywordChanges)),
+ slog.Int("Package", len(packages)),
+ slog.Int("CommitToPackage", len(packagesCommit)),
+ slog.Int("CommitToVersion", len(versionsCommits)),
+ slog.Int("Commit", len(commits)))
+
+ if len(keywordChanges) > 0 {
+ rows := make([]*models.KeywordChange, 0, len(keywordChanges))
+ for _, keywordChange := range keywordChanges {
+ rows = append(rows, keywordChange)
+ }
+ _, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed inserting KeywordChange", slog.Any("err", err))
}
+ clear(keywordChanges)
+ }
- _, err := database.DBCon.Model(addedpackage).Column("preceding_commits").WherePK().Update()
+ if len(packages) > 0 {
+ _, err := database.DBCon.Model(&packages).Column("preceding_commits").Update()
if err != nil {
- logger.Error.Println("Error updating precedingCommits (" + strconv.Itoa(precedingCommits) + ") of package: " + atom)
- logger.Error.Println(err)
+ slog.Error("Failed inserting Package", slog.Any("err", err))
}
+ packages = packages[:0]
+ }
+ if len(packagesCommit) > 0 {
+ _, err := database.DBCon.Model(&packagesCommit).OnConflict("(id) DO NOTHING").Insert()
+ if err != nil {
+ slog.Error("Failed inserting CommitToPackage", slog.Any("err", err))
+ }
+ packagesCommit = packagesCommit[:0]
}
-}
-func addChangedFile(changedFiles []*models.ChangedFile, path string, status string) []*models.ChangedFile {
- return append(changedFiles, &models.ChangedFile{
- Path: path,
- ChangeType: status,
- })
+ if len(versionsCommits) > 0 {
+ _, err := database.DBCon.Model(&versionsCommits).OnConflict("(id) DO NOTHING").Insert()
+ if err != nil {
+ slog.Error("Failed inserting CommitToVersion", slog.Any("err", err))
+ }
+ versionsCommits = versionsCommits[:0]
+ }
+
+ if len(commits) > 0 {
+ _, err := database.DBCon.Model(&commits).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed inserting Commit", slog.Any("err", err))
+ }
+ commits = commits[:0]
+ }
}
diff --git a/pkg/portage/repository/deprecated.go b/pkg/portage/repository/deprecated.go
new file mode 100644
index 0000000..594c553
--- /dev/null
+++ b/pkg/portage/repository/deprecated.go
@@ -0,0 +1,154 @@
+// Contains functions to import package deprecated entries into the database
+//
+// Example
+//
+// ## # Dev E. Loper <developer@gentoo.org> (2019-07-01)
+// ## # Deprecated upstream, see HOMEPAGE
+// ## dev-perl/Mail-Sender
+//
+
+package repository
+
+import (
+ "log/slog"
+ "soko/pkg/config"
+ "soko/pkg/database"
+ "soko/pkg/models"
+ "soko/pkg/portage/utils"
+ "strings"
+
+ "github.com/a-h/templ"
+ "github.com/go-pg/pg/v10"
+)
+
+// isPackagesDeprecated checks whether the path
+// points to a package.mask file
+func isPackagesDeprecated(path string) bool {
+ return path == "profiles/package.deprecated"
+}
+
+// UpdatePackagesDeprecated updates all entries in
+// the Deprecated table in the database
+func UpdatePackagesDeprecated(path string) {
+
+ splittedLine := strings.Split(path, "\t")
+
+ var status, changedFile string
+ switch len(splittedLine) {
+ case 2:
+ status = splittedLine[0]
+ changedFile = splittedLine[1]
+ case 1:
+ // This happens in case of a full update
+ status = "A"
+ changedFile = splittedLine[0]
+ default:
+ // should not happen
+ return
+ }
+
+ if status != "D" && isPackagesDeprecated(changedFile) {
+ slog.Info("Updating package.deprecated")
+
+ // delete all existing entries before parsing the file again
+ // in future we might implement a incremental version here
+ database.TruncateTable((*models.DeprecatedPackage)(nil))
+
+ for _, entry := range getDeprecatedPackages(changedFile) {
+ parsePackagesDeprecated(entry)
+ }
+ }
+}
+
+// parse the package.mask entries and
+// update the DeprecatedPackage table in the database
+func parsePackagesDeprecated(entry string) {
+ packageLines := strings.Split(entry, "\n")
+ if len(packageLines) >= 3 {
+ packageLine, packageLines := packageLines[0], packageLines[1:]
+ author, authorEmail, date := parseAuthorLine(packageLine)
+
+ var reason string
+ packageLine, packageLines = packageLines[0], packageLines[1:]
+ for strings.HasPrefix(packageLine, "#") {
+ if packageLine == "#" {
+ reason += "<br />"
+ } else {
+ reason = reason + " " + templ.EscapeString(strings.TrimPrefix(packageLine, "# "))
+ }
+ packageLine, packageLines = packageLines[0], packageLines[1:]
+ }
+
+ reason = bugListMatcher.ReplaceAllStringFunc(reason, func(bugList string) string {
+ return bugReplacer.ReplaceAllString(bugList, `<a href="https://bugs.gentoo.org/$1">$0</a>`)
+ })
+
+ packageLines = append(packageLines, packageLine)
+
+ for _, version := range packageLines {
+ entry := &models.DeprecatedPackage{
+ Author: strings.TrimSpace(author),
+ AuthorEmail: strings.TrimSpace(authorEmail),
+ Date: date,
+ Reason: strings.TrimSpace(reason),
+ Versions: version,
+ }
+
+ _, err := database.DBCon.Model(entry).OnConflict("(versions) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed inserting/updating package deprecated entry", slog.Any("err", err))
+ }
+ }
+ }
+
+}
+
+// get all entries from the package.deprecated file
+func getDeprecatedPackages(path string) []string {
+ var deprecates []string
+ lines, err := utils.ReadLines(config.PortDir() + "/" + path)
+ if err != nil {
+ slog.Error("Could not read package.deprecated file. Abort deprecated import", slog.Any("err", err))
+ return deprecates
+ }
+
+ line, lines := lines[0], lines[1:]
+ for !strings.Contains(line, "#--- END OF EXAMPLES ---") {
+ line, lines = lines[0], lines[1:]
+ }
+ lines = lines[1:]
+
+ return strings.Split(strings.Join(lines, "\n"), "\n\n")
+}
+
+// Calculate all versions that are currently
+// deprecated and update the DeprecatedToVersion Table
+func CalculateDeprecatedToVersion() {
+ database.TruncateTable((*models.DeprecatedToVersion)(nil))
+
+ var deprecates []*models.DeprecatedPackage
+ err := database.DBCon.Model(&deprecates).Select()
+ if err != nil && err != pg.ErrNoRows {
+ slog.Error("Failed to retrieve package masks. Aborting update", slog.Any("err", err))
+ return
+ }
+
+ for _, deprecate := range deprecates {
+ versionSpecifier := deprecate.Versions
+ packageAtom := versionSpecifierToPackageAtom(versionSpecifier)
+ versions := utils.CalculateAffectedVersions(versionSpecifier, packageAtom)
+
+ for _, version := range versions {
+ depToVersion := &models.DeprecatedToVersion{
+ Id: versionSpecifier + "-" + version.Id,
+ DeprecatedVersions: versionSpecifier,
+ VersionId: version.Id,
+ }
+
+ _, err := database.DBCon.Model(depToVersion).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed inserting/updating deprecated to version entry", slog.Any("err", err))
+ }
+ }
+ }
+}
diff --git a/pkg/portage/repository/mask.go b/pkg/portage/repository/mask.go
index 8a480b9..c6b500c 100644
--- a/pkg/portage/repository/mask.go
+++ b/pkg/portage/repository/mask.go
@@ -12,14 +12,17 @@
package repository
import (
- "github.com/go-pg/pg/v9"
+ "log/slog"
"regexp"
+ "soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
"strings"
"time"
+
+ "github.com/a-h/templ"
+ "github.com/go-pg/pg/v10"
)
// isMask checks whether the path
@@ -35,25 +38,25 @@ func UpdateMask(path string) {
splittedLine := strings.Split(path, "\t")
var status, changedFile string
- if len(splittedLine) == 2 {
+ switch len(splittedLine) {
+ case 2:
status = splittedLine[0]
changedFile = splittedLine[1]
- } else if len(splittedLine) == 1 {
+ case 1:
// This happens in case of a full update
status = "A"
changedFile = splittedLine[0]
- } else {
+ default:
// should not happen
return
}
if status != "D" && isMask(changedFile) {
-
- logger.Info.Println("Updating Masks")
+ slog.Info("Updating Masks")
// delete all existing masks before parsing the file again
// in future we might implement a incremental version here
- deleteAllMasks()
+ database.TruncateTable((*models.Mask)(nil))
for _, packageMask := range getMasks(changedFile) {
parsePackageMask(packageMask)
@@ -61,6 +64,8 @@ func UpdateMask(path string) {
}
}
+var versionNumber = regexp.MustCompile(`-[0-9]`)
+
// versionSpecifierToPackageAtom returns the package atom from a given version specifier
func versionSpecifierToPackageAtom(versionSpecifier string) string {
gpackage := strings.ReplaceAll(versionSpecifier, ">", "")
@@ -69,9 +74,7 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string {
gpackage = strings.ReplaceAll(gpackage, "~", "")
gpackage = strings.Split(gpackage, ":")[0]
-
- versionnumber := regexp.MustCompile(`-[0-9]`)
- gpackage = versionnumber.Split(gpackage, 2)[0]
+ gpackage = versionNumber.Split(gpackage, 2)[0]
return gpackage
}
@@ -79,10 +82,8 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string {
// parseAuthorLine parses the first line in the package.mask file
// and returns the author name, author email and the date
func parseAuthorLine(authorLine string) (string, string, time.Time) {
-
if !(strings.Contains(authorLine, "<") && strings.Contains(authorLine, ">")) {
- logger.Error.Println("Error while parsing the author line in mask entry:")
- logger.Error.Println(authorLine)
+ slog.Error("Error while parsing the author line in mask entry", slog.String("authorLine", authorLine))
return "", "", time.Now()
}
@@ -94,12 +95,15 @@ func parseAuthorLine(authorLine string) (string, string, time.Time) {
date = strings.ReplaceAll(date, ")", "")
parsedDate, err := time.Parse("2006-01-02", date)
if err != nil {
- logger.Error.Println("Error while parsing package mask date: " + date)
- logger.Error.Println(err)
+ slog.Error("Failed parsing package mask date", slog.String("date", date), slog.Any("err", err))
}
return author, authorEmail, parsedDate
}
+// based on regex from GLEP-0084
+var bugListMatcher = regexp.MustCompile(`[Bb]ugs? +#\d+(,? +#\d+)*`)
+var bugReplacer = regexp.MustCompile(`#(\d+)`)
+
// parse the package.mask entries and
// update the Mask table in the database
func parsePackageMask(packageMask string) {
@@ -108,29 +112,35 @@ func parsePackageMask(packageMask string) {
packageMaskLine, packageMaskLines := packageMaskLines[0], packageMaskLines[1:]
author, authorEmail, date := parseAuthorLine(packageMaskLine)
- reason := ""
+ var reason string
packageMaskLine, packageMaskLines = packageMaskLines[0], packageMaskLines[1:]
for strings.HasPrefix(packageMaskLine, "#") {
- reason = reason + " " + strings.Replace(packageMaskLine, "# ", "", 1)
+ if packageMaskLine == "#" {
+ reason += "<br />"
+ } else {
+ reason = reason + " " + templ.EscapeString(strings.TrimPrefix(packageMaskLine, "# "))
+ }
packageMaskLine, packageMaskLines = packageMaskLines[0], packageMaskLines[1:]
}
+ reason = bugListMatcher.ReplaceAllStringFunc(reason, func(bugList string) string {
+ return bugReplacer.ReplaceAllString(bugList, `<a href="https://bugs.gentoo.org/$1">$0</a>`)
+ })
+
packageMaskLines = append(packageMaskLines, packageMaskLine)
for _, version := range packageMaskLines {
- useflag := &models.Mask{
- Author: author,
- AuthorEmail: authorEmail,
+ mask := &models.Mask{
+ Author: strings.TrimSpace(author),
+ AuthorEmail: strings.TrimSpace(authorEmail),
Date: date,
- Reason: reason,
+ Reason: strings.TrimSpace(reason),
Versions: version,
}
- _, err := database.DBCon.Model(useflag).OnConflict("(versions) DO UPDATE").Insert()
-
+ _, err := database.DBCon.Model(mask).OnConflict("(versions) DO UPDATE").Insert()
if err != nil {
- logger.Error.Println("Error while inserting/updating package mask entry")
- logger.Error.Println(err)
+ slog.Error("Failed inserting/updating package mask entry", slog.Any("err", err))
}
}
}
@@ -140,11 +150,10 @@ func parsePackageMask(packageMask string) {
// get all mask entries from the package.mask file
func getMasks(path string) []string {
var masks []string
- lines, err := utils.ReadLines(path)
+ lines, err := utils.ReadLines(config.PortDir() + "/" + path)
if err != nil {
- logger.Error.Println("Could not read Masks file. Abort masks import")
- logger.Error.Println(err)
+ slog.Error("Could not read Masks file. Abort masks import", slog.Any("err", err))
return masks
}
@@ -160,128 +169,26 @@ func getMasks(path string) []string {
// Calculate all versions that are currently
// masked and update the MaskToVersion Table
func CalculateMaskedVersions() {
-
// clean up all masked versions before recalculating them
- deleteAllMasksToVersion()
+ database.TruncateTable((*models.MaskToVersion)(nil))
var masks []*models.Mask
err := database.DBCon.Model(&masks).Select()
if err != nil && err != pg.ErrNoRows {
- logger.Error.Println("Failed to retrieve package masks. Aborting update")
- logger.Error.Println(err)
+ slog.Error("Failed to retrieve package masks. Aborting update", slog.Any("err", err))
+ return
}
for _, mask := range masks {
versionSpecifier := mask.Versions
packageAtom := versionSpecifierToPackageAtom(versionSpecifier)
- var versions []*models.Version
-
- if strings.HasPrefix(versionSpecifier, "=") {
- versions = exaktVersion(versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "<=") {
- versions = comparedVersions("<=", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "<") {
- versions = comparedVersions("<", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, ">=") {
- versions = comparedVersions(">=", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, ">") {
- versions = comparedVersions(">", versionSpecifier, packageAtom)
- } else if strings.HasPrefix(versionSpecifier, "~") {
- versions = allRevisions(versionSpecifier, packageAtom)
- } else if strings.Contains(versionSpecifier, ":") {
- versions = versionsWithSlot(versionSpecifier, packageAtom)
- } else {
- versions = allVersions(versionSpecifier, packageAtom)
- }
-
+ versions := utils.CalculateAffectedVersions(versionSpecifier, packageAtom)
maskVersions(versionSpecifier, versions)
}
}
-// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version
-func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version {
- var results []*models.Version
- var versions []*models.Version
- versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "")
- versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "")
- versionSpecifier = strings.Split(versionSpecifier, ":")[0]
-
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Select()
-
- for _, v := range versions {
- givenVersion := models.Version{Version: versionSpecifier}
- if operator == ">" {
- if v.GreaterThan(givenVersion) {
- results = append(results, v)
- }
- } else if operator == ">=" {
- if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) {
- results = append(results, v)
- }
- } else if operator == "<" {
- if v.SmallerThan(givenVersion) {
- results = append(results, v)
- }
- } else if operator == "<=" {
- if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) {
- results = append(results, v)
- }
- }
- }
- return results
-}
-
-// allRevisions returns all revisions of the given version
-func allRevisions(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- revision := regexp.MustCompile(`-r[0-9]*$`)
- versionWithoutRevision := revision.Split(versionSpecifier, 1)[0]
- versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "")
- database.DBCon.Model(&versions).
- Where("id LIKE ?", versionWithoutRevision+"%").
- Select()
-
- return versions
-}
-
-// exaktVersion returns the exact version specified in the versionSpecifier
-func exaktVersion(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- database.DBCon.Model(&versions).
- Where("id = ?", strings.Replace(versionSpecifier, "=", "", 1)).
- Select()
-
- return versions
-}
-
-// TODO include subslot
-// versionsWithSlot returns all versions with the given slot
-func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- slot := strings.Split(versionSpecifier, ":")[1]
-
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Where("slot = ?", slot).
- Select()
-
- return versions
-}
-
-// allVersions returns all versions of the given package
-func allVersions(versionSpecifier string, packageAtom string) []*models.Version {
- var versions []*models.Version
- database.DBCon.Model(&versions).
- Where("atom = ?", packageAtom).
- Select()
- return versions
-}
-
// maskVersions updates the MaskToVersion table using the given versions
func maskVersions(versionSpecifier string, versions []*models.Version) {
-
for _, version := range versions {
maskToVersion := &models.MaskToVersion{
Id: versionSpecifier + "-" + version.Id,
@@ -291,27 +198,8 @@ func maskVersions(versionSpecifier string, versions []*models.Version) {
_, err := database.DBCon.Model(maskToVersion).OnConflict("(id) DO UPDATE").Insert()
- if err != nil{
- logger.Error.Println("Error while inserting mask to version entry")
- logger.Error.Println(err)
+ if err != nil {
+ slog.Error("Error while inserting mask to version entry", slog.Any("err", err))
}
}
}
-
-// deleteAllMasks deletes all entries in the mask table
-func deleteAllMasksToVersion() {
- var masks []*models.MaskToVersion
- database.DBCon.Model(&masks).Select()
- for _, mask := range masks {
- database.DBCon.Model(mask).WherePK().Delete()
- }
-}
-
-// deleteAllMasks deletes all entries in the mask table
-func deleteAllMasks() {
- var masks []*models.Mask
- database.DBCon.Model(&masks).Select()
- for _, mask := range masks {
- database.DBCon.Model(mask).WherePK().Delete()
- }
-}
diff --git a/pkg/portage/repository/package.go b/pkg/portage/repository/package.go
index b67888e..09c060e 100644
--- a/pkg/portage/repository/package.go
+++ b/pkg/portage/repository/package.go
@@ -4,12 +4,11 @@ package repository
import (
"encoding/xml"
- "io/ioutil"
+ "log/slog"
"os"
"regexp"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"strings"
)
@@ -17,93 +16,141 @@ import (
// isPackage checks whether the path points to a package
// descriptions that is an metadata.xml file
func isPackage(path string) bool {
- isPackage, _ := regexp.MatchString(`[^/]*\/[^/]*\/metadata\.xml`, path)
+ isPackage, _ := regexp.MatchString(`^[^/]*\/[^/]*\/metadata\.xml$`, path)
return isPackage
}
-// UpdatePackage updates the package in the database in case
-// the given path points to a package description
-func UpdatePackage(path string) {
-
- splittedLine := strings.Split(path, "\t")
+// UpdatePackages updates the packages in the database for each
+// given path that points to a package description
+func UpdatePackages(paths []string) {
+ deleted := map[string]*models.Package{}
+ modified := map[string]*models.Package{}
+
+ for _, path := range paths {
+ splittedLine := strings.Split(path, "\t")
+
+ if len(splittedLine) != 2 {
+ if len(splittedLine) == 1 && isPackage(path) {
+ if pkg := updateModifiedPackage(path); pkg != nil {
+ modified[pkg.Atom] = pkg
+ }
+ }
+ continue
+ }
- if len(splittedLine) != 2 {
- if len(splittedLine) == 1 && isPackage(path) {
- updateModifiedPackage(path)
+ status := splittedLine[0]
+ changedFile := splittedLine[1]
+
+ if !isPackage(changedFile) {
+ continue
+ } else if status == "D" {
+ pkg := updateDeletedPackage(changedFile)
+ deleted[pkg.Atom] = pkg
+ } else if status == "A" || status == "M" {
+ if pkg := updateModifiedPackage(changedFile); pkg != nil {
+ modified[pkg.Atom] = pkg
+ }
}
- return
}
- status := splittedLine[0]
- changedFile := splittedLine[1]
+ if len(deleted) > 0 {
+ rows := make([]*models.Package, 0, len(deleted))
+ for _, row := range deleted {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).Delete()
+ if err != nil {
+ slog.Error("Failed deleting packages", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted packages", slog.Int("rows", res.RowsAffected()))
+ }
+ }
- if isPackage(changedFile) && status == "D" {
- updateDeletedPackage(changedFile)
- } else if isPackage(changedFile) && (status == "A" || status == "M") {
- updateModifiedPackage(changedFile)
+ if len(modified) > 0 {
+ rows := make([]*models.Package, 0, len(modified))
+ for _, row := range modified {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(atom) DO UPDATE").
+ Set("atom = EXCLUDED.atom").
+ Set("category = EXCLUDED.category").
+ Set("name = EXCLUDED.name").
+ Set("longdescription = EXCLUDED.longdescription").
+ Set("maintainers = EXCLUDED.maintainers").
+ Set("upstream = EXCLUDED.upstream").
+ Insert()
+ if err != nil {
+ slog.Error("Failed updating packages", slog.Any("err", err))
+ } else {
+ slog.Info("Updated packages", slog.Int("rows", res.RowsAffected()))
+ }
}
}
// updateDeletedPackage deletes a package from the database
-func updateDeletedPackage(changedFile string) {
+func updateDeletedPackage(changedFile string) *models.Package {
splitted := strings.Split(changedFile, "/")
category := splitted[0]
packagename := splitted[1]
atom := category + "/" + packagename
- gpackage := &models.Package{Atom: atom}
- _, err := database.DBCon.Model(gpackage).WherePK().Delete()
-
- if err != nil {
- logger.Error.Println("Error during deleting package " + atom)
- logger.Error.Println(err)
- }
+ return &models.Package{Atom: atom}
}
// updateModifiedPackage adds a package to the database or
// updates it. To do so, it parses the metadata from metadata.xml
-func updateModifiedPackage(changedFile string) {
+func updateModifiedPackage(changedFile string) *models.Package {
splitted := strings.Split(changedFile, "/")
category := splitted[0]
packagename := splitted[1]
atom := category + "/" + packagename
- pkgmetadata := GetPkgMetadata(config.PortDir() + "/" + atom + "/metadata.xml")
- var maintainers []*models.Maintainer
+ xmlFile, err := os.Open(config.PortDir() + "/" + atom + "/metadata.xml")
+ if err != nil {
+ slog.Error("Failed reading package metadata", slog.String("atom", atom), slog.Any("err", err))
+ return nil
+ }
+ defer xmlFile.Close()
+ var pkgMetadata PkgMetadata
+ err = xml.NewDecoder(xmlFile).Decode(&pkgMetadata)
+ if err != nil {
+ slog.Error("Failed decoding package metadata", slog.String("atom", atom), slog.Any("err", err))
+ return nil
+ }
- for _, maintainer := range pkgmetadata.MaintainerList {
- maintainer := &models.Maintainer{
- Name: maintainer.Name,
- Type: maintainer.Type,
- Email: maintainer.Email,
+ maintainers := make([]*models.Maintainer, len(pkgMetadata.MaintainerList))
+ for i, maintainer := range pkgMetadata.MaintainerList {
+ maintainers[i] = &models.Maintainer{
+ Name: strings.TrimSpace(maintainer.Name),
+ Type: strings.TrimSpace(maintainer.Type),
+ Email: strings.TrimSpace(maintainer.Email),
Restrict: maintainer.Restrict,
}
- maintainers = append(maintainers, maintainer)
}
- longDescription := ""
- for _, l := range pkgmetadata.LongdescriptionList {
- if l.Language == "" {
+ var longDescription string
+ for _, l := range pkgMetadata.LongDescriptionList {
+ if l.Language == "" || l.Language == "en" {
longDescription = l.Content
}
}
- remoteIds := []models.RemoteId{}
- for _, r := range pkgmetadata.Upstream.RemoteIds {
- remoteIds = append(remoteIds, models.RemoteId{
+ remoteIds := make([]models.RemoteId, len(pkgMetadata.Upstream.RemoteIds))
+ for i, r := range pkgMetadata.Upstream.RemoteIds {
+ remoteIds[i] = models.RemoteId{
Type: r.Type,
Id: r.Content,
- })
+ }
}
upstream := models.Upstream{
RemoteIds: remoteIds,
- Doc: pkgmetadata.Upstream.Doc,
- BugsTo: pkgmetadata.Upstream.BugsTo,
- Changelog: pkgmetadata.Upstream.Changelog,
+ Doc: pkgMetadata.Upstream.Doc,
+ BugsTo: pkgMetadata.Upstream.BugsTo,
+ Changelog: pkgMetadata.Upstream.Changelog,
}
- gpackage := &models.Package{
+ return &models.Package{
Atom: atom,
Category: category,
Name: packagename,
@@ -111,42 +158,14 @@ func updateModifiedPackage(changedFile string) {
Maintainers: maintainers,
Upstream: upstream,
}
-
- _, err := database.DBCon.Model(gpackage).OnConflict("(atom) DO UPDATE").
- Set("atom = EXCLUDED.atom").
- Set("category = EXCLUDED.category").
- Set("name = EXCLUDED.name").
- Set("longdescription = EXCLUDED.longdescription").
- Set("maintainers = EXCLUDED.maintainers").
- Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating package " + atom)
- logger.Error.Println(err)
- }
-}
-
-// GetPkgMetadata reads and parses the package
-// metadata from the metadata.xml file
-func GetPkgMetadata(path string) Pkgmetadata {
- xmlFile, err := os.Open(path)
- if err != nil {
- logger.Error.Println("Error during reading package metadata")
- logger.Error.Println(err)
- }
- defer xmlFile.Close()
- byteValue, _ := ioutil.ReadAll(xmlFile)
- var pkgmetadata Pkgmetadata
- xml.Unmarshal(byteValue, &pkgmetadata)
- return pkgmetadata
}
// Descriptions of the package metadata.xml format
-type Pkgmetadata struct {
+type PkgMetadata struct {
XMLName xml.Name `xml:"pkgmetadata"`
MaintainerList []Maintainer `xml:"maintainer"`
- LongdescriptionList []LongdescriptionItem `xml:"longdescription"`
+ LongDescriptionList []LongDescriptionItem `xml:"longdescription"`
Upstream Upstream `xml:"upstream"`
}
@@ -158,7 +177,7 @@ type Maintainer struct {
Name string `xml:"name"`
}
-type LongdescriptionItem struct {
+type LongDescriptionItem struct {
XMLName xml.Name `xml:"longdescription"`
Content string `xml:",chardata"`
Language string `xml:"lang,attr"`
diff --git a/pkg/portage/repository/use.go b/pkg/portage/repository/use.go
index 5aa2798..a05e589 100644
--- a/pkg/portage/repository/use.go
+++ b/pkg/portage/repository/use.go
@@ -3,9 +3,9 @@
package repository
import (
+ "log/slog"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
"strings"
@@ -15,18 +15,18 @@ import (
// case the given file contains USE flags descriptions and imports
// each USE flag into the database
func UpdateUse(path string) {
-
splittedLine := strings.Split(path, "\t")
var status, changedFile string
- if len(splittedLine) == 2 {
+ switch len(splittedLine) {
+ case 2:
status = splittedLine[0]
changedFile = splittedLine[1]
- } else if len(splittedLine) == 1 {
+ case 1:
// This happens in case of a full update
status = "A"
changedFile = splittedLine[0]
- } else {
+ default:
// should not happen
return
}
@@ -34,28 +34,35 @@ func UpdateUse(path string) {
if status != "D" && (isLocalUseflag(changedFile) || isGlobalUseflag(changedFile) || isUseExpand(changedFile)) {
rawFlags, _ := utils.ReadLines(config.PortDir() + "/" + changedFile)
+ scope := getScope(changedFile)
+ useFlags := make(map[string]*models.Useflag, len(rawFlags))
for _, rawFlag := range rawFlags {
-
- if strings.TrimSpace(rawFlag) == "" || rawFlag[0:1] == "#" {
+ if strings.TrimSpace(rawFlag) == "" || rawFlag[0] == '#' {
continue
}
-
- scope := getScope(changedFile)
-
- var err error
- if scope == "local" || scope == "global" {
- err = createUseflag(rawFlag, scope)
- } else if scope == "use_expand" {
+ switch scope {
+ case "local", "global":
+ if flag := createUseflag(rawFlag, scope); flag != nil {
+ useFlags[flag.Id] = flag
+ }
+ case "use_expand":
file := strings.Split(changedFile, "/")[2]
- err = createUseExpand(rawFlag, file)
+ flag := createUseExpand(rawFlag, file)
+ useFlags[flag.Id] = flag
}
+ }
+ if len(useFlags) > 0 {
+ rows := make([]*models.Useflag, 0, len(useFlags))
+ for _, row := range useFlags {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert()
if err != nil {
- logger.Info.Println("Error during updating useflag " + rawFlag)
- logger.Info.Println(err)
- logger.Error.Println("Error during updating useflag " + rawFlag)
- logger.Error.Println(err)
+ slog.Error("Failed updating use flags", slog.Any("err", err))
+ } else {
+ slog.Info("Updated use flags", slog.Int("rows", res.RowsAffected()))
}
}
}
@@ -64,46 +71,42 @@ func UpdateUse(path string) {
// createUseflag parses the description from the file,
// creates a USE flag and imports it into the database
-func createUseflag(rawFlag string, scope string) error {
- line := strings.Split(rawFlag, " - ")
- splitted := strings.Split(line[0], ":")
- gpackage := ""
+func createUseflag(rawFlag string, scope string) *models.Useflag {
+ pkguse, description, found := strings.Cut(rawFlag, " - ")
+ if !found {
+ return nil
+ }
- if scope == "local" {
- gpackage = splitted[0]
+ pkg, use, found := strings.Cut(pkguse, ":")
+ if found != (scope == "local") {
+ return nil
+ } else if !found {
+ use = pkguse
}
- useflag := &models.Useflag{
- Id: line[0] + "-" + scope,
- Package: gpackage,
- Name: splitted[len(splitted)-1],
+ return &models.Useflag{
+ Id: pkguse + "-" + scope,
+ Package: pkg,
+ Name: use,
Scope: scope,
- Description: strings.Join(line[1:], ""),
+ Description: description,
}
-
- _, err := database.DBCon.Model(useflag).OnConflict("(id) DO UPDATE").Insert()
-
- return err
}
// createUseExpand parses the description from the file,
// creates a USE expand flag and imports it into the database
-func createUseExpand(rawFlag string, file string) error {
- name := strings.ReplaceAll(file, ".desc", "")
- line := strings.Split(rawFlag, " - ")
- id := name + "_" + line[0]
+func createUseExpand(rawFlag string, file string) *models.Useflag {
+ group := strings.TrimSuffix(file, ".desc")
+ unexpanded, description, _ := strings.Cut(rawFlag, " - ")
+ id := group + "_" + unexpanded
- useExpand := &models.Useflag{
+ return &models.Useflag{
Id: id,
- Name: name + "_" + line[0],
+ Name: id,
Scope: "use_expand",
- Description: strings.Join(line[1:], ""),
- UseExpand: name,
+ Description: description,
+ UseExpand: group,
}
-
- _, err := database.DBCon.Model(useExpand).OnConflict("(id) DO UPDATE").Insert()
-
- return err
}
// getScope returns either "local", "global", "use_expand"
diff --git a/pkg/portage/repository/version.go b/pkg/portage/repository/version.go
index 4fbe33d..178a9d2 100644
--- a/pkg/portage/repository/version.go
+++ b/pkg/portage/repository/version.go
@@ -3,10 +3,10 @@
package repository
import (
+ "log/slog"
"regexp"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
"strings"
@@ -15,36 +15,71 @@ import (
// isVersion checks whether the path points to a package version
// that is an .ebuild file
func isVersion(path string) bool {
- isVersion, _ := regexp.MatchString(`[^/]*\/[^/]*\/.*\.ebuild`, path)
+ isVersion, _ := regexp.MatchString(`^[^/]*\/[^/]*\/.*\.ebuild$`, path)
return isVersion
}
-// UpdateVersion updates the version in the database in case
-// the given path points to a package version
-func UpdateVersion(path string) {
+// UpdateVersions updates the versions in the database for each
+// given path that points to a package version
+func UpdateVersions(paths []string) {
+ deleted := map[string]*models.Version{}
+ modified := map[string]*models.Version{}
- line := strings.Split(path, "\t")
+ for _, path := range paths {
+ line := strings.Split(path, "\t")
- if len(line) != 2 {
- if len(line) == 1 && isVersion(path) {
- updateModifiedVersion(path)
+ if len(line) != 2 {
+ if len(line) == 1 && isVersion(path) {
+ ver := updateModifiedVersion(path)
+ modified[ver.Id] = ver
+ }
+ continue
+ }
+
+ status := line[0]
+ changedFile := line[1]
+
+ if !isVersion(changedFile) {
+ continue
+ } else if status == "D" {
+ ver := updateDeletedVersion(changedFile)
+ deleted[ver.Id] = ver
+ } else if status == "A" || status == "M" {
+ ver := updateModifiedVersion(changedFile)
+ modified[ver.Id] = ver
}
- return
}
- status := line[0]
- changedFile := line[1]
+ if len(deleted) > 0 {
+ rows := make([]*models.Version, 0, len(deleted))
+ for _, row := range deleted {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).Delete()
+ if err != nil {
+ slog.Error("Failed deleting versions", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted versions", slog.Int("rows", res.RowsAffected()))
+ }
+ }
- if isVersion(changedFile) && status == "D" {
- updateDeletedVersion(changedFile)
- } else if isVersion(changedFile) && (status == "A" || status == "M") {
- updateModifiedVersion(changedFile)
+ if len(modified) > 0 {
+ rows := make([]*models.Version, 0, len(modified))
+ for _, row := range modified {
+ rows = append(rows, row)
+ }
+ res, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert()
+ if err != nil {
+ slog.Error("Failed updating versions", slog.Any("err", err))
+ } else {
+ slog.Info("Updated versions", slog.Int("rows", res.RowsAffected()))
+ }
}
}
// updateDeletedVersion deletes a package version from the database
-func updateDeletedVersion(changedFile string) {
- splitted := strings.Split(strings.ReplaceAll(changedFile, ".ebuild", ""), "/")
+func updateDeletedVersion(changedFile string) *models.Version {
+ splitted := strings.Split(strings.TrimSuffix(changedFile, ".ebuild"), "/")
category := splitted[0]
packagename := splitted[1]
version := strings.ReplaceAll(splitted[2], packagename+"-", "")
@@ -52,19 +87,13 @@ func updateDeletedVersion(changedFile string) {
atom := category + "/" + packagename
id := atom + "-" + version
- versionObject := &models.Version{Id: id}
- _, err := database.DBCon.Model(versionObject).WherePK().Delete()
-
- if err != nil {
- logger.Error.Println("Error during deleting version " + id)
- logger.Error.Println(err)
- }
+ return &models.Version{Id: id}
}
// updateModifiedVersion adds a package version to the database or
// updates it. To do so, it parses the metadata from the md5-cache
-func updateModifiedVersion(changedFile string) {
- splitted := strings.Split(strings.ReplaceAll(changedFile, ".ebuild", ""), "/")
+func updateModifiedVersion(changedFile string) *models.Version {
+ splitted := strings.Split(strings.TrimSuffix(changedFile, ".ebuild"), "/")
category := splitted[0]
packagename := splitted[1]
version := strings.ReplaceAll(splitted[2], packagename+"-", "")
@@ -76,56 +105,45 @@ func updateModifiedVersion(changedFile string) {
slot := "0"
subslot := "0"
- eapi := ""
- keywords := ""
- var useflags []string
- var restricts []string
- var properties []string
- var homepages []string
- license := ""
- description := ""
+ var eapi, keywords, license, description string
+ var useflags, restricts, properties, homepages []string
for _, metadata := range version_metadata {
-
switch {
case strings.HasPrefix(metadata, "EAPI="):
- eapi = strings.ReplaceAll(metadata, "EAPI=", "")
+ eapi = strings.TrimPrefix(metadata, "EAPI=")
case strings.HasPrefix(metadata, "KEYWORDS="):
- keywords = strings.ReplaceAll(metadata, "KEYWORDS=", "")
+ keywords = strings.TrimPrefix(metadata, "KEYWORDS=")
case strings.HasPrefix(metadata, "IUSE="):
- useflags = strings.Split(strings.ReplaceAll(metadata, "IUSE=", ""), " ")
+ useflags = strings.Split(strings.TrimPrefix(metadata, "IUSE="), " ")
case strings.HasPrefix(metadata, "RESTRICT="):
- restricts = strings.Split(strings.ReplaceAll(strings.ReplaceAll(metadata, "RESTRICT=", ""), "!test? ( test )", ""), " ")
+ restricts = strings.Split(strings.ReplaceAll(strings.TrimPrefix(metadata, "RESTRICT="), "!test? ( test )", ""), " ")
if len(restricts) == 1 && restricts[0] == "" {
restricts = []string{}
}
case strings.HasPrefix(metadata, "PROPERTIES="):
- properties = strings.Split(strings.ReplaceAll(metadata, "PROPERTIES=", ""), " ")
+ properties = strings.Split(strings.TrimPrefix(metadata, "PROPERTIES="), " ")
case strings.HasPrefix(metadata, "HOMEPAGE="):
- homepages = strings.Split(strings.ReplaceAll(metadata, "HOMEPAGE=", ""), " ")
+ homepages = strings.Split(strings.TrimPrefix(metadata, "HOMEPAGE="), " ")
case strings.HasPrefix(metadata, "LICENSE="):
- license = strings.ReplaceAll(metadata, "LICENSE=", "")
+ license = strings.TrimPrefix(metadata, "LICENSE=")
case strings.HasPrefix(metadata, "DESCRIPTION="):
- description = strings.ReplaceAll(metadata, "DESCRIPTION=", "")
+ description = strings.TrimPrefix(metadata, "DESCRIPTION=")
case strings.HasPrefix(metadata, "SLOT="):
- rawslot := strings.ReplaceAll(metadata, "SLOT=", "")
- slot = strings.Split(rawslot, "/")[0]
- if len(strings.Split(rawslot, "/")) > 1 {
- subslot = strings.Split(rawslot, "/")[1]
- }
+ rawSlot := strings.TrimPrefix(metadata, "SLOT=")
+ slot, subslot, _ = strings.Cut(rawSlot, "/")
}
-
}
- ebuildVersion := &models.Version{
+ return &models.Version{
Id: id,
Category: category,
Package: packagename,
@@ -142,11 +160,4 @@ func updateModifiedVersion(changedFile string) {
License: license,
Description: description,
}
-
- _, err := database.DBCon.Model(ebuildVersion).OnConflict("(id) DO UPDATE").Insert()
-
- if err != nil {
- logger.Error.Println("Error during updating version " + id)
- logger.Error.Println(err)
- }
}
diff --git a/pkg/portage/update.go b/pkg/portage/update.go
index 551c5e8..8ad9187 100644
--- a/pkg/portage/update.go
+++ b/pkg/portage/update.go
@@ -3,11 +3,10 @@
package portage
import (
- "io/ioutil"
- "log"
+ "log/slog"
+ "os"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/repository"
"soko/pkg/portage/utils"
@@ -20,73 +19,65 @@ import (
// this is the first update that is there is no last update a full import
// starting with the first commit in the tree is done.
func Update() {
-
database.Connect()
defer database.DBCon.Close()
- if config.Quiet() == "true" {
- log.SetOutput(ioutil.Discard)
- }
-
- logger.Info.Println("Start update...")
+ slog.Info("Start update...")
// update the local useflags
repository.UpdateUse("profiles/use.local.desc")
- updateMetadata()
- updatePackageData()
+ latestCommit := utils.GetLatestCommit()
+ changed := utils.ChangedFiles(latestCommit, "HEAD")
+
+ updateMetadata(changed)
+ updatePackageData(changed)
updateHistory()
repository.CalculateMaskedVersions()
-
+ repository.CalculateDeprecatedToVersion()
}
// updateMetadata updates all USE flags, package masks and arches in the database
// by parsing:
-// - profiles/use.desc
-// - profiles/use.local.desc
-// - profiles/use.local.desc
-// - profiles/desc/*
-// - profiles/package.mask
-// - profiles/arch.list
+// - profiles/use.desc
+// - profiles/use.local.desc
+// - profiles/use.local.desc
+// - profiles/desc/*
+// - profiles/package.mask
+// - profiles/package.deprecated
+// - profiles/arch.list
//
// It works incrementally so that files are only parsed and updated whenever the
// file has been modified within the new commits. New commits are determined by
// retrieving the last commit in the database (if present) and parsing all
// following commits. In case no last commit is present a full import
// starting with the first commit in the tree is done.
-func updateMetadata() {
-
- logger.Info.Println("Start updating changed metadata")
-
- latestCommit := utils.GetLatestCommit()
-
- for _, path := range utils.ChangedFiles(latestCommit, "HEAD") {
+func updateMetadata(changed []string) {
+ slog.Info("Start updating changed metadata")
+ slog.Info("Iterating changed files", slog.Int("count", len(changed)))
+ for _, path := range changed {
repository.UpdateUse(path)
repository.UpdateMask(path)
+ repository.UpdatePackagesDeprecated(path)
repository.UpdateArch(path)
}
-
}
// updatePackageData incrementally updates all package data in the database, that has
// been changed since the last update. That is:
-// - categories
-// - packages
-// - versions
+// - categories
+// - packages
+// - versions
+//
// changed data is determined by parsing all commits since the last update.
-func updatePackageData() {
-
- logger.Info.Println("Start updating changed package data")
-
- latestCommit := utils.GetLatestCommit()
-
- for _, path := range utils.ChangedFiles(latestCommit, "HEAD") {
- repository.UpdateVersion(path)
- repository.UpdatePackage(path)
- repository.UpdateCategory(path)
- }
+func updatePackageData(changed []string) {
+ slog.Info("Start updating changed package data")
+ slog.Info("Iterating changed files", slog.Int("count", len(changed)))
+ repository.UpdateVersions(changed)
+ repository.UpdatePackages(changed)
+ repository.UpdateCategories(changed)
}
// updateHistory incrementally imports all new commits. New commits are
@@ -94,8 +85,7 @@ func updatePackageData() {
// and parsing all following commits. In case no last commit is present
// a full import starting with the first commit in the tree is done.
func updateHistory() {
-
- logger.Info.Println("Start updating the history")
+ slog.Info("Start updating the history")
latestCommit := repository.UpdateCommits()
@@ -111,13 +101,9 @@ func updateHistory() {
LastCommit: latestCommit,
}
- _, err := database.DBCon.Model(application).
- OnConflict("(id) DO UPDATE").
- Insert()
-
+ _, err := database.DBCon.Model(application).OnConflict("(id) DO UPDATE").Insert()
if err != nil {
- logger.Error.Println("Updating application data failed")
- logger.Error.Println(err)
+ slog.Error("Failed updating application data", slog.Any("err", err))
}
}
@@ -132,108 +118,125 @@ func updateHistory() {
// Once there is no outdated data found anymore this method may become
// obsolete.
func FullUpdate() {
-
database.Connect()
defer database.DBCon.Close()
- if config.Quiet() == "true" {
- log.SetOutput(ioutil.Discard)
- }
-
- logger.Info.Println("Full update up...")
+ slog.Info("Full update up...")
// Add new entries & update existing
- logger.Info.Println("Update all present files")
+ slog.Info("Update all present files")
- // update the local useflags
+ // update useflags
+ database.TruncateTable((*models.Useflag)(nil))
+ repository.UpdateUse("profiles/use.desc")
repository.UpdateUse("profiles/use.local.desc")
-
- for _, path := range utils.AllFiles() {
- repository.UpdateVersion(path)
- repository.UpdatePackage(path)
- repository.UpdateCategory(path)
+ if entries, err := os.ReadDir(config.PortDir() + "/profiles/desc"); err != nil {
+ slog.Error("Error reading profiles/desc", slog.Any("err", err))
+ } else {
+ for _, entry := range entries {
+ repository.UpdateUse("profiles/desc/" + entry.Name())
+ }
}
+ allFiles := utils.AllFiles()
+ updateMetadata(allFiles)
+ repository.UpdateVersions(allFiles)
+ repository.UpdatePackages(allFiles)
+ repository.UpdateCategories(allFiles)
+
// Delete removed entries
- logger.Info.Println("Delete removed files from the database")
+ slog.Info("Delete removed files from the database")
deleteRemovedVersions()
deleteRemovedPackages()
deleteRemovedCategories()
fixPrecedingCommitsOfPackages()
- logger.Info.Println("Finished update up...")
+ repository.CalculateMaskedVersions()
+ repository.CalculateDeprecatedToVersion()
+
+ slog.Info("Finished update up...")
}
// deleteRemovedVersions removes all versions from the database
// that are present in the database but not in the main tree.
func deleteRemovedVersions() {
- var versions []*models.Version
- database.DBCon.Model(&versions).Select()
+ var versions, toDelete []*models.Version
+ err := database.DBCon.Model(&versions).Column("id", "atom", "package", "version").Select()
+ if err != nil {
+ slog.Error("Failed fetching versions", slog.Any("err", err))
+ return
+ }
for _, version := range versions {
path := config.PortDir() + "/" + version.Atom + "/" + version.Package + "-" + version.Version + ".ebuild"
if !utils.FileExists(path) {
-
- logger.Error.Println("Found ebuild version in the database that does not exist at:")
- logger.Error.Println(path)
-
- _, err := database.DBCon.Model(version).WherePK().Delete()
-
- if err != nil {
- logger.Error.Println("Error deleting version " + version.Atom + " - " + version.Version)
- logger.Error.Println(err)
- }
+ slog.Error("Found ebuild version in the database that does not exist", slog.String("version", version.Id))
+ toDelete = append(toDelete, version)
}
+ }
+ if len(toDelete) > 0 {
+ res, err := database.DBCon.Model(&toDelete).Delete()
+ if err != nil {
+ slog.Error("Failed deleting versions", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted versions", slog.Int("rows", res.RowsAffected()))
+ }
}
}
// deleteRemovedPackages removes all packages from the database
// that are present in the database but not in the main tree.
func deleteRemovedPackages() {
- var packages []*models.Package
- database.DBCon.Model(&packages).Select()
-
- for _, gpackage := range packages {
- path := config.PortDir() + "/" + gpackage.Atom
- if !utils.FileExists(path) {
-
- logger.Error.Println("Found package in the database that does not exist at:")
- logger.Error.Println(path)
-
- _, err := database.DBCon.Model(gpackage).WherePK().Delete()
+ var packages, toDelete []*models.Package
+ err := database.DBCon.Model(&packages).Column("atom").Select()
+ if err != nil {
+ slog.Error("Failed fetching packages", slog.Any("err", err))
+ return
+ }
- if err != nil {
- logger.Error.Println("Error deleting package " + gpackage.Atom)
- logger.Error.Println(err)
- }
+ for _, pkg := range packages {
+ if !utils.FileExists(config.PortDir() + "/" + pkg.Atom) {
+ slog.Error("Found package in the database that does not exist", slog.String("atom", pkg.Atom))
+ toDelete = append(toDelete, pkg)
}
+ }
+ if len(toDelete) > 0 {
+ res, err := database.DBCon.Model(&toDelete).Delete()
+ if err != nil {
+ slog.Error("Failed deleting packages", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted packages", slog.Int("rows", res.RowsAffected()))
+ }
}
}
// deleteRemovedCategories removes all categories from the database
// that are present in the database but not in the main tree.
func deleteRemovedCategories() {
- var categories []*models.Category
- database.DBCon.Model(&categories).Select()
+ var categories, toDelete []*models.Category
+ err := database.DBCon.Model(&categories).Column("name").Select()
+ if err != nil {
+ slog.Error("Failed fetching categories", slog.Any("err", err))
+ return
+ }
for _, category := range categories {
- path := config.PortDir() + "/" + category.Name
- if !utils.FileExists(path) {
-
- logger.Error.Println("Found category in the database that does not exist at:")
- logger.Error.Println(path)
-
- _, err := database.DBCon.Model(category).WherePK().Delete()
-
- if err != nil {
- logger.Error.Println("Error deleting category " + category.Name)
- logger.Error.Println(err)
- }
+ if !utils.FileExists(config.PortDir() + "/" + category.Name) {
+ slog.Error("Found category in the database that does not exist", slog.String("name", category.Name))
+ toDelete = append(toDelete, category)
}
+ }
+ if len(toDelete) > 0 {
+ res, err := database.DBCon.Model(&toDelete).Delete()
+ if err != nil {
+ slog.Error("Failed deleting categories", slog.Any("err", err))
+ } else {
+ slog.Info("Deleted categories", slog.Int("rows", res.RowsAffected()))
+ }
}
}
@@ -245,15 +248,16 @@ func deleteRemovedCategories() {
// packages' section.
func fixPrecedingCommitsOfPackages() {
var packages []*models.Package
- database.DBCon.Model(&packages).Select()
- for _, gpackage := range packages {
- if gpackage.PrecedingCommits == 0 {
- logger.Error.Println("Preceding Commits of package " + gpackage.Atom + " is null.")
- logger.Error.Println("This should not happen. Preceding Commits will be set to 1")
- gpackage.PrecedingCommits = 1
- database.DBCon.Model(gpackage).WherePK().Update()
- }
+ database.DBCon.Model(&packages).Where("preceding_commits = 0").Select()
+ if len(packages) == 0 {
+ return
+ }
+
+ slog.Error("Found packages with preceding commits == 0. This should not happen. Fixing...", slog.Int("count", len(packages)))
+ for _, pkg := range packages {
+ pkg.PrecedingCommits = 1
}
+ database.DBCon.Model(&packages).Update()
}
// GetApplicationData is used to retrieve the
@@ -261,9 +265,9 @@ func fixPrecedingCommitsOfPackages() {
func getApplicationData() models.Application {
// Select user by primary key.
applicationData := &models.Application{Id: "latest"}
- err := database.DBCon.Select(applicationData)
+ err := database.DBCon.Model(applicationData).WherePK().Select()
if err != nil {
- logger.Error.Println("Error fetching application data")
+ slog.Error("Failed fetching application data", slog.Any("err", err))
return models.Application{
Id: "latest",
LastUpdate: time.Now(),
diff --git a/pkg/portage/utils/files.go b/pkg/portage/utils/files.go
index c328cec..a0d0065 100644
--- a/pkg/portage/utils/files.go
+++ b/pkg/portage/utils/files.go
@@ -27,9 +27,6 @@ func ReadLines(path string) ([]string, error) {
// FileExists checks whether the file
// at the given path does exist
func FileExists(path string) bool {
- if _, err := os.Stat(path); err == nil {
- return true
- } else {
- return false
- }
+ _, err := os.Stat(path)
+ return err == nil
}
diff --git a/pkg/portage/utils/git.go b/pkg/portage/utils/git.go
index 2f67c01..c576105 100644
--- a/pkg/portage/utils/git.go
+++ b/pkg/portage/utils/git.go
@@ -3,10 +3,10 @@
package utils
import (
+ "log/slog"
"os/exec"
"soko/pkg/config"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"strings"
)
@@ -23,8 +23,7 @@ func AllFiles() []string {
cmd.Dir = config.PortDir()
out, err := cmd.CombinedOutput()
if err != nil {
- logger.Error.Println("ERROR: cmd.Run() failed with:")
- logger.Error.Println(err)
+ slog.Error("cmd.Run() failed", slog.Any("err", err))
return allFiles
}
@@ -45,7 +44,7 @@ func ChangedFiles(startCommit string, endCommit string) []string {
cmd.Dir = config.PortDir()
out, err := cmd.CombinedOutput()
if err != nil {
- logger.Error.Println("ERROR: cmd.Run() failed with %s\n", err)
+ slog.Error("cmd.Run() failed", slog.Any("err", err))
return changedFiles
}
@@ -56,10 +55,11 @@ func ChangedFiles(startCommit string, endCommit string) []string {
// GetCommits returns the log message of all commits after
// the given startCommit and before the given endCommit. The
// log message:
-// - uses '%Y-%m-%dT%H:%M:%S%z' as date format
-// - doesn't include merges
-// - doesn't include renames
-// - includes the status of the changed files
+// - uses '%Y-%m-%dT%H:%M:%S%z' as date format
+// - doesn't include merges
+// - doesn't include renames
+// - includes the status of the changed files
+//
// Furthermore the commits are in reverse order.
func GetCommits(startCommit string, endCommit string) []string {
var commits []string
@@ -76,7 +76,7 @@ func GetCommits(startCommit string, endCommit string) []string {
cmd.Dir = config.PortDir()
out, err := cmd.CombinedOutput()
if err != nil {
- logger.Error.Println("cmd.Run() failed with %s\n", err)
+ slog.Error("cmd.Run() failed", slog.Any("err", err))
return commits
}
@@ -87,14 +87,14 @@ func GetCommits(startCommit string, endCommit string) []string {
// GetLatestCommit retrieves the latest commit in
// the database and returns the hash of the commit
func GetLatestCommit() string {
- latestCommit, _ := GetLatestCommitAndPreceeding()
+ latestCommit, _ := GetLatestCommitAndPreceding()
return latestCommit
}
-// GetLatestCommitAndPreceeding retrieves the latest
+// GetLatestCommitAndPreceding retrieves the latest
// commit in the database. The hash of the latest commit
// as well as the number of preceding commits is returned
-func GetLatestCommitAndPreceeding() (string, int) {
+func GetLatestCommitAndPreceding() (string, int) {
latestCommit := EmptyTree()
PrecedingCommitsOffset := 0
diff --git a/pkg/portage/utils/misc.go b/pkg/portage/utils/misc.go
deleted file mode 100644
index 3e4e79c..0000000
--- a/pkg/portage/utils/misc.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Contains miscellaneous utility functions
-
-package utils
-
-// Contains tells whether string a contains string x.
-func Contains(a []string, x string) bool {
- for _, n := range a {
- if x == n {
- return true
- }
- }
- return false
-}
diff --git a/pkg/portage/utils/version.go b/pkg/portage/utils/version.go
new file mode 100644
index 0000000..942bd53
--- /dev/null
+++ b/pkg/portage/utils/version.go
@@ -0,0 +1,145 @@
+package utils
+
+import (
+ "regexp"
+ "soko/pkg/database"
+ "soko/pkg/models"
+ "strings"
+)
+
+var (
+ revision = regexp.MustCompile(`-r[0-9]*$`)
+)
+
+func CalculateAffectedVersions(versionSpecifier, packageAtom string) []*models.Version {
+ if strings.HasPrefix(versionSpecifier, "=") {
+ return exactVersion(versionSpecifier, packageAtom)
+ } else if strings.HasPrefix(versionSpecifier, "<=") {
+ return comparedVersions("<=", versionSpecifier, packageAtom)
+ } else if strings.HasPrefix(versionSpecifier, "<") {
+ return comparedVersions("<", versionSpecifier, packageAtom)
+ } else if strings.HasPrefix(versionSpecifier, ">=") {
+ return comparedVersions(">=", versionSpecifier, packageAtom)
+ } else if strings.HasPrefix(versionSpecifier, ">") {
+ return comparedVersions(">", versionSpecifier, packageAtom)
+ } else if strings.HasPrefix(versionSpecifier, "~") {
+ return allRevisions(versionSpecifier, packageAtom)
+ } else if strings.Contains(versionSpecifier, ":") {
+ return versionsWithSlot(versionSpecifier, packageAtom)
+ } else {
+ return allVersions(versionSpecifier, packageAtom)
+ }
+}
+
+// extract slot and subslot name from versionSpecifier
+func slotAndSubslot(versionSpecifier string) (string, []string) {
+ version, fullslot, found := strings.Cut(versionSpecifier, ":")
+ if found {
+ return version, strings.SplitN(fullslot, "/", 2)
+ } else {
+ return version, nil
+ }
+}
+
+// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version
+func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version {
+ var results, versions []*models.Version
+ versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "")
+ versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "")
+ versionSpecifier, slots := slotAndSubslot(versionSpecifier)
+
+ q := database.DBCon.Model(&versions).
+ Where("atom = ?", packageAtom)
+ if len(slots) >= 1 {
+ q = q.Where("slot = ?", slots[0])
+ }
+ if len(slots) == 2 {
+ q = q.Where("subslot = ?", slots[1])
+ }
+ q.Select()
+
+ for _, v := range versions {
+ givenVersion := models.Version{Version: versionSpecifier}
+ if operator == ">" {
+ if v.GreaterThan(givenVersion) {
+ results = append(results, v)
+ }
+ } else if operator == ">=" {
+ if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) {
+ results = append(results, v)
+ }
+ } else if operator == "<" {
+ if v.SmallerThan(givenVersion) {
+ results = append(results, v)
+ }
+ } else if operator == "<=" {
+ if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) {
+ results = append(results, v)
+ }
+ }
+ }
+ return results
+}
+
+// allRevisions returns all revisions of the given version
+func allRevisions(versionSpecifier string, packageAtom string) []*models.Version {
+ var versions []*models.Version
+ versionSpecifier, slots := slotAndSubslot(versionSpecifier)
+ versionWithoutRevision := revision.Split(versionSpecifier, 1)[0]
+ versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "")
+
+ q := database.DBCon.Model(&versions).
+ Where("id LIKE ?", versionWithoutRevision+"%")
+ if len(slots) >= 1 {
+ q = q.Where("slot = ?", slots[0])
+ }
+ if len(slots) == 2 {
+ q = q.Where("subslot = ?", slots[1])
+ }
+ q.Select()
+
+ return versions
+}
+
+// exactVersion returns the exact version specified in the versionSpecifier
+func exactVersion(versionSpecifier string, packageAtom string) []*models.Version {
+ var versions []*models.Version
+ versionSpecifier, slots := slotAndSubslot(versionSpecifier)
+
+ q := database.DBCon.Model(&versions).
+ Where("id = ?", strings.Replace(versionSpecifier, "=", "", 1))
+ if len(slots) >= 1 {
+ q = q.Where("slot = ?", slots[0])
+ }
+ if len(slots) == 2 {
+ q = q.Where("subslot = ?", slots[1])
+ }
+ q.Select()
+
+ return versions
+}
+
+// versionsWithSlot returns all versions with the given slot
+func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version {
+ var versions []*models.Version
+ _, slots := slotAndSubslot(versionSpecifier)
+
+ q := database.DBCon.Model(&versions).
+ Where("atom = ?", packageAtom).
+ Where("slot = ?", slots[0])
+ if len(slots) == 2 {
+ q = q.Where("subslot = ?", slots[1])
+ }
+ q.Select()
+
+ return versions
+}
+
+// allVersions returns all versions of the given package
+func allVersions(versionSpecifier string, packageAtom string) []*models.Version {
+ var versions []*models.Version
+ database.DBCon.Model(&versions).
+ Where("atom = ?", packageAtom).
+ Select()
+ return versions
+}
diff --git a/pkg/selfcheck/check.go b/pkg/selfcheck/check.go
index b3634b9..6d02548 100644
--- a/pkg/selfcheck/check.go
+++ b/pkg/selfcheck/check.go
@@ -1,34 +1,35 @@
package selfcheck
import (
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promauto"
+ "log/slog"
"soko/pkg/database"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/selfcheck/metrics"
"soko/pkg/selfcheck/repository"
"soko/pkg/selfcheck/storage"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
)
-func AllPackages(){
- logger.Info.Println("selfcheck: Preparing new check...")
- logger.Info.Println("selfcheck: Updating selfcheck repository")
+func AllPackages() {
+ slog.Info("selfcheck: Preparing new check...")
+ slog.Info("selfcheck: Updating selfcheck repository")
repository.UpdateRepo()
- logger.Info.Println("selfcheck: Importing data")
+ slog.Info("selfcheck: Importing data")
repository.Import()
- logger.Info.Println("selfcheck: Resetting metrics")
+ slog.Info("selfcheck: Resetting metrics")
resetMetrics()
- logger.Info.Println("selfcheck: Start check")
+ slog.Info("selfcheck: Start check")
for _, category := range storage.Categories {
- //logger.Info.Println("Checking " + category.Name)
+ //slog.Info("Checking " + category.Name)
checkCategory(category)
}
- logger.Info.Println("selfcheck: Finished check")
+ slog.Info("selfcheck: Finished check")
}
-func resetMetrics(){
+func resetMetrics() {
for _, metric := range metrics.MissingPackages {
prometheus.Unregister(metric)
}
@@ -39,8 +40,7 @@ func resetMetrics(){
metrics.MissingVersions = map[string]prometheus.Gauge{}
}
-
-func checkCategory(category *models.Category){
+func checkCategory(category *models.Category) {
// create a client (safe to share across requests)
database.Connect()
@@ -53,9 +53,8 @@ func checkCategory(category *models.Category){
Relation("Packages.Versions").
Select()
-
if err != nil {
- logger.Error.Println(err)
+ slog.Error("Failed fetching category", slog.Any("err", err), slog.Any("category", category.Name))
return
}
@@ -75,8 +74,8 @@ func checkCategory(category *models.Category){
metric.Set(1)
} else {
metrics.MissingPackages[localPackage.Atom] = promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_missing_package",
- Help: "A package that is missing on packages.g.o although it's present in the tree",
+ Name: "pgo_missing_package",
+ Help: "A package that is missing on packages.g.o although it's present in the tree",
ConstLabels: prometheus.Labels{"atom": localPackage.Atom},
})
metrics.MissingPackages[localPackage.Atom].Set(1)
@@ -89,8 +88,7 @@ func checkCategory(category *models.Category){
}
-func checkVersions(remotePackage *models.Package){
-
+func checkVersions(remotePackage *models.Package) {
for _, localVersion := range storage.Versions {
@@ -99,7 +97,7 @@ func checkVersions(remotePackage *models.Package){
// search for local version in remote versions
versionFound := false
for _, remoteVersion := range remotePackage.Versions {
- if localVersion.Id == remoteVersion.Id && localVersion.Id == remoteVersion.Id {
+ if localVersion.Id == remoteVersion.Id {
versionFound = true
break
}
@@ -110,8 +108,8 @@ func checkVersions(remotePackage *models.Package){
metric.Set(1)
} else {
metrics.MissingVersions[localVersion.Id] = promauto.NewGauge(prometheus.GaugeOpts{
- Name: "pgo_missing_version",
- Help: "A version that is missing on packages.g.o although it's present in the tree",
+ Name: "pgo_missing_version",
+ Help: "A version that is missing on packages.g.o although it's present in the tree",
ConstLabels: prometheus.Labels{"id": localVersion.Id},
})
metrics.MissingVersions[localVersion.Id].Set(1)
@@ -123,4 +121,3 @@ func checkVersions(remotePackage *models.Package){
}
}
}
-
diff --git a/pkg/selfcheck/portage/category.go b/pkg/selfcheck/portage/category.go
index 62ef93d..c9b49db 100644
--- a/pkg/selfcheck/portage/category.go
+++ b/pkg/selfcheck/portage/category.go
@@ -4,11 +4,11 @@ package repository
import (
"encoding/xml"
- "io/ioutil"
+ "io"
+ "log/slog"
"os"
"regexp"
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/selfcheck/storage"
"strings"
@@ -29,14 +29,13 @@ func UpdateCategory(path string) {
}
}
-
// updateModifiedCategory adds a category to the database or
// updates it. To do so, it parses the metadata from metadata.xml
func updateModifiedCategory(changedFile string) {
splitted := strings.Split(changedFile, "/")
id := splitted[0]
- catmetadata := GetCatMetadata(config.PortDir() + "/" + changedFile)
+ catmetadata := GetCatMetadata(config.SelfCheckPortDir() + "/" + changedFile)
description := ""
for _, longdescription := range catmetadata.Longdescriptions {
@@ -51,7 +50,7 @@ func updateModifiedCategory(changedFile string) {
})
}
-func addCategory(category *models.Category){
+func addCategory(category *models.Category) {
found := false
for _, cat := range storage.Categories {
if cat.Name == category.Name {
@@ -69,11 +68,11 @@ func addCategory(category *models.Category){
func GetCatMetadata(path string) Catmetadata {
xmlFile, err := os.Open(path)
if err != nil {
- logger.Error.Println("Error during reading category metadata")
- logger.Error.Println(err)
+ slog.Error("Failed reading category metadata", slog.String("path", path), slog.Any("err", err))
+ return Catmetadata{}
}
defer xmlFile.Close()
- byteValue, _ := ioutil.ReadAll(xmlFile)
+ byteValue, _ := io.ReadAll(xmlFile)
var catmetadata Catmetadata
xml.Unmarshal(byteValue, &catmetadata)
return catmetadata
diff --git a/pkg/selfcheck/portage/mask.go b/pkg/selfcheck/portage/mask.go
index 12e2f86..1d8fc53 100644
--- a/pkg/selfcheck/portage/mask.go
+++ b/pkg/selfcheck/portage/mask.go
@@ -12,8 +12,8 @@
package repository
import (
+ "log/slog"
"regexp"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
"soko/pkg/selfcheck/storage"
@@ -57,8 +57,7 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string {
func parseAuthorLine(authorLine string) (string, string, time.Time) {
if !(strings.Contains(authorLine, "<") && strings.Contains(authorLine, ">")) {
- logger.Error.Println("Error while parsing the author line in mask entry:")
- logger.Error.Println(authorLine)
+ slog.Error("Error while parsing the author line in mask entry", slog.String("authorLine", authorLine))
return "", "", time.Now()
}
@@ -70,8 +69,7 @@ func parseAuthorLine(authorLine string) (string, string, time.Time) {
date = strings.ReplaceAll(date, ")", "")
parsedDate, err := time.Parse("2006-01-02", date)
if err != nil {
- logger.Error.Println("Error while parsing package mask date: " + date)
- logger.Error.Println(err)
+ slog.Error("Failed parsing package mask date", slog.String("date", date), slog.Any("err", err))
}
return author, authorEmail, parsedDate
}
@@ -115,8 +113,7 @@ func getMasks(path string) []string {
lines, err := utils.ReadLines(path)
if err != nil {
- logger.Error.Println("Could not read Masks file. Abort masks import")
- logger.Error.Println(err)
+ slog.Error("Could not read Masks file. Abort masks import", slog.Any("err", err))
return masks
}
@@ -171,7 +168,7 @@ func comparedVersions(operator string, versionSpecifier string, packageAtom stri
versionSpecifier = strings.Split(versionSpecifier, ":")[0]
for _, version := range storage.Versions {
- if version.Atom == packageAtom {
+ if version.Atom == packageAtom {
versions = append(versions, version)
}
}
@@ -207,7 +204,7 @@ func allRevisions(versionSpecifier string, packageAtom string) []*models.Version
versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "")
for _, version := range storage.Versions {
- if strings.HasPrefix(version.Id, versionWithoutRevision) {
+ if strings.HasPrefix(version.Id, versionWithoutRevision) {
versions = append(versions, version)
}
}
@@ -268,4 +265,4 @@ func maskVersions(mask *models.Mask, versions []*models.Version) {
}
}
-} \ No newline at end of file
+}
diff --git a/pkg/selfcheck/portage/package.go b/pkg/selfcheck/portage/package.go
index 4e03724..ad011ff 100644
--- a/pkg/selfcheck/portage/package.go
+++ b/pkg/selfcheck/portage/package.go
@@ -4,11 +4,11 @@ package repository
import (
"encoding/xml"
- "io/ioutil"
+ "io"
+ "log/slog"
"os"
"regexp"
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/selfcheck/storage"
"strings"
@@ -37,7 +37,7 @@ func updateModifiedPackage(changedFile string) {
packagename := splitted[1]
atom := category + "/" + packagename
- pkgmetadata := GetPkgMetadata(config.PortDir() + "/" + atom + "/metadata.xml")
+ pkgmetadata := GetPkgMetadata(config.SelfCheckPortDir() + "/" + atom + "/metadata.xml")
var maintainers []*models.Maintainer
for _, maintainer := range pkgmetadata.MaintainerList {
@@ -52,7 +52,7 @@ func updateModifiedPackage(changedFile string) {
longDescription := ""
for _, l := range pkgmetadata.LongdescriptionList {
- if l.Language == "" {
+ if l.Language == "" || l.Language == "en" {
longDescription = l.Content
}
}
@@ -83,8 +83,7 @@ func updateModifiedPackage(changedFile string) {
}
-
-func addPackage(newPackage *models.Package){
+func addPackage(newPackage *models.Package) {
found := false
for _, p := range storage.Packages {
if p.Atom == newPackage.Atom {
@@ -102,11 +101,11 @@ func addPackage(newPackage *models.Package){
func GetPkgMetadata(path string) Pkgmetadata {
xmlFile, err := os.Open(path)
if err != nil {
- logger.Error.Println("Error during reading package metadata")
- logger.Error.Println(err)
+ slog.Error("Failed reading package metadata", slog.String("path", path), slog.Any("err", err))
+ return Pkgmetadata{}
}
defer xmlFile.Close()
- byteValue, _ := ioutil.ReadAll(xmlFile)
+ byteValue, _ := io.ReadAll(xmlFile)
var pkgmetadata Pkgmetadata
xml.Unmarshal(byteValue, &pkgmetadata)
return pkgmetadata
diff --git a/pkg/selfcheck/portage/use.go b/pkg/selfcheck/portage/use.go
index a47f543..21ea283 100644
--- a/pkg/selfcheck/portage/use.go
+++ b/pkg/selfcheck/portage/use.go
@@ -3,8 +3,8 @@
package repository
import (
+ "log/slog"
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/models"
"soko/pkg/portage/utils"
"soko/pkg/selfcheck/storage"
@@ -18,7 +18,7 @@ func UpdateUse(path string) {
if isLocalUseflag(path) || isGlobalUseflag(path) || isUseExpand(path) {
- rawFlags, _ := utils.ReadLines(config.PortDir() + "/" + path)
+ rawFlags, _ := utils.ReadLines(config.SelfCheckPortDir() + "/" + path)
for _, rawFlag := range rawFlags {
@@ -37,10 +37,7 @@ func UpdateUse(path string) {
}
if err != nil {
- logger.Info.Println("Error during updating useflag " + rawFlag)
- logger.Info.Println(err)
- logger.Error.Println("Error during updating useflag " + rawFlag)
- logger.Error.Println(err)
+ slog.Error("Failed updating useflag", slog.String("useflag", rawFlag), slog.Any("err", err))
}
}
}
diff --git a/pkg/selfcheck/portage/version.go b/pkg/selfcheck/portage/version.go
index 7018593..f71612f 100644
--- a/pkg/selfcheck/portage/version.go
+++ b/pkg/selfcheck/portage/version.go
@@ -40,7 +40,7 @@ func updateModifiedVersion(changedFile string) {
atom := category + "/" + packagename
id := atom + "-" + version
- version_metadata, _ := utils.ReadLines(config.PortDir() + "/metadata/md5-cache/" + id)
+ version_metadata, _ := utils.ReadLines(config.SelfCheckPortDir() + "/metadata/md5-cache/" + id)
slot := "0"
subslot := "0"
@@ -113,7 +113,7 @@ func updateModifiedVersion(changedFile string) {
}
-func addVersion(newVersion *models.Version){
+func addVersion(newVersion *models.Version) {
found := false
for _, v := range storage.Versions {
if v.Id == newVersion.Id {
diff --git a/pkg/selfcheck/serve.go b/pkg/selfcheck/serve.go
index 857e6f6..7d5498b 100644
--- a/pkg/selfcheck/serve.go
+++ b/pkg/selfcheck/serve.go
@@ -1,29 +1,32 @@
package selfcheck
import (
- "github.com/prometheus/client_golang/prometheus/promhttp"
- "log"
+ "log/slog"
"net/http"
+ "os"
+
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/metrics"
)
// Serve is used to serve the web application
func Serve() {
-
// prometheus metrics
http.Handle("/metrics", metricsHandler())
- logger.Info.Println("Serving on port: " + config.Port())
- log.Fatal(http.ListenAndServe(":"+config.Port(), nil))
-
+ address := ":" + config.Port()
+ slog.Info("Serving self-check", slog.String("address", address))
+ err := http.ListenAndServe(address, nil)
+ slog.Error("exited server", "err", err)
+ os.Exit(1)
}
// metricsHandler is used as default middleware to update the metrics
func metricsHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
metrics.Update()
- promhttp.Handler().ServeHTTP(w,r)
+ promhttp.Handler().ServeHTTP(w, r)
})
}
diff --git a/soko.go b/soko.go
index 6d18d41..c38f660 100644
--- a/soko.go
+++ b/soko.go
@@ -2,13 +2,17 @@ package main
import (
"flag"
- "github.com/jasonlvhit/gocron"
- "io"
- "io/ioutil"
+ "log"
+ "log/slog"
"os"
+ "time"
+
+ "github.com/jasonlvhit/gocron"
+ "github.com/lmittmann/tint"
+ slogmulti "github.com/samber/slog-multi"
+
"soko/pkg/app"
"soko/pkg/config"
- "soko/pkg/logger"
"soko/pkg/portage"
"soko/pkg/portage/bugs"
"soko/pkg/portage/dependencies"
@@ -18,16 +22,10 @@ import (
"soko/pkg/portage/projects"
"soko/pkg/portage/repology"
"soko/pkg/selfcheck"
- "time"
)
func main() {
-
- waitForPostgres()
-
- errorLogFile := logger.CreateLogFile(config.LogFile())
- defer errorLogFile.Close()
- initLoggers(os.Stdout, errorLogFile)
+ initLoggers()
serve := flag.Bool("serve", false, "Start serving the application")
selfchecks := flag.Bool("enable-selfchecks", false, "Perform selfchecks periodicals to monitor the consistency of the data")
@@ -36,7 +34,7 @@ func main() {
updateOutdatedPackages := flag.Bool("update-outdated-packages", false, "Update the repology.org data of outdated packages")
updatePkgcheckResults := flag.Bool("update-pkgcheck-results", false, "Update the qa-reports that is the pkgcheck results")
updatePullrequests := flag.Bool("update-pullrequests", false, "Update the pull requests")
- initBugs := flag.Bool("init-bugs", false, "Import all bugs, including the old ones. This is usually just done once.")
+ flag.Bool("init-bugs", false, "Import all bugs, including the old ones. This is usually just done once.")
updateBugs := flag.Bool("update-bugs", false, "Update the bugs belonging to the packages")
updateDependencies := flag.Bool("update-dependencies", false, "Update the dependencies and reverse dependencies of the packages")
updateProjects := flag.Bool("update-projects", false, "Update the project information")
@@ -47,39 +45,36 @@ func main() {
flag.Parse()
if *selfchecks {
- logger.Info.Println("Enabling periodical selfcheck")
+ slog.Info("Enabling periodical selfcheck")
go runSelfChecks()
selfcheck.Serve()
}
if *update {
- logger.Info.Println("Updating package data")
+ slog.Info("Updating package data")
portage.Update()
}
if *fullupdate {
- logger.Info.Println("Performing full update of the package data")
+ slog.Info("Performing full update of the package data")
portage.FullUpdate()
}
if *updateOutdatedPackages {
- logger.Info.Println("Updating the repology data")
+ slog.Info("Updating the repology data")
repology.UpdateOutdated()
}
if *updatePkgcheckResults {
- logger.Info.Println("Updating the qa-reports that is the pkgcheck data")
+ slog.Info("Updating the qa-reports that is the pkgcheck data")
pkgcheck.UpdatePkgCheckResults()
}
if *updatePullrequests {
- logger.Info.Println("Updating the pull requests data")
+ slog.Info("Updating the pull requests data")
github.FullUpdatePullRequests()
}
- if *initBugs {
- bugs.UpdateBugs(true)
- }
if *updateBugs {
- logger.Info.Println("Updating the bugs data")
- bugs.UpdateBugs(false)
+ slog.Info("Updating the bugs data")
+ bugs.UpdateBugs()
}
if *updateDependencies {
- logger.Info.Println("Updating the dependencies data")
+ slog.Info("Updating the dependencies data")
dependencies.FullPackageDependenciesUpdate()
}
if *updateProjects {
@@ -88,7 +83,7 @@ func main() {
// updateMaintainers should always be executed last, as it is using
// the updated bugs, pullrequests and and outdated packages
if *updateMaintainers {
- logger.Info.Println("Updating the maintainers data")
+ slog.Info("Updating the maintainers data")
maintainers.FullImport()
}
@@ -99,26 +94,45 @@ func main() {
if *help {
flag.PrintDefaults()
}
-
}
// initialize the loggers depending on whether
// config.debug is set to true
-func initLoggers(infoHandler io.Writer, errorHandler io.Writer) {
- if config.Debug() == "true" {
- logger.Init(os.Stdout, infoHandler, errorHandler)
- } else {
- logger.Init(ioutil.Discard, infoHandler, errorHandler)
+func initLoggers() {
+ errorHandler, err := os.OpenFile(config.LogFile(), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ log.Println("failed to open error log file", config.LogFile(), "error:", err)
+ errorHandler = os.Stderr
}
-}
-// TODO this has to be solved differently
-// wait for postgres to come up
-func waitForPostgres() {
- time.Sleep(5 * time.Second)
+ var handler slog.Handler
+ if config.Debug() {
+ handler = tint.NewHandler(os.Stdout, &tint.Options{
+ Level: slog.LevelDebug,
+ AddSource: true,
+ TimeFormat: time.DateTime,
+ })
+ } else {
+ handler = slogmulti.Fanout(
+ tint.NewHandler(os.Stdout, &tint.Options{
+ Level: slog.LevelInfo,
+ AddSource: true,
+ TimeFormat: time.DateTime,
+ NoColor: true,
+ }),
+ tint.NewHandler(errorHandler, &tint.Options{
+ Level: slog.LevelError,
+ AddSource: true,
+ TimeFormat: time.DateTime,
+ NoColor: true,
+ }),
+ )
+ }
+ slog.SetLogLoggerLevel(slog.LevelInfo)
+ slog.SetDefault(slog.New(handler))
}
func runSelfChecks() {
gocron.Every(1).Hour().From(gocron.NextTick()).Do(selfcheck.AllPackages)
- <- gocron.Start()
+ <-gocron.Start()
}
diff --git a/web/packs/application.js b/web/packs/application.js
index b4479bc..87bc08e 100644
--- a/web/packs/application.js
+++ b/web/packs/application.js
@@ -3,9 +3,7 @@ import "regenerator-runtime/runtime";
require("turbolinks").start();
import {} from 'jquery-ujs';
-import './src/vendor/javascripts/moment.min';
-import './src/javascript/arches';
import './src/javascript/kkuleomi';
import 'bootstrap';
diff --git a/web/packs/index.js b/web/packs/index.js
index 3790f16..2064302 100644
--- a/web/packs/index.js
+++ b/web/packs/index.js
@@ -1,3 +1,3 @@
-import './src/vendor/javascripts/jquery.typeahead.min'
+import 'jquery-typeahead/dist/jquery.typeahead.min.js'
import './src/javascript/index/typeahead'
import './src/javascript/index/query_generator'
diff --git a/web/packs/packages.js b/web/packs/packages.js
deleted file mode 100644
index cfdbfe1..0000000
--- a/web/packs/packages.js
+++ /dev/null
@@ -1 +0,0 @@
-import './src/javascript/packages/show' \ No newline at end of file
diff --git a/web/packs/src/javascript/arches.js b/web/packs/src/javascript/arches.js
deleted file mode 100644
index dee720f..0000000
--- a/web/packs/src/javascript/arches.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// Place all the behaviors and hooks related to the matching controller here.
-// All this logic will automatically be available in application.js.
diff --git a/web/packs/src/javascript/kkuleomi.js b/web/packs/src/javascript/kkuleomi.js
index 3a01529..73e1bce 100644
--- a/web/packs/src/javascript/kkuleomi.js
+++ b/web/packs/src/javascript/kkuleomi.js
@@ -1,9 +1,3 @@
-$(document).on('ready page:load kkuleomi:ajax', function(event) {
+$(document).on('ready page:load kkuleomi:ajax', function() {
$('[data-toggle="tooltip"]').tooltip();
-
- $('.kk-i18n-date').each(function(idx) {
- // TODO: Support different date formats
- var me = $(this);
- me.text(moment.unix(me.data('utcts')).local().format('ddd, D MMM YYYY HH:mm'));
- });
});
diff --git a/web/packs/src/javascript/packages/show.js b/web/packs/src/javascript/packages/show.js
deleted file mode 100644
index 9f25fd5..0000000
--- a/web/packs/src/javascript/packages/show.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// $(function() {
-// var atom = $('#package-title').data('atom');
-//
-// $.ajax({
-// url: '/packages/' + atom + '/changelog.html'
-// }).done(function(data) {
-// $('#changelog-container').html(data);
-// $(document).trigger('kkuleomi:ajax');
-// }).fail(function() {
-// $('#changelog-container > li').html('<span class="fa fa-fw fa-3x fa-ban text-danger"></span><br><br>Changelog currently not available. Please check back later.');
-// });
-// });
diff --git a/web/packs/src/stylesheets/application.scss b/web/packs/src/stylesheets/application.scss
index 135491d..dd8228a 100644
--- a/web/packs/src/stylesheets/application.scss
+++ b/web/packs/src/stylesheets/application.scss
@@ -11,4 +11,4 @@
@import "sprockets-octicons";
@import "useflags";
-@import "../vendor/stylesheets/jquery.typeahead.min";
+@import "~jquery-typeahead/dist/jquery.typeahead.min"
diff --git a/web/packs/src/stylesheets/misc.scss b/web/packs/src/stylesheets/misc.scss
index 17c9f2e..df35790 100644
--- a/web/packs/src/stylesheets/misc.scss
+++ b/web/packs/src/stylesheets/misc.scss
@@ -146,7 +146,7 @@ td .alert {
}
}
-body.kk .typeahead-list > li > a {
+body.kk .typeahead__list > li > a {
// Firefox workaround again
white-space: normal;
}
@@ -304,4 +304,4 @@ input[type="checkbox"].user-pref-checkbox:checked + label, input[type="checkbox"
.modal-content {
width: 100%;
}
-} \ No newline at end of file
+}
diff --git a/web/packs/src/vendor/javascripts/.keep b/web/packs/src/vendor/javascripts/.keep
deleted file mode 100644
index e69de29..0000000
--- a/web/packs/src/vendor/javascripts/.keep
+++ /dev/null
diff --git a/web/packs/src/vendor/javascripts/d3.min.js b/web/packs/src/vendor/javascripts/d3.min.js
deleted file mode 100644
index 6733ae4..0000000
--- a/web/packs/src/vendor/javascripts/d3.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
-},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
-},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
-},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
-return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();
diff --git a/web/packs/src/vendor/javascripts/jquery.typeahead.min.js b/web/packs/src/vendor/javascripts/jquery.typeahead.min.js
deleted file mode 100644
index 402bdd6..0000000
--- a/web/packs/src/vendor/javascripts/jquery.typeahead.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*!
- * jQuery Typeahead
- * Copyright (C) 2015 RunningCoder.org
- * Licensed under the MIT license
- *
- * @author Tom Bertrand
- * @version 2.1.2 (2015-09-28)
- * @link http://www.runningcoder.org/jquerytypeahead/
-*/
-!function(a,b,c,d){a.Typeahead={version:"2.1.2"};var e={input:null,minLength:2,maxItem:8,dynamic:!1,delay:300,order:null,offset:!1,hint:!1,accent:!1,highlight:!0,group:!1,maxItemPerGroup:null,dropdownFilter:!1,dynamicFilter:null,backdrop:!1,cache:!1,ttl:36e5,compression:!1,suggestion:!1,searchOnFocus:!1,resultContainer:null,generateOnLoad:null,mustSelectItem:!1,href:null,display:["display"],template:null,correlativeTemplate:!1,emptyTemplate:!1,source:null,callback:{onInit:null,onReady:null,onSearch:null,onResult:null,onLayoutBuiltBefore:null,onLayoutBuiltAfter:null,onNavigate:null,onMouseEnter:null,onMouseLeave:null,onClickBefore:null,onClickAfter:null,onSendRequest:null,onReceiveRequest:null,onSubmit:null},selector:{container:"typeahead-container",group:"typeahead-group",result:"typeahead-result",list:"typeahead-list",display:"typeahead-display",query:"typeahead-query",filter:"typeahead-filter",filterButton:"typeahead-filter-button",filterValue:"typeahead-filter-value",dropdown:"typeahead-dropdown",dropdownCarret:"typeahead-caret",button:"typeahead-button",backdrop:"typeahead-backdrop",hint:"typeahead-hint"},debug:!1},f=".typeahead",g={from:"ãàáäâẽèéëêìíïîõòóöôùúüûñç",to:"aaaaaeeeeeiiiiooooouuuunc"},h=~navigator.appVersion.indexOf("MSIE 9."),i=function(a,b){this.rawQuery="",this.query="",this.source={},this.isGenerated=null,this.generatedGroupCount=0,this.groupCount=0,this.groupBy="group",this.result=[],this.resultCount=0,this.options=b,this.node=a,this.container=null,this.resultContainer=null,this.item=null,this.xhr={},this.hintIndex=null,this.filters={dropdown:{},dynamic:{}},this.requests={},this.backdrop={},this.hint={},this.__construct()};i.prototype={extendOptions:function(){this.options.dynamic&&(this.options.cache=!1,this.options.compression=!1),this.options.cache&&(this.options.cache=function(){var b="undefined"!=typeof a.localStorage;if(b)try{a.localStorage.setItem("typeahead","typeahead"),a.localStorage.removeItem("typeahead")}catch(c){b=!1}return b}()),this.options.compression&&("object"==typeof LZString&&this.options.cache||(this.options.compression=!1)),"undefined"==typeof this.options.maxItem||/^\d+$/.test(this.options.maxItem)&&0!==this.options.maxItem||(this.options.maxItem=1/0),this.options.maxItemPerGroup&&!/^\d+$/.test(this.options.maxItemPerGroup)&&(this.options.maxItemPerGroup=null),!this.options.display||this.options.display instanceof Array||(this.options.display=[this.options.display]),!this.options.group||this.options.group instanceof Array||(this.options.group=[this.options.group]),!this.options.dynamicFilter||this.options.dynamicFilter instanceof Array||(this.options.dynamicFilter=[this.options.dynamicFilter]),this.options.resultContainer&&("string"==typeof this.options.resultContainer&&(this.options.resultContainer=c(this.options.resultContainer)),this.options.resultContainer instanceof jQuery&&this.options.resultContainer[0]&&(this.resultContainer=this.options.resultContainer)),this.options.group&&"string"==typeof this.options.group[0]&&this.options.maxItemPerGroup&&(this.groupBy=this.options.group[0]),this.options.callback&&this.options.callback.onClick&&(this.options.callback.onClickBefore=this.options.callback.onClick,delete this.options.callback.onClick),this.options=c.extend(!0,{},e,this.options)},unifySourceFormat:function(){if(this.options.source instanceof Array)return this.options.source={group:{data:this.options.source}},this.groupCount+=1,!0;("undefined"!=typeof this.options.source.data||"undefined"!=typeof this.options.source.url)&&(this.options.source={group:this.options.source});for(var a in this.options.source)if(this.options.source.hasOwnProperty(a)){if(("string"==typeof this.options.source[a]||this.options.source[a]instanceof Array)&&(this.options.source[a]={url:this.options.source[a]}),!this.options.source[a].data&&!this.options.source[a].url)return!1;!this.options.source[a].display||this.options.source[a].display instanceof Array||(this.options.source[a].display=[this.options.source[a].display]),this.options.source[a].ignore&&(this.options.source[a].ignore instanceof RegExp||delete this.options.source[a].ignore),this.groupCount+=1}return!0},init:function(){this.helper.executeCallback(this.options.callback.onInit,[this.node]),this.container=this.node.closest("."+this.options.selector.container)},delegateEvents:function(){var a=this,b=["focus"+f,"input"+f,"propertychange"+f,"keydown"+f,"keyup"+f,"dynamic"+f,"generateOnLoad"+f];this.container.off(f).on("click"+f+" touchstart"+f,function(b){b.stopPropagation(),a.options.dropdownFilter&&a.container.find("."+a.options.selector.dropdown.replace(" ",".")).hide()}),this.node.closest("form").on("submit",function(b){return a.options.mustSelectItem&&a.helper.isEmpty(a.item)?void b.preventDefault():(a.hideLayout(),a.rawQuery="",a.query="",a.helper.executeCallback(a.options.callback.onSubmit,[a.node,this,a.item,b])?!1:void 0)});var c=!1;this.node.off(f).on(b.join(" "),function(b){switch(b.type){case"generateOnLoad":case"focus":a.isGenerated&&a.options.searchOnFocus&&a.query.length>=a.options.minLength&&a.showLayout(),null!==a.isGenerated||a.options.dynamic||a.generateSource();break;case"keydown":a.isGenerated&&a.result.length&&b.keyCode&&~[13,27,38,39,40].indexOf(b.keyCode)&&(c=!0,a.navigate(b));break;case"keyup":h&&a.node[0].value.replace(/^\s+/,"").toString().length<a.query.length&&a.node.trigger("input"+f);break;case"propertychange":if(c){c=!1;break}case"input":if(a.rawQuery=a.node[0].value.toString(),a.query=a.node[0].value.replace(/^\s+/,"").toString(),a.options.hint&&a.hint.container&&""!==a.hint.container.val()&&0!==a.hint.container.val().indexOf(a.rawQuery)&&a.hint.container.val(""),a.options.dynamic)return a.isGenerated=null,void a.helper.typeWatch(function(){a.query.length>=a.options.minLength?a.generateSource():a.hideLayout()},a.options.delay);case"dynamic":if(!a.isGenerated)break;if(a.query.length<a.options.minLength){a.hideLayout();break}a.searchResult(),a.buildLayout(),a.result.length>0||a.options.emptyTemplate?a.showLayout():a.hideLayout()}}),this.options.generateOnLoad&&this.node.trigger("generateOnLoad"+f)},generateSource:function(){if(!this.isGenerated||this.options.dynamic){if(this.generatedGroupCount=0,this.isGenerated=!1,!this.helper.isEmpty(this.xhr)){for(var b in this.xhr)this.xhr.hasOwnProperty(b)&&this.xhr[b].abort();this.xhr={}}var c,d,e;for(c in this.options.source)if(this.options.source.hasOwnProperty(c)){if(this.options.cache&&(d=a.localStorage.getItem(this.node.selector+":"+c))){this.options.compression&&(d=LZString.decompressFromUTF16(d)),e=!1;try{d=JSON.parse(d+""),d.data&&d.ttl>(new Date).getTime()?(this.populateSource(d.data,c),e=!0):a.localStorage.removeItem(this.node.selector+":"+c)}catch(f){}if(e)continue}!this.options.source[c].data||this.options.source[c].url?this.options.source[c].url&&(this.requests[c]||(this.requests[c]=this.generateRequestObject(c))):this.populateSource("function"==typeof this.options.source[c].data&&this.options.source[c].data()||this.options.source[c].data,c)}this.handleRequests()}},generateRequestObject:function(a){var b={request:{url:null,dataType:"json"},extra:{path:null,group:a,callback:{done:null,fail:null,always:null,always:null}},validForGroup:[a]};!(this.options.source[a].url instanceof Array)&&this.options.source[a].url instanceof Object&&(this.options.source[a].url=[this.options.source[a].url]),this.options.source[a].url instanceof Array?(this.options.source[a].url[0]instanceof Object?(this.options.source[a].url[0].callback&&(b.extra.callback=this.options.source[a].url[0].callback,delete this.options.source[a].url[0].callback),b.request=c.extend(!0,b.request,this.options.source[a].url[0])):"string"==typeof this.options.source[a].url[0]&&(b.request.url=this.options.source[a].url[0]),this.options.source[a].url[1]&&"string"==typeof this.options.source[a].url[1]&&(b.extra.path=this.options.source[a].url[1])):"string"==typeof this.options.source[a].url&&(b.request.url=this.options.source[a].url),"jsonp"===b.request.dataType.toLowerCase()&&(b.request.jsonpCallback="callback_"+a);var d;for(var e in this.requests)if(this.requests.hasOwnProperty(e)&&(d=JSON.stringify(this.requests[e].request),d===JSON.stringify(b.request))){this.requests[e].validForGroup.push(a),b.isDuplicated=!0,delete b.validForGroup;break}return b},handleRequests:function(){var a=this,b=Object.keys(this.requests).length;b&&this.helper.executeCallback(this.options.callback.onSendRequest,[this.node,this.query]);for(var d in this.requests)this.requests.hasOwnProperty(d)&&(this.requests[d].isDuplicated||!function(d,e){var f;if(~e.request.url.indexOf("{{query}}")&&(e.request.url=e.request.url.replace("{{query}}",a.query)),e.request.data)for(var g in e.request.data)if(e.request.data.hasOwnProperty(g)&&~String(e.request.data[g]).indexOf("{{query}}")){e=c.extend(!0,{},e),e.request.data[g]=e.request.data[g].replace("{{query}}",a.query);break}a.xhr[d]=c.ajax(e.request).done(function(c,d,g){for(var h,i=0;i<e.validForGroup.length;i++)f=a.requests[e.validForGroup[i]],f.extra.callback.done instanceof Function&&(h=f.extra.callback.done(c,d,g),c=h instanceof Array&&h||c),a.populateSource(c,f.extra.group,f.extra.path),b-=1,0===b&&a.helper.executeCallback(a.options.callback.onReceiveRequest,[a.node,a.query])}).fail(function(b,c,d){for(var g=0;g<e.validForGroup.length;g++)f=a.requests[e.validForGroup[g]],f.extra.callback.fail instanceof Function&&f.extra.callback.fail(b,c,d)}).always(function(b,c){for(var d=0;d<e.validForGroup.length;d++)f=a.requests[e.validForGroup[d]],f.extra.callback.always instanceof Function&&f.extra.callback.always(b,c)}).always(function(b,c,d){for(var g=0;g<e.validForGroup.length;g++)f=a.requests[e.validForGroup[g]],f.extra.callback.always instanceof Function&&f.extra.callback.always(b,c,d)})}(d,this.requests[d]))},populateSource:function(a,b,c){var d=this,e=this.options.source[b].url&&this.options.source[b].data;a="string"==typeof c?this.helper.namespace(c,a):a,a instanceof Array||(a=[]),e&&("function"==typeof e&&(e=e()),e instanceof Array&&(a=a.concat(e)));for(var f,g=this.options.source[b].display?"compiled"===this.options.source[b].display[0]?this.options.source[b].display[1]:this.options.source[b].display[0]:"compiled"===this.options.display[0]?this.options.display[1]:this.options.display[0],h=0;h<a.length;h++)"string"==typeof a[h]&&(f={},f[g]=a[h],a[h]=f),a[h].group=b;if(this.options.correlativeTemplate){var i=this.options.source[b].template||this.options.template;if(i){i=i.replace(/<.+?>/g,"");for(var h=0;h<a.length;h++)a[h].compiled=i.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(b,c){return d.helper.namespace(c,a[h],"get","")}).trim();this.options.source[b].display?~this.options.source[b].display.indexOf("compiled")||this.options.source[b].display.unshift("compiled"):~this.options.display.indexOf("compiled")||this.options.display.unshift("compiled")}else;}if(this.source[b]=a,this.options.cache&&!localStorage.getItem(this.node.selector+":"+b)){var j=JSON.stringify({data:a,ttl:(new Date).getTime()+this.options.ttl});this.options.compression&&(j=LZString.compressToUTF16(j)),localStorage.setItem(this.node.selector+":"+b,j)}this.incrementGeneratedGroup()},incrementGeneratedGroup:function(){this.generatedGroupCount+=1,this.groupCount===this.generatedGroupCount&&(this.isGenerated=!0,this.node.trigger("dynamic"+f))},navigate:function(a){this.helper.executeCallback(this.options.callback.onNavigate,[this.node,this.query,a]);var b=this.resultContainer.find("> ul > li:not([data-search-group])"),c=b.filter(".active"),d=c[0]&&b.index(c)||null;if(27===a.keyCode)return void(this.container.hasClass("result")&&(a.preventDefault(),this.hideLayout()));if(13===a.keyCode){if(c.length>0)return a.preventDefault(),a.stopPropagation(),void c.find("a:first").trigger("click");if(this.options.mustSelectItem&&this.helper.isEmpty(this.item))return;return void this.hideLayout()}if(39===a.keyCode)return void(d?b.eq(d).find("a:first").trigger("click"):this.options.hint&&""!==this.hint.container.val()&&this.helper.getCaret(this.node[0])>=this.query.length&&b.find('a[data-index="'+this.hintIndex+'"]').trigger("click"));if(b.length>0&&c.removeClass("active"),38===a.keyCode?(a.preventDefault(),c.length>0?d-1>=0&&b.eq(d-1).addClass("active"):b.last().addClass("active")):40===a.keyCode&&(a.preventDefault(),c.length>0?d+1<b.length&&b.eq(d+1).addClass("active"):b.first().addClass("active")),c=b.filter(".active"),this.options.hint&&this.hint.container&&(c.length>0?this.hint.container.css("color",this.hint.container.css("background-color")||"fff"):this.hint.container.css("color",this.hint.css.color)),c.length>0){var e=c.find("a:first").attr("data-index");e&&this.node.val(this.result[e][this.result[e].matchedKey])}else this.node.val(this.rawQuery)},searchResult:function(a){a||(this.item={}),this.helper.executeCallback(this.options.callback.onSearch,[this.node,this.query]),this.result=[],this.resultCount=0;var b,c,d,e,f,g,h,i,j,k=this,l=this.query.toLowerCase(),m={},n=this.filters.dropdown&&this.filters.dropdown.key||this.groupBy,o=this.filters.dynamic&&!this.helper.isEmpty(this.filters.dynamic);this.options.accent&&(l=this.helper.removeAccent(l));for(b in this.source)if(this.source.hasOwnProperty(b)&&(!this.filters.dropdown||"group"!==this.filters.dropdown.key||this.filters.dropdown.value===b)){if(this.options.maxItemPerGroup&&"group"===n)if(m[b]){if(m[b]>=this.options.maxItemPerGroup&&!this.options.callback.onResult)break}else m[b]=0;g="undefined"==typeof this.options.source[b].filter||this.options.source[b].filter===!0;for(var p=0;p<this.source[b].length&&(!(this.result.length>=this.options.maxItem)||this.options.callback.onResult);p++)if(!o||this.dynamicFilter.validate.apply(this,[this.source[b][p]])){if(c=this.source[b][p],this.options.maxItemPerGroup&&"group"!==n)if(m[c[n]]){if(m[c[n]]>=this.options.maxItemPerGroup&&!this.options.callback.onResult)continue}else m[c[n]]=0;f=this.options.source[b].display||this.options.display;for(var q=0;q<f.length;q++){if(g){if(e=c[f[q]],!e)continue;if(e=e.toString().toLowerCase(),this.options.accent&&(e=this.helper.removeAccent(e)),d=e.indexOf(l),this.options.correlativeTemplate&&"compiled"===f[q]&&0>d&&/\s/.test(l)){h=!0,i=l.split(" "),j=e;for(var r=0;r<i.length;r++)if(""!==i[r]){if(!~j.indexOf(i[r])){h=!1;break}j=j.replace(i[r],"")}}if(0>d&&!h)continue;if(this.options.offset&&0!==d)continue;if(this.options.source[b].ignore&&this.options.source[b].ignore.test(e))continue}if(!this.filters.dropdown||this.filters.dropdown.value==c[this.filters.dropdown.key]){if(this.resultCount+=1,this.options.callback.onResult&&this.result.length>=this.options.maxItem||this.options.maxItemPerGroup&&m[c[n]]>=this.options.maxItemPerGroup)break;c.matchedKey=f[q],this.result.push(c),this.options.maxItemPerGroup&&(m[c[n]]+=1);break}}}}if(this.options.order){for(var s,f=[],q=0;q<this.result.length;q++)s=this.options.source[this.result[q].group].display||this.options.display,~f.indexOf(s[0])||f.push(s[0]);this.result.sort(k.helper.sort(f,"asc"===k.options.order,function(a){return a.toString().toUpperCase()}))}this.helper.executeCallback(this.options.callback.onResult,[this.node,this.query,this.result,this.resultCount])},buildLayout:function(){this.resultContainer||(this.resultContainer=c("<div/>",{"class":this.options.selector.result}),this.container.append(this.resultContainer));var a=this.query.toLowerCase();this.options.accent&&(a=this.helper.removeAccent(a));var b=this,d=c("<ul/>",{"class":this.options.selector.list+(b.helper.isEmpty(b.result)?" empty":""),html:function(){if(b.options.emptyTemplate&&b.helper.isEmpty(b.result))return c("<li/>",{html:c("<a/>",{href:"javascript:;",html:"function"==typeof b.options.emptyTemplate&&b.options.emptyTemplate(b.query)||b.options.emptyTemplate.replace(/\{\{query}}/gi,b.query)})});for(var d in b.result)b.result.hasOwnProperty(d)&&!function(d,e,f){var g,h,i,j,k,l=e.group,m={},n=b.options.source[e.group].display||b.options.display,o=b.options.source[e.group].href||b.options.href;b.options.group&&("boolean"!=typeof b.options.group[0]&&e[b.options.group[0]]&&(l=e[b.options.group[0]]),c(f).find('li[data-search-group="'+l+'"]')[0]||c(f).append(c("<li/>",{"class":b.options.selector.group,html:c("<a/>",{href:"javascript:;",html:b.options.group[1]&&b.options.group[1].replace(/(\{\{group}})/gi,e[b.options.group[0]]||l)||l}),"data-search-group":l})));for(var p=0;p<n.length;p++)i=n[p],m[i]=e[i];g=c("<li/>",{html:c("<a/>",{href:function(){return o&&("string"==typeof o?o=o.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(a,c,d){var f=b.helper.namespace(c,e,"get","");return d&&"raw"===d?f:b.helper.slugify(f)}):"function"==typeof o&&(o=o(e)),e.href=o),o||"javascript:;"},"data-group":l,"data-index":d,html:function(){k=e.group&&b.options.source[e.group].template||b.options.template,h=k?k.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(a,c,d){var f=b.helper.namespace(c,e,"get","");return d&&"raw"===d?f:b.helper.namespace(c,m,"get","")||f}):'<span class="'+b.options.selector.display+'">'+b.helper.joinObject(m," ")+"</span>",b.options.highlight&&(h=b.helper.highlight(h,a.split(" "),b.options.accent)),c(this).append(h)},click:function(a){return b.options.mustSelectItem&&b.helper.isEmpty(e)?void a.preventDefault():(b.item=e,b.helper.executeCallback(b.options.callback.onClickBefore,[b.node,this,e,a]),void(a.isDefaultPrevented()||(a.preventDefault(),b.query=b.rawQuery=e[e.matchedKey].toString(),b.node.val(b.query).focus(),b.searchResult(!0),b.buildLayout(),b.hideLayout(),b.helper.executeCallback(b.options.callback.onClickAfter,[b.node,this,e,a]))))},mouseenter:function(a){c(this).closest("ul").find("li.active").removeClass("active"),c(this).closest("li").addClass("active"),b.helper.executeCallback(b.options.callback.onMouseEnter,[b.node,this,e,a])},mouseleave:function(a){c(this).closest("li").removeClass("active"),b.helper.executeCallback(b.options.callback.onMouseLeave,[b.node,this,e,a])}})}),b.options.group?(j=c(f).find('a[data-group="'+l+'"]:last').closest("li"),j[0]||(j=c(f).find('li[data-search-group="'+l+'"]')),c(g).insertAfter(j)):c(f).append(g)}(d,b.result[d],this)}});if(this.options.callback.onLayoutBuiltBefore){var f=this.helper.executeCallback(this.options.callback.onLayoutBuiltBefore,[this.node,this.query,this.result,d]);f instanceof jQuery&&(d=f)}if(this.container.addClass("result"),this.resultContainer.html(d),this.options.callback.onLayoutBuiltAfter&&this.helper.executeCallback(this.options.callback.onLayoutBuiltAfter,[this.node,this.query,this.result]),this.options.backdrop&&(this.backdrop.container?this.backdrop.container.show():(this.backdrop.css=c.extend({opacity:.6,filter:"alpha(opacity=60)",position:"fixed",top:0,right:0,bottom:0,left:0,"z-index":1040,"background-color":"#000"},this.options.backdrop),this.backdrop.container=c("<div/>",{"class":this.options.selector.backdrop,css:this.backdrop.css,click:function(){b.hideLayout()}}).insertAfter(this.container)),this.container.addClass("backdrop").css({"z-index":this.backdrop.css["z-index"]+1,position:"relative"})),this.options.hint){var g="";if(this.result.length>0&&this.query.length>0){this.hint.container||(this.hint.css=c.extend({"border-color":"transparent",position:"absolute",top:0,display:"inline","z-index":-1,"float":"none",color:"silver","box-shadow":"none",cursor:"default","-webkit-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none"},this.options.hint),this.hint.container=c("<input/>",{type:this.node.attr("type"),"class":this.node.attr("class"),readonly:!0,unselectable:"on",tabindex:-1,click:function(){b.node.focus()}}).addClass(e.selector.hint).css(this.hint.css).insertAfter(this.node),this.node.parent().css({position:"relative"})),this.hint.container.css("color",this.hint.css.color);var h,i,j;this.hintIndex=null;for(var k=0;k<this.result.length;k++){i=this.result[k].group,h=b.options.source[i].display||b.options.display;for(var l=0;l<h.length;l++)if(j=String(this.result[k][h[l]]).toLowerCase(),this.options.accent&&(j=this.helper.removeAccent(j)),0===j.indexOf(a)){g=String(this.result[k][h[l]]),this.hintIndex=k;break}if(null!==this.hintIndex)break}}this.hint.container&&this.hint.container.val(g.length>0&&this.rawQuery+g.substring(this.query.length)||"").show()}},buildDropdownLayout:function(){function a(a){"*"===a.value?delete this.filters.dropdown:this.filters.dropdown=a,this.container.removeClass("filter").find("."+this.options.selector.filterValue).html(a.display||a.value),this.node.trigger("dynamic"+f),this.node.focus()}if(this.options.dropdownFilter){var b,d=this;if("boolean"==typeof this.options.dropdownFilter)b="all";else if("string"==typeof this.options.dropdownFilter)b=this.options.dropdownFilter;else if(this.options.dropdownFilter instanceof Array)for(var e=0;e<this.options.dropdownFilter.length;e++)if("*"===this.options.dropdownFilter[e].value&&this.options.dropdownFilter[e].display){b=this.options.dropdownFilter[e].display;break}c("<span/>",{"class":this.options.selector.filter,html:function(){c(this).append(c("<button/>",{type:"button","class":d.options.selector.filterButton,html:"<span class='"+d.options.selector.filterValue+"'>"+b+"</span> <span class='"+d.options.selector.dropdownCarret+"'></span>",click:function(a){a.stopPropagation();var b=d.container.find("."+d.options.selector.dropdown.replace(" ","."));b.is(":visible")?(d.container.removeClass("filter"),b.hide(),c("html").off(f+".dropdownFilter")):(d.container.addClass("filter"),b.show(),c("html").off(f+".dropdownFilter").on("click"+f+".dropdownFilter touchstart"+f+".dropdownFilter",function(){d.container.removeClass("filter"),b.hide(),c(this).off(f+".dropdownFilter")}))}})),c(this).append(c("<ul/>",{"class":d.options.selector.dropdown,html:function(){var b=d.options.dropdownFilter;if(~["string","boolean"].indexOf(typeof d.options.dropdownFilter)){b=[];for(var e in d.options.source)d.options.source.hasOwnProperty(e)&&b.push({key:"group",value:e});b.push({key:"group",value:"*",display:"string"==typeof d.options.dropdownFilter&&d.options.dropdownFilter||"All"})}for(var f=0;f<b.length;f++)!function(b,e,f){(e.key||"*"===e.value)&&e.value&&("*"===e.value&&c(f).append(c("<li/>",{"class":"divider"})),c(f).append(c("<li/>",{html:c("<a/>",{href:"javascript:;",html:e.display||e.value,click:function(b){b.preventDefault(),a.apply(d,[e])}})})))}(f,b[f],this)}}))}}).insertAfter(d.container.find("."+d.options.selector.query))}},dynamicFilter:{validate:function(a){var b,c,d=null,e=null;for(var f in this.filters.dynamic)if(this.filters.dynamic.hasOwnProperty(f)&&(c=~f.indexOf(".")?this.helper.namespace(f,a,"get"):a[f],"|"!==this.filters.dynamic[f].modifier||d||(d=c==this.filters.dynamic[f].value||!1),"&"===this.filters.dynamic[f].modifier)){if(c!=this.filters.dynamic[f].value){e=!1;break}e=!0}return b=d,null!==e&&(b=e,e===!0&&null!==d&&(b=d)),!!b},set:function(a,b){var c=a.match(/^([|&])?(.+)/);b?this.filters.dynamic[c[2]]={modifier:c[1]||"|",value:b}:delete this.filters.dynamic[c[2]],this.searchResult(),this.buildLayout()},bind:function(){if(this.options.dynamicFilter)for(var a,b=this,d=0;d<this.options.dynamicFilter.length;d++)a=this.options.dynamicFilter[d],"string"==typeof a.selector&&(a.selector=c(a.selector)),a.selector instanceof jQuery&&a.selector[0]&&a.key&&!function(a){a.selector.off(f).on("change"+f,function(){b.dynamicFilter.set.apply(b,[a.key,b.dynamicFilter.getValue(this)])}).trigger("change"+f)}(a)},getValue:function(a){var b;return"SELECT"===a.tagName?b=a.value:"INPUT"===a.tagName&&("checkbox"===a.type?b=a.checked||null:"radio"===a.type&&a.checked&&(b=a.value)),b}},showLayout:function(){var a=this;c("html").off(f).on("click"+f+" touchstart"+f,function(){a.hideLayout(),c(this).off(f)}),(this.result.length||this.options.emptyTemplate)&&this.container.addClass("result hint backdrop")},hideLayout:function(){this.container.removeClass("result hint backdrop filter")},__construct:function(){this.extendOptions(),this.unifySourceFormat()&&(this.init(),this.delegateEvents(),this.buildDropdownLayout(),this.dynamicFilter.bind.apply(this),this.helper.executeCallback(this.options.callback.onReady,[this.node]))},helper:{isEmpty:function(a){for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},removeAccent:function(a){return"string"==typeof a?a=a.toLowerCase().replace(new RegExp("["+g.from+"]","g"),function(a){return g.to[g.from.indexOf(a)]}):void 0},slugify:function(a){return a=String(a),""!==a&&(a=this.removeAccent(a),a=a.replace(/[^-a-z0-9]+/g,"-").replace(/-+/g,"-").trim("-")),a},sort:function(a,b,c){var d=function(b){for(var d=0;d<a.length;d++)if("undefined"!=typeof b[a[d]])return c(b[a[d]])};return b=[-1,1][+!!b],function(a,c){return a=d(a),c=d(c),b*((a>c)-(c>a))}},replaceAt:function(a,b,c,d){return a.substring(0,b)+d+a.substring(b+c)},highlight:function(a,b,c){a=String(a);var d=c&&this.removeAccent(a)||a,e=[];b instanceof Array||(b=[b]),b.sort(function(a,b){return b.length-a.length});for(var f=b.length-1;f>=0;f--)""!==b[f].trim()?b[f]=b[f].replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"):b.splice(f,1);d.replace(new RegExp("(?:"+b.join("|")+")(?!([^<]+)?>)","gi"),function(a,b,c){e.push({offset:c,length:a.length})});for(var f=e.length-1;f>=0;f--)a=this.replaceAt(a,e[f].offset,e[f].length,"<strong>"+a.substr(e[f].offset,e[f].length)+"</strong>");return a},joinObject:function(a,b){var c="",d=0;for(var e in a)a.hasOwnProperty(e)&&(0!==d&&(c+=b),c+=a[e],d++);return c},getCaret:function(a){if(a.selectionStart)return a.selectionStart;if(b.selection){a.focus();var c=b.selection.createRange();if(null==c)return 0;var d=a.createTextRange(),e=d.duplicate();return d.moveToBookmark(c.getBookmark()),e.setEndPoint("EndToStart",d),e.text.length}return 0},executeCallback:function(b,d){if(!b)return!1;var e;d[0];if("function"==typeof b)e=b;else if(("string"==typeof b||b instanceof Array)&&("string"==typeof b&&(b=[b,[]]),e=this.helper.namespace(b[0],a),"function"!=typeof e))return!1;return e.apply(this,c.merge(b[1]||[],d?d:[]))||!0},namespace:function(b,c,e,f){if("string"!=typeof b||""===b)return!1;for(var g=b.split("."),h=c||a,e=e||"get",i=f||{},j="",k=0,l=g.length;l>k;k++){if(j=g[k],"undefined"==typeof h[j]){if(~["get","delete"].indexOf(e))return"undefined"!=typeof f?f:d;h[j]={}}if(~["set","create","delete"].indexOf(e)&&k===l-1){if("set"!==e&&"create"!==e)return delete h[j],!0;h[j]=i}h=h[j]}return h},typeWatch:function(){var a=0;return function(b,c){clearTimeout(a),a=setTimeout(b,c)}}()}},c.fn.typeahead=c.typeahead=function(a){return j.typeahead(this,a)};var j={typeahead:function(b,d){if(d&&d.source&&"object"==typeof d.source){if("function"==typeof b){if(!d.input)return;b=c(d.input)}if(b.length)for(var e,f=0;f<b.length;f++)e=1===b.length?b:c(b.selector.split(",")[f].trim()),a.Typeahead[e.selector]=new i(e,d)}}};a.console=a.console||{log:function(){}},"trim"in String.prototype||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),"indexOf"in Array.prototype||(Array.prototype.indexOf=function(a,b){b===d&&(b=0),0>b&&(b+=this.length),0>b&&(b=0);for(var c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1}),Object.keys||(Object.keys=function(a){var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c})}(window,document,window.jQuery);
diff --git a/web/packs/src/vendor/javascripts/moment.min.js b/web/packs/src/vendor/javascripts/moment.min.js
deleted file mode 100644
index 3272fa4..0000000
--- a/web/packs/src/vendor/javascripts/moment.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-//! moment.js
-//! version : 2.10.6
-//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
-//! license : MIT
-//! momentjs.com
-!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Hc.apply(null,arguments)}function b(a){Hc=a}function c(a){return"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function f(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function g(a,b){for(var c in b)f(b,c)&&(a[c]=b[c]);return f(b,"toString")&&(a.toString=b.toString),f(b,"valueOf")&&(a.valueOf=b.valueOf),a}function h(a,b,c,d){return Ca(a,b,c,d,!0).utc()}function i(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function j(a){return null==a._pf&&(a._pf=i()),a._pf}function k(a){if(null==a._isValid){var b=j(a);a._isValid=!(isNaN(a._d.getTime())||!(b.overflow<0)||b.empty||b.invalidMonth||b.invalidWeekday||b.nullInput||b.invalidFormat||b.userInvalidated),a._strict&&(a._isValid=a._isValid&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour)}return a._isValid}function l(a){var b=h(NaN);return null!=a?g(j(b),a):j(b).userInvalidated=!0,b}function m(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=j(b)),"undefined"!=typeof b._locale&&(a._locale=b._locale),Jc.length>0)for(c in Jc)d=Jc[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function n(b){m(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),Kc===!1&&(Kc=!0,a.updateOffset(this),Kc=!1)}function o(a){return a instanceof n||null!=a&&null!=a._isAMomentObject}function p(a){return 0>a?Math.ceil(a):Math.floor(a)}function q(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=p(b)),c}function r(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&q(a[d])!==q(b[d]))&&g++;return g+f}function s(){}function t(a){return a?a.toLowerCase().replace("_","-"):a}function u(a){for(var b,c,d,e,f=0;f<a.length;){for(e=t(a[f]).split("-"),b=e.length,c=t(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=v(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&r(e,c,!0)>=b-1)break;b--}f++}return null}function v(a){var b=null;if(!Lc[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Ic._abbr,require("./locale/"+a),w(b)}catch(c){}return Lc[a]}function w(a,b){var c;return a&&(c="undefined"==typeof b?y(a):x(a,b),c&&(Ic=c)),Ic._abbr}function x(a,b){return null!==b?(b.abbr=a,Lc[a]=Lc[a]||new s,Lc[a].set(b),w(a),Lc[a]):(delete Lc[a],null)}function y(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Ic;if(!c(a)){if(b=v(a))return b;a=[a]}return u(a)}function z(a,b){var c=a.toLowerCase();Mc[c]=Mc[c+"s"]=Mc[b]=a}function A(a){return"string"==typeof a?Mc[a]||Mc[a.toLowerCase()]:void 0}function B(a){var b,c,d={};for(c in a)f(a,c)&&(b=A(c),b&&(d[b]=a[c]));return d}function C(b,c){return function(d){return null!=d?(E(this,b,d),a.updateOffset(this,c),this):D(this,b)}}function D(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function E(a,b,c){return a._d["set"+(a._isUTC?"UTC":"")+b](c)}function F(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=A(a),"function"==typeof this[a])return this[a](b);return this}function G(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function H(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Qc[a]=e),b&&(Qc[b[0]]=function(){return G(e.apply(this,arguments),b[1],b[2])}),c&&(Qc[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function I(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function J(a){var b,c,d=a.match(Nc);for(b=0,c=d.length;c>b;b++)Qc[d[b]]?d[b]=Qc[d[b]]:d[b]=I(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function K(a,b){return a.isValid()?(b=L(b,a.localeData()),Pc[b]=Pc[b]||J(b),Pc[b](a)):a.localeData().invalidDate()}function L(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Oc.lastIndex=0;d>=0&&Oc.test(a);)a=a.replace(Oc,c),Oc.lastIndex=0,d-=1;return a}function M(a){return"function"==typeof a&&"[object Function]"===Object.prototype.toString.call(a)}function N(a,b,c){dd[a]=M(b)?b:function(a){return a&&c?c:b}}function O(a,b){return f(dd,a)?dd[a](b._strict,b._locale):new RegExp(P(a))}function P(a){return a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function Q(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=q(a)}),c=0;c<a.length;c++)ed[a[c]]=d}function R(a,b){Q(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function S(a,b,c){null!=b&&f(ed,a)&&ed[a](b,c._a,c,a)}function T(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function U(a){return this._months[a.month()]}function V(a){return this._monthsShort[a.month()]}function W(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function X(a,b){var c;return"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),T(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function Y(b){return null!=b?(X(this,b),a.updateOffset(this,!0),this):D(this,"Month")}function Z(){return T(this.year(),this.month())}function $(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[gd]<0||c[gd]>11?gd:c[hd]<1||c[hd]>T(c[fd],c[gd])?hd:c[id]<0||c[id]>24||24===c[id]&&(0!==c[jd]||0!==c[kd]||0!==c[ld])?id:c[jd]<0||c[jd]>59?jd:c[kd]<0||c[kd]>59?kd:c[ld]<0||c[ld]>999?ld:-1,j(a)._overflowDayOfYear&&(fd>b||b>hd)&&(b=hd),j(a).overflow=b),a}function _(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function aa(a,b){var c=!0;return g(function(){return c&&(_(a+"\n"+(new Error).stack),c=!1),b.apply(this,arguments)},b)}function ba(a,b){od[a]||(_(b),od[a]=!0)}function ca(a){var b,c,d=a._i,e=pd.exec(d);if(e){for(j(a).iso=!0,b=0,c=qd.length;c>b;b++)if(qd[b][1].exec(d)){a._f=qd[b][0];break}for(b=0,c=rd.length;c>b;b++)if(rd[b][1].exec(d)){a._f+=(e[6]||" ")+rd[b][0];break}d.match(ad)&&(a._f+="Z"),va(a)}else a._isValid=!1}function da(b){var c=sd.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(ca(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function ea(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function fa(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function ga(a){return ha(a)?366:365}function ha(a){return a%4===0&&a%100!==0||a%400===0}function ia(){return ha(this.year())}function ja(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=Da(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function ka(a){return ja(a,this._week.dow,this._week.doy).week}function la(){return this._week.dow}function ma(){return this._week.doy}function na(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function oa(a){var b=ja(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function pa(a,b,c,d,e){var f,g=6+e-d,h=fa(a,0,1+g),i=h.getUTCDay();return e>i&&(i+=7),c=null!=c?1*c:e,f=1+g+7*(b-1)-i+c,{year:f>0?a:a-1,dayOfYear:f>0?f:ga(a-1)+f}}function qa(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function ra(a,b,c){return null!=a?a:null!=b?b:c}function sa(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function ta(a){var b,c,d,e,f=[];if(!a._d){for(d=sa(a),a._w&&null==a._a[hd]&&null==a._a[gd]&&ua(a),a._dayOfYear&&(e=ra(a._a[fd],d[fd]),a._dayOfYear>ga(e)&&(j(a)._overflowDayOfYear=!0),c=fa(e,0,a._dayOfYear),a._a[gd]=c.getUTCMonth(),a._a[hd]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[id]&&0===a._a[jd]&&0===a._a[kd]&&0===a._a[ld]&&(a._nextDay=!0,a._a[id]=0),a._d=(a._useUTC?fa:ea).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[id]=24)}}function ua(a){var b,c,d,e,f,g,h;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=ra(b.GG,a._a[fd],ja(Da(),1,4).year),d=ra(b.W,1),e=ra(b.E,1)):(f=a._locale._week.dow,g=a._locale._week.doy,c=ra(b.gg,a._a[fd],ja(Da(),f,g).year),d=ra(b.w,1),null!=b.d?(e=b.d,f>e&&++d):e=null!=b.e?b.e+f:f),h=pa(c,d,e,g,f),a._a[fd]=h.year,a._dayOfYear=h.dayOfYear}function va(b){if(b._f===a.ISO_8601)return void ca(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=L(b._f,b._locale).match(Nc)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(O(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),Qc[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),S(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[id]<=12&&b._a[id]>0&&(j(b).bigHour=void 0),b._a[id]=wa(b._locale,b._a[id],b._meridiem),ta(b),$(b)}function wa(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function xa(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=m({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],va(b),k(b)&&(f+=j(b).charsLeftOver,f+=10*j(b).unusedTokens.length,j(b).score=f,(null==d||d>f)&&(d=f,c=b));g(a,c||b)}function ya(a){if(!a._d){var b=B(a._i);a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],ta(a)}}function za(a){var b=new n($(Aa(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Aa(a){var b=a._i,e=a._f;return a._locale=a._locale||y(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),o(b)?new n($(b)):(c(e)?xa(a):e?va(a):d(b)?a._d=b:Ba(a),a))}function Ba(b){var f=b._i;void 0===f?b._d=new Date:d(f)?b._d=new Date(+f):"string"==typeof f?da(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),ta(b)):"object"==typeof f?ya(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ca(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,za(f)}function Da(a,b,c,d){return Ca(a,b,c,d,!1)}function Ea(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Da();for(d=b[0],e=1;e<b.length;++e)(!b[e].isValid()||b[e][a](d))&&(d=b[e]);return d}function Fa(){var a=[].slice.call(arguments,0);return Ea("isBefore",a)}function Ga(){var a=[].slice.call(arguments,0);return Ea("isAfter",a)}function Ha(a){var b=B(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=y(),this._bubble()}function Ia(a){return a instanceof Ha}function Ja(a,b){H(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+G(~~(a/60),2)+b+G(~~a%60,2)})}function Ka(a){var b=(a||"").match(ad)||[],c=b[b.length-1]||[],d=(c+"").match(xd)||["-",0,0],e=+(60*d[1])+q(d[2]);return"+"===d[0]?e:-e}function La(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(o(b)||d(b)?+b:+Da(b))-+e,e._d.setTime(+e._d+f),a.updateOffset(e,!1),e):Da(b).local()}function Ma(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Na(b,c){var d,e=this._offset||0;return null!=b?("string"==typeof b&&(b=Ka(b)),Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ma(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?bb(this,Ya(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ma(this)}function Oa(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Pa(a){return this.utcOffset(0,a)}function Qa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ma(this),"m")),this}function Ra(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ka(this._i)),this}function Sa(a){return a=a?Da(a).utcOffset():0,(this.utcOffset()-a)%60===0}function Ta(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ua(){if("undefined"!=typeof this._isDSTShifted)return this._isDSTShifted;var a={};if(m(a,this),a=Aa(a),a._a){var b=a._isUTC?h(a._a):Da(a._a);this._isDSTShifted=this.isValid()&&r(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Va(){return!this._isUTC}function Wa(){return this._isUTC}function Xa(){return this._isUTC&&0===this._offset}function Ya(a,b){var c,d,e,g=a,h=null;return Ia(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=yd.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:q(h[hd])*c,h:q(h[id])*c,m:q(h[jd])*c,s:q(h[kd])*c,ms:q(h[ld])*c}):(h=zd.exec(a))?(c="-"===h[1]?-1:1,g={y:Za(h[2],c),M:Za(h[3],c),d:Za(h[4],c),h:Za(h[5],c),m:Za(h[6],c),s:Za(h[7],c),w:Za(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=_a(Da(g.from),Da(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Ha(g),Ia(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function Za(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function $a(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function _a(a,b){var c;return b=La(b,a),a.isBefore(b)?c=$a(a,b):(c=$a(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c}function ab(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(ba(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Ya(c,d),bb(this,e,a),this}}function bb(b,c,d,e){var f=c._milliseconds,g=c._days,h=c._months;e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&E(b,"Date",D(b,"Date")+g*d),h&&X(b,D(b,"Month")+h*d),e&&a.updateOffset(b,g||h)}function cb(a,b){var c=a||Da(),d=La(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse";return this.format(b&&b[f]||this.localeData().calendar(f,this,Da(c)))}function db(){return new n(this)}function eb(a,b){var c;return b=A("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+this>+a):(c=o(a)?+a:+Da(a),c<+this.clone().startOf(b))}function fb(a,b){var c;return b=A("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+a>+this):(c=o(a)?+a:+Da(a),+this.clone().endOf(b)<c)}function gb(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)}function hb(a,b){var c;return b=A(b||"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+this===+a):(c=+Da(a),+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))}function ib(a,b,c){var d,e,f=La(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=A(b),"year"===b||"month"===b||"quarter"===b?(e=jb(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:p(e)}function jb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function kb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function lb(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?"function"==typeof Date.prototype.toISOString?this.toDate().toISOString():K(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):K(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function mb(b){var c=K(this,b||a.defaultFormat);return this.localeData().postformat(c)}function nb(a,b){return this.isValid()?Ya({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function ob(a){return this.from(Da(),a)}function pb(a,b){return this.isValid()?Ya({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function qb(a){return this.to(Da(),a)}function rb(a){var b;return void 0===a?this._locale._abbr:(b=y(a),null!=b&&(this._locale=b),this)}function sb(){return this._locale}function tb(a){switch(a=A(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function ub(a){return a=A(a),void 0===a||"millisecond"===a?this:this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms")}function vb(){return+this._d-6e4*(this._offset||0)}function wb(){return Math.floor(+this/1e3)}function xb(){return this._offset?new Date(+this):this._d}function yb(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function zb(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function Ab(){return k(this)}function Bb(){return g({},j(this))}function Cb(){return j(this).overflow}function Db(a,b){H(0,[a,a.length],0,b)}function Eb(a,b,c){return ja(Da([a,11,31+b-c]),b,c).week}function Fb(a){var b=ja(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")}function Gb(a){var b=ja(this,1,4).year;return null==a?b:this.add(a-b,"y")}function Hb(){return Eb(this.year(),1,4)}function Ib(){var a=this.localeData()._week;return Eb(this.year(),a.dow,a.doy)}function Jb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Kb(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Lb(a){return this._weekdays[a.day()]}function Mb(a){return this._weekdaysShort[a.day()]}function Nb(a){return this._weekdaysMin[a.day()]}function Ob(a){var b,c,d;for(this._weekdaysParse=this._weekdaysParse||[],b=0;7>b;b++)if(this._weekdaysParse[b]||(c=Da([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b}function Pb(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Kb(a,this.localeData()),this.add(a-b,"d")):b}function Qb(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Rb(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)}function Sb(a,b){H(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Tb(a,b){return b._meridiemParse}function Ub(a){return"p"===(a+"").toLowerCase().charAt(0)}function Vb(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Wb(a,b){b[ld]=q(1e3*("0."+a))}function Xb(){return this._isUTC?"UTC":""}function Yb(){return this._isUTC?"Coordinated Universal Time":""}function Zb(a){return Da(1e3*a)}function $b(){return Da.apply(null,arguments).parseZone()}function _b(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.call(b,c):d}function ac(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function bc(){return this._invalidDate}function cc(a){return this._ordinal.replace("%d",a)}function dc(a){return a}function ec(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)}function fc(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)}function gc(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function hc(a,b,c,d){var e=y(),f=h().set(d,b);return e[c](f,a)}function ic(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return hc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=hc(a,f,c,e);return g}function jc(a,b){return ic(a,b,"months",12,"month")}function kc(a,b){return ic(a,b,"monthsShort",12,"month")}function lc(a,b){return ic(a,b,"weekdays",7,"day")}function mc(a,b){return ic(a,b,"weekdaysShort",7,"day")}function nc(a,b){return ic(a,b,"weekdaysMin",7,"day")}function oc(){var a=this._data;return this._milliseconds=Wd(this._milliseconds),this._days=Wd(this._days),this._months=Wd(this._months),a.milliseconds=Wd(a.milliseconds),a.seconds=Wd(a.seconds),a.minutes=Wd(a.minutes),a.hours=Wd(a.hours),a.months=Wd(a.months),a.years=Wd(a.years),this}function pc(a,b,c,d){var e=Ya(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function qc(a,b){return pc(this,a,b,1)}function rc(a,b){return pc(this,a,b,-1)}function sc(a){return 0>a?Math.floor(a):Math.ceil(a)}function tc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*sc(vc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=p(f/1e3),i.seconds=a%60,b=p(a/60),i.minutes=b%60,c=p(b/60),i.hours=c%24,g+=p(c/24),e=p(uc(g)),h+=e,g-=sc(vc(e)),d=p(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function uc(a){return 4800*a/146097}function vc(a){return 146097*a/4800}function wc(a){var b,c,d=this._milliseconds;if(a=A(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+uc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(vc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function xc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*q(this._months/12)}function yc(a){return function(){return this.as(a)}}function zc(a){return a=A(a),this[a+"s"]()}function Ac(a){return function(){return this._data[a]}}function Bc(){return p(this.days()/7)}function Cc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Dc(a,b,c){var d=Ya(a).abs(),e=ke(d.as("s")),f=ke(d.as("m")),g=ke(d.as("h")),h=ke(d.as("d")),i=ke(d.as("M")),j=ke(d.as("y")),k=e<le.s&&["s",e]||1===f&&["m"]||f<le.m&&["mm",f]||1===g&&["h"]||g<le.h&&["hh",g]||1===h&&["d"]||h<le.d&&["dd",h]||1===i&&["M"]||i<le.M&&["MM",i]||1===j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,Cc.apply(null,k)}function Ec(a,b){return void 0===le[a]?!1:void 0===b?le[a]:(le[a]=b,!0)}function Fc(a){var b=this.localeData(),c=Dc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function Gc(){var a,b,c,d=me(this._milliseconds)/1e3,e=me(this._days),f=me(this._months);a=p(d/60),b=p(a/60),d%=60,a%=60,c=p(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var Hc,Ic,Jc=a.momentProperties=[],Kc=!1,Lc={},Mc={},Nc=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Oc=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Pc={},Qc={},Rc=/\d/,Sc=/\d\d/,Tc=/\d{3}/,Uc=/\d{4}/,Vc=/[+-]?\d{6}/,Wc=/\d\d?/,Xc=/\d{1,3}/,Yc=/\d{1,4}/,Zc=/[+-]?\d{1,6}/,$c=/\d+/,_c=/[+-]?\d+/,ad=/Z|[+-]\d\d:?\d\d/gi,bd=/[+-]?\d+(\.\d{1,3})?/,cd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,dd={},ed={},fd=0,gd=1,hd=2,id=3,jd=4,kd=5,ld=6;H("M",["MM",2],"Mo",function(){return this.month()+1}),H("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),H("MMMM",0,0,function(a){return this.localeData().months(this,a)}),z("month","M"),N("M",Wc),N("MM",Wc,Sc),N("MMM",cd),N("MMMM",cd),Q(["M","MM"],function(a,b){b[gd]=q(a)-1}),Q(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[gd]=e:j(c).invalidMonth=a});var md="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),nd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),od={};a.suppressDeprecationWarnings=!1;var pd=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,qd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],rd=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],sd=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=aa("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),H(0,["YY",2],0,function(){return this.year()%100}),H(0,["YYYY",4],0,"year"),H(0,["YYYYY",5],0,"year"),H(0,["YYYYYY",6,!0],0,"year"),z("year","y"),N("Y",_c),N("YY",Wc,Sc),N("YYYY",Yc,Uc),N("YYYYY",Zc,Vc),N("YYYYYY",Zc,Vc),Q(["YYYYY","YYYYYY"],fd),Q("YYYY",function(b,c){c[fd]=2===b.length?a.parseTwoDigitYear(b):q(b)}),Q("YY",function(b,c){c[fd]=a.parseTwoDigitYear(b)}),a.parseTwoDigitYear=function(a){return q(a)+(q(a)>68?1900:2e3)};var td=C("FullYear",!1);H("w",["ww",2],"wo","week"),H("W",["WW",2],"Wo","isoWeek"),z("week","w"),z("isoWeek","W"),N("w",Wc),N("ww",Wc,Sc),N("W",Wc),N("WW",Wc,Sc),R(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=q(a)});var ud={dow:0,doy:6};H("DDD",["DDDD",3],"DDDo","dayOfYear"),z("dayOfYear","DDD"),N("DDD",Xc),N("DDDD",Tc),Q(["DDD","DDDD"],function(a,b,c){c._dayOfYear=q(a)}),a.ISO_8601=function(){};var vd=aa("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Da.apply(null,arguments);return this>a?this:a}),wd=aa("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Da.apply(null,arguments);return a>this?this:a});Ja("Z",":"),Ja("ZZ",""),N("Z",ad),N("ZZ",ad),Q(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ka(a)});var xd=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var yd=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,zd=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;Ya.fn=Ha.prototype;var Ad=ab(1,"add"),Bd=ab(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Cd=aa("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});H(0,["gg",2],0,function(){return this.weekYear()%100}),H(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Db("gggg","weekYear"),Db("ggggg","weekYear"),Db("GGGG","isoWeekYear"),Db("GGGGG","isoWeekYear"),z("weekYear","gg"),z("isoWeekYear","GG"),N("G",_c),N("g",_c),N("GG",Wc,Sc),N("gg",Wc,Sc),N("GGGG",Yc,Uc),N("gggg",Yc,Uc),N("GGGGG",Zc,Vc),N("ggggg",Zc,Vc),R(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=q(a)}),R(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),H("Q",0,0,"quarter"),z("quarter","Q"),N("Q",Rc),Q("Q",function(a,b){b[gd]=3*(q(a)-1)}),H("D",["DD",2],"Do","date"),z("date","D"),N("D",Wc),N("DD",Wc,Sc),N("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),Q(["D","DD"],hd),Q("Do",function(a,b){b[hd]=q(a.match(Wc)[0],10)});var Dd=C("Date",!0);H("d",0,"do","day"),H("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),H("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),H("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),H("e",0,0,"weekday"),H("E",0,0,"isoWeekday"),z("day","d"),z("weekday","e"),z("isoWeekday","E"),N("d",Wc),N("e",Wc),N("E",Wc),N("dd",cd),N("ddd",cd),N("dddd",cd),R(["dd","ddd","dddd"],function(a,b,c){var d=c._locale.weekdaysParse(a);null!=d?b.d=d:j(c).invalidWeekday=a}),R(["d","e","E"],function(a,b,c,d){b[d]=q(a)});var Ed="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Fd="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Gd="Su_Mo_Tu_We_Th_Fr_Sa".split("_");H("H",["HH",2],0,"hour"),H("h",["hh",2],0,function(){return this.hours()%12||12}),Sb("a",!0),Sb("A",!1),z("hour","h"),N("a",Tb),N("A",Tb),N("H",Wc),N("h",Wc),N("HH",Wc,Sc),N("hh",Wc,Sc),Q(["H","HH"],id),Q(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),Q(["h","hh"],function(a,b,c){b[id]=q(a),j(c).bigHour=!0});var Hd=/[ap]\.?m?\.?/i,Id=C("Hours",!0);H("m",["mm",2],0,"minute"),z("minute","m"),N("m",Wc),N("mm",Wc,Sc),Q(["m","mm"],jd);var Jd=C("Minutes",!1);H("s",["ss",2],0,"second"),z("second","s"),N("s",Wc),N("ss",Wc,Sc),Q(["s","ss"],kd);var Kd=C("Seconds",!1);H("S",0,0,function(){return~~(this.millisecond()/100)}),H(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),H(0,["SSS",3],0,"millisecond"),H(0,["SSSS",4],0,function(){return 10*this.millisecond()}),H(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),H(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),H(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),H(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),H(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),z("millisecond","ms"),N("S",Xc,Rc),N("SS",Xc,Sc),N("SSS",Xc,Tc);var Ld;for(Ld="SSSS";Ld.length<=9;Ld+="S")N(Ld,$c);for(Ld="S";Ld.length<=9;Ld+="S")Q(Ld,Wb);var Md=C("Milliseconds",!1);H("z",0,0,"zoneAbbr"),H("zz",0,0,"zoneName");var Nd=n.prototype;Nd.add=Ad,Nd.calendar=cb,Nd.clone=db,Nd.diff=ib,Nd.endOf=ub,Nd.format=mb,Nd.from=nb,Nd.fromNow=ob,Nd.to=pb,Nd.toNow=qb,Nd.get=F,Nd.invalidAt=Cb,Nd.isAfter=eb,Nd.isBefore=fb,Nd.isBetween=gb,Nd.isSame=hb,Nd.isValid=Ab,Nd.lang=Cd,Nd.locale=rb,Nd.localeData=sb,Nd.max=wd,Nd.min=vd,Nd.parsingFlags=Bb,Nd.set=F,Nd.startOf=tb,Nd.subtract=Bd,Nd.toArray=yb,Nd.toObject=zb,Nd.toDate=xb,Nd.toISOString=lb,Nd.toJSON=lb,Nd.toString=kb,Nd.unix=wb,Nd.valueOf=vb,Nd.year=td,Nd.isLeapYear=ia,Nd.weekYear=Fb,Nd.isoWeekYear=Gb,Nd.quarter=Nd.quarters=Jb,Nd.month=Y,Nd.daysInMonth=Z,Nd.week=Nd.weeks=na,Nd.isoWeek=Nd.isoWeeks=oa,Nd.weeksInYear=Ib,Nd.isoWeeksInYear=Hb,Nd.date=Dd,Nd.day=Nd.days=Pb,Nd.weekday=Qb,Nd.isoWeekday=Rb,Nd.dayOfYear=qa,Nd.hour=Nd.hours=Id,Nd.minute=Nd.minutes=Jd,Nd.second=Nd.seconds=Kd,
-Nd.millisecond=Nd.milliseconds=Md,Nd.utcOffset=Na,Nd.utc=Pa,Nd.local=Qa,Nd.parseZone=Ra,Nd.hasAlignedHourOffset=Sa,Nd.isDST=Ta,Nd.isDSTShifted=Ua,Nd.isLocal=Va,Nd.isUtcOffset=Wa,Nd.isUtc=Xa,Nd.isUTC=Xa,Nd.zoneAbbr=Xb,Nd.zoneName=Yb,Nd.dates=aa("dates accessor is deprecated. Use date instead.",Dd),Nd.months=aa("months accessor is deprecated. Use month instead",Y),Nd.years=aa("years accessor is deprecated. Use year instead",td),Nd.zone=aa("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Oa);var Od=Nd,Pd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Qd={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Rd="Invalid date",Sd="%d",Td=/\d{1,2}/,Ud={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Vd=s.prototype;Vd._calendar=Pd,Vd.calendar=_b,Vd._longDateFormat=Qd,Vd.longDateFormat=ac,Vd._invalidDate=Rd,Vd.invalidDate=bc,Vd._ordinal=Sd,Vd.ordinal=cc,Vd._ordinalParse=Td,Vd.preparse=dc,Vd.postformat=dc,Vd._relativeTime=Ud,Vd.relativeTime=ec,Vd.pastFuture=fc,Vd.set=gc,Vd.months=U,Vd._months=md,Vd.monthsShort=V,Vd._monthsShort=nd,Vd.monthsParse=W,Vd.week=ka,Vd._week=ud,Vd.firstDayOfYear=ma,Vd.firstDayOfWeek=la,Vd.weekdays=Lb,Vd._weekdays=Ed,Vd.weekdaysMin=Nb,Vd._weekdaysMin=Gd,Vd.weekdaysShort=Mb,Vd._weekdaysShort=Fd,Vd.weekdaysParse=Ob,Vd.isPM=Ub,Vd._meridiemParse=Hd,Vd.meridiem=Vb,w("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===q(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=aa("moment.lang is deprecated. Use moment.locale instead.",w),a.langData=aa("moment.langData is deprecated. Use moment.localeData instead.",y);var Wd=Math.abs,Xd=yc("ms"),Yd=yc("s"),Zd=yc("m"),$d=yc("h"),_d=yc("d"),ae=yc("w"),be=yc("M"),ce=yc("y"),de=Ac("milliseconds"),ee=Ac("seconds"),fe=Ac("minutes"),ge=Ac("hours"),he=Ac("days"),ie=Ac("months"),je=Ac("years"),ke=Math.round,le={s:45,m:45,h:22,d:26,M:11},me=Math.abs,ne=Ha.prototype;ne.abs=oc,ne.add=qc,ne.subtract=rc,ne.as=wc,ne.asMilliseconds=Xd,ne.asSeconds=Yd,ne.asMinutes=Zd,ne.asHours=$d,ne.asDays=_d,ne.asWeeks=ae,ne.asMonths=be,ne.asYears=ce,ne.valueOf=xc,ne._bubble=tc,ne.get=zc,ne.milliseconds=de,ne.seconds=ee,ne.minutes=fe,ne.hours=ge,ne.days=he,ne.weeks=Bc,ne.months=ie,ne.years=je,ne.humanize=Fc,ne.toISOString=Gc,ne.toString=Gc,ne.toJSON=Gc,ne.locale=rb,ne.localeData=sb,ne.toIsoString=aa("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Gc),ne.lang=Cd,H("X",0,0,"unix"),H("x",0,0,"valueOf"),N("x",_c),N("X",bd),Q("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),Q("x",function(a,b,c){c._d=new Date(q(a))}),a.version="2.10.6",b(Da),a.fn=Od,a.min=Fa,a.max=Ga,a.utc=h,a.unix=Zb,a.months=jc,a.isDate=d,a.locale=w,a.invalid=l,a.duration=Ya,a.isMoment=o,a.weekdays=lc,a.parseZone=$b,a.localeData=y,a.isDuration=Ia,a.monthsShort=kc,a.weekdaysMin=nc,a.defineLocale=x,a.weekdaysShort=mc,a.normalizeUnits=A,a.relativeTimeThreshold=Ec;var oe=a;return oe});
diff --git a/web/packs/src/vendor/stylesheets/.keep b/web/packs/src/vendor/stylesheets/.keep
deleted file mode 100644
index e69de29..0000000
--- a/web/packs/src/vendor/stylesheets/.keep
+++ /dev/null
diff --git a/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css b/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css
deleted file mode 100644
index c0720b9..0000000
--- a/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.typeahead-field,.typeahead-query{position:relative;width:100%}.typeahead-button,.typeahead-container,.typeahead-field,.typeahead-filter,.typeahead-query{position:relative}.typeahead-container button,.typeahead-field input,.typeahead-select{border:1px solid #ccc;line-height:1.42857143;padding:6px 12px;height:32px}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}.typeahead-container,.typeahead-result.detached .typeahead-list{font-family:"Open Sans",Arial,Helvetica,Sans-Serif}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}.typeahead-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.typeahead-query{z-index:2}.typeahead-filter button{min-width:66px}.typeahead-field{display:table;border-collapse:separate}.typeahead-button{font-size:0;white-space:nowrap;width:1%;vertical-align:middle}.typeahead-field>span{display:table-cell;vertical-align:top}.typeahead-button button{border-top-right-radius:2px;border-bottom-right-radius:2px}.typeahead-field input,.typeahead-select{display:block;width:100%;font-size:13px;color:#555;background:0 0;border-radius:2px 0 0 2px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.typeahead-field input{-webkit-appearance:none;background:0 0}.typeahead-field input:last-child,.typeahead-hint{background:#fff}.typeahead-container button{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-color:#fff;white-space:nowrap;font-size:13px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#333;box-shadow:inset 0 -2px 0 rgba(0,0,0,.05);-moz-box-shadow:inset 0 -2px 0 rgba(0,0,0,.05);-webkit-box-shadow:inset 0 -2px 0 rgba(0,0,0,.05)}.typeahead-container button:active,.typeahead-container button:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.typeahead-container button:focus,.typeahead-container button:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.typeahead-container button.active,.typeahead-container button:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.typeahead-container button.disabled,.typeahead-container button[disabled],.typeahead-field input.disabled,.typeahead-field input[disabled]{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;background-color:#fff;border-color:#ccc}.typeahead-button button,.typeahead-filter button{margin-left:-1px;border-bottom-left-radius:0;border-top-left-radius:0}.typeahead-button,.typeahead-filter{z-index:1}.typeahead-button:active,.typeahead-button:active button:active,.typeahead-button:focus,.typeahead-button:focus button:focus,.typeahead-button:hover,.typeahead-container.filter .typeahead-filter,.typeahead-filter:active,.typeahead-filter:focus,.typeahead-filter:hover{z-index:1001}.typeahead-dropdown,.typeahead-list{position:absolute;top:100%;left:0;z-index:1000;width:100%;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:2px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.typeahead-result.detached .typeahead-list{position:relative;z-index:1041;top:auto;left:auto}.typeahead-dropdown{right:0;left:auto;z-index:1001}.typeahead-list>li:first-child{border-top:none}.typeahead-list>li{position:relative;border-top:solid 1px rgba(0,0,0,.15)}.typeahead-dropdown>li>a,.typeahead-list>li>a{display:block;padding:6px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap;text-decoration:none}.typeahead-dropdown>li.active>a,.typeahead-dropdown>li>a:focus,.typeahead-dropdown>li>a:hover,.typeahead-list>li.active>a,.typeahead-list>li>a:focus,.typeahead-list>li>a:hover{background-color:#ebebeb;color:#333}.typeahead-list.empty>li.active>a,.typeahead-list.empty>li>a:focus,.typeahead-list.empty>li>a:hover{background-color:transparent}.typeahead-list.empty>li>a{cursor:default}.typeahead-list>li.typeahead-group.active>a,.typeahead-list>li.typeahead-group>a,.typeahead-list>li.typeahead-group>a:focus,.typeahead-list>li.typeahead-group>a:hover{border-color:#9cb4c5;color:#305d8c;background-color:#d6dde7;cursor:default}.typeahead-container.backdrop+.typeahead-backdrop,.typeahead-container.filter .typeahead-dropdown,.typeahead-container.hint .typeahead-hint,.typeahead-container.result .typeahead-list{display:block!important}.typeahead-container .typeahead-dropdown,.typeahead-container .typeahead-hint,.typeahead-container .typeahead-list,.typeahead-container+.typeahead-backdrop{display:none!important}.typeahead-dropdown .divider{height:1px;margin:5px 0;overflow:hidden;background-color:#e5e5e5}.typeahead-caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.typeahead-search-icon{min-width:40px;height:18px;font-size:13px;display:block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABH0lEQVR4nJ3SvyvFYRTH8deVkkJ3UUZJIbJ8bzJjMtyMym6w2Njs/gCDP0AGCyWjxYDF5GdJYpS6xaIUw/d8771dT7qc+vZ8vs95zvuc5zmnlGWZsG6sYBGjsXeNHWzjQ8JKARjCEUZSh3CJeTy3OjoicxF8hwX0oi/0HSZwiK4UYKUpeBoHeMdb6OnwTWI5BVgMvYZaovwa1kMvpQBjoY8TwVp84ylAO/YV62cKcBt65hfAbKwPKcBu6E2UE8Hl8MF+CrCFG/nwnKKKnviqONOYj6NWQDFIg/I+/3ikFnuUX6d+lY4mR4ZVnMvnoIYLbKCCp0h0otG5egXt2HAED+BFPmAP7bYR7jGHV/RjCjr/AICryFzB3n8ARSX3xc83qRk4q9rDNWcAAAAASUVORK5CYII=) center center no-repeat}
diff --git a/web/packs/useflags.js b/web/packs/useflags.js
index 2c98c55..79db5ee 100644
--- a/web/packs/useflags.js
+++ b/web/packs/useflags.js
@@ -1,4 +1,4 @@
import 'd3/d3'
-import './src/vendor/javascripts/jquery.typeahead.min'
+import 'jquery-typeahead/dist/jquery.typeahead.min.js'
import './src/javascript/useflags/typeahead'
import './src/javascript/useflags/render-bubbles'
diff --git a/web/templates/about/feedback.tmpl b/web/templates/about/feedback.tmpl
deleted file mode 100644
index e7d50a8..0000000
--- a/web/templates/about/feedback.tmpl
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
- <ol class="breadcrumb">
- <li class="breadcrumb-item"><a href="/">Home</a></li>
- <li class="breadcrumb-item"><a href="/about">About</a></li>
- <li class="breadcrumb-item active">Feedback</li>
- </ol>
-
- <h1>Feedback</h1>
-
- <p class="lead">
- Thanks for checking out the new packages.gentoo.org!
- </p>
- <p>
- This site is currently in an <abbr title="minimum viable product">MVP</abbr> state and will be extended further to provide more useful features.
- To help us prioritize new features and learn about your use case for the site, please share your ideas below.
- <br><br>
- </p>
-
- <div class="row">
- <div class="col-md-8">
- <div class="card">
- <h4 class="card-header">
- Send Feedback
- </h4>
- <div class="card-body">
- <form class="form-horizontal" method="post" action="/about/feedback">
- <div class="form-group row">
- <label for="feedback" class="col-sm-2 col-form-label font-weight-bold text-right">Your Feedback:</label>
- <div class="col-sm-10">
- <textarea name="feedback" id="feedback" class="form-control" rows="10" placeholder="Please be sure to explain issues in detail and with exact URL references."></textarea>
- </div>
- </div>
- <div class="form-group row">
- <label for="contact" class="col-sm-2 col-form-label font-weight-bold text-right">Contact (optional):</label>
- <div class="col-sm-10">
- <input type="text" name="contact" class="form-control" id="contact" placeholder="How can we reach you to follow up on your feedback?">
- </div>
- </div>
- <div class="form-group row">
- <div class="offset-sm-2 col-sm-10">
- <button type="submit" class="btn btn-outline-primary">Send</button>
- </div>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div class="col-md-4">
- <div class="card">
- <h4 class="card-header">
- Other ways to get in touch
- </h4>
- <div class="list-group">
- <a href="mailto:gpackages@gentoo.org" class="list-group-item list-group-item-action text-dark">
- <span class="fa fa-fw fa-envelope"></span>
- E-Mail: gpackages@gentoo.org
- </a>
- <a href="irc://irc.gentoo.org/gentoo-www" class="list-group-item list-group-item-action text-dark">
- <span class="fa fa-fw fa-comments-o"></span>
- IRC: #gentoo-www
- </a>
- </div>
- </div>
- </div>
- </div>
-
- </div>
-</div>
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/about/feeds.tmpl b/web/templates/about/feeds.tmpl
deleted file mode 100644
index a1560ad..0000000
--- a/web/templates/about/feeds.tmpl
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
- <ol class="breadcrumb">
- <li class="breadcrumb-item"><a href="/">Home</a></li>
- <li class="breadcrumb-item"><a href="/about">About</a></li>
- <li class="breadcrumb-item active">Update Feeds</li>
- </ol>
-
- <h1>Update Feeds</h1>
-
- <p>
- You can find Atom feeds here:
- </p>
-
- <ul>
- <li>
- For all packages: Right column on the <a href="/categories">category listing</a>.
- </li>
- <li>
- For specific architectures: In the <a href="/arches">architectures section</a>.
- </li>
- <li>
- For specific packages: In the <em>Resources</em> box on the respective package pages.
- </li>
- </ul>
-
- </div>
-</div>
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/about/help.tmpl b/web/templates/about/help.tmpl
deleted file mode 100644
index e2c1fe6..0000000
--- a/web/templates/about/help.tmpl
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
- <ol class="breadcrumb">
- <li class="breadcrumb-item"><a href="/">Home</a></li>
- <li class="breadcrumb-item"><a href="/about">About</a></li>
- <li class="breadcrumb-item active">Help</li>
- </ol>
-
- <h1>Help</h1>
-
- <h2 id="keyword-legend">Keyword table legend</h2>
-
- <ul class="list-group kk-keyword-legend">
- <li class="list-group-item kk-keyword-stable">
- <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg> &nbsp;Stable
- </li>
- <li class="list-group-item kk-keyword-testing">
- <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg> &nbsp;Testing
- </li>
- <li class="list-group-item kk-keyword-unavailable">
- <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> &nbsp;Explicitly unavailable
- </li>
- <li class="list-group-item kk-keyword-masked">
- <svg height="16" class="octicon octicon-diff-ignored" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> &nbsp;Masked
- </li>
- <li class="list-group-item kk-keyword-unknown">
- <span class="kk-octicon-spacer"></span>&nbsp;Unknown
- </li>
- </ul>
-
-
- </div>
-</div>
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/about/index.tmpl b/web/templates/about/index.tmpl
deleted file mode 100644
index f280b64..0000000
--- a/web/templates/about/index.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12 text-center">
-
- <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1>
- <span style="font-size: 90%;" class="text-muted">Feel free to <a href="/about/feedback">get in touch</a> if you have any questions that are not answered on this page.<br/>
- And welcome to the new packages.gentoo.org!</span>
-
- </div>
-
- <div class="col-12 mt-5 pt-4">
-
-
- <h2>FAQ</h2>
-
- <dl>
- <dt>Which version is currently running?</dt>
- <dd>
- Currently {{.Application.Version}} is running.
- </dd>
- <br>
- <dt>How often is the site updated?</dt>
- <dd>
- Updates are scheduled <strong>every 5 minutes now</strong>.
- You can find the last time an import task was started in the footer.
- </dd>
- </dl>
-
-</div>
-</div>
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/about/status.tmpl b/web/templates/about/status.tmpl
deleted file mode 100644
index e2af6ac..0000000
--- a/web/templates/about/status.tmpl
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12 text-center">
-
- <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1>
- <span style="font-size: 90%;" class="text-muted">Feel free to <a href="/about/feedback">get in touch</a> if you have any questions that are not answered on this page.<br/>
- And welcome to the new packages.gentoo.org!</span>
-
- </div>
-
- <div class="col-8 offset-md-2 mt-5 pt-4">
-
- <table class="table">
- <thead>
- <tr>
- <th scope="col">Type</th>
- <th scope="col">Last Update</th>
- <th scope="col">Age</th>
- </tr>
- </thead>
- <tbody>
- {{range .Applications}}
- <tr>
- <th scope="row" class="text-capitalize">{{.Id}}</th>
- <td>{{.LastUpdate.Format "2 Jan 2006 15:04:05"}} UTC</td>
- <td>{{timeSince .LastUpdate}}</td>
- </tr>
- {{end}}
- </tbody>
- </table>
-
- </div>
-</div>
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/api/explore/graphiql.tmpl b/web/templates/api/explore/graphiql.tmpl
deleted file mode 100644
index 584b5fc..0000000
--- a/web/templates/api/explore/graphiql.tmpl
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>GraphiQL - Gentoo Packages</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="theme-color" content="#54487a">
- <meta name="description" content="Gentoo Packages GraphiQL GraphQL API Explorer">
- <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon">
- <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
- <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
- <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" />
- </head>
-
- <body>
- <div id="graphiql">
- Loading...
- </div>
- <script src="https://unpkg.com/graphiql@0.17.5/graphiql.min.js" type="application/javascript"></script>
- <script>
- window.graphqlEndpoint = '{{ . }}';
- </script>
- <script src="/assets/graphiql.js" type="application/javascript"></script>
- </body>
-</html>
diff --git a/web/templates/arches/archesheader.tmpl b/web/templates/arches/archesheader.tmpl
deleted file mode 100644
index a873732..0000000
--- a/web/templates/arches/archesheader.tmpl
+++ /dev/null
@@ -1,31 +0,0 @@
-{{define "archesheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3">
- <div class="col-md-5 pt-2">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-server"></span><span class="ml-2">Architectures</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
-
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- {{range $.UserPreferences.Arches.Visible}}
- <a class="nav-link {{if eq $.Arch .}}active{{end}}" href="/arches/{{.}}/{{$.UserPreferences.Arches.DefaultPage}}">{{.}}</a>
- {{end}}
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/arches/changedVersionRows.tmpl b/web/templates/arches/changedVersionRows.tmpl
deleted file mode 100644
index d27def4..0000000
--- a/web/templates/arches/changedVersionRows.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-{{define "changedversions"}}
- {{range $index, $version := .Versions}}
- <li class="list-group-item kk-package-detailed">
- <div class="row">
- <div class="col-xs-12 col-md-6">
- <h4 class="stick-top"><a href="/packages/{{.Atom}}">{{.Atom}}</a></h4>
- <div class="kk-package-detailed-toolbox">
-
- <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
- <span class="fa fa-fw fa-navicon"></span>
- </button>
- <div class="dropdown-menu dropdown-menu-right">
- <a class="dropdown-item" href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Category}}%2F{{.Package}}" target="_blank">
- <span class="fa fa-fw fa-bug"></span>
- Related bugs
- </a>
- <a class="dropdown-item" href="https://wiki.gentoo.org/index.php?title=Special%3ASearch&amp;fulltext=Search&amp;search={{.Package}}" target="_blank">
- <span class="fa fa-fw fa-book"></span>
- Documentation
- </a>
- <a class="dropdown-item" href="https://forums.gentoo.org/search.php?search_terms=all&amp;show_results=topics&amp;search_keywords={{.Package}}&amp;mode=results" target="_blank">
- <span class="fa fa-fw fa-comments-o"></span>
- Forums posts
- </a>
- <div class="dropdown-divider"></div>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Atom}}" target="_blank">
- <span class="fa fa-fw fa-code-fork"></span>
- Git repository browser
- </a>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Atom}}?showmsg=1" target="_blank">
- <span class="fa fa-fw fa-history"></span>
- Git log
- </a>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Atom}}?h=master" target="_blank">
- <span class="fa fa-fw fa-rss"></span>
- Changes feed
- </a>
- </div>
-
- </div>
- {{.Description}}
- <br>
- <small class="text-muted">
- </small>
- {{if ge (len .Commits) 1 }}
- <div class="kk-inline-changelog-entry">
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{ (index .Commits 0).Id }}" title="Git commit">
- <span class="octicon octicon-git-pull-request"></span>
- <span class="kk-commit-message">{{ (index .Commits 0).Message }}</span>
- </a>
- </div>
- {{end}}
- </div>
- <div class="col-xs-12 col-md-6">
- <small class="text-muted pull-right">
- <span class="kk-i18n-date" title="{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}">{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}</span>
- </small>
- <div class="kk-version-card">
- <p class="mb-2"><strong>{{.Version}}</strong><span class="kk-slot"> : {{.Slot}}</span> {{if .Restricts}}<span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{range .Restricts}}{{.}} {{end}}">{{formatRestricts .Restricts}}</span>{{end}}</p>
- <p>
- {{ range $.UserPreferences.Arches.Visible }}
- {{if contains (print " " $version.Keywords " ") (print " " . " ")}}
- <span class="label kk-keyword-stable" title="{{$version.Version}} is testing on {{.}}">{{.}}</span>
- {{else if contains (print " " $version.Keywords " ") (print "~" . " ")}}
- <span class="label kk-keyword-testing" title="{{$version}} is stable on {{.}}">~{{.}}</span>
- {{else}}
- <span class="label kk-keyword-unknown" title="{{$version.Version}} is unknown on {{.}}">?{{.}}</span>
- {{end}}
- {{end}}
- </p>
- </div>
-
- </div>
- </div>
- </li>
- {{end}}
-{{end}}
diff --git a/web/templates/arches/changedVersions.tmpl b/web/templates/arches/changedVersions.tmpl
deleted file mode 100644
index cdfafac..0000000
--- a/web/templates/arches/changedVersions.tmpl
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "archesheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-11">
-
- {{if eq .Name "Keyworded"}}
- <h3>
- <a class="text-dark"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a>
- <a href="/arches/{{.Arch}}/stable" class="ml-3 text-muted"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a>
- </h3>
- {{else}}
- <h3>
- <a href="/arches/{{.Arch}}/keyworded" class="text-muted"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a>
- <a class="ml-3 text-dark"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a>
- </h3>
- {{end}}
- </div>
- <div class="col-1 text-right">
- <h3>
- <a title="Atom feed" href="/arches/{{.Arch}}/{{.FeedName}}.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </h3>
- </div>
- <div class="col-12">
- <li class="list-group">
- {{template "changedversions" .}}
- </li>
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/arches/index.tmpl b/web/templates/arches/index.tmpl
deleted file mode 100644
index 340f33a..0000000
--- a/web/templates/arches/index.tmpl
+++ /dev/null
@@ -1,149 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "archesheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
- <div class="card border-top-0">
- <div class="table-responsive">
- <table class="table table-striped mb-0">
- <colgroup><col>
- <col style="width: 20em;">
- <col style="width: 20em;">
- </colgroup><tbody>
- <tr>
- <th class="kk-nobreak-cell">alpha</th>
- <td>
- <a href="/arches/alpha/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/alpha/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/alpha/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/alpha/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">amd64</th>
- <td>
- <a href="/arches/amd64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/amd64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/amd64/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/amd64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">arm</th>
- <td>
- <a href="/arches/arm/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/arm/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/arm/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/arm/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">arm64</th>
- <td>
- <a href="/arches/arm64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/arm64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/arm64/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/arm64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">hppa</th>
- <td>
- <a href="/arches/hppa/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/hppa/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/hppa/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/hppa/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">ia64</th>
- <td>
- <a href="/arches/ia64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/ia64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/ia64/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/ia64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">ppc</th>
- <td>
- <a href="/arches/ppc/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/ppc/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/ppc/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/ppc/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">ppc64</th>
- <td>
- <a href="/arches/ppc64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/ppc64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/ppc64/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/ppc64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">sparc</th>
- <td>
- <a href="/arches/sparc/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/sparc/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/sparc/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/sparc/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- <tr>
- <th class="kk-nobreak-cell">x86</th>
- <td>
- <a href="/arches/x86/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a>
- <a title="Atom feed" href="/arches/x86/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- <td>
- <a href="/arches/x86/stable">Newly Stable Packages</a>
- <a title="Atom feed" href="/arches/x86/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
-
- </div>
-</div>
-</div>
-
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/categories/browsecategoriesheader.tmpl b/web/templates/categories/browsecategoriesheader.tmpl
deleted file mode 100644
index c5a43a5..0000000
--- a/web/templates/categories/browsecategoriesheader.tmpl
+++ /dev/null
@@ -1,36 +0,0 @@
-{{define "browsecategoriesheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3">
- <div class="col-md-5 pt-2">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">Packages</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
-
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link active" href="/categories/browse"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Categories</a>
- <a class="nav-link" href="/packages/added"><i class="fa fa-history mr-1" aria-hidden="true"></i> Added</a>
- <a class="nav-link" href="/packages/updated"><i class="fa fa-asterisk mr-1" aria-hidden="true"></i> Updated</a>
- <a class="nav-link" href="/packages/stable"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Newly Stable</a>
- <a class="nav-link" href="/packages/keyworded"><i class="fa fa-circle-o mr-1" aria-hidden="true"></i> Keyworded</a>
-
- <a class="nav-link d-none" href="/categories/insights"><i class="fa fa-bar-chart mr-1" aria-hidden="true"></i> Insights</a>
-
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/categories/categoryheader.tmpl b/web/templates/categories/categoryheader.tmpl
deleted file mode 100644
index 3f51db6..0000000
--- a/web/templates/categories/categoryheader.tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "categoryheader"}}
-
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3 pt-2">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">{{.Name}}</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
- {{.Description}}
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link active" href="/categories"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Packages</a>
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/categories/index.tmpl b/web/templates/categories/index.tmpl
deleted file mode 100644
index f56624e..0000000
--- a/web/templates/categories/index.tmpl
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-{{template "browsecategoriesheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
- <div class="row">
- <div class="col-md-12">
- <h3 class="d-none mb-2">Browse all Categories</h3>
- <div class="card rounded" style="background: none;border: none;">
- <div class="card-body">
- <ul class="kk-col-list kk-6col-list kk-category-listing">
- {{ $prevletter := "z"}}
- {{range .Categories}}
- {{ if (ne (printf "%.1s" .Name) $prevletter)}}
- <li class="kk-col-list-header"><span class="kk-group-header">{{ printf "%.1s" .Name }}</span></li>
- {{end}}
- {{ $prevletter = (printf "%.1s" .Name) }}
-
- <li>
- <a title="{{.Description}}" data-toggle="tooltip" data-placement="right" href="/categories/{{.Name}}">{{.Name}}</a>
- </li>
- {{end}}
- </ul>
- </div>
- </div>
- </div>
- </div>
-
-
- </div>
- </div>
-</div>
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/categories/packageline.tmpl b/web/templates/categories/packageline.tmpl
deleted file mode 100644
index 64a10df..0000000
--- a/web/templates/categories/packageline.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-{{define "packageline"}}
- <tr>
- <th class="kk-nobreak-cell"><a href="/packages/{{.Atom}}">{{.Name}}</a></th>
- <td>{{ (index .Versions 0).Description }}</td>
- </tr>
-{{end}}
diff --git a/web/templates/categories/show.tmpl b/web/templates/categories/show.tmpl
deleted file mode 100644
index 51c48de..0000000
--- a/web/templates/categories/show.tmpl
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-{{template "categoryheader" .Category }}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
-
- <div class="row">
- <div class="col-md-9">
- <!--<p>
- <input type="text" class="form-control form-control-xl" placeholder="Search packages in <%= @category.name %>">
- </p>-->
-
- <div class="card border-top-0 rounded">
- <table class="table mb-0 rounded">
- {{$prevCatLetter := (printf "%.1s" (index .Category.Packages 0).Name) }}
- {{range .Category.Packages}}
- {{ if ne (printf "%.1s" .Name) $prevCatLetter}}
- {{$prevCatLetter = (printf "%.1s" .Name)}}
- <tr id="{{$prevCatLetter}}"></tr>
- {{end}}
- {{template "packageline" .}}
- {{end}}
- </table>
- </div>
- </div>
- <div class="col-md-3">
- <h4>Statistics</h4>
- <dd class="ml-3">
- <dl>Packages: {{ len .Category.Packages }}</dl>
- </dd>
- <h4 class="mt-4">Filter by Category</h4>
- <div class="row pl-4 pr-5 mr-5">
- {{$prevLetter := (printf "%.1s" (index .Category.Packages 0).Name) }}
- {{ range .Category.Packages }}
- {{ if ne (printf "%.1s" .Name) $prevLetter}}
- <div class="col-md-2 px-2"><a href="#{{$prevLetter}}" class="text-muted text-capitalize">{{$prevLetter}}</a></div>
- {{$prevLetter = (printf "%.1s" .Name)}}
- {{end}}
- {{end}}
- <div class="col-md-2 px-2"><a href="#{{$prevLetter}}" class="text-muted text-capitalize">{{$prevLetter}}</a></div>
- </div>
- </div>
- </div>
-
-
- </div>
- </div>
-</div>
-
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/index/show.tmpl b/web/templates/index/show.tmpl
deleted file mode 100644
index 5f732e6..0000000
--- a/web/templates/index/show.tmpl
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
-
- <div class="jumbotron mb-3" style="background: none!important;">
- <h2 class="site-welcome stick-top">Welcome to the Home <br/>
- of <span class="text-primary"> {{.PackageCount}} </span> Gentoo Packages</h2>
-
- <form action="/packages/search" method="get">
- <div class="typeahead-container px-5">
- <div class="typeahead-field">
- <span class="typeahead-query" style="font-size: 1.1em; height: 2.3em;">
- <input class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus>
- </span>
-
- <span class="typeahead-button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;">
- <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit" title="Find" aria-label="Find">
- <span class="typeahead-search-icon"></span><span class="sr-only">Find</span>
- </button>
- </span>
- </div>
- </div>
- </form>
- <br/>
- <small class="mt-4 px-5 text-muted" style="font-size: 12px;">This is the new packages.gentoo.org site. If anything isn't working as expected, <a href="mailto:gpackages@gentoo.org">contact us</a>.</small><br>
- <small class="px-5 text-muted" style
-
- ="font-size: 12px;">You can search by <a href="/packages/search?q=sys-kernel/gentoo-sources">atom</a>, <a href="/packages/search?q=sys-kernel">category</a>, <a href="/packages/search?q=gentoo-sources">name</a>, <a href="/packages/search?q=kernel@gentoo.org">maintainer</a> or <a href="/packages/search?q=x11-wm%20haskell@gentoo.org">combine</a> queries. Results similar to your query will be found as well.</small>
-
- </div>
- </div>
- <div class="col-12">
- <h3 class="mb-2"><span class="fa fa-fw fa-history"></span>
- {{if eq .UserPreferences.General.LandingPageLayout "classic"}}<a class="text-dark" href="/packages/added">Added Packages</a>{{else}}<a class="text-dark">Search History</a>{{end}}
- </h3>
- <div class="card border-top-0 mb-4">
- <div class="table-responsive rounded">
- <table class="table table-striped rounded mb-0">
- <tbody>
- {{range .AddedPackages}}
- <tr>
- <td>
- <a href="/packages/{{.Atom}}">
- <span class="text-muted">{{.Category}}</span>/<strong>{{.Name}}</strong>
- </a>
- </td>
- <td>{{(index .Versions 0).Description}}</td>
- </tr>
- {{end}}
- {{if eq .UserPreferences.General.LandingPageLayout "full"}}
- {{if eq (len .AddedPackages) 0}}
- <tr><td class="text-center"><i>Visited packages will be displayed here in future</i></td></tr>
- {{end}}
- {{end}}
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <div class="col-12">
- <h3 class="pt-3 mb-2"><span class="fa fa-fw fa-asterisk"></span>
- <a class="text-dark" href="/packages/updated">Updated Packages</a></h3>
- <ul class="list-group">
- {{range .UpdatedPackages}}
- {{template "changedversion" .}}
- {{end}}
- </ul>
-
- </div>
- </div>
-</div>
-
-
-{{template "footer" .Application}}
-
-<script src="assets/index.js"></script>
-
-</body>
-</html>
diff --git a/web/templates/layout/footer.tmpl b/web/templates/layout/footer.tmpl
deleted file mode 100644
index 280d137..0000000
--- a/web/templates/layout/footer.tmpl
+++ /dev/null
@@ -1,49 +0,0 @@
-{{define "footer"}}
- <footer style="background-color: #fafafa; box-shadow:none!important;">
- <div class="container pt-4" style="border-top: 1px solid #dddddd;">
- <div class="row d-none">
- <div class="col-12 offset-md-2 col-md-7">
- <h3 class="footerhead">Gentoo Packages Database</h3>
- <div class="row">
- <div class="col-xs-12 col-md-4">
- <span class="kk-group-header">Data as current of</span><br>{{ .LastUpdate.Format "Jan 02, 2006 15:04:05 UTC" }}
- </div>
- <div class="col-xs-12 col-md-4">
- </div>
- <div class="col-xs-12 col-md-4">
- </div>
- </div>
- </div>
- <div class="col-12 col-md-3">
- <h3 class="footerhead">Questions or comments?</h3>
- Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>.
- <p class="mt-2"><a href="https://gitweb.gentoo.org/sites/soko.git/">{{ .Version }}</a></p>
- </div>
- </div>
- <div class="row">
- <div class="col-2 col-sm-2 col-md-2">
- <ul class="footerlinks three-icons">
- <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li>
- <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li>
- <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li>
- </ul>
- </div>
- <div class="col-8 col-sm-8 col-md-8">
- <strong>&copy; 2001&ndash;2020 Gentoo Foundation, Inc.</strong><br>
- <small>
- Gentoo is a trademark of the Gentoo Foundation, Inc.
- The contents of this document, unless otherwise expressly stated, are licensed under the
- <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license.
- The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply.
- </small>
- </div>
- <div class="col-2 col-sm-2 col-md-2 text-right">
- <strong><a class="text-dark" href="https://www.gentoo.org/inside-gentoo/contact/">Contact</a></strong><br>
- <small>
- {{ .Version }}
- </small>
- </div>
- </div>
- </div>
- </footer>
-{{end}}
diff --git a/web/templates/layout/head.tmpl b/web/templates/layout/head.tmpl
deleted file mode 100644
index 3dc694d..0000000
--- a/web/templates/layout/head.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-{{define "head"}}
- <head>
- <title>{{.Title}}Gentoo Packages</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="theme-color" content="#54487a">
- <meta name="description" content="Gentoo Packages Database">
- <!-- link rel="stylesheet" media="screen" href="/packs/css/application-024b2074.css" /-->
- <!-- script src="/packs/js/application-cfb73e71df8935c3a9ed.js"></script -->
- <script src="/assets/stylesheets.js"></script>
- <script src="/assets/application.js"></script>
- <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon">
- </head>
-{{end}}
diff --git a/web/templates/layout/header.tmpl b/web/templates/layout/header.tmpl
deleted file mode 100644
index 571a58b..0000000
--- a/web/templates/layout/header.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-{{define "header"}}
- <header>
- {{template "sitetitle"}}
- {{template "tyrian-navbar" .}}
- </header>
-{{end}}
diff --git a/web/templates/layout/sitetitle.tmpl b/web/templates/layout/sitetitle.tmpl
deleted file mode 100644
index f528d70..0000000
--- a/web/templates/layout/sitetitle.tmpl
+++ /dev/null
@@ -1,37 +0,0 @@
-{{define "sitetitle"}}
- <div class="site-title">
- <div class="container">
- <div class="row justify-content-between">
- <div class="logo">
- <a href="/" title="Back to the homepage" class="site-logo">
- <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/site-logo.svg">
- </a>
- <span class="site-label">Packages</span>
- </div>
- <div class="site-title-buttons">
- <div class="btn-group btn-group-sm">
- <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a>
- <div class="btn-group btn-group-sm">
- <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
- <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span>
- </a>
- <div class="dropdown-menu dropdown-menu-right">
- <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a>
- <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a>
- <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a>
- <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a>
- <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a>
- <div class="dropdown-divider"></div>
- <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a>
- <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a>
- <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a>
- <div class="dropdown-divider"></div>
- <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/layout/tyriannav.tmpl b/web/templates/layout/tyriannav.tmpl
deleted file mode 100644
index 575b32d..0000000
--- a/web/templates/layout/tyriannav.tmpl
+++ /dev/null
@@ -1,45 +0,0 @@
-{{define "tyrian-navbar"}}
- <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation">
- <div class="container">
- <div class="navbar-header">
- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation">
- <span class="navbar-toggler-icon"></span>
- </button>
- </div>
- <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse">
- <ul class="navbar-nav mr-auto">
-
- <li class="nav-item {{ if (eq .Tab "home")}}active{{end}}"><a class="nav-link" href="/">Home</a></li>
- <li class="nav-item {{ if (eq .Tab "packages")}}active{{end}}"><a class="nav-link" href="/categories">Packages</a></li>
- <li class="nav-item {{ if (eq .Tab "maintainers")}}active{{end}}"><a class="nav-link" href="/maintainers">Maintainers</a></li>
- <li class="nav-item {{ if (eq .Tab "useflags")}}active{{end}}"><a class="nav-link" href="/useflags">USE flags</a></li>
- <li class="nav-item {{ if (eq .Tab "arches")}}active{{end}}"><a class="nav-link" href="/arches">Architectures</a></li>
- <li class="nav-item {{ if (eq .Tab "about")}}active{{end}}"><a class="nav-link" href="/about">About</a></li>
-
- </ul>
-
- {{ if ne .Tab "home"}}
- <form class="form-inline inlinesearch" role="search" action="/packages/search" method="get">
-
- <div class="input-group">
-
- <div class="input-group-prepend">
- <span class="input-group-text" id="basic-addon1"><i class="fa fa-search" aria-hidden="true"></i></span>
- </div>
-
- <input class="form-control" type="text" name="q" type="text" placeholder="Find Packages" aria-label="Find Packages">
- </div>
-
- </form>
- {{end}}
-
- <!--
- <ul class="navbar-nav">
- <li class="nav-item"><a class="nav-link" href="/user/preferences"><i class="fa fa-user-circle-o" aria-hidden="true"></i></a></li>
- </ul>
- -->
-
- </div>
- </div>
- </nav>
-{{end}}
diff --git a/web/templates/maintainer/browse.tmpl b/web/templates/maintainer/browse.tmpl
deleted file mode 100644
index 822142d..0000000
--- a/web/templates/maintainer/browse.tmpl
+++ /dev/null
@@ -1,103 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "maintainersbrowseheader" .}}
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
- <div class="row">
- <div class="col-md-12">
- {{if eq .TabName "projects"}}
- <ul class="kk-col-list kk-6col-list kk-category-listing">
- {{ $prevletter := "z"}}
- {{range .Maintainers}}
- {{ if eq .Type "project"}}
- {{ if (ne (printf "%.1s" .Name) $prevletter)}}
- <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li>
- {{end}}
- {{ $prevletter = (printf "%.1s" .Name) }}
-
- <li>
- <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{else if eq .TabName "gentoo-developers"}}
- <ul class="kk-col-list kk-6col-list kk-category-listing">
- {{ $prevletter := "z"}}
- {{range .Maintainers}}
- {{ if eq .Type "gentoo-developer"}}
- {{ if (ne (printf "%.1s" .Name) $prevletter)}}
- <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li>
- {{end}}
- {{ $prevletter = (printf "%.1s" .Name) }}
-
- <li>
- <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{else if eq .TabName "proxied-maintainers"}}
- <ul class="kk-col-list kk-6col-list kk-category-listing">
- {{ $prevletter := "z"}}
- {{range .Maintainers}}
- {{ if eq .Type "proxied-maintainer"}}
- {{ if (ne (printf "%.1s" .Name) $prevletter)}}
- <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li>
- {{end}}
- {{ $prevletter = (printf "%.1s" .Name) }}
-
- <li>
- <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
-
-
- </div>
- <div class="col-md-3 d-none">
- <h4 class="">Description</h4>
- {{if eq .TabName "projects"}}
- <span class="text-muted">
- A project in Gentoo is according to <a href="https://www.gentoo.org/glep/glep-0039.html">GLEP 39</a> a group of developers working towards a goal (or a set of goals).
- </span>
- {{else if eq .TabName "gentoo-developers"}}
- <span class="text-muted">
- Here you can see all official <a href="https://www.gentoo.org/inside-gentoo/developers/">Gentoo developers</a> that are listed as the maintainer of at least one package in the tree.<br/><br/>
- Interested into becoming a Gentoo developer? We do have some <a href="https://www.gentoo.org/get-involved/become-developer/">guidance</a>.
- </span>
- {{else if eq .TabName "proxied-maintainers"}}
- <span class="text-muted">
- Proxied maintainers are users who are maintaining packages in the official Gentoo package repository. <br/><br/>
- Want to become a Proxied maintainer? Follow <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers/User_Guide">this guide</a>.<br/><br/>
- You might especially be intersted into <a href="/maintainer/maintainer-needed@gentoo.org">packages that need a maintainer</a>.
- </span>
-
- {{end}}
- </div>
- </div>
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/maintainer/components/bugs.tmpl b/web/templates/maintainer/components/bugs.tmpl
deleted file mode 100644
index f069dad..0000000
--- a/web/templates/maintainer/components/bugs.tmpl
+++ /dev/null
@@ -1,136 +0,0 @@
-{{define "bugs"}}
- <div class="row">
- <div class="col-md-9">
- {{$security_bugs := 0}}
- {{$non_security_bugs := 0}}
- {{range getAllBugs .Packages}}
- {{if eq .Component "Vulnerabilities"}}
- {{$security_bugs = (add $security_bugs 1)}}
- {{else}}
- {{$non_security_bugs = (add $non_security_bugs 1)}}
- {{end}}
- {{end}}
-
- {{$general_bugs := 0}}
- {{$stabilization_bugs := 0}}
- {{$keywording_bugs := 0}}
- {{range getAllBugs .Packages}}
- {{if eq .Component "Current packages"}}
- {{$general_bugs = (add $general_bugs 1)}}
- {{else if eq .Component "Stabilization"}}
- {{$stabilization_bugs = (add $stabilization_bugs 1)}}
- {{else if eq .Component "Keywording"}}
- {{$keywording_bugs = (add $keywording_bugs 1)}}
- {{end}}
- {{end}}
-
-
- {{if $non_security_bugs}}
-
- {{if $general_bugs}}
- <h3 id="packages" class="mb-4">Bug Reports</h3>
- <ul class="list-group">
- {{range getAllBugs .Packages}}
- {{if eq .Component "Current packages"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
-
- {{if $stabilization_bugs}}
- <h3 id="stabilization" class="my-4">Stabilization Bug Reports</h3>
- <ul class="list-group">
- {{range getAllBugs .Packages}}
- {{if eq .Component "Stabilization"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
-
- {{if $keywording_bugs}}
- <h3 id="keywording" class="my-4">Keywording Bug Reports</h3>
- <ul class="list-group">
- {{range getAllBugs .Packages}}
- {{if eq .Component "Keywording"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
- {{else}}
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>Good job! There are no bugs.</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/enter_bug.cgi">new bug</a>.</span>
- </div>
- </div>
- {{end}}
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs:
- <ul>
- <li><a href="https://bugs.gentoo.org/enter_bug.cgi">File a new Bug</a></li>
- <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li>
- <li><a href="https://sites.google.com/site/yacoset/Home/how-to-fix-bugs-step-by-step">Offer solutions for open bugs</a></li>
- <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li>
- </ul>
- </span>
- </div>
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts">
- Shortcuts
- </a>
- </h4>
- <div class="collapse show" id="collapseShortcuts">
- <ul>
- <li>{{if $general_bugs}}<a href="#packages">Packages Bugs ({{$general_bugs}})</a>{{else}}<a>Packages Bugs (0)</a>{{end}}</li>
- <li>{{if $stabilization_bugs}}<a href="#stabilization">Stabilization Bugs ({{$stabilization_bugs}})</a>{{else}}<a>Stabilization Bugs (0)</a>{{end}}</li>
- <li>{{if $keywording_bugs}}<a href="#keywording">Keywording Bugs ({{$keywording_bugs}})</a>{{else}}<a>Keywording Bugs (0)</a>{{end}}</li>
- </ul>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/maintainer/components/changelog.tmpl b/web/templates/maintainer/components/changelog.tmpl
deleted file mode 100644
index 79ae1e7..0000000
--- a/web/templates/maintainer/components/changelog.tmpl
+++ /dev/null
@@ -1,173 +0,0 @@
-{{define "changelog"}}
-<div class="row">
- <div class="col-md-9">
- {{ $commits := (index .Packages 0).Commits}}
- {{ range $key, $value := .Packages}}
- {{if ne $key 0}}
- {{$commits = appendCommits $commits $value.Commits}}
- {{end}}
- {{end}}
-
- {{$commits = sortCommits $commits}}
-
- {{ if $commits }}
-
- <div class="col-md-12">
- <h3>Latest Commits</h3>
- <ul class="timeline">
- <li>
- <span class="text-muted">Commits on {{((index $commits 0).CommitterDate).Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- {{$last_date := (index $commits 0).CommitterDate}}
- {{range $commits}}
- {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12" style="color:#424242!important;">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range $key, $value := .ChangedFiles.Added }}
- {{if le $key 100}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Modified }}
- {{if le $key 100}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Deleted }}
- {{if le $key 100}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- </div>
- </div>
- </li>
- {{else}}
- </ul>
- </li>
- <li>
- <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range $key, $value := .ChangedFiles.Added }}
- {{if le $key 100}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{ .Path }} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Modified }}
- {{if le $key 100}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{ .Path }} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path}}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Deleted }}
- {{if le $key 100}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{ .Path }} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span>
- {{end}}
- {{end}}
- {{if gt (len .ChangedFiles.Added) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{else if gt (len .ChangedFiles.Modified) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{else if gt (len .ChangedFiles.Deleted) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{end}}
- </div>
- </div>
- </li>
- {{end}}
- {{$last_date = .CommitterDate}}
- {{end}}
- </ul>
- </li>
- </ul>
- </div>
-
- {{else}}
- <li class="list-group-item kk-panel-content-sorry">
- This package has not been changed since our repository has moved to Git.
- <br><br>
- <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default">
- <span class="fa fa-fw fa-history"></span>
- View old CVS Changelog
- </a>
- </li>
- {{end}}
- </div>
-</div>
-{{end}} \ No newline at end of file
diff --git a/web/templates/maintainer/components/outdated.tmpl b/web/templates/maintainer/components/outdated.tmpl
deleted file mode 100644
index dc2fd6e..0000000
--- a/web/templates/maintainer/components/outdated.tmpl
+++ /dev/null
@@ -1,52 +0,0 @@
-{{define "outdated"}}
- <div class="row">
- <div class="col-md-9">
- {{if .Maintainer.PackagesInformation.Outdated}}
- <h3 class="mb-4">Outdated Packages</h3>
- <ul class="list-group">
- {{range .Packages}}
- {{if .Outdated}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-4">
- <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a>
- </div>
- <div class="col-md-8 text-muted">
- {{.Description}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
-
- {{else}}
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>Good job!</h2>
- <span>According to repology.org there are no outdated packages here. <br/>
- Please use this information with care though. The repology data might not be accurate.
- </span>
- </div>
- </div>
- {{end}}
- </div>
- <div class="col-md-3 pt-4">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Based on the data of <a href="https://repology.org/">repology.org</a>, there might be a new version available for these packages. <br/>
- Please don't solely rely on this information, as the repology data might not be accurate.
- </span>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/maintainer/components/packages.tmpl b/web/templates/maintainer/components/packages.tmpl
deleted file mode 100644
index f399678..0000000
--- a/web/templates/maintainer/components/packages.tmpl
+++ /dev/null
@@ -1,121 +0,0 @@
-{{define "packages"}}
- <div class="row">
- <div class="col-md-9">
- {{if .Packages}}
- <ul class="list-group">
- {{$category := ""}}
-
- {{ range .Packages }}
- {{ if eq .Category $category}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-4">
- <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a>
- </div>
- <div class="col-md-8 text-muted">
- {{.Description}}
- </div>
- </div>
- </li>
- {{$category = .Category}}
- {{else}}
- </ul>
- <h3 id="{{.Category}}" class="{{if ne $category ""}}mt-4{{end}}">
- {{$category = .Category}}
- {{$category}}
- </h3>
- <ul class="list-group">
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-4">
- <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a>
- </div>
- <div class="col-md-8 text-muted">
- {{.Description}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
-
-
- </ul>
-
- {{else}}
- <div class="row">
- <div class="col-md-8">
- </div>
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- </div>
- {{end}}
- </div>
- <div class="col-md-3 pt-4">
- {{if .Maintainer.Project.Description}}
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <dl>
- <dd class="ml-3 mb-0 text-muted">
- {{.Maintainer.Project.Description}}
- </dd>
- </dl>
- </div>
-
- <h4 class="mt-4">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseMembers" role="button" aria-expanded="false" aria-controls="collapseMembers">
- Members
- </a>
- </h4>
- <div class="collapse show" id="collapseMembers">
- <dl>
- {{range .Maintainer.Project.Members}}
- <dd class="ml-3 mb-0"><a href="/maintainer/{{.Email}}">{{.Name}}</a>{{if .IsLead}} (Lead){{end}}</dd>
- {{end}}
- </dl>
- </div>
- {{end}}
- {{if .Maintainer.Projects}}
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseProjects" role="button" aria-expanded="false" aria-controls="collapseProjects">
- Projects
- </a>
- </h4>
- <div class="collapse show" id="collapseProjects">
- <dl>
- {{range .Maintainer.Projects}}
- <dd class="ml-3 mb-0"><a href="/maintainer/{{.Email}}">{{.Name}}</a></dd>
- {{end}}
- </dl>
- </div>
- {{end}}
- <h4 class="{{if .Maintainer.Project.Description}}mt-4{{end}}">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts">
- Shortcuts
- </a>
- </h4>
- <div class="collapse show" id="collapseShortcuts">
- <dl>
- {{$category := (index .Packages 0).Category}}
- {{$packageCounter := 0}}
- {{ range .Packages }}
- {{ if ne .Category $category}}
- <dd class="ml-3 mb-0"><a href="#{{$category}}">{{$category}} ({{$packageCounter}})</a></dd>
- {{$category = .Category}}
- {{$packageCounter = 1}}
- {{else}}
- {{$packageCounter = add $packageCounter 1}}
- {{end}}
- {{end}}
- <dd class="ml-3 mb-0"><a href="#{{$category}}">{{$category}} ({{$packageCounter}})</a></dd>
- </dl>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/maintainer/components/pullrequests.tmpl b/web/templates/maintainer/components/pullrequests.tmpl
deleted file mode 100644
index 83c262a..0000000
--- a/web/templates/maintainer/components/pullrequests.tmpl
+++ /dev/null
@@ -1,73 +0,0 @@
-{{define "pull-requests"}}
-
- <div class="row">
- <div class="col-md-9">
-
- {{if .Maintainer.PackagesInformation.PullRequests}}
-
- <h3 class="mb-4">Pull Requests</h3>
- <ul class="list-group">
-
- {{range getPullRequests .Packages}}
-
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-11">
- <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span>
- <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-dark"><b>{{.Title}}</b></a>
- {{if eq .CiState "SUCCESS"}}
- <a href="{{.CiStateLink}}"><i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i></a>
- {{else}}
- <a href="{{.CiStateLink}}"><i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i></a>
- {{end}}
- {{range .Labels}}
- <span class="badge badge-pill badge-light p-1" style="font-weight: normal; {{if eq .Color "5319e7" "0052cc" "b60205"}}color:#FFF;{{end}} background-color: #{{.Color}}!important;">{{.Name}}</span>
- {{end}}
- </div>
- <div class="col-md-1 text-right">
- <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-muted">
- <i class="fa fa-comment-o" aria-hidden="true"></i>
- {{.Comments}}
- </a>
- </div>
- <div class="col-md-12 text-muted">
- <span style="font-size: 90%;">
- #{{.Id}} opened {{.CreatedAt}} by {{.Author}}
- </span>
- </div>
- </div>
- </li>
-
- {{end}}
- </ul>
-
- {{else}}
-
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>There are no pull requests</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span>
- </div>
- </div>
-
- {{end}}
- </div>
- <div class="col-md-3 pt-4">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub.<br/>
- Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>.
- </span>
- </div>
- </div>
- </div>
-
-{{end}}
diff --git a/web/templates/maintainer/components/security.tmpl b/web/templates/maintainer/components/security.tmpl
deleted file mode 100644
index fd05247..0000000
--- a/web/templates/maintainer/components/security.tmpl
+++ /dev/null
@@ -1,52 +0,0 @@
-{{define "security"}}
- <div class="row">
- <div class="col-md-9">
-
- {{if .Maintainer.PackagesInformation.SecurityBugs}}
-
- <h3 class="mb-4">Security Bug Reports</h3>
- <ul class="list-group">
- {{range (getAllBugs .Packages)}}
- {{if eq .Component "Vulnerabilities"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
-
- {{else}}
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>There are no open security bugs.</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/">new security bug</a>.</span>
- </div>
- </div>
- {{end}}
- </div>
- <div class="col-md-3 pt-4">
- <h4>
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Contact Information
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Please file new vulnerability reports on <a href="https://bugs.gentoo.org/">Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component.
- </span>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/maintainer/components/stabilization.tmpl b/web/templates/maintainer/components/stabilization.tmpl
deleted file mode 100644
index 7026be5..0000000
--- a/web/templates/maintainer/components/stabilization.tmpl
+++ /dev/null
@@ -1,96 +0,0 @@
-{{define "stabilization"}}
- <div class="row">
- <div class="col-md-9">
-
- <h3>Stable Requests</h3>
- <ul class="timeline">
- {{$stable_requests := 0}}
- {{range .Packages}}
- {{range $index, $element := .Versions}}
- {{ if .PkgCheckResults }}
- {{ range .PkgCheckResults }}
- {{if eq .Class "StableRequest"}}
- {{$stable_requests = (add $stable_requests 1)}}
- <li>
- <ul class="list-group">
- <li class="list-group-item">
- <a href="/packages/{{.Category}}/{{.Package}}" class="text-dark"><strong>{{.Category}}/{{.Package}}-{{.Version}}</strong></a><br/>
- <span class="kk-version kk-cell-sep-right text-muted">
- {{ .Message }}
- </span>
- </li>
- </ul>
- </li>
- {{end}}
- {{end}}
- {{end}}
- {{end}}
- {{end}}
- </ul>
- {{if eq $stable_requests 0}}
- <div class="text-center w-100"><i>- No Stable Requests found -</i></div>
- {{end}}
-
-
- {{$security_bugs := 0}}
- {{$non_security_bugs := 0}}
- {{range getAllBugs .Packages}}
- {{if eq .Component "Vulnerabilities"}}
- {{$security_bugs = (add $security_bugs 1)}}
- {{else}}
- {{$non_security_bugs = (add $non_security_bugs 1)}}
- {{end}}
- {{end}}
-
- {{$general_bugs := 0}}
- {{$stabilization_bugs := 0}}
- {{$keywording_bugs := 0}}
- {{range getAllBugs .Packages}}
- {{if eq .Component "Current packages"}}
- {{$general_bugs = (add $general_bugs 1)}}
- {{else if eq .Component "Stabilization"}}
- {{$stabilization_bugs = (add $stabilization_bugs 1)}}
- {{else if eq .Component "Keywording"}}
- {{$keywording_bugs = (add $keywording_bugs 1)}}
- {{end}}
- {{end}}
-
-
- {{if $non_security_bugs}}
- {{if $stabilization_bugs}}
- <h3 id="stabilization" class="my-4">Stabilization Bug Reports</h3>
- <ul class="list-group">
- {{range getAllBugs .Packages}}
- {{if eq .Component "Stabilization"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
- {{end}}
- </div>
- <div class="col-md-3 pt-4">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- This page lists potential stabilization candidates. Please have a look at the <a href="https://wiki.gentoo.org/wiki/Stable_request">wiki page</a> for more information.
- </span>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/maintainer/maintainerheader.tmpl b/web/templates/maintainer/maintainerheader.tmpl
deleted file mode 100644
index c0a4de9..0000000
--- a/web/templates/maintainer/maintainerheader.tmpl
+++ /dev/null
@@ -1,68 +0,0 @@
-{{define "maintainerheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
- <small class="kk-package-cat">
- {{if eq .Maintainer.Type "project"}}
- Gentoo Project
- {{else if contains .Maintainer.Email "@gentoo.org"}}
- Gentoo Developer
- {{else if ne .Maintainer.Email ""}}
- Proxied Maintainer
- {{end}}</small>
- <div>
- <svg height="32" class="octicon octicon-person right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg>
- <div class="kk-package-name">{{if .Maintainer.Name}}{{.Maintainer.Name}}{{else if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}Maintainer Needed{{end}}</div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
- <p class="lead kk-package-maindesc">
- <!-- TODO -->
- </p>
- </div>
- {{$outdated_packages_counts := 0}}
- {{range .Packages}}
- {{if .Outdated}}
- {{$outdated_packages_counts = add $outdated_packages_counts 1}}
- {{end}}
- {{end}}
-
- {{$pull_requests_counts := 0}}
- {{range .Packages}}
- {{$pull_requests_counts = add $pull_requests_counts (len .PullRequests)}}
- {{end}}
-
- {{$security_bugs := 0}}
- {{$non_security_bugs := 0}}
- {{range .Packages}}
- {{range .Bugs}}
- {{if eq .Component "Vulnerabilities"}}
- {{$security_bugs = (add $security_bugs 1)}}
- {{else}}
- {{$non_security_bugs = (add $non_security_bugs 1)}}
- {{end}}
- {{end}}
- {{end}}
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link {{if eq .PageName "packages"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}"><i class="fa fa-info mr-1" aria-hidden="true"></i> Packages <span class="ml-1 badge badge-pill kk-misc-badge">{{len .Packages}}</span></a>
- <a class="nav-link {{if eq .PageName "stabilization"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/stabilization"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Stabilization <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.StableRequests}}</span></a>
- <a class="nav-link {{if eq .PageName "outdated"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/outdated"><i class="fa fa-tag mr-1" aria-hidden="true"></i> Outdated <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.Outdated}}</span></a>
- <a class="nav-link {{if eq .PageName "pull-requests"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/pull-requests"><span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> Pull requests <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.PullRequests}}</span></a>
- <a class="nav-link {{if eq .PageName "bugs"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/bugs"><i class="fa fa-bug" aria-hidden="true"></i> Bugs <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.Bugs}}</span></a>
- <a class="nav-link {{if eq .PageName "security"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/security"><i class="fa fa-shield" aria-hidden="true"></i> Security <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.SecurityBugs}}</span></a>
- <a class="nav-link {{if eq .PageName "changelog"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/changelog"><i class="fa fa-fw fa-history"></i> Changelog</a>
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/maintainer/maintainersbrowseheader.tmpl b/web/templates/maintainer/maintainersbrowseheader.tmpl
deleted file mode 100644
index 548ee66..0000000
--- a/web/templates/maintainer/maintainersbrowseheader.tmpl
+++ /dev/null
@@ -1,31 +0,0 @@
-{{define "maintainersbrowseheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3">
- <div class="col-md-5 pt-2">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-users"></span><span class="ml-2">Maintainers</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
-
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link {{if eq .TabName "projects"}}active{{end}}" href="/maintainers/gentoo-projects"><i class="fa fa-users mr-1" aria-hidden="true"></i>Gentoo Projects</a>
- <a class="nav-link {{if eq .TabName "gentoo-developers"}}active{{end}}" href="/maintainers/gentoo-developers"><i class="fa fa-user mr-1" aria-hidden="true"></i>Gentoo Developers</a>
- <a class="nav-link {{if eq .TabName "proxied-maintainers"}}active{{end}}" href="/maintainers/proxied-maintainers"><i class="fa fa-user-o mr-1" aria-hidden="true"></i>Proxied Maintainers</a>
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/maintainer/show.tmpl b/web/templates/maintainer/show.tmpl
deleted file mode 100644
index 2f7ee1e..0000000
--- a/web/templates/maintainer/show.tmpl
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "maintainerheader" .}}
-
-<div class="tab-content" id="myTabContent">
- <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
- {{if eq .PageName "packages"}}
- {{template "packages" .}}
- {{else if eq .PageName "outdated"}}
- {{template "outdated" .}}
- {{else if eq .PageName "pull-requests"}}
- {{template "pull-requests" .}}
- {{else if eq .PageName "stabilization"}}
- {{template "stabilization" .}}
- {{else if eq .PageName "bugs"}}
- {{template "bugs" .}}
- {{else if eq .PageName "security"}}
- {{template "security" .}}
- {{else if eq .PageName "changelog"}}
- {{template "changelog" .}}
- {{end}}
- </div>
-</div>
-
-{{template "footer" .Application }}
-
-
-</body>
-</html>
diff --git a/web/templates/packages/browsepackagesheader.tmpl b/web/templates/packages/browsepackagesheader.tmpl
deleted file mode 100644
index 75317a2..0000000
--- a/web/templates/packages/browsepackagesheader.tmpl
+++ /dev/null
@@ -1,34 +0,0 @@
-{{define "browsepackagesheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3 pt-2">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">Packages</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
-
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link {{if eq .Name "Categories"}}active{{end}}" href="/categories"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Categories</a>
- <a class="nav-link {{if eq .Name "Added"}}active{{end}}" href="/packages/added"><i class="fa fa-history mr-1" aria-hidden="true"></i> Added</a>
- <a class="nav-link {{if eq .Name "Updated"}}active{{end}}" href="/packages/updated"><i class="fa fa-asterisk mr-1" aria-hidden="true"></i> Updated</a>
- <a class="nav-link {{if eq .Name "Stabilized"}}active{{end}}" href="/packages/stable"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Newly Stable</a>
- <a class="nav-link {{if eq .Name "Keyworded"}}active{{end}}" href="/packages/keyworded"><i class="fa fa-circle-o mr-1" aria-hidden="true"></i> Keyworded</a>
-
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/packages/changedVersionRow.tmpl b/web/templates/packages/changedVersionRow.tmpl
deleted file mode 100644
index 22b27b9..0000000
--- a/web/templates/packages/changedVersionRow.tmpl
+++ /dev/null
@@ -1,76 +0,0 @@
-{{define "changedversion"}}
- <li class="list-group-item kk-package-detailed">
- <div class="row">
- <div class="col-xs-12 col-md-6">
- <h4 class="stick-top"><a href="/packages/{{.Atom}}">{{.Atom}}</a></h4>
- <div class="kk-package-detailed-toolbox">
-
- <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
- <span class="fa fa-fw fa-navicon"></span>
- </button>
- <div class="dropdown-menu dropdown-menu-right">
- <a class="dropdown-item" href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Category}}%2F{{.Package}}" target="_blank">
- <span class="fa fa-fw fa-bug"></span>
- Related bugs
- </a>
- <a class="dropdown-item" href="https://wiki.gentoo.org/index.php?title=Special%3ASearch&amp;fulltext=Search&amp;search={{.Package}}" target="_blank">
- <span class="fa fa-fw fa-book"></span>
- Documentation
- </a>
- <a class="dropdown-item" href="https://forums.gentoo.org/search.php?search_terms=all&amp;show_results=topics&amp;search_keywords={{.Package}}&amp;mode=results" target="_blank">
- <span class="fa fa-fw fa-comments-o"></span>
- Forums posts
- </a>
- <div class="dropdown-divider"></div>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Atom}}" target="_blank">
- <span class="fa fa-fw fa-code-fork"></span>
- Git repository browser
- </a>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Atom}}?showmsg=1" target="_blank">
- <span class="fa fa-fw fa-history"></span>
- Git log
- </a>
- <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Atom}}?h=master" target="_blank">
- <span class="fa fa-fw fa-rss"></span>
- Changes feed
- </a>
- </div>
-
- </div>
- {{.Description}}
- <br>
- <small class="text-muted">
- </small>
- {{if ge (len .Commits) 1 }}
- <div class="kk-inline-changelog-entry">
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{ (index .Commits 0).Id }}" title="Git commit">
- <span class="octicon octicon-git-pull-request"></span>
- <span class="kk-commit-message">{{ (index .Commits 0).Message }}</span>
- </a>
- </div>
- {{end}}
- </div>
- <div class="col-xs-12 col-md-6">
- <small class="text-muted pull-right">
- <span class="kk-i18n-date" title="{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}">{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}</span>
- </small>
- <div class="kk-version-card">
- <p class="mb-2"><strong>{{.Version}}</strong><span class="kk-slot"> : {{.Slot}}</span> {{if .Restricts}}<span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{range .Restricts}}{{.}} {{end}}">{{formatRestricts .Restricts}}</span>{{end}}</p>
- <p>
- {{ $arches := mkSlice "amd64" "x86" "alpha" "arm" "arm64" "hppa" "ia64" "ppc" "ppc64" "sparc" }}
- {{ range $arches }}
- {{if contains (print " " $.Keywords " ") (print " " . " ")}}
- <span class="label kk-keyword-stable" title="{{$.Version}} is testing on {{.}}">{{.}}</span>
- {{else if contains (print " " $.Keywords " ") (print "~" . " ")}}
- <span class="label kk-keyword-testing" title="{{$.Version}} is stable on {{.}}">~{{.}}</span>
- {{else}}
- <span class="label kk-keyword-unknown" title="{{$.Version}} is unknown on {{.}}">?{{.}}</span>
- {{end}}
- {{end}}
- </p>
- </div>
-
- </div>
- </div>
- </li>
-{{end}}
diff --git a/web/templates/packages/changedVersions.tmpl b/web/templates/packages/changedVersions.tmpl
deleted file mode 100644
index 3c60338..0000000
--- a/web/templates/packages/changedVersions.tmpl
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "browsepackagesheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
- <h3 class="mb-2">{{.Name}} Packages <a title="Atom feed" href="/packages/{{tolower .Name}}.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a></h3>
-
- <li class="list-group rounded">
- {{range .Versions}}
- {{template "changedversion" .}}
- {{end}}
-
- </li>
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-</body>
-</html>
diff --git a/web/templates/packages/changelog/changelog.tmpl b/web/templates/packages/changelog/changelog.tmpl
deleted file mode 100644
index 261e1ed..0000000
--- a/web/templates/packages/changelog/changelog.tmpl
+++ /dev/null
@@ -1,175 +0,0 @@
-<html>
-<head></head>
-<body>
-
-{{ if .Commits }}
-
- <div class="col-md-12">
- <h3>Latest Commits</h3>
- <ul class="timeline">
- <li>
- <span class="text-muted">Commits on {{(index .Package.Commits 0).CommitterDate.Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- {{$last_date := (index .Commits 0).CommitterDate}}
- {{range .Commits}}
- {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><b style="color:#424242!important;">{{.Message}}</b></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12" style="color:#424242!important;">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range $key, $value := .ChangedFiles.Added }}
- {{if le $key 100}}
- {{ if contains .Path (print $.Atom "/")}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Modified }}
- {{if le $key 100}}
- {{ if contains $value.Path (print $.Atom "/")}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall $value.Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Deleted }}
- {{if le $key 100}}
- {{ if contains .Path (print $.Atom "/")}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{end}}
- {{if gt (len .ChangedFiles.Added) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{else if gt (len .ChangedFiles.Modified) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{else if gt (len .ChangedFiles.Deleted) 100}}
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a>
- {{end}}
- </div>
- </div>
- </li>
- {{else}}
- </ul>
- </li>
- <li>
- <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><b>{{.Message}}</b></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range $key, $value := .ChangedFiles.Added }}
- {{if le $key 50}}
- {{ if contains $value.Path (print $.Atom "/")}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{replaceall $value.Path (print $.Atom "/") ""}} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall $value.Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{end}}
- {{range $key, $value := .ChangedFiles.Modified }}
- {{if le $key 50}}
- {{ if contains $value.Path (print $.Atom "/")}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{replaceall $value.Path (print $.Atom "/") ""}} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{end}}
- {{range .ChangedFiles.Deleted }}
- {{ if contains .Path (print $.Atom "/")}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{replaceall .Path (print $.Atom "/") ""}} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- </div>
- </div>
- </li>
- {{end}}
- {{$last_date = .CommitterDate}}
- {{end}}
- </ul>
- </li>
- </ul>
- </div>
-
-{{else}}
- <li class="list-group-item kk-panel-content-sorry">
- This package has not been changed since our repository has moved to Git.
- <br><br>
- <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default">
- <span class="fa fa-fw fa-history"></span>
- View old CVS Changelog
- </a>
- </li>
-{{end}}
-
-</body>
-</html>
diff --git a/web/templates/packages/changelogwrapper.tmpl b/web/templates/packages/changelogwrapper.tmpl
deleted file mode 100644
index 98de287..0000000
--- a/web/templates/packages/changelogwrapper.tmpl
+++ /dev/null
@@ -1,17 +0,0 @@
-{{define "changelogwrapper"}}
-
- <div id="changelog-container">
- <li class="list-group-item kk-panel-content-sorry">
- <span class="fa fa-refresh fa-spin fa-3x"></span>
- <noscript>
- <br><br>
- Inline Changelog cannot be displayed.
- <br><br>
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{ .Package.Atom }}?showmsg=1" class="btn btn-default">
- <span class="fa fa-fw fa-history"></span>
- View Git Changelog
- </a>
- </noscript>
- </li>
- </div>
-{{end}}
diff --git a/web/templates/packages/components/bugs.tmpl b/web/templates/packages/components/bugs.tmpl
deleted file mode 100644
index e63a986..0000000
--- a/web/templates/packages/components/bugs.tmpl
+++ /dev/null
@@ -1,127 +0,0 @@
-{{define "bugs"}}
- <div class="row">
- <div class="col-md-9">
- {{$general_bugs := 0}}
- {{$stabilization_bugs := 0}}
- {{$keywording_bugs := 0}}
- {{range .Package.AllBugs}}
- {{if eq .Component "Current packages"}}
- {{$general_bugs = (add $general_bugs 1)}}
- {{else if eq .Component "Stabilization"}}
- {{$stabilization_bugs = (add $stabilization_bugs 1)}}
- {{else if eq .Component "Keywording"}}
- {{$keywording_bugs = (add $keywording_bugs 1)}}
- {{end}}
- {{end}}
-
- {{if .Package.AllBugs}}
-
- {{if $general_bugs}}
- <h3 class="mb-4">Bug Reports</h3>
- <ul class="list-group">
- {{range .Package.Bugs}}
- {{if eq .Component "Current packages"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
-
-
-
- {{if $stabilization_bugs}}
- <h3 class="my-4">Stabilization Bug Reports</h3>
- <ul class="list-group">
- {{range .Package.AllBugs}}
- {{if eq .Component "Stabilization"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
-
- {{if $keywording_bugs}}
- <h3 class="my-4">Keywording Bug Reports</h3>
- <ul class="list-group">
- {{range .Package.AllBugs}}
- {{if eq .Component "Keywording"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
- {{end}}
- {{else}}
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>Good job! There are no bugs.</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/enter_bug.cgi">new bug</a>.</span>
- </div>
- </div>
- {{end}}
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs:
- <ul>
- <li><a href="https://bugs.gentoo.org/enter_bug.cgi">File a new Bug</a></li>
- <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li>
- <li><a href="https://sites.google.com/site/yacoset/Home/how-to-fix-bugs-step-by-step">Offer solutions for open bugs</a></li>
- <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li>
- </ul>
- </span>
- </div>
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts">
- Shortcuts
- </a>
- </h4>
- <div class="collapse show" id="collapseShortcuts">
- <ul>
- <li>{{if $general_bugs}}<a href="#packages">Packages Bugs ({{$general_bugs}})</a>{{else}}<a>Packages Bugs (0)</a>{{end}}</li>
- <li>{{if $stabilization_bugs}}<a href="#stabilization">Stabilization Bugs ({{$stabilization_bugs}})</a>{{else}}<a>Stabilization Bugs (0)</a>{{end}}</li>
- <li>{{if $keywording_bugs}}<a href="#keywording">Keywording Bugs ({{$keywording_bugs}})</a>{{else}}<a>Keywording Bugs (0)</a>{{end}}</li>
- </ul>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/packages/components/changelog.tmpl b/web/templates/packages/components/changelog.tmpl
deleted file mode 100644
index 4e01724..0000000
--- a/web/templates/packages/components/changelog.tmpl
+++ /dev/null
@@ -1,153 +0,0 @@
-{{define "changelog"}}
-
- {{ if .Package.Commits }}
-
-
- <h3>Latest Commits</h3>
- <ul class="timeline">
- <li>
- <span class="text-muted">Commits on {{(index .Package.Commits 0).CommitterDate.Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- {{$last_date := (index .Package.Commits 0).CommitterDate}}
- {{range .Package.Commits}}
- {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12" style="color:#424242!important;">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range .ChangedFiles.Added }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{range .ChangedFiles.Modified }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{range .ChangedFiles.Deleted }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- </div>
- </div>
- </li>
- {{else}}
- </ul>
- </li>
- <li>
- <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span>
- <ul class="list-group">
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div>
- <div class="col-md-12">
- {{ if (ne .AuthorName .CommitterName)}}
- <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}">
- <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and&nbsp;
- {{end}}
- <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}">
- <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }}
- </div>
- <div class="col-md-12">
- {{$commit := .}}
- {{range .ChangedFiles.Added }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-added-file-badge {
- background-color: #dff0d8;
- font-weight: normal;
- }
- .kk-added-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{range .ChangedFiles.Modified }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-modified-file-badge {
- background-color: #fcf8e3;
- font-weight: normal;
- }
- .kk-modified-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- {{range .ChangedFiles.Deleted }}
- {{ if contains .Path (print $.Package.Atom "/")}}
- <style>
- .kk-deleted-file-badge {
- background-color: #f2dede;
- font-weight: normal;
- }
- .kk-deleted-file-badge > a {
- color: #424242!important;
- }
- </style>
- <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span>
- {{end}}
- {{end}}
- </div>
- </div>
- </li>
- {{end}}
- {{$last_date = .CommitterDate}}
- {{end}}
- </ul>
- </li>
- </ul>
-
- {{else}}
- <li class="list-group-item kk-panel-content-sorry">
- This package has not been changed since our repository has moved to Git.
- <br><br>
- <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default">
- <span class="fa fa-fw fa-history"></span>
- View old CVS Changelog
- </a>
- </li>
- {{end}}
-{{end}} \ No newline at end of file
diff --git a/web/templates/packages/components/dependencies.tmpl b/web/templates/packages/components/dependencies.tmpl
deleted file mode 100644
index d63a0b5..0000000
--- a/web/templates/packages/components/dependencies.tmpl
+++ /dev/null
@@ -1,63 +0,0 @@
-{{define "dependencies"}}
- <div class="row">
- <div class="col-md-9">
- <h3><a class="text-dark"><i class="fa fa-level-down" aria-hidden="true"></i> Dependencies</a> <a href="/packages/{{.Package.Atom}}/reverse-dependencies" class="ml-3 text-muted"><i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies</a></h3>
-
- <ul class="timeline">
-
- {{range $index, $element := .Package.Versions}}
- <li>
- <span class="text-muted">{{.Version}}</span>
-
- {{$depMap := $element.BuildDepMap}}
-
- {{if len $depMap}}
- <div class="card mt-4">
- <div class="table-responsive border-0">
- <table class="table mb-0">
- <thead>
- <tr>
- <th scope="col">Version</th>
- <th scope="col">RDEPEND</th>
- <th scope="col">DEPEND</th>
- <th scope="col">BDEPEND</th>
- <th scope="col">PDEPEND</th>
- </tr>
- </thead>
- <tbody>
-
- {{ range $key, $value := $depMap }}
- <tr>
- <th scope="row"><a class="text-dark" href="/packages/{{$value.Atom}}">{{$key}}</a></th>
- <td>{{if $value.rdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.depend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.bdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.pdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- </tr>
- {{end}}
-
- </tbody>
- </table>
- </div>
- </div>
- {{end}}
-
- </li>
- {{end}}
- </ul>
-
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- The dependencies are regularly computed based on the <a href="https://qa-reports.gentoo.org/">qa-reports</a>.
- </span>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/packages/components/overview.tmpl b/web/templates/packages/components/overview.tmpl
deleted file mode 100644
index 3f5bca3..0000000
--- a/web/templates/packages/components/overview.tmpl
+++ /dev/null
@@ -1,86 +0,0 @@
-{{define "overview"}}
-<div class="row">
- <div class="col-md-9">
-
- {{ if .UserPreferences.Packages.Overview.ShowOutdated}}
- {{ if .Package.Outdated }}
- {{$outdatedFound := false}}
- {{range .Versions}}
- {{if eq (index $.Package.Outdated 0).NewestVersion .Version}}
- {{$outdatedFound = true}}
- {{end}}
- {{end}}
- {{if not $outdatedFound}}
- <div class="alert alert-info">
- <strong><span class="fa fa-fw fa-lightbulb-o"></span> Version {{ (index .Package.Outdated 0).NewestVersion }} is available upstream. Please consider updating!</strong><br>
- It seems that version {{ (index .Package.Outdated 0).NewestVersion }} is available upstream, while the latest version in the Gentoo tree is {{ (index .Package.Outdated 0).GentooVersion }}.<br/>
- <small><i>You think this warning is false? Read more about it <a href="https://archives.gentoo.org/gentoo-dev/message/b793f4da5a5b5e20a063ea431500a820">here</a>.</i></small>
- </div>
- {{end}}
- {{ end }}
- {{ end }}
-
- {{template "versions" .}}
-
- {{ if isMasked .Versions }}
-
- <h3 class="pt-3 mb-2">Masks</h3>
-
- <div class="card kk-mask mb-3">
- <ul class="list-group list-group-flush kk-mask">
- <li class="list-group-item kk-mask">
- {{ if showRemovalNotice .Versions }}
- <p style="color:#721c24;">
- <strong><span class="fa fa-fw fa-warning"></span> This package is masked and could be removed soon!</strong><br>
- The mask comment indicates that this package is scheduled for removal from our package repository.<br>
- Please review the mask information below for more details.
- </p>
- {{end}}
-
- <strong class="kk-mask-reason">{{(getMask .Versions).Reason}}</strong>
-
- <div class="kk-mask-details">
-
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- Affected packages
- </div>
- <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden">
- {{(getMask .Versions).Versions}}
- </div>
- </div>
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- Author/Date
- </div>
- <div class="col-xs-12 col-md-9">
- {{(getMask .Versions).Author}} &lt;{{(getMask .Versions).AuthorEmail}}&gt; <span class="text-muted">({{(getMask .Versions).Date}})</span>
- </div>
- </div>
- </div>
- </li>
- </ul>
- </div>
- {{end}}
-
- {{ if not .Package.Maintainers }}
- <div class="alert alert-info">
- <strong><span class="fa fa-fw fa-wrench"></span> This package needs a new maintainer!</strong><br>
- If you are interested in helping with the maintenance of {{.Package.Name}}, please get in touch with our
- <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers" class="alert-link">Proxy Maintainers team</a>.
- </div>
- {{end}}
-
- {{template "metadata" .}}
-
- {{ if eq .UserPreferences.Packages.Overview.Layout "full" }}
- <div class="mt-4 pt-4"></div>
- {{template "changelog" .}}
- {{end}}
-
- </div>
- <div class="col-md-3 pl-4 pt-4 mt-2">
- {{template "resources" .}}
- </div>
-</div>
-{{end}}
diff --git a/web/templates/packages/components/pullrequests.tmpl b/web/templates/packages/components/pullrequests.tmpl
deleted file mode 100644
index 7782c62..0000000
--- a/web/templates/packages/components/pullrequests.tmpl
+++ /dev/null
@@ -1,75 +0,0 @@
-{{define "pull-requests"}}
-
- <div class="row">
- <div class="col-md-9">
-
- {{if .Package.PullRequests}}
-
- <h3 class="mb-4">Pull Requests</h3>
-
- <ul class="list-group">
-
- {{range .Package.PullRequests}}
-
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-11">
- <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span>
- <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-dark"><b>{{.Title}}</b></a>
- {{if eq .CiState "SUCCESS"}}
- <a href="{{.CiStateLink}}"><i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i></a>
- {{else}}
- <a href="{{.CiStateLink}}"><i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i></a>
- {{end}}
- {{range .Labels}}
- <span class="badge badge-pill badge-light p-1" style="font-weight: normal; {{if eq .Color "5319e7" "0052cc" "b60205"}}color:#FFF;{{end}} background-color: #{{.Color}}!important;">{{.Name}}</span>
- {{end}}
- </div>
- <div class="col-md-1 text-right">
- <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-muted">
- <i class="fa fa-comment-o" aria-hidden="true"></i>
- {{.Comments}}
- </a>
- </div>
- <div class="col-md-12 text-muted">
- <span style="font-size: 90%;">
- #{{.Id}} opened {{.CreatedAt}} by {{.Author}}
- </span>
- </div>
- </div>
- </li>
-
- {{end}}
- </ul>
-
- {{else}}
-
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>There are no pull requests</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span>
- </div>
- </div>
-
- {{end}}
-
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub.<br/>
- Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>.
- </span>
- </div>
- </div>
- </div>
-
-{{end}}
diff --git a/web/templates/packages/components/qareport.tmpl b/web/templates/packages/components/qareport.tmpl
deleted file mode 100644
index 536e382..0000000
--- a/web/templates/packages/components/qareport.tmpl
+++ /dev/null
@@ -1,82 +0,0 @@
-{{define "qa-report"}}
- <div class="row">
- <div class="col-md-9">
-
- <h3>Pkgcheck Warnings</h3>
- <ul class="timeline">
- <li>
- <span class="text-muted">All Versions</span>
- <ul class="list-group">
-
- {{ if .Package.PkgCheckResults }}
- {{ range $.Package.PkgCheckResults }}
- {{if $.UserPreferences.ContainsPkgcheckClass .Class}}
- {{if not .Version}}
- <li class="list-group-item">
- <strong>{{ .Class }}</strong><br/>
- <span class="kk-version kk-cell-sep-right text-muted">
- {{ .Message }}
- </span>
- </li>
- {{end}}
- {{end}}
- {{end}}
- {{end}}
- </ul>
- </li>
-
- {{range $index, $element := .Package.Versions}}
- <li>
- <span class="text-muted">{{.Version}}</span>
- <ul class="list-group">
-
- {{ if .PkgCheckResults }}
- {{ range .PkgCheckResults }}
- {{if $.UserPreferences.ContainsPkgcheckClass .Class}}
- <li class="list-group-item">
- <strong>{{ .Class }}</strong><br/>
- <span class="kk-version kk-cell-sep-right text-muted">
- {{ .Message }}
- </span>
- </li>
- {{end}}
- {{end}}
- {{end}}
- </ul>
- </li>
- {{end}}
- </ul>
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Pkgcheck is used regularly to generate QA reports. Pkgcheck is a pkgcore-based QA utility for ebuild repos.
- </span>
- </div>
- <h4 class="mt-4">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources">
- External Resources
- </a>
- </h4>
- <div class="collapse show" id="collapseExternalResources">
- <ul>
- <li>
- <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg={{.Package.Category}}:{{.Package.Name}}" target="_blank">
- CI Report
- </a>
- </li>
- <li>
- <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg={{.Package.Category}}:{{.Package.Name}}" target="_blank">
- CI Report (verbose)
- </a>
- </li>
- </ul>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/packages/components/reverse-dependencies.tmpl b/web/templates/packages/components/reverse-dependencies.tmpl
deleted file mode 100644
index 0415b78..0000000
--- a/web/templates/packages/components/reverse-dependencies.tmpl
+++ /dev/null
@@ -1,59 +0,0 @@
-{{define "reverse-dependencies"}}
- <div class="row">
- <div class="col-md-9">
-
- <h3><a class="text-muted" href="/packages/{{.Package.Atom}}/dependencies"><i class="fa fa-level-down" aria-hidden="true"></i> Dependencies</a> <a class="ml-3 text-dark"><i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies</a></h3>
-
- {{$revDevMap := .Package.BuildRevDepMap}}
-
- <div class="card mt-4">
- <div class="table-responsive border-0">
- <table class="table mb-0">
- <thead>
- <tr>
- <th scope="col">Version</th>
- <th scope="col">RDEPEND</th>
- <th scope="col">DEPEND</th>
- <th scope="col">BDEPEND</th>
- <th scope="col">PDEPEND</th>
- </tr>
- </thead>
- <tbody>
-
- {{ range $key, $value := $revDevMap }}
- <tr>
- <th scope="row"><a class="text-dark" href="/packages/{{replaceall $value.Atom "[B]" ""}}">{{$key}}</a></th>
- <td>{{if $value.rdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.depend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.bdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- <td>{{if $value.pdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td>
- </tr>
- {{end}}
-
- </tbody>
- </table>
- </div>
- </div>
-
-
- </div>
- <div class="col-md-3 pt-5">
- <h4 class="">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Description
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- The reverse dependencies are regularly parsed from the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. The sources can be found at:
- <ul>
- <li><a href="https://qa-reports.gentoo.org/output/genrdeps/rindex/{{.Package.Atom}}">rdepend</a></li>
- <li><a href="https://qa-reports.gentoo.org/output/genrdeps/dindex/{{.Package.Atom}}">depend</a></li>
- <li><a href="https://qa-reports.gentoo.org/output/genrdeps/bindex/{{.Package.Atom}}">bdepend</a></li>
- <li><a href="https://qa-reports.gentoo.org/output/genrdeps/pindex/{{.Package.Atom}}">pdepend</a></li>
- </ul>
- </span>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/packages/components/security.tmpl b/web/templates/packages/components/security.tmpl
deleted file mode 100644
index 8b4cd91..0000000
--- a/web/templates/packages/components/security.tmpl
+++ /dev/null
@@ -1,72 +0,0 @@
-{{define "security"}}
- <div class="row">
- <div class="col-md-9">
-
- {{$security_bugs := 0}}
- {{range .Package.AllBugs}}
- {{if eq .Component "Vulnerabilities"}}
- {{$security_bugs = (add $security_bugs 1)}}
- {{end}}
- {{end}}
-
- {{if $security_bugs}}
-
- <h3 class="mb-4">Security Bug Reports</h3>
- <ul class="list-group">
- {{range .Package.AllBugs}}
- {{if eq .Component "Vulnerabilities"}}
- <li class="list-group-item">
- <div class="row">
- <div class="col-md-12">
- <i class="fa fa-bug" aria-hidden="true"></i>
- <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a>
- </div>
- <div class="col-md-12 text-muted">
- {{.Id}} - Assigned to {{.Assignee}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- </ul>
-
- {{else}}
-
- <div class="row pt-5">
- <div class="col-md-4">
- <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/>
- </div>
- <div class="col-md-8 pt-3">
- <h2>There are no open security bugs.</h2>
- <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/">new security bug</a>.</span>
- </div>
- </div>
-
- {{end}}
-
- </div>
- <div class="col-md-3 pt-5">
- <h4>
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription">
- Contact Information
- </a>
- </h4>
- <div class="collapse show" id="collapseDescription">
- <span class="text-muted">
- Please file new vulnerability reports on <a href="https://bugs.gentoo.org/">Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component.
- </span>
- </div>
- <h4 class="mt-4">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources">
- External Resources
- </a>
- </h4>
- <div class="collapse show" id="collapseExternalResources">
- <ul>
- <li><a href="https://bugs.gentoo.org/buglist.cgi?bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&bug_status=RESOLVED&bug_status=VERIFIED&email1=security%40gentoo.org&emailassigned_to1=1&emailtype1=equals&list_id=4699406&query_format=advanced&resolution=---&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&short_desc={{.Package.Category}}%2F{{.Package.Name}}&short_desc_type=allwordssubstr">All security bugs for this package</a></li>
- </ul>
- </div>
- </div>
- </div>
-{{end}}
-
diff --git a/web/templates/packages/metadata.tmpl b/web/templates/packages/metadata.tmpl
deleted file mode 100644
index 758e01c..0000000
--- a/web/templates/packages/metadata.tmpl
+++ /dev/null
@@ -1,171 +0,0 @@
-{{define "metadata"}}
-{{if gt (len .UserPreferences.Packages.Overview.MetadataFields) 0 }}
- <h3 class="pt-3 mb-2">Package Metadata</h3>
-{{end}}
-
-<div class="card border-0 mb-3">
- <ul class="list-group kk-metadata-list">
-
- <!-- TODO -->
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "homepage"}}
- {{ if gt (len (index .Versions 0).Homepage) 1 }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-home"></span>
- Other homepage(s)
- </div>
- <div class="col-xs-12 col-md-9">
- <a href="{{ (index (index .Versions 0).Homepage 1) }}">{{ (index (index .Versions 0).Homepage 1) }}</a>
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "upstream"}}
- {{ if .Package.Upstream }}
- {{ if or .Package.Upstream.Doc .Package.Upstream.Changelog .Package.Upstream.BugsTo .Package.Upstream.RemoteIds }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-code-fork"></span>
- Upstream
- </div>
- <div class="col-xs-12 col-md-9">
- <table>
- {{if .Package.Upstream.Doc}}
- {{range $k, $v := .Package.Upstream.Doc}}
- <tr>
- <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Documentation </span>{{end}}</td>
- {{if not (eq $v "")}}
- <td><a href="{{ $v}}">{{ $v }}</a></td>
- {{end}}
- </tr>
- {{end}}
- {{end}}
- {{if .Package.Upstream.Changelog}}
- {{range $k, $v := .Package.Upstream.Changelog}}
- <tr>
- <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Changelog</span>{{end}}</td>
- {{if not (eq $v "")}}
- <td><a href="{{ $v}}">{{ $v }}</a></td>
- {{end}}
- </tr>
- {{end}}
- {{end}}
- {{if .Package.Upstream.BugsTo}}
- {{range $k, $v := .Package.Upstream.BugsTo}}
- <tr>
- <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Bugs-To</span>{{end}}</td>
- {{if not (eq $v "")}}
- <td><a href="{{ $v}}">{{ $v }}</a></td>
- {{end}}
- </tr>
- {{end}}
- {{end}}
- {{if .Package.Upstream.RemoteIds}}
- {{range $k, $v := .Package.Upstream.RemoteIds}}
- {{ $link := RemoteIdLink . }}
- {{if not (eq $link "")}}
- <tr>
- <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Remote-Id</span>{{end}}</td>
- <td><a href="{{ $link}}">{{ $link }}</a></td>
- </tr>
- {{end}}
- {{end}}
- {{end}}
- </table>
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
- {{end}}
-
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "longdescription"}}
- {{ if .Package.Longdescription }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-info"></span>
- Full description
- </div>
- <div class="col-xs-12 col-md-9">
- {{ .Package.Longdescription }}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "useflags"}}
- {{ if or .LocalUseflags .GlobalUseflags .UseExpands }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-sliders"></span>
- USE flags
- </div>
- <div class="col-xs-12 col-md-9">
- {{ template "useflag" .}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "license"}}
- {{ if (index .Versions 0).License }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-legal"></span>
- License
- </div>
- <div class="col-xs-12 col-md-9">
- {{ (index .Versions 0).License }}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
- <!-- TODO
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-group"></span>
- <%= t :herds %>
- </div>
- <div class="col-xs-12 col-md-9">
- <%= render partial: 'herd', collection: package.herds.sort, as: 'herd', spacer_template: 'maintainer_spacer' %>
- </div>
- </div>
- </li>
- -->
-
- {{if listContains .UserPreferences.Packages.Overview.MetadataFields "maintainers"}}
- {{ if .Package.Maintainers }}
- <li class="kk-metadata-item list-group-item">
- <div class="row">
- <div class="col-xs-12 col-md-3 kk-metadata-key">
- <span class="fa fa-fw fa-user"></span>
- Maintainer(s)
- </div>
- <div class="col-xs-12 col-md-9">
- {{ range .Package.Maintainers }}
- {{if (ne .Name (index $.Package.Maintainers 0).Name)}}
- ,&nbsp;
- {{end}}
- <a title="{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a> <a href="mailto:{{.Email}}"><i class="fa fa-envelope-o" style="font-size: .925em;" aria-hidden="true"></i></a>
- {{end}}
- </div>
- </div>
- </li>
- {{end}}
- {{end}}
-
- </ul>
-</div>
-{{end}}
diff --git a/web/templates/packages/packageheader.tmpl b/web/templates/packages/packageheader.tmpl
deleted file mode 100644
index 06a4ff0..0000000
--- a/web/templates/packages/packageheader.tmpl
+++ /dev/null
@@ -1,72 +0,0 @@
-{{define "packageheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title" data-atom="{{.Package.Atom}}" data-category="{{.Package.Category}}" data-name="{{.Package.Name}}">
- <small class="kk-package-cat"><a href="/categories/{{.Package.Category}}" class="text-dark">{{.Package.Category}}</a>/</small>
- <div>
- <svg height="32" class="octicon octicon-package right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"></path></svg>
- <div class="kk-package-name">{{.Package.Name}}</div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
- <p class="lead kk-package-maindesc">
- {{(index .Versions 0).Description}}
- </p>
- {{if (index .Versions 0).Homepage}}
- <p class="kk-package-homepage">
- <a href="{{ ( index (index .Versions 0).Homepage 0) }}">{{ ( index (index .Versions 0).Homepage 0) }}</a>
- </p>
- {{end}}
- </div>
- {{$security_bugs := 0}}
- {{$non_security_bugs := 0}}
- {{range .Package.AllBugs}}
- {{if eq .Component "Vulnerabilities"}}
- {{$security_bugs = (add $security_bugs 1)}}
- {{else}}
- {{$non_security_bugs = (add $non_security_bugs 1)}}
- {{end}}
- {{end}}
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Overview"}}
- <a class="nav-link {{if eq .PageName "overview"}}active{{end}}" href="/packages/{{.Package.Atom}}"><i class="fa fa-info mr-1" aria-hidden="true"></i> Overview</a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Dependencies"}}
- <a class="nav-link {{if eq .PageName "dependencies" "reverse-dependencies"}}active{{end}}" href="/packages/{{.Package.Atom}}/{{.UserPreferences.Packages.Dependencies.Default}}"><i class="fa fa-link"></i> Dependencies</a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "QA report"}}
- <a class="nav-link {{if eq .PageName "qa-report"}}active{{end}}" href="/packages/{{.Package.Atom}}/qa-report"><i class="fa fa-fw fa-chain-broken"></i> QA report </a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Pull requests"}}
- <a class="nav-link {{if eq .PageName "pull-requests"}}active{{end}}" href="/packages/{{.Package.Atom}}/pull-requests"><span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> Pull requests <span class="ml-1 badge badge-pill kk-misc-badge">{{len .Package.PullRequests}}</span></a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Bugs"}}
- <a class="nav-link {{if eq .PageName "bugs"}}active{{end}}" href="/packages/{{.Package.Atom}}/bugs"><i class="fa fa-bug" aria-hidden="true"></i> Bugs <span class="ml-1 badge badge-pill kk-misc-badge">{{$non_security_bugs}}</span></a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Security"}}
- <a class="nav-link {{if eq .PageName "security"}}active{{end}}" href="/packages/{{.Package.Atom}}/security"><i class="fa fa-shield" aria-hidden="true"></i> Security <span class="ml-1 badge badge-pill kk-misc-badge">{{$security_bugs}}</span></a>
- {{end}}
-
- {{if listContains $.UserPreferences.Packages.Tabs.Visible "Changelog"}}
- <a class="nav-link {{if eq .PageName "changelog"}}active{{end}}" href="/packages/{{.Package.Atom}}/changelog"><i class="fa fa-fw fa-history"></i> Changelog</a>
- {{end}}
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/packages/resources.tmpl b/web/templates/packages/resources.tmpl
deleted file mode 100644
index 784a691..0000000
--- a/web/templates/packages/resources.tmpl
+++ /dev/null
@@ -1,65 +0,0 @@
-{{define "resources"}}
-
- <h4 class="mb-2 ml-1">
- <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources">
- External Resources
- </a>
- </h4>
-
- <div class="collapse show" id="collapseExternalResources">
- <dl class="ml-3">
- <dd>
- <span class="fa fa-fw fa-bug"></span>
- <a href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Package.Atom}}" class="" target="_blank">
- Related bugs
- </a>
- </dd>
- <dd>
- <span class="fa fa-fw fa-chain-broken"></span>
- <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg={{.Package.Category}}:{{.Package.Name}}" title="CI report" target="_blank">CI Report</a>
- (<a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg={{.Package.Category}}:{{.Package.Name}}" title="Verbose CI report" target="_blank">verbose</a>)
- </dd>
- <dd>
- <span class="fa fa-fw fa-sort-numeric-desc"></span>
- <a href="https://repology.org/project/{{.Package.Name}}" target="_blank">
- Repology
- </a>
- </dd>
- <dd>
- <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span>
- <a href="https://github.com/gentoo/gentoo/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+{{.Package.Category}}%2F{{.Package.Name}}" target="_blank">
- Open Pull Requests
- </a>
- </dd>
- <dd>
- <span class="fa fa-fw fa-book"></span>
- <a href="https://wiki.gentoo.org/wiki/Special:Search/{{.Package.Name}}" target="_blank">
- Documentation
- </a>
- </dd>
- <dd>
- <span class="fa fa-fw fa-comments-o"></span>
- <a href="https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords={{.Package.Name}}&mode=results" target="_blank">
- Forums posts
- </a>
- </dd>
- <dd>
- <span class="fa fa-fw fa-code-fork"></span>
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Package.Atom}}" target="_blank">
- Git repository browser
- </a>
- </dd>
- <dd>
- <span class="fa fa-fw fa-history"></span>
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Package.Atom}}?showmsg=1" title="Git log" target="_blank">Git log</a>
- (<a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Package.Atom}}" title="Short git log" target="_blank">short</a>)
- </dd>
- <dd>
- <span class="fa fa-fw fa-rss"></span>
- <a href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Package.Atom}}?h=master" target="_blank">
- Changes Feed
- </a>
- </dd>
- </dl>
- </div>
-{{end}}
diff --git a/web/templates/packages/search.tmpl b/web/templates/packages/search.tmpl
deleted file mode 100644
index 476830b..0000000
--- a/web/templates/packages/search.tmpl
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
-
- <h1 class="first-header">Search Results <small>for {{.Search}}</small>
- <a title="Atom feed" href="/packages/search.atom?q={{.Search}}" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a></h1>
-
- {{ if .Packages }}
- <div class="panel panel-default">
- <div class="panel-heading">
- Results 1—{{len .Packages}} of {{len .Packages}}
- </div>
- <div class="list-group">
- {{range .Packages}}
- <a class="list-group-item list-group-item-action" href="/packages/{{.Atom}}">
- <h3 class="kk-search-result-header"><span class="text-muted">{{.Category}}/</span>{{.Name}}</h3>
- {{ (index .Versions 0).Description}}
- </a>
- {{end}}
- </div>
- <!-- TODO paging
- <div class="panel-footer">
- <div class="btn-group" role="group" aria-label="Result navigation">
- <%= link_to '< Prev', search_packages_path(q: params[:q], o: [@offset - PackageRepository.default_search_size, 0].max), class: 'btn btn-default' + (@offset > 0 ? '' : ' disabled') %>
- <%= link_to 'Next >', search_packages_path(q: params[:q], o: @offset + PackageRepository.default_search_size), class: 'btn btn-default ' + ((@offset + PackageRepository.default_search_size) > @packages.total ? 'disabled' : '') %>
- </div>
- </div>
- -->
-
- </div>
-
- <!-- TODO in head: alternate_feed_link(search_packages_url(format: :atom, params: request.query_parameters), t(:atom_feed)) -->
- {{ else }}
- <div class="jumbotron">
- <h2 class="site-welcome stick-top">Nothing found. :( Try again?</h2>
-
- <form action="/packages/search" method="get">
- <div class="typeahead-container">
- <div class="typeahead-field">
- <span class="typeahead-query">
- <input id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" value="{{.Search}}">
- </span>
- <span class="typeahead-button">
- <button type="submit" title="Find" aria-label="Find">
- <span class="typeahead-search-icon"></span><span class="sr-only">Find</span>
- </button>
- </span>
- </div>
- </div>
- </form>
- </div>
- {{end}}
-
-
- </div>
- </div>
-</div>
-
-
-{{template "footer" .Application }}
-
-
-</body>
-</html>
diff --git a/web/templates/packages/show.tmpl b/web/templates/packages/show.tmpl
deleted file mode 100644
index c2f2a39..0000000
--- a/web/templates/packages/show.tmpl
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "packageheader" .}}
-
-<div class="tab-content" id="myTabContent">
- <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
- {{if eq .PageName "overview"}}
- {{template "overview" .}}
- {{else if eq .PageName "qa-report"}}
- {{template "qa-report" .}}
- {{else if eq .PageName "pull-requests"}}
- {{template "pull-requests" .}}
- {{else if eq .PageName "bugs"}}
- {{template "bugs" .}}
- {{else if eq .PageName "security"}}
- {{template "security" .}}
- {{else if eq .PageName "dependencies"}}
- {{template "dependencies" .}}
- {{else if eq .PageName "reverse-dependencies"}}
- {{template "reverse-dependencies" .}}
- {{else if eq .PageName "changelog"}}
- <div class="row">
- <div class="col-md-9">
- {{template "changelog" .}}
- </div>
- </div>
- {{end}}
- </div>
-</div>
-
-{{template "footer" .Application }}
-
-<script src="/assets/packages.js"></script>
-
-
-</body>
-</html>
diff --git a/web/templates/packages/useflag.tmpl b/web/templates/packages/useflag.tmpl
deleted file mode 100644
index ce136af..0000000
--- a/web/templates/packages/useflag.tmpl
+++ /dev/null
@@ -1,40 +0,0 @@
-{{define "useflag"}}
- {{ if .LocalUseflags }}
- <span class="kk-useflag-group">Local Use Flags</span>
- <ul class="kk-useflag-container {{ if ge (len .LocalUseflags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}">
- {{range .LocalUseflags}}
- <li class="kk-useflag">
- <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{.Name}}</a>
- </li>
- {{end}}
- </ul>
-
- {{end}}
-
-
-
- {{ if .GlobalUseflags }}
- <span class="kk-useflag-group">Global Use Flags</span>
- <ul class="kk-useflag-container {{ if ge (len .GlobalUseflags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}">
- {{range .GlobalUseflags}}
- <li class="kk-useflag">
- <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{.Name}}</a>
- </li>
- {{end}}
- </ul>
- {{end}}
-
-
- {{ if .UseExpands }}
- {{range $key, $flags := .UseExpands}}
- <span class="kk-useflag-group">{{ $key }} (Use Expand)</span>
- <ul class="kk-useflag-container {{ if ge (len $flags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}">
- {{range $flags}}
- <li class="kk-useflag">
- <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{ replaceall .Name (print .UseExpand "_") "" }}</a>
- </li>
- {{end}}
- </ul>
- {{end}}
- {{end}}
-{{end}}
diff --git a/web/templates/packages/versionrows.tmpl b/web/templates/packages/versionrows.tmpl
deleted file mode 100644
index 56248ae..0000000
--- a/web/templates/packages/versionrows.tmpl
+++ /dev/null
@@ -1,75 +0,0 @@
-{{define "versionrows"}}
- {{range $index, $version := .Package.Versions}}
- <tr>
- <td class="kk-version "><strong><a class="kk-ebuild-link" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{$version.Atom}}/{{$version.Package}}-{{$version.Version}}.ebuild">{{$version.Version}}</a></strong><span class="kk-slot" title="subslot {{ $version.Subslot }}"> : {{ $version.Slot }}</span>
- {{ if $version.Restricts }}
- <span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{ $version.Restricts }}">{{ formatRestricts $version.Restricts }}</span>
- {{ end }}
- {{ if eq $.UserPreferences.Packages.Overview.EAPI "inline"}}
- <span style="background-color: white;border:1px solid grey;color: grey;" class="badge badge-danger kk-restrict-label" title="The following features are restricted:">EAPI {{$version.EAPI}}</span>
- {{end}}
- </td>
-
- {{ if eq $.UserPreferences.Packages.Overview.EAPI "column"}}
- <td class="text-center">
- {{$version.EAPI}}
- </td>
- {{end}}
-
- {{ range $.UserPreferences.Packages.Overview.Keywords }}
-
- {{ if contains (print " " $version " ") (print "~" . " ") }}
-
- {{ if ge (len $version.Masks) 1 }}
- <td class="kk-keyword kk-keyword-masked" title="{{$version.Version}} is masked (testing) on {{.}}">
- <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg>
- <span class="sr-only">~{{.}}</span>
- </td>
- {{else}}
- <td class="kk-keyword kk-keyword-testing" title="{{$version.Version}} is testing on {{.}}">
- <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg>
- <span class="sr-only">~{{.}}</span>
- </td>
- {{end}}
-
- {{ else if contains (print " " $version.Keywords " ") (print "-" . " ") }}
-
- <td class="kk-keyword kk-keyword-unavailable" title="{{$version.Version}} is unavailable on {{.}}">
- <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg>
- <span class="sr-only">-{{.}}</span>
- </td>
-
- {{ else if contains (print " " $version.Keywords " ") (print . " ") }}
-
- {{ if ge (len $version.Masks) 1 }}
- <td class="kk-keyword kk-keyword-masked" title="{{$version.Version}} is masked (stable) on {{.}}">
- <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg>
- <span class="sr-only">{{.}}</span>
- </td>
- {{else}}
- <td class="kk-keyword kk-keyword-stable" title="{{$version.Version}} is stable on {{.}}">
- <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg>
- <span class="sr-only">{{.}}</span>
- </td>
- {{end}}
-
- {{ else if contains $version.Keywords "-*" }}
-
- <td class="kk-keyword kk-keyword-unavailable" title="{{$version.Version}} is unavailable on {{.}}">
- <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg>
- <span class="sr-only">-{{.}}</span>
- </td>
-
- {{else}}
-
- <td class="kk-keyword kk-keyword-unkown" title="{{$version.Version}} is unknown on {{.}}">
- <span class="sr-only">{{.}}</span>
- </td>
-
- {{end}}
-
- {{end}}
-
- </tr>
- {{end}}
-{{end}}
diff --git a/web/templates/packages/versions.tmpl b/web/templates/packages/versions.tmpl
deleted file mode 100644
index 1b36baf..0000000
--- a/web/templates/packages/versions.tmpl
+++ /dev/null
@@ -1,25 +0,0 @@
-{{define "versions"}}
-
- <h3 class="mb-2">Available Versions</h3>
-
- <div class="card mb-4 rounded">
- <div class="table-responsive border-0">
- <table class="table table-bordered kk-versions-table mb-0 overflow-hidden border-0">
- <thead class="border-0">
- <tr class="border-0">
- <th class="kk-version border-left-0 border-top-0">Version</th>
- {{ if eq .UserPreferences.Packages.Overview.EAPI "column"}}
- <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">EAPI</th>
- {{end}}
- {{range .UserPreferences.Packages.Overview.Keywords}}
- <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">{{.}}</th>
- {{end}}
- </tr>
- </thead>
- <tbody>
- {{template "versionrows" .}}
- </tbody>
- </table>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/useflags/browseuseflagsheader.tmpl b/web/templates/useflags/browseuseflagsheader.tmpl
deleted file mode 100644
index fd26f82..0000000
--- a/web/templates/useflags/browseuseflagsheader.tmpl
+++ /dev/null
@@ -1,33 +0,0 @@
-{{define "browseuseflagsheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3 pt-2">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-sliders"></span><span class="ml-2">USE flags</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
-
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link {{if eq .Page "browse"}}active{{end}}" href="/useflags"><i class="fa fa-line-chart mr-1" aria-hidden="true"></i> Widely used</a>
- <a class="nav-link {{if eq .Page "search"}}active{{end}}" href="/useflags/search"><i class="fa fa-search mr-1" aria-hidden="true"></i> Search</a>
- <a class="nav-link {{if eq .Page "global"}}active{{end}}" href="/useflags/global"><i class="fa fa-globe mr-1" aria-hidden="true"></i> Global</a>
- <a class="nav-link {{if eq .Page "local"}}active{{end}}" href="/useflags/local"><i class="fa fa-map-marker mr-1" aria-hidden="true"></i> Local</a>
-
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/useflags/index.tmpl b/web/templates/useflags/index.tmpl
deleted file mode 100644
index 455e7d3..0000000
--- a/web/templates/useflags/index.tmpl
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "browseuseflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-
-<div class="container mb-5">
- <div class="row">
-
- <div class="col-12">
-
-
- <div class="card" style="background: none;border: none;">
- <noscript>
- <div class="panel-body kk-panel-content-sorry">
- This feature requires JavaScript to work.
- </div>
- </noscript>
- <div class="panel-body kk-useflag-bubble-container" id="bubble-placeholder" style="overflow: hidden!important; display: none;">
- </div>
- </div>
-
- <!-- javascript_pack_tag 'useflags' -->
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-<script src="/assets/useflags.js"></script>
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/list.tmpl b/web/templates/useflags/list.tmpl
deleted file mode 100644
index 27c29dc..0000000
--- a/web/templates/useflags/list.tmpl
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "browseuseflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
- {{if .Useflags}}
- <h3><span class="text-capitalize">{{.Page}}</span> USE flags</h3>
-
- <div class="card border-0">
- <div class="list-group">
- {{ range .Useflags }}
- <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}">
- <h3 class="kk-search-result-header">{{.Name}}</h3>
- {{.Description}}
- </a>
- {{end}}
- </div>
- </div>
- {{end}}
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/listlocal.tmpl b/web/templates/useflags/listlocal.tmpl
deleted file mode 100644
index e6d52eb..0000000
--- a/web/templates/useflags/listlocal.tmpl
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "browseuseflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
- {{if .Useflags}}
- {{$package := (index .Useflags 0).Package}}
- <h3>{{$package}}</h3>
-
- <div class="card border-0">
- <div class="list-group">
- {{ range .Useflags }}
- {{ if eq .Package $package}}
- <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}">
- <h3 class="kk-search-result-header">{{.Name}}</h3>
- {{.Description}}
- </a>
- {{$package = .Package}}
- {{else}}
- {{$package = .Package}}
- </div>
- </div>
- <h3 class="mt-4">{{$package}}</h3>
-
- <div class="card border-0">
- <div class="list-group">
- <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}">
- <h3 class="kk-search-result-header">{{.Name}}</h3>
- {{.Description}}
- </a>
- {{end}}
- {{end}}
- </div>
- </div>
- {{end}}
-
-
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/search.tmpl b/web/templates/useflags/search.tmpl
deleted file mode 100644
index 210d7e1..0000000
--- a/web/templates/useflags/search.tmpl
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "browseuseflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12 {{if not .Useflags}}mt-5 pt-5{{end}}">
-
- <div class="col-12 mt-3 text-center">
- <h2>Find USE flags</h2>
- </div>
-
- <div class="col-12">
- <form action="/useflags/search" method="get" class="useflag-search mt-3 mb-5 mx-5 px-5">
- <div class="typeahead-container mx-5 px-5">
- <div class="typeahead-field">
- <span class="typeahead-query" style="font-size: 1.1em; height: 2.3em;">
- <input id="q" name="q" class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" type="search" autocomplete="off" placeholder="Find USE flags">
- </span>
- <span class="typeahead-button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;">
- <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit">
- <span class="typeahead-search-icon"></span>
- </button>
- </span>
- </div>
- </div>
- </form>
- </div>
-
- {{if .Search}}
- {{if .Useflags}}
- <h2>USE Flag Search Results <small>for {{ .Search }}</small></h2>
-
- <div class="card border-0">
- <div class="list-group">
- {{ range .Useflags }}
- <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}">
- <h3 class="kk-search-result-header">{{.Name}}</h3>
- {{.Description}}
- </a>
- {{end}}
- </div>
- </div>
- {{else}}
- <h2>No results found <small> for {{ .Search }}</small></h2>
- {{end}}
- {{end}}
- </div>
- </div>
-</div>
-
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/show.tmpl b/web/templates/useflags/show.tmpl
deleted file mode 100644
index 48d6048..0000000
--- a/web/templates/useflags/show.tmpl
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-{{template "useflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
-
- {{ if .LocalUseflags }}
- <h3 class="mb-2">Packages describing “{{.Useflag.Name}}” as local USE flag</h3>
- <div class="card mb-4 border-top-0">
- <div class="table-responsive">
- <table class="table mb-0">
- <thead>
- <th>Package</th>
- <th>“{{.Useflag.Name}}” Flag Description</th>
- </thead>
- <tbody>
- <!-- TODO sort by package -->
- {{ range .LocalUseflags}}
- <tr>
- <th class="kk-nobreak-cell"><a href="/packages/{{.Package}}">{{.Package}}</a></th>
- <!-- TODO sanitization needed here? -->
- <td>{{.Description}}</td>
- </tr>
- {{end}}
- </tbody>
- </table>
- </div>
- </div>
- {{end}}
-
- {{ if .Packages }}
- <h3 class="mb-2 pt-2">All packages providing a “{{.Useflag.Name}}” USE flag ({{len .Packages}})</h3>
- <div class="card">
- <div class="card-body">
- <ul class="kk-col-list kk-3col-list kk-useflag-listing mb-0">
- {{range .Packages}}
- <li><a href="/packages/{{.}}">{{.}}</a></li>
- {{end}}
- </ul>
- </div>
- </div>
- {{end}}
-
- </div>
- </div>
-</div>
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/showexpand.tmpl b/web/templates/useflags/showexpand.tmpl
deleted file mode 100644
index 9ed145a..0000000
--- a/web/templates/useflags/showexpand.tmpl
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-
-
-{{template "useflagsheader" .}}
-
-
-<div class="tab-content" id="myTabContent">
-
-<div class="container mb-5">
- <div class="row">
- <div class="col-12">
-
- {{ if .OtherUseExpands }}
- <h3 class="mb-2">Other “{{.Useflag.UseExpand}}” USE_EXPAND flag values</h3>
- <div class="card">
- <div class="table-responsive">
- <table class="table">
- <thead>
- <th>Use Flag</th>
- <th>Description</th>
- </thead>
- <tbody>
- {{range .OtherUseExpands}}
- <tr>
- <th class="kk-nobreak-cell"><a href="/useflags/{{.Name}}">{{.Name}}</a></th>
- <td>{{.Description}}</td>
- </tr>
- {{end}}
- </tbody>
- </table>
- </div>
- </div>
- {{end}}
-
- {{ if .Packages }}
- <h3 class="mb-2 mt-4">All packages providing a “{{.Useflag.Name}}” USE flag ({{len .Packages}})</h3>
- <div class="card">
- <div class="card-body">
- <ul class="kk-col-list kk-3col-list kk-useflag-listing">
- {{range .Packages}}
- <li><a href="/packages/{{.}}">{{.}}</a></li>
- {{end}}
- </ul>
- </div>
- </div>
- {{end}}
-
- </div>
- </div>
-</div>
-
-</div>
-
-
-{{template "footer" .Application }}
-
-
-
-</body>
-</html>
diff --git a/web/templates/useflags/useflagsheader.tmpl b/web/templates/useflags/useflagsheader.tmpl
deleted file mode 100644
index 05291df..0000000
--- a/web/templates/useflags/useflagsheader.tmpl
+++ /dev/null
@@ -1,34 +0,0 @@
-{{define "useflagsheader"}}
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3 pt-2">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
-
- <small class="kk-package-cat"><a href="/useflags" class="text-dark ml-1 {{if .Useflag.UseExpand}}{{else}}text-capitalize{{end}}">{{if .Useflag.UseExpand}}{{.Useflag.UseExpand}}{{else}}{{.Useflag.Scope}} USE flag{{end}}</a></small>
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-sliders"></span><span class="ml-2">{{if .Useflag.UseExpand}}{{ replaceall .Useflag.Name (print .Useflag.UseExpand "_") ""}}{{else}}{{.Useflag.Name}}{{end}}</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
- <p class="lead kk-package-maindesc">
- {{.Useflag.Description}}
- </p>
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link active" href="/categories/browse"><i class="fa fa-list mr-1" aria-hidden="true"></i> Packages</a>
-
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/web/templates/user/preferences.tmpl b/web/templates/user/preferences.tmpl
deleted file mode 100644
index d7fe321..0000000
--- a/web/templates/user/preferences.tmpl
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-{{template "head" .Header}}
-<body>
-{{template "header" .Header}}
-
-{{template "userheader" . }}
-
-
-<div class="tab-content" id="myTabContent">
-
- <div class="container mb-5">
- {{if eq .PageName "general"}}
- {{template "general" .}}
- {{else if eq .PageName "packages"}}
- {{template "packages" .}}
- {{else if eq .PageName "maintainers"}}
- {{template "maintainers" .}}
- {{else if eq .PageName "useflags"}}
- {{template "useflags" .}}
- {{else if eq .PageName "arches"}}
- {{template "arches" .}}
- {{end}}
- </div>
-
-</div>
-
-
-{{template "footer" .Application }}
-
-<script src="/assets/userpref.js"></script>
-<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
-<script>
- if(document.getElementById("example1") != null && document.getElementById("example2") != null) {
- new Sortable(example1, {
- group: 'shared',
- animation: 150,
- ghostClass: 'bg-info'
- });
- new Sortable(example2, {
- group: 'shared',
- animation: 150,
- ghostClass: 'bg-info'
- });
- }
-</script>
-
-</body>
-</html>
diff --git a/web/templates/user/preferences/arches.tmpl b/web/templates/user/preferences/arches.tmpl
deleted file mode 100644
index df1c653..0000000
--- a/web/templates/user/preferences/arches.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-{{define "arches"}}
- <div class="row">
-
- <div class="col-2 mt-1">
- <div class="nav flex-column" role="tablist" aria-orientation="vertical" style="position: fixed;">
- <a class="nav-link user-pref-nav-link active" id="keywords-tab" href="#keywords" aria-controls="overview-settings">Keywords</a>
- <a class="nav-link user-pref-nav-link" id="defaults-tab" href="#defaults">Defaults</a>
- </div>
- </div>
-
- <div class="col-10 mt-1">
-
- <form method="post" action="/user/preferences/arches/visible">
- <h3 class="" id="keywords">Keywords</h3><hr class="mt-1"/>
- <div class="row pl-3">
- <ul id="example1" class="list-group col-6">
- {{range $index, $keyword := .UserPreferences.Arches.Visible}}
- <li class="list-group-item">
- <div class="form-check form-check-inline w-100">
- <input type="checkbox" id="visible-arches-{{$keyword}}" name="visible-arches" value="{{$keyword}}" {{if Contains $.UserPreferences.Arches.Visible $keyword}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-arches-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i>
- </div>
- </li>
- {{end}}
- {{$counter := 0}}
- {{range $index, $keyword := .UserPreferences.GetAllKeywords}}
- {{if not (Contains $.UserPreferences.Arches.Visible $keyword)}}
- {{$counter = add $counter 1}}
- <li class="list-group-item">
- <div class="form-check form-check-inline w-100">
- <input type="checkbox" id="visible-arches-{{$keyword}}" name="visible-arches" value="{{$keyword}}" {{if Contains $.UserPreferences.Arches.Visible $keyword}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-arches-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i>
- </div>
- </li>
- {{end}}
-
- {{if eq (add (len $.UserPreferences.Arches.Visible) $counter) 16}}
- </ul>
- <ul id="example2" class="list-group col-6">
- {{end}}
- {{end}}
- </ul>
- </div>
-
- <h3 class="mt-5" id="defaults">Defaults</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- <div class="row">
- <div class="col-6">
- Default arch <select class="form-control" style="max-width: 200px;display: inline;" name="arches-default-arch" id="arches-default-arch">
- {{range $index, $keyword := .UserPreferences.GetAllKeywords}}
- <option value="{{$keyword}}" {{if eq $.UserPreferences.Arches.DefaultArch $keyword}}selected{{end}}>{{$keyword}}</option>
- {{end}}
- </select>
- </div>
- <div class="col-6">
- Default page <select class="form-control" style="max-width: 150px;display: inline;" name="arches-default-page" id="arches-default-page">
- <option value="keyworded" {{if eq .UserPreferences.Arches.DefaultPage "keyworded"}}selected{{end}}>keyworded</option>
- <option value="stable" {{if eq .UserPreferences.Arches.DefaultPage "stable"}}selected{{end}}>newly stable</option>
- </select>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row">
- <div class="col-12 mt-4">
- <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
- <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/arches/reset">Reset to Defaults</a>
- </div>
- </div>
-
- </form>
-
- </div>
- </div>
-{{end}}
diff --git a/web/templates/user/preferences/general.tmpl b/web/templates/user/preferences/general.tmpl
deleted file mode 100644
index bfc6883..0000000
--- a/web/templates/user/preferences/general.tmpl
+++ /dev/null
@@ -1,46 +0,0 @@
-{{define "general"}}
- <form method="post" action="/user/preferences/general/layout">
- <div class="row">
-
- <div class="col-5 offset-1 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img1" alt="Recently Added Packages (default)" src="/assets/pgo3.png" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="classicLandingpageLayout" name="landingpage-layout" value="classic" {{if eq .UserPreferences.General.LandingPageLayout "classic"}}checked{{end}}>
- <label class="form-check-label ml-1" for="classicLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Added Packages (default)">Recently Added Packages <i>(default)</i></label>
- </div>
- </div>
- </div>
-
- <div class="col-5 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img2" alt="Recently Visited Packages" src="/assets/pgo4.png" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="fullLandingpageLayout" name="landingpage-layout" value="full" {{if eq .UserPreferences.General.LandingPageLayout "full"}}checked{{end}}>
- <label class="form-check-label ml-1" for="fullLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Visited Packages">Recently Visited Packages</label>
- </div>
- </div>
- </div>
-
- <div class="col-10 offset-1 mt-4">
- <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
- <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/general/reset">Reset to Defaults</a>
- </div>
-
- </div>
- </form>
-
- <div id="myModal" class="modal">
- <span class="close">&times;</span>
- <img class="modal-content" id="img01">
- <div id="caption"></div>
- </div>
-{{end}}
diff --git a/web/templates/user/preferences/maintainers.tmpl b/web/templates/user/preferences/maintainers.tmpl
deleted file mode 100644
index 561aad7..0000000
--- a/web/templates/user/preferences/maintainers.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-{{define "maintainers"}}
- <form method="post" action="/user/preferences/maintainers/edit">
- <div class="row">
- <div class="col-12">
- <h3 class="mt-0" id="qa-report">Include Project Packages</h3>
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" id="include-packages" name="include-packages" value="true" {{if $.UserPreferences.Maintainers.IncludeProjectPackages }}checked{{end}} />
- <label class="form-check-label ml-1" for="include-packages" style="overflow:hidden;text-overflow: ellipsis;" title="">Include packages of projects the maintainer is part of</label>
- </div>
- <i>If this option is enabled, all packages, QA reports, pull requests and bugs of projects a maintainer is part of will be displayed as well on the maintainer page. That is, if <i>Larry</i> is part of the <i>Python</i> project, all packages, QA reports, pull requests and bugs of the Python project will be displayed as well on the maintainer page of <i>Larry</i>.<br/>Below you can furthermore specify projects that will be excluded on the maintainer page. E.g. if Larry is furthermore part of the proxy-maintainers project, and the project is marked below, packages of the proxy maintainers project won't be shown on Larry's maintainer page.</i>
- </div>
-
-
- <div class="col-12">
- <h3 class="mt-4 pt-3" id="qa-report">Excluded Projects</h3>
- </div>
- <div class="col-3">
- {{range $index, $project := .Projects}}
- <ul class="list-group mb-2">
- <li class="list-group-item">
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;height:21px;">
- <input type="checkbox" id="excluded-projects-{{$project.Email}}" name="excluded-projects" value="{{$project.Email}}" {{if (Contains $.UserPreferences.Maintainers.ExcludedProjects $project.Email) }}checked{{end}}/>
- <label class="form-check-label ml-1" for="excluded-projects-{{$project.Email}}" style="overflow:hidden;text-overflow: ellipsis;height:21px;" title="{{$project.Name}}">{{$project.Name}}</label>
- </div>
- </li>
- </ul>
- {{if eq $index 40}}
- </div><div class="col-3">
- {{else if eq $index 81}}
- </div><div class="col-3">
- {{else if eq $index 122}}
- </div><div class="col-3">
- {{end}}
- {{end}}
- </div>
-
- <div class="col-12 mt-4">
- <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
- <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/maintainers/reset">Reset to Defaults</a>
- </div>
-
- </div>
- </form>
-{{end}}
diff --git a/web/templates/user/preferences/packages.tmpl b/web/templates/user/preferences/packages.tmpl
deleted file mode 100644
index ae4e9b2..0000000
--- a/web/templates/user/preferences/packages.tmpl
+++ /dev/null
@@ -1,319 +0,0 @@
-{{define "packages"}}
- <div class="row">
-
- <div class="col-2 mt-1">
- <div class="nav flex-column" role="tablist" aria-orientation="vertical" style="position: fixed;">
- <a class="nav-link user-pref-nav-link active" id="overview-tab" href="#overview" aria-controls="overview-settings">Overview</a>
- <a class="nav-link user-pref-nav-link" id="dependencies-tab" href="#dependencies">Dependencies</a>
- <a class="nav-link user-pref-nav-link" id="pull-requests-tab" href="#pull-requests" aria-controls="pull-requests-settings">Pull requests</a>
- <a class="nav-link user-pref-nav-link" id="bugs-tab" href="#bugs" aria-controls="bugs-settings">Bugs</a>
- <a class="nav-link user-pref-nav-link" id="security-tab" href="#security" aria-controls="security-settings">Security</a>
- <a class="nav-link user-pref-nav-link" id="changelog-tab" href="#changelog" aria-controls="changelog-settings">Changelog</a>
- <a class="nav-link user-pref-nav-link" id="qa-report-tab" href="#qa-report" aria-controls="qa-report-settings">QA report</a>
- <a class="nav-link user-pref-nav-link" id="tabs-tab" href="#tabs" aria-controls="tabs-settings">Tabs</a>
- </div>
- </div>
-
- <div class="col-9 mt-1">
-
- <form method="post" action="/user/preferences/packages/edit">
-
- <h3 id="overview">Overview</h3><hr class="mt-1"/>
- <h4 class="mb-1">Layout</h4>
-
- <div class="row">
- <div class="col-6 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img1" alt="Versions + Metadata (default)" src="/assets/pgo2.png" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="minimalOverviewLayout" name="overview-layout" value="minimal" {{if eq .UserPreferences.Packages.Overview.Layout "minimal"}}checked{{end}}>
- <label class="form-check-label ml-1" for="minimalOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata (default)">Versions + Metadata <i>(default)</i></label>
- </div>
- </div>
- </div>
-
- <div class="col-6 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img2" alt="Versions + Metadata + Changelog" src="/assets/pgo1.png" onclick="document.getElementById('fullOverviewLayout').checked = true;" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="fullOverviewLayout" name="overview-layout" value="full" {{if eq .UserPreferences.Packages.Overview.Layout "full"}}checked{{end}}>
- <label class="form-check-label ml-1" for="fullOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata + Changelog">Versions + Metadata + Changelog</label>
- </div>
- </div>
- </div>
- </div>
-
- <h4 class="mt-4 mb-1">Keywords</h4>
- <div class="row pl-3">
- <ul id="example1" class="list-group col-6">
- {{range $index, $keyword := .UserPreferences.Packages.Overview.Keywords}}
- <li class="list-group-item">
- <div class="form-check form-check-inline w-100">
- <input type="checkbox" id="overview-keywords-{{$keyword}}" name="overview-keywords" value="{{$keyword}}" {{if Contains $.UserPreferences.Packages.Overview.Keywords $keyword}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-keywords-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i>
- </div>
- </li>
- {{end}}
- {{$counter := 0}}
- {{range $index, $keyword := .UserPreferences.GetAllKeywords}}
- {{if not (Contains $.UserPreferences.Packages.Overview.Keywords $keyword)}}
- {{$counter = add $counter 1}}
- <li class="list-group-item">
- <div class="form-check form-check-inline w-100">
- <input type="checkbox" id="overview-keywords-{{$keyword}}" name="overview-keywords" value="{{$keyword}}" {{if Contains $.UserPreferences.Packages.Overview.Keywords $keyword}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-keywords-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i>
- </div>
- </li>
- {{end}}
-
- {{if eq (add (len $.UserPreferences.Packages.Overview.Keywords) $counter) 16}}
- </ul>
- <ul id="example2" class="list-group col-6">
- {{end}}
- {{end}}
- </ul>
- </div>
-
- <h4 class="mt-4 mb-1">EAPI version</h4>
- <div class="card">
- <div class="card-body">
- Show <select class="form-control form-control-sm ml-2" style="max-width: 100px;display: inline;" name="overview-eapi" id="overview-eapi">
- <option value="none" {{if eq .UserPreferences.Packages.Overview.EAPI "none"}}selected{{end}}>none</option>
- <option value="column" {{if eq .UserPreferences.Packages.Overview.EAPI "column"}}selected{{end}}>in column</option>
- <option value="inline" {{if eq .UserPreferences.Packages.Overview.EAPI "inline"}}selected{{end}}>inline</option>
- </select>
- </div>
- </div>
-
- <h4 class="mt-4 mb-1">Outdated Versions</h4>
- <div class="card">
- <div class="card-body">
-
- <div class="form-check form-check-inline">
- <input type="checkbox" class="" id="overview-showOutdated" name="overview-showOutdated" value="true" {{if .UserPreferences.Packages.Overview.ShowOutdated}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-showOutdated">Show Outdated warnings?</label>
- </div>
- </div>
- </div>
-
- <h4 class="mt-4 mb-1">Metadata</h4>
- <div class="card">
- <div class="card-body">
- <div class="row">
-
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-homepage" value="homepage" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "homepage"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-homepage">Homepage</label>
- </div>
- </div>
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-upstream" value="upstream" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "upstream"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-upstream">Upstream</label>
- </div>
- </div>
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-longdescription" value="longdescription" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "longdescription"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-longdescription">Longdescription</label>
- </div>
- </div>
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-useflags" value="useflags" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "useflags"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-useflags">USE flags</label>
- </div>
- </div>
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-license" value="license" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "license"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-license">License</label>
- </div>
- </div>
- <div class="col-4">
- <div class="form-check form-check-inline">
- <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-maintainers" value="maintainers" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "maintainers"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="overview-metadata-fields-maintainers">Maintainers</label>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <h4 class="mt-4 mb-1">Changelog</h4>
- <div class="card">
- <div class="card-body">
- <div class="row">
- <div class="col-6">
- Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="overview-changelog-type" id="overview-changelog-type" disabled>
- <option value="compact">default</option>
- </select>
- </div>
- <div class="col-6">
- Size <input type="number" name="overview-changelog-size" class="form-control form-control-sm ml-1" style="width:150px;display: inline;" value="{{.UserPreferences.Packages.Overview.ChangelogLength }}" />
- </div>
- </div>
- </div>
- </div>
-
-
- <h3 class="mt-5" id="dependencies">Dependencies</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- Default Page <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="dependencies-default-page" id="dependencies-default-page">
- <option value="dependencies" {{if eq .UserPreferences.Packages.Dependencies.Default "dependencies"}}selected{{end}}>dependencies</option>
- <option value="reverse-dependencies" {{if eq .UserPreferences.Packages.Dependencies.Default "reverse-dependencies"}}selected{{end}}>reverse-dependencies</option>
- </select>
- </div>
- </div>
-
-
- <h3 class="mt-5" id="pull-requests">Pull requests</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- Layout <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="pullrequests-layout" id="pullrequests-layout" disabled>
- <option value="default" {{if eq .UserPreferences.Packages.PullRequests.Layout "default"}}selected{{end}}>default</option>
- </select>
- </div>
- </div>
-
-
- <h3 class="mt-5" id="bugs">Bugs</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- Layout <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="bugs-layout" id="bugs-layout" disabled>
- <option value="default" {{if eq .UserPreferences.Packages.PullRequests.Layout "default"}}selected{{end}}>default</option>
- </select>
- </div>
- </div>
-
-
- <h3 class="mt-5" id="security">Security</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- <div class="row">
- <div class="col-6">
- Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="security-layout" id="security-layout" disabled>
- <option value="default">default</option>
- </select>
- </div>
- <div class="col-6">
- <div class="form-check form-check-inline pt-2">
- <input type="checkbox" name="security-show-glsas" id="security-show-glsas" class="disabled" value="true" {{if .UserPreferences.Packages.Security.ShowGLSAs}}checked{{end}} disabled/>
- <label class="form-check-label ml-1" style="color:grey;">Show GLSAs</label>
- </div>
- </div>
- </div>
- </div>
- </div>
-
-
- <h3 class="mt-5" id="changelog">Changelog</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- <div class="row">
- <div class="col-6">
- Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="changelog-type" id="changelog-type" disabled>
- <option value="compact">default</option>
- </select>
- </div>
- <div class="col-6">
- Size <input type="number" name="changelog-size" class="form-control form-control-sm" style="display: inline;width: 150px;" value="{{.UserPreferences.Packages.Changelog.Size }}" />
- </div>
- </div>
- </div>
- </div>
-
- <h3 class="mt-5" id="qa-report">QA Report</h3><hr class="mt-1"/>
- <div class="row">
- <div class="col-4">
- {{range (CreateSlice 190)}}
- <ul class="list-group mb-2">
- <li class="list-group-item">
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" id="qareport-classes-{{.}}" name="qareport-classes" value="{{.}}" {{if not (ContainsInt $.UserPreferences.Packages.QAReport.ExcludedWarningClasses .) }}checked{{end}} />
- <label class="form-check-label ml-1" for="qareport-classes-{{.}}" style="overflow:hidden;text-overflow: ellipsis;" title="{{GetPkgcheckClass .}}">{{GetPkgcheckClass .}}</label>
- </div>
- </li>
- </ul>
- {{if eq . 63}}
- </div><div class="col-4">
- {{else if eq . 127}}
- </div><div class="col-4">
- {{end}}
- {{end}}
- </div>
- </div>
-
-
- <h3 class="mt-5" id="tabs">Visible Tabs</h3><hr class="mt-1"/>
- <div class="card">
- <div class="card-body">
- <div style="columns:3;">
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-overview" value="Overview" {{if Contains .UserPreferences.Packages.Tabs.Visible "Overview"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-overview" style="overflow:hidden;text-overflow: ellipsis;" title="Overview">Overview</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-dependencies" value="Dependencies" {{if Contains .UserPreferences.Packages.Tabs.Visible "Dependencies"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-dependencies" style="overflow:hidden;text-overflow: ellipsis;" title="Dependencies">Dependencies</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-qa-report" value="QA report" {{if Contains .UserPreferences.Packages.Tabs.Visible "QA report"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-qa-report" style="overflow:hidden;text-overflow: ellipsis;" title="QA report">QA report</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-pull-requests" value="Pull requests" {{if Contains .UserPreferences.Packages.Tabs.Visible "Pull requests"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-pull-requests" style="overflow:hidden;text-overflow: ellipsis;" title="Pull Requests">Pull Requests</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-bugs" value="Bugs" {{if Contains .UserPreferences.Packages.Tabs.Visible "Bugs"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-bugs" style="overflow:hidden;text-overflow: ellipsis;" title="Bugs">Bugs</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-security" value="Security" {{if Contains .UserPreferences.Packages.Tabs.Visible "Security"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-security" style="overflow:hidden;text-overflow: ellipsis;" title="Security">Security</label>
- </div>
-
- <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;">
- <input type="checkbox" name="visible-tabs" id="visible-tabs-changelog" value="Changelog" {{if Contains .UserPreferences.Packages.Tabs.Visible "Changelog"}}checked{{end}}/>
- <label class="form-check-label ml-1" for="visible-tabs-changelog" style="overflow:hidden;text-overflow: ellipsis;" title="Changelog">Changelog</label>
- </div>
-
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-12 mt-4">
- <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
- <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/packages/reset">Reset to Defaults</a>
- </div>
- </div>
-
- </form>
- </div>
-
- </div>
-
- <div id="myModal" class="modal">
- <span class="close">&times;</span>
- <img class="modal-content" id="img01">
- <div id="caption"></div>
- </div>
-
-{{end}}
diff --git a/web/templates/user/preferences/useflags.tmpl b/web/templates/user/preferences/useflags.tmpl
deleted file mode 100644
index a59241e..0000000
--- a/web/templates/user/preferences/useflags.tmpl
+++ /dev/null
@@ -1,46 +0,0 @@
-{{define "useflags"}}
- <form method="post" action="/user/preferences/useflags/edit">
- <div class="row">
-
- <div class="col-5 offset-1 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img1" alt="Popular USE flags (default)" src="/assets/pgo6.png" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="BubbleUseflagDefaultPage" name="useflag-default-page" value="bubble" {{if eq .UserPreferences.Useflags.Layout "bubble"}}checked{{end}}>
- <label class="form-check-label ml-1" for="BubbleUseflagDefaultPage" style="overflow:hidden;text-overflow: ellipsis;" title="Popular USE flags (default)">Popular USE flags <i>(default)</i></label>
- </div>
- </div>
- </div>
-
- <div class="col-5 mt-1">
- <div class="card" style="background: transparent;">
- <div class="card-body">
- <img id="img2" alt="USE flags search" src="/assets/pgo5.png" style="width: 100%;cursor: pointer;" />
- </div>
- </div>
- <div class="text-center mt-2">
- <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;">
- <input type="radio" id="SearchUseflagDefaultPage" name="useflag-default-page" value="search" {{if eq .UserPreferences.Useflags.Layout "search"}}checked{{end}}>
- <label class="form-check-label ml-1" for="SearchUseflagDefaultPage" style="overflow:hidden;text-overflow: ellipsis;" title="USE flags search">USE flags search</label>
- </div>
- </div>
- </div>
-
- <div class="col-10 offset-1 mt-4">
- <button type="submit" class="float-right btn btn-sm btn-primary">Save</button>
- <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/useflags/reset">Reset to Defaults</a>
- </div>
-
- </div>
- </form>
-
- <div id="myModal" class="modal">
- <span class="close">&times;</span>
- <img class="modal-content" id="img01">
- <div id="caption"></div>
- </div>
-{{end}}
diff --git a/web/templates/user/userheader.tmpl b/web/templates/user/userheader.tmpl
deleted file mode 100644
index 05fb535..0000000
--- a/web/templates/user/userheader.tmpl
+++ /dev/null
@@ -1,34 +0,0 @@
-{{define "userheader"}}
-
- <div class="kk-header-container">
- <div class="container">
- <div class="row">
- <div class="col-12">
-
- <div class="row mt-3 pt-2">
- <div class="col-md-5">
- <h1 class="stick-top kk-package-title" id="package-title">
- <div>
- <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cog"></span><span class="ml-2">Preferences</span></div>
- </div>
- </h1>
- </div>
- <div class="col-md-7">
- <!-- You can customize the page contents to your needs here -->
- </div>
-
- <div class="col-md-12 pt-4 mt-1">
- <nav class="nav kk-package-nav">
- <a class="nav-link {{if eq .PageName "general"}}active{{end}}" href="/user/preferences/general"><i class="fa fa-globe mr-1" aria-hidden="true"></i>General</a>
- <a class="nav-link {{if eq .PageName "packages"}}active{{end}}" href="/user/preferences/packages"><i class="fa fa-cube mr-1" aria-hidden="true"></i>Packages</a>
- <a class="nav-link {{if eq .PageName "maintainers"}}active{{end}}" href="/user/preferences/maintainers"><i class="fa fa-users mr-1" aria-hidden="true"></i>Maintainers</a>
- <a class="nav-link {{if eq .PageName "useflags"}}active{{end}}" href="/user/preferences/useflags"><i class="fa fa-sliders mr-1" aria-hidden="true"></i>USE flags</a>
- <a class="nav-link {{if eq .PageName "arches"}}active{{end}}" href="/user/preferences/arches"><i class="fa fa-server mr-1" aria-hidden="true"></i>Architectures</a>
- </nav>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-{{end}}
diff --git a/webpack.config.js b/webpack.config.js
index 84deb53..a6dd3e3 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,3 +1,4 @@
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const path = require('path');
@@ -5,33 +6,25 @@ module.exports = {
entry: {
stylesheets: './web/packs/stylesheets.js',
application: './web/packs/application.js',
- graphiql: './web/packs/graphiql.js',
- index: './web/packs/index.js',
- packages: './web/packs/packages.js',
- useflags: './web/packs/useflags.js',
- userpref: './web/packs/userpref.js',
+ graphiql: './web/packs/graphiql.js',
+ index: './web/packs/index.js',
+ useflags: './web/packs/useflags.js',
+ userpref: './web/packs/userpref.js',
},
+ mode: 'production',
output: {
path: path.resolve(__dirname, 'assets'),
filename: '[name].js',
+ assetModuleFilename: '[name].[ext]'
},
- plugins: [
- require('postcss-import')
- ],
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
- // Creates `style` nodes from JS strings
- 'style-loader',
- // Translates CSS into CommonJS
- {
- loader: 'css-loader',
- },{
- loader: 'resolve-url-loader',
- },
- // Compiles Sass to CSS
+ MiniCssExtractPlugin.loader,
+ 'css-loader',
+ 'resolve-url-loader',
{
loader: 'sass-loader',
options: {
@@ -42,15 +35,7 @@ module.exports = {
},
{
test: /\.(woff(2)?|ttf|eot|svg|png)(\?v=\d+\.\d+\.\d+)?$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- name: '[name].[ext]',
- publicPath: '/assets'
- }
- }
- ]
+ type: 'asset/resource',
}
],
},
@@ -67,5 +52,8 @@ module.exports = {
'window.Tether': 'tether',
Modal: 'exports-loader?Modal!bootstrap/js/dist/modal',
}),
+ new MiniCssExtractPlugin({
+ filename: '[name].css',
+ }),
],
};