diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..3f96633e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: "Goreleaser" + +on: + push: + tags: + - "v*" +permissions: + contents: write + +jobs: + build-and-push: + runs-on: [self-hosted, linux] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Node + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Node Build + run: make install-ui-packages ui + + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version: 1.19 + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/upload-artifact@v3 + with: + name: answer + path: ./dist/* diff --git a/.github/workflows/build_dockerhub_img.yml b/.github/workflows/build_dockerhub_img.yml index a176b322..07c5a0a9 100644 --- a/.github/workflows/build_dockerhub_img.yml +++ b/.github/workflows/build_dockerhub_img.yml @@ -12,7 +12,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: [self-hosted, linux] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.github/workflows/build_github_img.yml b/.github/workflows/build_github_img.yml index 358a296b..67fe28ea 100644 --- a/.github/workflows/build_github_img.yml +++ b/.github/workflows/build_github_img.yml @@ -17,7 +17,7 @@ env: jobs: build-and-push: - runs-on: ubuntu-latest + runs-on: [self-hosted, linux] permissions: packages: write diff --git a/.github/workflows/go_build_test.yml b/.github/workflows/go_build_test.yml index ecd2f4f0..21045786 100644 --- a/.github/workflows/go_build_test.yml +++ b/.github/workflows/go_build_test.yml @@ -9,7 +9,7 @@ on: jobs: build-and-push: - runs-on: ubuntu-latest + runs-on: [self-hosted, linux] steps: - name: Checkout diff --git a/.github/workflows/node_build_test.yml b/.github/workflows/node_build_test.yml index edf5b8cb..41c2c4c6 100644 --- a/.github/workflows/node_build_test.yml +++ b/.github/workflows/node_build_test.yml @@ -8,8 +8,7 @@ on: jobs: build-and-push: - runs-on: ubuntu-latest - + runs-on: [self-hosted, linux] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index 5776cd0c..c762475f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,11 @@ /configs/config-dev.yaml /go.work* /logs -/ui/build /ui/node_modules +/ui/build/*/*/* +/ui/build/*.json +/ui/build/*.html +/ui/build/*.txt /vendor Thumbs*.db tmp diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 18cbbd55..9feb6d72 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -2,7 +2,7 @@ env: - GO11MODULE=on - GO111MODULE=on - GOPROXY=https://goproxy.io - - CGO_ENABLED=1 + - CGO_ENABLED=0 before: hooks: @@ -16,74 +16,48 @@ builds: - linux goarch: - amd64 - # linux windows need cgomingw64-gcc - id: build-windows main: ./cmd/answer/. binary: answer ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser - env: - - CC=x86_64-w64-mingw32-gcc - - CXX=x86_64-w64-mingw32-g++ goos: - windows goarch: - amd64 - # linux arm64 need cgo arm64 - id: build-arm64 main: ./cmd/answer/. binary: answer ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser - env: - - CC=aarch64-linux-gnu-gcc - - CXX=aarch64-linux-gnu-g++ goos: - linux goarch: - - arm64 - - id: build-arm7 - main: ./cmd/answer/. - binary: answer - ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser - env: - - CC=arm-linux-gnueabihf-gcc - - CXX=arm-linux-gnueabihf-g++ - - AR=arm-linux-gnueabihf-ar - goos: - - linux - goarch: - - arm - goarm: - - 7 + - arm64 - id: build-darwin-arm64 main: ./cmd/answer/. binary: answer - env: - - CC=oa64-clang - - CXX=oa64-clang++ goos: - darwin goarch: - arm64 - ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser + ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser flags: -v - id: build-darwin-amd64 main: ./cmd/answer/. binary: answer - env: - - CC=o64-clang - - CXX=o64-clang++ goos: - darwin goarch: - amd64 - ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser + ldflags: -s -w -X main.Version={{.Version}} -X main.Revision={{.ShortCommit}} -X main.Time={{.Date}} -X main.BuildUser=goreleaser flags: -v archives: - replacements: - darwin: Darwin + darwin: macOS amd64: x86_64 + linux: Linux + windows: Windows checksum: name_template: 'checksums.txt' snapshot: @@ -95,10 +69,4 @@ changelog: - '^docs:' - '^test:' - -# sudo apt-get install build-essential -# sudo apt-get install gcc-multilib g++-multilib -# sudo apt-get install gcc-mingw-w64 -# sudo apt-get -y install gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf -# sudo apt-get install clang llvm -# goreleaser release --snapshot --rm-dist \ No newline at end of file +# goreleaser release --snapshot --rm-dist diff --git a/Makefile b/Makefile index d5c46a40..dd7c76d5 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,32 @@ .PHONY: build clean ui -VERSION=1.0.3 +VERSION=1.0.4 BIN=answer DIR_SRC=./cmd/answer DOCKER_CMD=docker -#GO_ENV=CGO_ENABLED=0 +GO_ENV=CGO_ENABLED=0 GO111MODULE=on Revision=$(shell git rev-parse --short HEAD) GO_FLAGS=-ldflags="-X main.Version=$(VERSION) -X 'main.Revision=$(Revision)' -X 'main.Time=`date`' -extldflags -static" GO=$(GO_ENV) $(shell which go) -build: - @$(GO_ENV) $(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC) +build: generate + @$(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC) # https://dev.to/thewraven/universal-macos-binaries-with-go-1-16-3mm3 -universal: +universal: generate @GOOS=darwin GOARCH=amd64 $(GO_ENV) $(GO) build $(GO_FLAGS) -o ${BIN}_amd64 $(DIR_SRC) @GOOS=darwin GOARCH=arm64 $(GO_ENV) $(GO) build $(GO_FLAGS) -o ${BIN}_arm64 $(DIR_SRC) @lipo -create -output ${BIN} ${BIN}_amd64 ${BIN}_arm64 @rm -f ${BIN}_amd64 ${BIN}_arm64 generate: - go get github.com/google/wire/cmd/wire@latest - go install github.com/golang/mock/mockgen@v1.6.0 - go generate ./... - go mod tidy + @$(GO) get github.com/google/wire/cmd/wire@v0.5.0 + @$(GO) get github.com/golang/mock/mockgen@v1.6.0 + @$(GO) install github.com/google/wire/cmd/wire@v0.5.0 + @$(GO) install github.com/golang/mock/mockgen@v1.6.0 + @$(GO) generate ./... + @$(GO) mod tidy test: @$(GO) test ./internal/repo/repo_test @@ -39,6 +41,6 @@ install-ui-packages: @corepack prepare pnpm@v7.12.2 --activate ui: - @cd ui && pnpm install && pnpm build && cd - + @cd ui && pnpm install && pnpm build && sed -i 's/%AnswerVersion%/'$(VERSION)'/g' ./build/index.html && cd - all: clean build diff --git a/docs/docs.go b/docs/docs.go index cce01432..3adfd474 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -2911,6 +2911,45 @@ const docTemplate = `{ } } }, + "/answer/api/v1/post/render": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "render post content", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Upload" + ], + "summary": "render post content", + "parameters": [ + { + "description": "PostRenderReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.PostRenderReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/api/v1/question": { "put": { "security": [ @@ -5425,8 +5464,7 @@ const docTemplate = `{ "type": "object", "required": [ "object_id", - "original_text", - "parsed_text" + "original_text" ], "properties": { "mention_username_list": { @@ -5442,11 +5480,9 @@ const docTemplate = `{ }, "original_text": { "description": "original comment content", - "type": "string" - }, - "parsed_text": { - "description": "parsed comment content", - "type": "string" + "type": "string", + "maxLength": 600, + "minLength": 2 }, "reply_comment_id": { "description": "reply comment id", @@ -5535,46 +5571,41 @@ const docTemplate = `{ }, "schema.AnswerAddReq": { "type": "object", + "required": [ + "content" + ], "properties": { "content": { - "description": "content", - "type": "string" - }, - "html": { - "description": "html", - "type": "string" + "type": "string", + "maxLength": 65535, + "minLength": 6 }, "question_id": { - "description": "question_id", "type": "string" } } }, "schema.AnswerUpdateReq": { "type": "object", + "required": [ + "content" + ], "properties": { "content": { - "description": "content", - "type": "string" + "type": "string", + "maxLength": 65535, + "minLength": 6 }, "edit_summary": { - "description": "edit_summary", - "type": "string" - }, - "html": { - "description": "html", "type": "string" }, "id": { - "description": "id", "type": "string" }, "question_id": { - "description": "question_id", "type": "string" }, "title": { - "description": "title", "type": "string" } } @@ -6589,11 +6620,18 @@ const docTemplate = `{ } } }, + "schema.PostRenderReq": { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + }, "schema.QuestionAdd": { "type": "object", "required": [ "content", - "html", "tags", "title" ], @@ -6604,12 +6642,6 @@ const docTemplate = `{ "maxLength": 65535, "minLength": 6 }, - "html": { - "description": "html", - "type": "string", - "maxLength": 65535, - "minLength": 6 - }, "tags": { "description": "tags", "type": "array", @@ -6669,6 +6701,9 @@ const docTemplate = `{ "collection_count": { "type": "integer" }, + "created_at": { + "type": "integer" + }, "description": { "type": "string" }, @@ -6739,7 +6774,6 @@ const docTemplate = `{ "type": "object", "required": [ "content", - "html", "id", "tags", "title" @@ -6755,12 +6789,6 @@ const docTemplate = `{ "description": "edit summary", "type": "string" }, - "html": { - "description": "html", - "type": "string", - "maxLength": 65535, - "minLength": 6 - }, "id": { "description": "question id", "type": "string" @@ -7326,10 +7354,6 @@ const docTemplate = `{ "description": "original text", "type": "string" }, - "parsed_text": { - "description": "parsed text", - "type": "string" - }, "slug_name": { "description": "slug_name", "type": "string", @@ -7416,7 +7440,8 @@ const docTemplate = `{ "schema.UpdateCommentReq": { "type": "object", "required": [ - "comment_id" + "comment_id", + "original_text" ], "properties": { "comment_id": { @@ -7425,11 +7450,9 @@ const docTemplate = `{ }, "original_text": { "description": "original comment content", - "type": "string" - }, - "parsed_text": { - "description": "parsed comment content", - "type": "string" + "type": "string", + "maxLength": 600, + "minLength": 2 } } }, @@ -7460,11 +7483,6 @@ const docTemplate = `{ "type": "string", "maxLength": 4096 }, - "bio_html": { - "description": "bio", - "type": "string", - "maxLength": 4096 - }, "display_name": { "description": "display_name", "type": "string", @@ -7549,10 +7567,6 @@ const docTemplate = `{ "description": "original text", "type": "string" }, - "parsed_text": { - "description": "parsed text", - "type": "string" - }, "slug_name": { "description": "slug_name", "type": "string", diff --git a/docs/swagger.json b/docs/swagger.json index 3503fce7..0282b612 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2899,6 +2899,45 @@ } } }, + "/answer/api/v1/post/render": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "render post content", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Upload" + ], + "summary": "render post content", + "parameters": [ + { + "description": "PostRenderReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.PostRenderReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/api/v1/question": { "put": { "security": [ @@ -5413,8 +5452,7 @@ "type": "object", "required": [ "object_id", - "original_text", - "parsed_text" + "original_text" ], "properties": { "mention_username_list": { @@ -5430,11 +5468,9 @@ }, "original_text": { "description": "original comment content", - "type": "string" - }, - "parsed_text": { - "description": "parsed comment content", - "type": "string" + "type": "string", + "maxLength": 600, + "minLength": 2 }, "reply_comment_id": { "description": "reply comment id", @@ -5523,46 +5559,41 @@ }, "schema.AnswerAddReq": { "type": "object", + "required": [ + "content" + ], "properties": { "content": { - "description": "content", - "type": "string" - }, - "html": { - "description": "html", - "type": "string" + "type": "string", + "maxLength": 65535, + "minLength": 6 }, "question_id": { - "description": "question_id", "type": "string" } } }, "schema.AnswerUpdateReq": { "type": "object", + "required": [ + "content" + ], "properties": { "content": { - "description": "content", - "type": "string" + "type": "string", + "maxLength": 65535, + "minLength": 6 }, "edit_summary": { - "description": "edit_summary", - "type": "string" - }, - "html": { - "description": "html", "type": "string" }, "id": { - "description": "id", "type": "string" }, "question_id": { - "description": "question_id", "type": "string" }, "title": { - "description": "title", "type": "string" } } @@ -6577,11 +6608,18 @@ } } }, + "schema.PostRenderReq": { + "type": "object", + "properties": { + "content": { + "type": "string" + } + } + }, "schema.QuestionAdd": { "type": "object", "required": [ "content", - "html", "tags", "title" ], @@ -6592,12 +6630,6 @@ "maxLength": 65535, "minLength": 6 }, - "html": { - "description": "html", - "type": "string", - "maxLength": 65535, - "minLength": 6 - }, "tags": { "description": "tags", "type": "array", @@ -6657,6 +6689,9 @@ "collection_count": { "type": "integer" }, + "created_at": { + "type": "integer" + }, "description": { "type": "string" }, @@ -6727,7 +6762,6 @@ "type": "object", "required": [ "content", - "html", "id", "tags", "title" @@ -6743,12 +6777,6 @@ "description": "edit summary", "type": "string" }, - "html": { - "description": "html", - "type": "string", - "maxLength": 65535, - "minLength": 6 - }, "id": { "description": "question id", "type": "string" @@ -7314,10 +7342,6 @@ "description": "original text", "type": "string" }, - "parsed_text": { - "description": "parsed text", - "type": "string" - }, "slug_name": { "description": "slug_name", "type": "string", @@ -7404,7 +7428,8 @@ "schema.UpdateCommentReq": { "type": "object", "required": [ - "comment_id" + "comment_id", + "original_text" ], "properties": { "comment_id": { @@ -7413,11 +7438,9 @@ }, "original_text": { "description": "original comment content", - "type": "string" - }, - "parsed_text": { - "description": "parsed comment content", - "type": "string" + "type": "string", + "maxLength": 600, + "minLength": 2 } } }, @@ -7448,11 +7471,6 @@ "type": "string", "maxLength": 4096 }, - "bio_html": { - "description": "bio", - "type": "string", - "maxLength": 4096 - }, "display_name": { "description": "display_name", "type": "string", @@ -7537,10 +7555,6 @@ "description": "original text", "type": "string" }, - "parsed_text": { - "description": "parsed text", - "type": "string" - }, "slug_name": { "description": "slug_name", "type": "string", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b02e9494..3fac2ae0 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -147,9 +147,8 @@ definitions: type: string original_text: description: original comment content - type: string - parsed_text: - description: parsed comment content + maxLength: 600 + minLength: 2 type: string reply_comment_id: description: reply comment id @@ -157,7 +156,6 @@ definitions: required: - object_id - original_text - - parsed_text type: object schema.AddReportReq: properties: @@ -217,35 +215,30 @@ definitions: schema.AnswerAddReq: properties: content: - description: content - type: string - html: - description: html + maxLength: 65535 + minLength: 6 type: string question_id: - description: question_id type: string + required: + - content type: object schema.AnswerUpdateReq: properties: content: - description: content + maxLength: 65535 + minLength: 6 type: string edit_summary: - description: edit_summary - type: string - html: - description: html type: string id: - description: id type: string question_id: - description: question_id type: string title: - description: title type: string + required: + - content type: object schema.AvatarInfo: properties: @@ -976,6 +969,11 @@ definitions: type: type: string type: object + schema.PostRenderReq: + properties: + content: + type: string + type: object schema.QuestionAdd: properties: content: @@ -983,11 +981,6 @@ definitions: maxLength: 65535 minLength: 6 type: string - html: - description: html - maxLength: 65535 - minLength: 6 - type: string tags: description: tags items: @@ -1000,7 +993,6 @@ definitions: type: string required: - content - - html - tags - title type: object @@ -1036,6 +1028,8 @@ definitions: type: integer collection_count: type: integer + created_at: + type: integer description: type: string follow_count: @@ -1090,11 +1084,6 @@ definitions: edit_summary: description: edit summary type: string - html: - description: html - maxLength: 65535 - minLength: 6 - type: string id: description: question id type: string @@ -1110,7 +1099,6 @@ definitions: type: string required: - content - - html - id - tags - title @@ -1490,9 +1478,6 @@ definitions: original_text: description: original text type: string - parsed_text: - description: parsed text - type: string slug_name: description: slug_name maxLength: 35 @@ -1558,12 +1543,12 @@ definitions: type: string original_text: description: original comment content - type: string - parsed_text: - description: parsed comment content + maxLength: 600 + minLength: 2 type: string required: - comment_id + - original_text type: object schema.UpdateFollowTagsReq: properties: @@ -1582,10 +1567,6 @@ definitions: description: bio maxLength: 4096 type: string - bio_html: - description: bio - maxLength: 4096 - type: string display_name: description: display_name maxLength: 30 @@ -1648,9 +1629,6 @@ definitions: original_text: description: original text type: string - parsed_text: - description: parsed text - type: string slug_name: description: slug_name maxLength: 35 @@ -3684,6 +3662,30 @@ paths: summary: user's votes tags: - Activity + /answer/api/v1/post/render: + post: + consumes: + - application/json + description: render post content + parameters: + - description: PostRenderReq + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.PostRenderReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: render post content + tags: + - Upload /answer/api/v1/question: delete: consumes: diff --git a/go.mod b/go.mod index 33c4a499..1db48ddb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/Chain-Zhang/pinyin v0.1.3 github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267 + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/bwmarrin/snowflake v0.3.0 github.com/davecgh/go-spew v1.1.1 github.com/disintegration/imaging v1.6.2 @@ -14,7 +15,7 @@ require ( github.com/go-playground/validator/v10 v10.11.1 github.com/go-sql-driver/mysql v1.6.0 github.com/goccy/go-json v0.9.11 - github.com/golang/mock v1.4.4 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/google/wire v0.5.0 github.com/gosimple/slug v1.13.1 @@ -22,7 +23,6 @@ require ( github.com/jinzhu/copier v0.3.5 github.com/jinzhu/now v1.1.5 github.com/lib/pq v1.10.7 - github.com/mattn/go-sqlite3 v1.14.16 github.com/microcosm-cc/bluemonday v1.0.21 github.com/mojocn/base64Captcha v1.3.5 github.com/ory/dockertest/v3 v3.9.1 @@ -43,6 +43,7 @@ require ( golang.org/x/net v0.1.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 + modernc.org/sqlite v1.14.2 xorm.io/builder v0.3.12 xorm.io/core v0.7.3 xorm.io/xorm v1.3.2 @@ -79,12 +80,14 @@ require ( github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect github.com/lestrrat-go/strftime v1.0.6 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -97,6 +100,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -113,6 +117,7 @@ require ( go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.23.0 // indirect golang.org/x/image v0.1.0 // indirect + golang.org/x/mod v0.6.0 // indirect golang.org/x/sys v0.1.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.2.0 // indirect @@ -120,5 +125,14 @@ require ( gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + lukechampine.com/uint128 v1.1.1 // indirect + modernc.org/cc/v3 v3.35.18 // indirect + modernc.org/ccgo/v3 v3.12.82 // indirect + modernc.org/libc v1.11.87 // indirect + modernc.org/mathutil v1.4.1 // indirect + modernc.org/memory v1.0.5 // indirect + modernc.org/opt v0.1.1 // indirect + modernc.org/strutil v1.1.1 // indirect + modernc.org/token v1.0.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index a808586a..a84e52f3 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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= @@ -142,6 +144,7 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/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= @@ -237,8 +240,9 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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= @@ -696,6 +700,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -793,6 +798,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -832,6 +838,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -912,9 +919,11 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1009,6 +1018,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= @@ -1219,7 +1229,9 @@ modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3 modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= modernc.org/ccgo/v3 v3.12.82 h1:wudcnJyjLj1aQQCXF3IM9Gz2X6UNjw+afIghzdtn0v8= modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= +modernc.org/ccorpus v1.11.1 h1:K0qPfpVG1MJh5BYazccnmhywH4zHuOgJXgbjzyp6dWA= modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= @@ -1271,9 +1283,11 @@ modernc.org/sqlite v1.14.2 h1:ohsW2+e+Qe2To1W6GNezzKGwjXwSax6R+CrhRxVaFbE= modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8= modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.8.13 h1:V0sTNBw0Re86PvXZxuCub3oO9WrSTqALgrwNZNvLFGw= modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY= modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.2.19 h1:BGyRFWhDVn5LFS5OcX4Yd/MlpRTOc7hOPTdcIpCiUao= modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index ac0b6254..9d1c1b20 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -52,6 +52,8 @@ backend: other: "Comment are not allowed to edit." not_found: other: "Comment not found." + cannot_edit_after_deadline: + other: "The comment time has been too long to modify." email: duplicate: other: "Email already exists." @@ -508,6 +510,8 @@ ui: label: Revision answer: label: Answer + feedback: + characters: content must be at least 6 characters in length. edit_summary: label: Edit Summary placeholder: >- @@ -638,7 +642,7 @@ ui: msg: empty: Email cannot be empty. change_email: - page_title: Welcome to Answer + page_title: Welcome to {{site_name}} btn_cancel: Cancel btn_update: Update email address send_success: >- @@ -772,6 +776,7 @@ ui:

Are you sure you want to add another answer?

You could use the edit link to refine and improve your existing answer, instead.

empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. reopen: title: Reopen this post content: Are you sure you want to reopen? @@ -838,7 +843,7 @@ ui: modal_confirm: title: Error... account_result: - page_title: Welcome to Answer + page_title: Welcome to {{site_name}} success: Your new account is confirmed; you will be redirected to the home page. link: Continue to homepage invalid: >- @@ -993,8 +998,12 @@ ui: database tables first. db_failed: Database connection failed db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host’s database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted page_404: desc: "Unfortunately, this page doesn't exist." back_home: Back to homepage diff --git a/internal/base/constant/comment.go b/internal/base/constant/comment.go new file mode 100644 index 00000000..6a0c7137 --- /dev/null +++ b/internal/base/constant/comment.go @@ -0,0 +1,7 @@ +package constant + +import "time" + +const ( + CommentEditDeadline = time.Minute * 5 +) diff --git a/internal/base/data/data.go b/internal/base/data/data.go index 356c7157..0a16659e 100644 --- a/internal/base/data/data.go +++ b/internal/base/data/data.go @@ -7,10 +7,10 @@ import ( "github.com/answerdev/answer/pkg/dir" _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" - _ "github.com/mattn/go-sqlite3" "github.com/segmentfault/pacman/cache" "github.com/segmentfault/pacman/contrib/cache/memory" "github.com/segmentfault/pacman/log" + _ "modernc.org/sqlite" "xorm.io/core" "xorm.io/xorm" ormlog "xorm.io/xorm/log" @@ -38,11 +38,13 @@ func NewDB(debug bool, dataConf *Database) (*xorm.Engine, error) { dataConf.Driver = string(schemas.MYSQL) } if dataConf.Driver == string(schemas.SQLITE) { + dataConf.Driver = "sqlite" dbFileDir := filepath.Dir(dataConf.Connection) log.Debugf("try to create database directory %s", dbFileDir) if err := dir.CreateDirIfNotExist(dbFileDir); err != nil { log.Errorf("create database dir failed: %s", err) } + dataConf.MaxOpenConn = 1 } engine, err := xorm.NewEngine(dataConf.Driver, dataConf.Connection) if err != nil { diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go index 9d2880e0..af4b5b71 100644 --- a/internal/base/reason/reason.go +++ b/internal/base/reason/reason.go @@ -16,6 +16,7 @@ const ( const ( EmailOrPasswordWrong = "error.object.email_or_password_incorrect" CommentNotFound = "error.comment.not_found" + CommentCannotEditAfterDeadline = "error.comment.cannot_edit_after_deadline" QuestionNotFound = "error.question.not_found" QuestionCannotDeleted = "error.question.cannot_deleted" QuestionCannotClose = "error.question.cannot_close" diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go index 8eae14e1..206e5808 100644 --- a/internal/base/validator/validator.go +++ b/internal/base/validator/validator.go @@ -97,8 +97,29 @@ func getTran(lo locales.Translator) ut.Translator { return tran } +func NotBlank(fl validator.FieldLevel) (res bool) { + field := fl.Field() + switch field.Kind() { + case reflect.String: + trimSpace := strings.TrimSpace(field.String()) + res := len(trimSpace) > 0 + if !res { + field.SetString(trimSpace) + } + return true + case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array: + return field.Len() > 0 + case reflect.Ptr, reflect.Interface, reflect.Func: + return !field.IsNil() + default: + return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface() + } +} + func createDefaultValidator(la i18n.Language) *validator.Validate { validate := validator.New() + // _ = validate.RegisterValidation("notblank", validators.NotBlank) + _ = validate.RegisterValidation("notblank", NotBlank) validate.RegisterTagNameFunc(func(fld reflect.StructField) (res string) { defer func() { if len(res) > 0 { diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go index eb025139..79ed9681 100644 --- a/internal/controller/comment_controller.go +++ b/internal/controller/comment_controller.go @@ -111,6 +111,7 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) { } req.UserID = middleware.GetLoginUserIDFromContext(ctx) + req.IsAdmin = middleware.GetIsAdminFromContext(ctx) can, err := cc.rankService.CheckOperationPermission(ctx, req.UserID, permission.CommentEdit, req.CommentID) if err != nil { handler.HandleResponse(ctx, err, nil) diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index c97c81b4..894b4930 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -139,6 +139,9 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) { } siteInfo := tc.SiteInfo(ctx) siteInfo.Canonical = fmt.Sprintf("%s/questions", siteInfo.General.SiteUrl) + if page > 1 { + siteInfo.Canonical = fmt.Sprintf("%s/questions?page=%d", siteInfo.General.SiteUrl, page) + } UrlUseTitle := false if siteInfo.SiteSeo.PermaLink == schema.PermaLinkQuestionIDAndTitle { @@ -327,6 +330,9 @@ func (tc *TemplateController) TagList(ctx *gin.Context) { siteInfo := tc.SiteInfo(ctx) siteInfo.Canonical = fmt.Sprintf("%s/tags", siteInfo.General.SiteUrl) + if req.Page > 1 { + siteInfo.Canonical = fmt.Sprintf("%s/tags?page=%d", siteInfo.General.SiteUrl, req.Page) + } siteInfo.Title = fmt.Sprintf("%s - %s", "Tags", siteInfo.General.Name) tc.html(ctx, http.StatusOK, "tags.html", siteInfo, gin.H{ "page": page, @@ -353,6 +359,9 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) { siteInfo := tc.SiteInfo(ctx) siteInfo.Canonical = fmt.Sprintf("%s/tags/%s", siteInfo.General.SiteUrl, tag) + if req.Page > 1 { + siteInfo.Canonical = fmt.Sprintf("%s/tags/%s?page=%d", siteInfo.General.SiteUrl, tag, req.Page) + } siteInfo.Description = htmltext.FetchExcerpt(taginifo.ParsedText, "...", 240) if len(taginifo.ParsedText) == 0 { siteInfo.Description = "The tag has no description." @@ -437,6 +446,7 @@ func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteI data["HeadCode"] = siteInfo.CustomCssHtml.CustomHead data["HeaderCode"] = siteInfo.CustomCssHtml.CustomHeader data["FooterCode"] = siteInfo.CustomCssHtml.CustomFooter + data["Version"] = constant.Version _, ok := data["path"] if !ok { data["path"] = "" diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go index 909581cc..c2cf25bf 100644 --- a/internal/controller/user_controller.go +++ b/internal/controller/user_controller.go @@ -157,8 +157,8 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) { return } _, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP()) - code, err := uc.userService.RetrievePassWord(ctx, req) - handler.HandleResponse(ctx, err, code) + _, err := uc.userService.RetrievePassWord(ctx, req) + handler.HandleResponse(ctx, err, nil) } // UseRePassWord godoc diff --git a/internal/install/install_req.go b/internal/install/install_req.go index ff544406..a465d6bd 100644 --- a/internal/install/install_req.go +++ b/internal/install/install_req.go @@ -5,6 +5,10 @@ import ( "net/url" "strings" + "github.com/answerdev/answer/internal/base/reason" + "github.com/answerdev/answer/internal/base/validator" + "github.com/answerdev/answer/pkg/checker" + "github.com/segmentfault/pacman/errors" "xorm.io/xorm/schemas" ) @@ -82,6 +86,18 @@ type InitBaseInfoReq struct { AdminEmail string `validate:"required,email,gt=0,lte=500" json:"email"` } +func (r *InitBaseInfoReq) Check() (errFields []*validator.FormErrorField, err error) { + if checker.IsInvalidUsername(r.AdminName) { + errField := &validator.FormErrorField{ + ErrorField: "name", + ErrorMsg: reason.UsernameInvalid, + } + errFields = append(errFields, errField) + return errFields, errors.BadRequest(reason.UsernameInvalid) + } + return +} + func (r *InitBaseInfoReq) FormatSiteUrl() { parsedUrl, err := url.Parse(r.SiteURL) if err != nil { diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go index f73c74b7..396398c5 100644 --- a/internal/repo/collection/collection_repo.go +++ b/internal/repo/collection/collection_repo.go @@ -11,6 +11,7 @@ import ( collectioncommon "github.com/answerdev/answer/internal/service/collection_common" "github.com/answerdev/answer/internal/service/unique" "github.com/segmentfault/pacman/errors" + "xorm.io/xorm" ) // collectionRepo collection repository @@ -29,15 +30,28 @@ func NewCollectionRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo) collec // AddCollection add collection func (cr *collectionRepo) AddCollection(ctx context.Context, collection *entity.Collection) (err error) { - id, err := cr.uniqueIDRepo.GenUniqueIDStr(ctx, collection.TableName()) - if err == nil { - collection.ID = id - _, err = cr.data.DB.Insert(collection) + _, err = cr.data.DB.Transaction(func(session *xorm.Session) (result any, err error) { + var has bool + dbcollection := &entity.Collection{} + result = nil + has, err = session.Where("user_id = ? and object_id = ?", collection.UserID, collection.ObjectID).Get(dbcollection) if err != nil { - return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return } - } - return nil + if has { + return + } + id, err := cr.uniqueIDRepo.GenUniqueIDStr(ctx, collection.TableName()) + if err == nil { + collection.ID = id + _, err = session.Insert(collection) + if err != nil { + return result, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + } + return + }) + return err } // RemoveCollection delete collection diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index eac0620c..987fea5c 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -33,7 +33,7 @@ var ( "`user_id`", "`vote_count`", "`answer_count`", - "0 as `accepted`", + "CASE WHEN `accepted_answer_id` > 0 THEN 2 ELSE 0 END as `accepted`", "`question`.`status` as `status`", "`post_update_time`", } diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 724d9af9..7fc6a12d 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -20,10 +20,10 @@ const ( ) type AnswerAddReq struct { - QuestionID string `json:"question_id" ` // question_id - Content string `json:"content" ` // content - HTML string `json:"html" ` // html - UserID string `json:"-" ` // user_id + QuestionID string `json:"question_id"` + Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` + HTML string `json:"-"` + UserID string `json:"-"` } func (req *AnswerAddReq) Check() (errFields []*validator.FormErrorField, err error) { @@ -32,13 +32,13 @@ func (req *AnswerAddReq) Check() (errFields []*validator.FormErrorField, err err } type AnswerUpdateReq struct { - ID string `json:"id"` // id - QuestionID string `json:"question_id" ` // question_id - UserID string `json:"-" ` // user_id - Title string `json:"title" ` // title - Content string `json:"content"` // content - HTML string `json:"html" ` // html - EditSummary string `validate:"omitempty" json:"edit_summary"` // edit_summary + ID string `json:"id"` + QuestionID string `json:"question_id"` + Title string `json:"title"` + Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` + EditSummary string `validate:"omitempty" json:"edit_summary"` + HTML string `json:"-"` + UserID string `json:"-"` NoNeedReview bool `json:"-"` // whether user can edit it CanEdit bool `json:"-"` diff --git a/internal/schema/comment_schema.go b/internal/schema/comment_schema.go index 05b3e18a..dcc44bd5 100644 --- a/internal/schema/comment_schema.go +++ b/internal/schema/comment_schema.go @@ -14,9 +14,9 @@ type AddCommentReq struct { // reply comment id ReplyCommentID string `validate:"omitempty" json:"reply_comment_id"` // original comment content - OriginalText string `validate:"required" json:"original_text"` + OriginalText string `validate:"required,notblank,gte=2,lte=600" json:"original_text"` // parsed comment content - ParsedText string `validate:"required" json:"parsed_text"` + ParsedText string `json:"-"` // @ user id list MentionUsernameList []string `validate:"omitempty" json:"mention_username_list"` // user id @@ -47,11 +47,12 @@ type UpdateCommentReq struct { // comment id CommentID string `validate:"required" json:"comment_id"` // original comment content - OriginalText string `validate:"omitempty" json:"original_text"` + OriginalText string `validate:"required,notblank,gte=2,lte=600" json:"original_text"` // parsed comment content - ParsedText string `validate:"omitempty" json:"parsed_text"` + ParsedText string `json:"-"` // user id - UserID string `json:"-"` + UserID string `json:"-"` + IsAdmin bool `json:"-"` } func (req *UpdateCommentReq) Check() (errFields []*validator.FormErrorField, err error) { diff --git a/internal/schema/question_schema.go b/internal/schema/question_schema.go index 4d4bda23..b656b834 100644 --- a/internal/schema/question_schema.go +++ b/internal/schema/question_schema.go @@ -41,11 +41,11 @@ type ReopenQuestionReq struct { type QuestionAdd struct { // question title - Title string `validate:"required,gte=6,lte=150" json:"title"` + Title string `validate:"required,notblank,gte=6,lte=150" json:"title"` // content - Content string `validate:"required,gte=6,lte=65535" json:"content"` + Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` // html - HTML string `validate:"required,gte=6,lte=65535" json:"html"` + HTML string `json:"-"` // tags Tags []*TagItem `validate:"required,dive" json:"tags"` // user id @@ -90,11 +90,11 @@ type QuestionUpdate struct { // question id ID string `validate:"required" json:"id"` // question title - Title string `validate:"required,gte=6,lte=150" json:"title"` + Title string `validate:"required,notblank,gte=6,lte=150" json:"title"` // content - Content string `validate:"required,gte=6,lte=65535" json:"content"` + Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` // html - HTML string `validate:"required,gte=6,lte=65535" json:"html"` + HTML string `json:"-"` // tags Tags []*TagItem `validate:"required,dive" json:"tags"` // edit summary @@ -219,7 +219,7 @@ type UserQuestionInfo struct { ViewCount int `json:"view_count"` AnswerCount int `json:"answer_count"` CollectionCount int `json:"collection_count"` - CreateTime int `json:"create_time"` + CreatedAt int64 `json:"created_at"` AcceptedAnswerID string `json:"accepted_answer_id"` Status string `json:"status"` } @@ -253,6 +253,7 @@ const ( type QuestionPageResp struct { ID string `json:"id" ` + CreatedAt int64 `json:"created_at"` Title string `json:"title"` UrlTitle string `json:"url_title"` Description string `json:"description"` diff --git a/internal/schema/tag_schema.go b/internal/schema/tag_schema.go index 3b7100a2..654e9178 100644 --- a/internal/schema/tag_schema.go +++ b/internal/schema/tag_schema.go @@ -144,7 +144,7 @@ type TagItem struct { // original text OriginalText string `validate:"omitempty" json:"original_text"` // parsed text - ParsedText string `validate:"omitempty" json:"parsed_text"` + ParsedText string `json:"-"` } // RemoveTagReq delete tag request @@ -166,7 +166,7 @@ type UpdateTagReq struct { // original text OriginalText string `validate:"omitempty" json:"original_text"` // parsed text - ParsedText string `validate:"omitempty" json:"parsed_text"` + ParsedText string `json:"-"` // edit summary EditSummary string `validate:"omitempty" json:"edit_summary"` // user id diff --git a/internal/schema/user_schema.go b/internal/schema/user_schema.go index 9b449b80..308568c8 100644 --- a/internal/schema/user_schema.go +++ b/internal/schema/user_schema.go @@ -2,12 +2,12 @@ package schema import ( "encoding/json" - "regexp" "github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/validator" "github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/pkg/checker" + "github.com/answerdev/answer/pkg/converter" "github.com/jinzhu/copier" "github.com/segmentfault/pacman/errors" ) @@ -283,7 +283,7 @@ type UpdateInfoRequest struct { // bio Bio string `validate:"omitempty,gt=0,lte=4096" json:"bio"` // bio - BioHTML string `validate:"omitempty,gt=0,lte=4096" json:"bio_html"` + BioHTML string `json:"-"` // website Website string `validate:"omitempty,gt=0,lte=500" json:"website"` // location @@ -298,12 +298,9 @@ type AvatarInfo struct { Custom string `validate:"omitempty,gt=0,lte=200" json:"custom"` } -func (u *UpdateInfoRequest) Check() (errFields []*validator.FormErrorField, err error) { - if len(u.Username) > 0 { - errFields := make([]*validator.FormErrorField, 0) - re := regexp.MustCompile(`^[a-z0-9._-]{4,30}$`) - match := re.MatchString(u.Username) - if !match { +func (req *UpdateInfoRequest) Check() (errFields []*validator.FormErrorField, err error) { + if len(req.Username) > 0 { + if checker.IsInvalidUsername(req.Username) { errField := &validator.FormErrorField{ ErrorField: "username", ErrorMsg: reason.UsernameInvalid, @@ -312,6 +309,7 @@ func (u *UpdateInfoRequest) Check() (errFields []*validator.FormErrorField, err return errFields, errors.BadRequest(reason.UsernameInvalid) } } + req.BioHTML = converter.Markdown2HTML(req.Bio) return nil, nil } diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go index 92d9a194..18b755ab 100644 --- a/internal/service/comment/comment_service.go +++ b/internal/service/comment/comment_service.go @@ -121,33 +121,14 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment return nil, err } - if objInfo.ObjectType == constant.QuestionObjectType { - cs.notificationQuestionComment(ctx, objInfo.ObjectCreatorUserID, - objInfo.QuestionID, objInfo.Title, comment.ID, req.UserID, comment.OriginalText) - } else if objInfo.ObjectType == constant.AnswerObjectType { - cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, - objInfo.ObjectCreatorUserID, comment.ID, req.UserID, comment.OriginalText) - } - if len(req.MentionUsernameList) > 0 { - cs.notificationMention(ctx, req.MentionUsernameList, comment.ID, req.UserID) - } - resp = &schema.GetCommentResp{} resp.SetFromComment(comment) - resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, req.CanEdit, req.CanDelete) + resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, + time.Now(), req.CanEdit, req.CanDelete) - // get reply user info - if len(resp.ReplyUserID) > 0 { - replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID) - if err != nil { - return nil, err - } - if exist { - resp.ReplyUsername = replyUser.Username - resp.ReplyUserDisplayName = replyUser.DisplayName - resp.ReplyUserStatus = replyUser.Status - } - cs.notificationCommentReply(ctx, replyUser.ID, objInfo.QuestionID, req.UserID) + commentResp, err := cs.addCommentNotification(ctx, req, resp, comment, objInfo) + if err != nil { + return commentResp, err } // get user info @@ -178,6 +159,50 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment return resp, nil } +func (cs *CommentService) addCommentNotification( + ctx context.Context, req *schema.AddCommentReq, resp *schema.GetCommentResp, + comment *entity.Comment, objInfo *schema.SimpleObjectInfo) (*schema.GetCommentResp, error) { + // The priority of the notification + // 1. reply to user + // 2. comment mention to user + // 3. answer or question was commented + alreadyNotifiedUserID := make(map[string]bool) + + // get reply user info + if len(resp.ReplyUserID) > 0 && resp.ReplyUserID != req.UserID { + replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID) + if err != nil { + return nil, err + } + if exist { + resp.ReplyUsername = replyUser.Username + resp.ReplyUserDisplayName = replyUser.DisplayName + resp.ReplyUserStatus = replyUser.Status + } + cs.notificationCommentReply(ctx, replyUser.ID, comment.ID, req.UserID) + alreadyNotifiedUserID[replyUser.ID] = true + return nil, nil + } + + if len(req.MentionUsernameList) > 0 { + alreadyNotifiedUserIDs := cs.notificationMention( + ctx, req.MentionUsernameList, comment.ID, req.UserID, alreadyNotifiedUserID) + for _, userID := range alreadyNotifiedUserIDs { + alreadyNotifiedUserID[userID] = true + } + return nil, nil + } + + if objInfo.ObjectType == constant.QuestionObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] { + cs.notificationQuestionComment(ctx, objInfo.ObjectCreatorUserID, + objInfo.QuestionID, objInfo.Title, comment.ID, req.UserID, comment.OriginalText) + } else if objInfo.ObjectType == constant.AnswerObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] { + cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, + objInfo.ObjectCreatorUserID, comment.ID, req.UserID, comment.OriginalText) + } + return nil, nil +} + // RemoveComment delete comment func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveCommentReq) (err error) { return cs.commentRepo.RemoveComment(ctx, req.CommentID) @@ -185,6 +210,19 @@ func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveC // UpdateComment update comment func (cs *CommentService) UpdateComment(ctx context.Context, req *schema.UpdateCommentReq) (err error) { + old, exist, err := cs.commentCommonRepo.GetComment(ctx, req.CommentID) + if err != nil { + return + } + if !exist { + return errors.BadRequest(reason.CommentNotFound) + } + + // user can edit the comment that was posted by himself before deadline. + if !req.IsAdmin && (time.Now().After(old.CreatedAt.Add(constant.CommentEditDeadline))) { + return errors.BadRequest(reason.CommentCannotEditAfterDeadline) + } + comment := &entity.Comment{} _ = copier.Copy(comment, req) comment.ID = req.CommentID @@ -198,7 +236,7 @@ func (cs *CommentService) GetComment(ctx context.Context, req *schema.GetComment return } if !exist { - return nil, errors.BadRequest(reason.UnknownError) + return nil, errors.BadRequest(reason.CommentNotFound) } resp = &schema.GetCommentResp{ @@ -243,7 +281,8 @@ func (cs *CommentService) GetComment(ctx context.Context, req *schema.GetComment // check if current user vote this comment resp.IsVote = cs.checkIsVote(ctx, req.UserID, resp.CommentID) - resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, req.CanEdit, req.CanDelete) + resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, + comment.CreatedAt, req.CanEdit, req.CanDelete) return resp, nil } @@ -339,7 +378,7 @@ func (cs *CommentService) convertCommentEntity2Resp(ctx context.Context, req *sc commentResp.IsVote = cs.checkIsVote(ctx, req.UserID, commentResp.CommentID) commentResp.MemberActions = permission.GetCommentPermission(ctx, - req.UserID, commentResp.UserID, req.CanEdit, req.CanDelete) + req.UserID, commentResp.UserID, comment.CreatedAt, req.CanEdit, req.CanDelete) return commentResp, nil } @@ -521,14 +560,16 @@ func (cs *CommentService) notificationCommentReply(ctx context.Context, replyUse notice_queue.AddNotification(msg) } -func (cs *CommentService) notificationMention(ctx context.Context, mentionUsernameList []string, commentID, commentUserID string) { +func (cs *CommentService) notificationMention( + ctx context.Context, mentionUsernameList []string, commentID, commentUserID string, + alreadyNotifiedUserID map[string]bool) (alreadyNotifiedUserIDs []string) { for _, username := range mentionUsernameList { userInfo, exist, err := cs.userCommon.GetUserBasicInfoByUserName(ctx, username) if err != nil { log.Error(err) continue } - if exist { + if exist && !alreadyNotifiedUserID[userInfo.ID] { msg := &schema.NotificationMsg{ ReceiverUserID: userInfo.ID, TriggerUserID: commentUserID, @@ -538,6 +579,8 @@ func (cs *CommentService) notificationMention(ctx context.Context, mentionUserna msg.ObjectType = constant.CommentObjectType msg.NotificationAction = constant.MentionYou notice_queue.AddNotification(msg) + alreadyNotifiedUserIDs = append(alreadyNotifiedUserIDs, userInfo.ID) } } + return alreadyNotifiedUserIDs } diff --git a/internal/service/permission/comment_permission.go b/internal/service/permission/comment_permission.go index 026b885a..7f8839ae 100644 --- a/internal/service/permission/comment_permission.go +++ b/internal/service/permission/comment_permission.go @@ -2,13 +2,15 @@ package permission import ( "context" + "time" + "github.com/answerdev/answer/internal/base/constant" "github.com/answerdev/answer/internal/schema" ) // GetCommentPermission get comment permission -func GetCommentPermission(ctx context.Context, userID string, creatorUserID string, canEdit, canDelete bool) ( - actions []*schema.PermissionMemberAction) { +func GetCommentPermission(ctx context.Context, userID string, creatorUserID string, + createdAt time.Time, canEdit, canDelete bool) (actions []*schema.PermissionMemberAction) { actions = make([]*schema.PermissionMemberAction, 0) if len(userID) > 0 { actions = append(actions, &schema.PermissionMemberAction{ @@ -17,7 +19,8 @@ func GetCommentPermission(ctx context.Context, userID string, creatorUserID stri Type: "reason", }) } - if canEdit || userID == creatorUserID { + deadline := createdAt.Add(constant.CommentEditDeadline) + if canEdit || (userID == creatorUserID && time.Now().Before(deadline)) { actions = append(actions, &schema.PermissionMemberAction{ Action: "edit", Name: "Edit", diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index deafa5b1..43be1b78 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -254,6 +254,7 @@ func (qs *QuestionCommon) FormatQuestionsPage( for _, questionInfo := range questionList { t := &schema.QuestionPageResp{ ID: questionInfo.ID, + CreatedAt: questionInfo.CreatedAt.Unix(), Title: questionInfo.Title, UrlTitle: htmltext.UrlTitle(questionInfo.Title), Description: htmltext.FetchExcerpt(questionInfo.ParsedText, "...", 240), diff --git a/internal/service/user_common/user.go b/internal/service/user_common/user.go index 946319d5..da66f4ce 100644 --- a/internal/service/user_common/user.go +++ b/internal/service/user_common/user.go @@ -4,7 +4,6 @@ import ( "context" "encoding/hex" "math/rand" - "regexp" "strings" "github.com/Chain-Zhang/pinyin" @@ -120,9 +119,7 @@ func (us *UserCommon) MakeUsername(ctx context.Context, displayName string) (use username = strings.ToLower(username) suffix := "" - re := regexp.MustCompile(`^[a-z0-9._-]{4,30}$`) - match := re.MatchString(username) - if !match { + if checker.IsInvalidUsername(username) { return "", errors.BadRequest(reason.UsernameInvalid) } diff --git a/pkg/checker/username.go b/pkg/checker/username.go new file mode 100644 index 00000000..0225ec0b --- /dev/null +++ b/pkg/checker/username.go @@ -0,0 +1,11 @@ +package checker + +import "regexp" + +var ( + usernameReg = regexp.MustCompile(`^[a-z0-9._-]{4,30}$`) +) + +func IsInvalidUsername(username string) bool { + return !usernameReg.MatchString(username) +} diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go index d302c1be..4f4a3c41 100644 --- a/pkg/converter/markdown.go +++ b/pkg/converter/markdown.go @@ -3,6 +3,7 @@ package converter import ( "bytes" + "github.com/asaskevich/govalidator" "github.com/microcosm-cc/bluemonday" "github.com/segmentfault/pacman/log" "github.com/yuin/goldmark" @@ -10,6 +11,7 @@ import ( "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" goldmarkHTML "github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/util" ) @@ -54,6 +56,7 @@ type DangerousHTMLRenderer struct { func (r *DangerousHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindHTMLBlock, r.renderHTMLBlock) reg.Register(ast.KindRawHTML, r.renderRawHTML) + reg.Register(ast.KindLink, r.renderLink) } func (r *DangerousHTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -85,3 +88,30 @@ func (r *DangerousHTMLRenderer) renderHTMLBlock(w util.BufWriter, source []byte, } return ast.WalkContinue, nil } + +func (r *DangerousHTMLRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Link) + if entering && r.renderLinkIsUrl(string(n.Destination)) { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + return ast.WalkContinue, nil +} + +func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyUrl string) bool { + return govalidator.IsURL(verifyUrl) +} diff --git a/ui/.gitignore b/ui/.gitignore index fe3fdef0..f5128c7c 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -9,7 +9,11 @@ /coverage # production -/build + +/build/*/*/* +/build/*.json +/build/*.html +/build/*.txt # misc .DS_Store diff --git a/ui/build/favicon.ico b/ui/build/favicon.ico new file mode 100644 index 00000000..6ab1fbda Binary files /dev/null and b/ui/build/favicon.ico differ diff --git a/ui/build/index.html b/ui/build/index.html deleted file mode 100644 index f7ae498a..00000000 --- a/ui/build/index.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/ui/package.json b/ui/package.json index dfd2c04d..5c23dc5d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -22,7 +22,9 @@ "copy-to-clipboard": "^3.3.2", "dayjs": "^1.11.5", "diff": "^5.1.0", + "dompurify": "^2.4.3", "emoji-regex": "^10.2.1", + "html-react-parser": "^3.0.8", "i18next": "^21.9.0", "katex": "^0.16.2", "lodash": "^4.17.21", @@ -51,6 +53,7 @@ "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", "@types/color": "^3.0.3", + "@types/dompurify": "^2.4.0", "@types/jest": "^27.5.2", "@types/lodash": "^4.14.184", "@types/marked": "^4.0.6", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index d4e96662..8ec5b138 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -9,6 +9,7 @@ specifiers: '@testing-library/react': ^13.3.0 '@testing-library/user-event': ^13.5.0 '@types/color': ^3.0.3 + '@types/dompurify': ^2.4.0 '@types/jest': ^27.5.2 '@types/lodash': ^4.14.184 '@types/marked': ^4.0.6 @@ -28,6 +29,7 @@ specifiers: customize-cra: ^1.0.0 dayjs: ^1.11.5 diff: ^5.1.0 + dompurify: ^2.4.3 emoji-regex: ^10.2.1 eslint: ^8.0.1 eslint-config-airbnb: ^19.0.4 @@ -41,6 +43,7 @@ specifiers: eslint-plugin-promise: ^6.0.0 eslint-plugin-react: ^7.30.1 eslint-plugin-react-hooks: ^4.6.0 + html-react-parser: ^3.0.8 husky: ^8.0.1 i18next: ^21.9.0 katex: ^0.16.2 @@ -80,7 +83,9 @@ dependencies: copy-to-clipboard: 3.3.2 dayjs: 1.11.5 diff: 5.1.0 + dompurify: registry.npmjs.org/dompurify/2.4.3 emoji-regex: 10.2.1 + html-react-parser: registry.npmjs.org/html-react-parser/3.0.8_react@18.2.0 i18next: 21.9.2 katex: 0.16.2 lodash: 4.17.21 @@ -109,6 +114,7 @@ devDependencies: '@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y '@testing-library/user-event': 13.5.0_znccgeejomvff3jrsk3ljovfpu '@types/color': registry.npmjs.org/@types/color/3.0.3 + '@types/dompurify': registry.npmjs.org/@types/dompurify/2.4.0 '@types/jest': 27.5.2 '@types/lodash': 4.14.185 '@types/marked': 4.0.7 @@ -1894,7 +1900,7 @@ packages: collect-v8-coverage: 1.0.1 exit: 0.1.2 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 istanbul-lib-coverage: 3.2.0 istanbul-lib-instrument: 5.2.0 istanbul-lib-report: 3.0.0 @@ -1923,7 +1929,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: callsites: 3.1.0 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 source-map: 0.6.1 /@jest/test-result/27.5.1: @@ -1949,7 +1955,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/test-result': 27.5.1 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jest-haste-map: 27.5.1 jest-runtime: 27.5.1 transitivePeerDependencies: @@ -2630,9 +2636,6 @@ packages: /@types/stack-utils/2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - /@types/trusted-types/2.0.2: - resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} - /@types/warning/3.0.0: resolution: {integrity: sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==} dev: false @@ -3437,7 +3440,7 @@ packages: peerDependencies: '@popperjs/core': ^2.11.6 dependencies: - '@popperjs/core': 2.11.6 + '@popperjs/core': registry.npmjs.org/@popperjs/core/2.11.6 dev: false /brace-expansion/1.1.11: @@ -3590,7 +3593,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmjs.org/fsevents/2.3.2 /chrome-trace-event/1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} @@ -3989,7 +3992,7 @@ packages: dependencies: boolbase: 1.0.0 css-what: 3.4.2 - domutils: 1.7.0 + domutils: registry.npmjs.org/domutils/1.7.0 nth-check: 1.0.2 /css-select/4.3.0: @@ -3997,8 +4000,8 @@ packages: dependencies: boolbase: 1.0.0 css-what: 6.1.0 - domhandler: 4.3.1 - domutils: 2.8.0 + domhandler: registry.npmjs.org/domhandler/4.3.1 + domutils: registry.npmjs.org/domutils/2.8.0 nth-check: 2.1.1 /css-tree/1.0.0-alpha.37: @@ -4830,54 +4833,12 @@ packages: csstype: 3.1.1 dev: false - /dom-serializer/0.2.2: - resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} - dependencies: - domelementtype: 2.3.0 - entities: 2.2.0 - - /dom-serializer/1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - - /domelementtype/1.3.1: - resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} - - /domelementtype/2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - /domexception/2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} engines: {node: '>=8'} dependencies: webidl-conversions: 5.0.0 - /domhandler/4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - - /dompurify/2.4.0: - resolution: {integrity: sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==} - dev: false - - /domutils/1.7.0: - resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} - dependencies: - dom-serializer: 0.2.2 - domelementtype: 1.3.1 - - /domutils/2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - /dot-case/3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: @@ -4948,12 +4909,9 @@ packages: resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==} engines: {node: '>=10.13.0'} dependencies: - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 tapable: 2.2.1 - /entities/2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -5040,7 +4998,7 @@ packages: esutils: 2.0.3 optionator: 0.8.3 optionalDependencies: - source-map: 0.6.1 + source-map: registry.npmjs.org/source-map/0.6.1 /eslint-config-airbnb-base/15.0.0_hdzsmr7kawaomymueo2tso6fjq: resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} @@ -5226,8 +5184,8 @@ packages: '@babel/plugin-transform-react-jsx': ^7.14.9 eslint: ^8.1.0 dependencies: - '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.19.1 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.1 + '@babel/plugin-syntax-flow': registry.npmjs.org/@babel/plugin-syntax-flow/7.18.6_@babel+core@7.19.1 + '@babel/plugin-transform-react-jsx': registry.npmjs.org/@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.1 eslint: 8.23.1 lodash: 4.17.21 string-natural-compare: 3.0.1 @@ -5828,7 +5786,7 @@ packages: engines: {node: '>=10'} dependencies: at-least-node: 1.0.0 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jsonfile: 6.1.0 universalify: 2.0.0 @@ -5838,13 +5796,6 @@ packages: /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - optional: true - /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} @@ -6104,14 +6055,6 @@ packages: tapable: 2.2.1 webpack: 5.74.0 - /htmlparser2/6.1.0: - resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils: 2.8.0 - entities: 2.2.0 - /http-deceiver/1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} @@ -6623,7 +6566,7 @@ packages: ci-info: 3.4.0 deepmerge: 4.2.2 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jest-circus: 27.5.1 jest-environment-jsdom: 27.5.1 jest-environment-node: 27.5.1 @@ -6735,7 +6678,7 @@ packages: micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmjs.org/fsevents/2.3.2 /jest-jasmine2/27.5.1: resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==} @@ -6795,7 +6738,7 @@ packages: '@jest/types': 27.5.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 micromatch: 4.0.5 pretty-format: 27.5.1 slash: 3.0.0 @@ -6809,7 +6752,7 @@ packages: '@jest/types': 28.1.3 '@types/stack-utils': 2.0.1 chalk: 4.1.2 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 micromatch: 4.0.5 pretty-format: 28.1.3 slash: 3.0.0 @@ -6878,7 +6821,7 @@ packages: '@types/node': 16.11.59 chalk: 4.1.2 emittery: 0.8.1 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jest-docblock: 27.5.1 jest-environment-jsdom: 27.5.1 jest-environment-node: 27.5.1 @@ -6913,7 +6856,7 @@ packages: collect-v8-coverage: 1.0.1 execa: 5.1.1 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-mock: 27.5.1 @@ -6931,7 +6874,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@types/node': 16.11.59 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 /jest-snapshot/27.5.1: resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} @@ -6949,7 +6892,7 @@ packages: babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.1 chalk: 4.1.2 expect: 27.5.1 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 jest-diff: 27.5.1 jest-get-type: 27.5.1 jest-haste-map: 27.5.1 @@ -6981,7 +6924,7 @@ packages: '@types/node': 16.11.59 chalk: 4.1.2 ci-info: 3.4.0 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 picomatch: 2.3.1 /jest-validate/27.5.1: @@ -7179,7 +7122,7 @@ packages: dependencies: universalify: 2.0.0 optionalDependencies: - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 /jsonp/0.2.1: resolution: {integrity: sha512-pfog5gdDxPdV4eP7Kg87M8/bHgshlZ5pybl+yKxAnCZ5O7lCIn7Ixydj03wOlnDQesky2BPyA91SQ+5Y/mNwzw==} @@ -7490,7 +7433,7 @@ packages: d3: 7.6.1 dagre: 0.8.5 dagre-d3: 0.6.4 - dompurify: 2.4.0 + dompurify: registry.npmjs.org/dompurify/2.4.0 graphlib: 2.1.8 khroma: 2.0.0 moment-mini: 2.24.0 @@ -8795,7 +8738,7 @@ packages: webpack: '*' dependencies: purgecss: 4.1.3 - webpack: 5.74.0 + webpack: registry.npmjs.org/webpack/5.74.0 webpack-sources: 3.2.3 dev: true @@ -9105,7 +9048,7 @@ packages: webpack-manifest-plugin: 4.1.1_webpack@5.74.0 workbox-webpack-plugin: 6.5.4_webpack@5.74.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmjs.org/fsevents/2.3.2 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -9283,7 +9226,7 @@ packages: dependencies: css-select: 4.3.0 dom-converter: 0.2.0 - htmlparser2: 6.1.0 + htmlparser2: registry.npmjs.org/htmlparser2/6.1.0 lodash: 4.17.21 strip-ansi: 6.0.1 @@ -9408,7 +9351,7 @@ packages: engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmjs.org/fsevents/2.3.2 /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -10513,7 +10456,7 @@ packages: engines: {node: '>=10.13.0'} dependencies: glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 /wbuf/1.7.3: resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} @@ -10864,7 +10807,7 @@ packages: /workbox-window/6.5.4: resolution: {integrity: sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==} dependencies: - '@types/trusted-types': 2.0.2 + '@types/trusted-types': registry.npmjs.org/@types/trusted-types/2.0.2 workbox-core: 6.5.4 /wrap-ansi/6.2.0: @@ -11012,6 +10955,343 @@ packages: use-sync-external-store: 1.2.0_react@18.2.0 dev: false + registry.npmjs.org/@ampproject/remapping/2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz} + name: '@ampproject/remapping' + version: 2.2.0 + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': registry.npmjs.org/@jridgewell/gen-mapping/0.1.1 + '@jridgewell/trace-mapping': registry.npmjs.org/@jridgewell/trace-mapping/0.3.15 + + registry.npmjs.org/@babel/code-frame/7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz} + name: '@babel/code-frame' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': registry.npmjs.org/@babel/highlight/7.18.6 + + registry.npmjs.org/@babel/compat-data/7.19.1: + resolution: {integrity: sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz} + name: '@babel/compat-data' + version: 7.19.1 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/core/7.19.1: + resolution: {integrity: sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz} + name: '@babel/core' + version: 7.19.1 + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': registry.npmjs.org/@ampproject/remapping/2.2.0 + '@babel/code-frame': registry.npmjs.org/@babel/code-frame/7.18.6 + '@babel/generator': registry.npmjs.org/@babel/generator/7.19.0 + '@babel/helper-compilation-targets': registry.npmjs.org/@babel/helper-compilation-targets/7.19.1_@babel+core@7.19.1 + '@babel/helper-module-transforms': registry.npmjs.org/@babel/helper-module-transforms/7.19.0 + '@babel/helpers': registry.npmjs.org/@babel/helpers/7.19.0 + '@babel/parser': registry.npmjs.org/@babel/parser/7.19.1 + '@babel/template': registry.npmjs.org/@babel/template/7.18.10 + '@babel/traverse': registry.npmjs.org/@babel/traverse/7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + convert-source-map: registry.npmjs.org/convert-source-map/1.8.0 + debug: registry.npmjs.org/debug/4.3.4 + gensync: registry.npmjs.org/gensync/1.0.0-beta.2 + json5: registry.npmjs.org/json5/2.2.1 + semver: registry.npmjs.org/semver/6.3.0 + transitivePeerDependencies: + - supports-color + + registry.npmjs.org/@babel/generator/7.19.0: + resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz} + name: '@babel/generator' + version: 7.19.0 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + '@jridgewell/gen-mapping': registry.npmjs.org/@jridgewell/gen-mapping/0.3.2 + jsesc: registry.npmjs.org/jsesc/2.5.2 + + registry.npmjs.org/@babel/helper-annotate-as-pure/7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz} + name: '@babel/helper-annotate-as-pure' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-compilation-targets/7.19.1_@babel+core@7.19.1: + resolution: {integrity: sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz} + id: registry.npmjs.org/@babel/helper-compilation-targets/7.19.1 + name: '@babel/helper-compilation-targets' + version: 7.19.1 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': registry.npmjs.org/@babel/compat-data/7.19.1 + '@babel/core': registry.npmjs.org/@babel/core/7.19.1 + '@babel/helper-validator-option': registry.npmjs.org/@babel/helper-validator-option/7.18.6 + browserslist: registry.npmjs.org/browserslist/4.21.4 + semver: registry.npmjs.org/semver/6.3.0 + + registry.npmjs.org/@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz} + name: '@babel/helper-environment-visitor' + version: 7.18.9 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/helper-function-name/7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz} + name: '@babel/helper-function-name' + version: 7.19.0 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': registry.npmjs.org/@babel/template/7.18.10 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz} + name: '@babel/helper-hoist-variables' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-module-imports/7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz} + name: '@babel/helper-module-imports' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-module-transforms/7.19.0: + resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz} + name: '@babel/helper-module-transforms' + version: 7.19.0 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': registry.npmjs.org/@babel/helper-environment-visitor/7.18.9 + '@babel/helper-module-imports': registry.npmjs.org/@babel/helper-module-imports/7.18.6 + '@babel/helper-simple-access': registry.npmjs.org/@babel/helper-simple-access/7.18.6 + '@babel/helper-split-export-declaration': registry.npmjs.org/@babel/helper-split-export-declaration/7.18.6 + '@babel/helper-validator-identifier': registry.npmjs.org/@babel/helper-validator-identifier/7.19.1 + '@babel/template': registry.npmjs.org/@babel/template/7.18.10 + '@babel/traverse': registry.npmjs.org/@babel/traverse/7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + transitivePeerDependencies: + - supports-color + + registry.npmjs.org/@babel/helper-plugin-utils/7.19.0: + resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz} + name: '@babel/helper-plugin-utils' + version: 7.19.0 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/helper-simple-access/7.18.6: + resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz} + name: '@babel/helper-simple-access' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz} + name: '@babel/helper-split-export-declaration' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/helper-string-parser/7.18.10: + resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz} + name: '@babel/helper-string-parser' + version: 7.18.10 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz} + name: '@babel/helper-validator-identifier' + version: 7.19.1 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/helper-validator-option/7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz} + name: '@babel/helper-validator-option' + version: 7.18.6 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/@babel/helpers/7.19.0: + resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz} + name: '@babel/helpers' + version: 7.19.0 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': registry.npmjs.org/@babel/template/7.18.10 + '@babel/traverse': registry.npmjs.org/@babel/traverse/7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + transitivePeerDependencies: + - supports-color + + registry.npmjs.org/@babel/highlight/7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz} + name: '@babel/highlight' + version: 7.18.6 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': registry.npmjs.org/@babel/helper-validator-identifier/7.19.1 + chalk: registry.npmjs.org/chalk/2.4.2 + js-tokens: registry.npmjs.org/js-tokens/4.0.0 + + registry.npmjs.org/@babel/parser/7.19.1: + resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz} + name: '@babel/parser' + version: 7.19.1 + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/plugin-syntax-flow/7.18.6_@babel+core@7.19.1: + resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz} + id: registry.npmjs.org/@babel/plugin-syntax-flow/7.18.6 + name: '@babel/plugin-syntax-flow' + version: 7.18.6 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': registry.npmjs.org/@babel/core/7.19.1 + '@babel/helper-plugin-utils': registry.npmjs.org/@babel/helper-plugin-utils/7.19.0 + + registry.npmjs.org/@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.1: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz} + id: registry.npmjs.org/@babel/plugin-syntax-jsx/7.18.6 + name: '@babel/plugin-syntax-jsx' + version: 7.18.6 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': registry.npmjs.org/@babel/core/7.19.1 + '@babel/helper-plugin-utils': registry.npmjs.org/@babel/helper-plugin-utils/7.19.0 + + registry.npmjs.org/@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.1: + resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz} + id: registry.npmjs.org/@babel/plugin-transform-react-jsx/7.19.0 + name: '@babel/plugin-transform-react-jsx' + version: 7.19.0 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': registry.npmjs.org/@babel/core/7.19.1 + '@babel/helper-annotate-as-pure': registry.npmjs.org/@babel/helper-annotate-as-pure/7.18.6 + '@babel/helper-module-imports': registry.npmjs.org/@babel/helper-module-imports/7.18.6 + '@babel/helper-plugin-utils': registry.npmjs.org/@babel/helper-plugin-utils/7.19.0 + '@babel/plugin-syntax-jsx': registry.npmjs.org/@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/template/7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz} + name: '@babel/template' + version: 7.18.10 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': registry.npmjs.org/@babel/code-frame/7.18.6 + '@babel/parser': registry.npmjs.org/@babel/parser/7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + + registry.npmjs.org/@babel/traverse/7.19.1: + resolution: {integrity: sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz} + name: '@babel/traverse' + version: 7.19.1 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': registry.npmjs.org/@babel/code-frame/7.18.6 + '@babel/generator': registry.npmjs.org/@babel/generator/7.19.0 + '@babel/helper-environment-visitor': registry.npmjs.org/@babel/helper-environment-visitor/7.18.9 + '@babel/helper-function-name': registry.npmjs.org/@babel/helper-function-name/7.19.0 + '@babel/helper-hoist-variables': registry.npmjs.org/@babel/helper-hoist-variables/7.18.6 + '@babel/helper-split-export-declaration': registry.npmjs.org/@babel/helper-split-export-declaration/7.18.6 + '@babel/parser': registry.npmjs.org/@babel/parser/7.19.1 + '@babel/types': registry.npmjs.org/@babel/types/7.19.0 + debug: registry.npmjs.org/debug/4.3.4 + globals: registry.npmjs.org/globals/11.12.0 + transitivePeerDependencies: + - supports-color + + registry.npmjs.org/@babel/types/7.19.0: + resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz} + name: '@babel/types' + version: 7.19.0 + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': registry.npmjs.org/@babel/helper-string-parser/7.18.10 + '@babel/helper-validator-identifier': registry.npmjs.org/@babel/helper-validator-identifier/7.19.1 + to-fast-properties: registry.npmjs.org/to-fast-properties/2.0.0 + + registry.npmjs.org/@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz} + name: '@jridgewell/gen-mapping' + version: 0.1.1 + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': registry.npmjs.org/@jridgewell/set-array/1.1.2 + '@jridgewell/sourcemap-codec': registry.npmjs.org/@jridgewell/sourcemap-codec/1.4.14 + + registry.npmjs.org/@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz} + name: '@jridgewell/gen-mapping' + version: 0.3.2 + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': registry.npmjs.org/@jridgewell/set-array/1.1.2 + '@jridgewell/sourcemap-codec': registry.npmjs.org/@jridgewell/sourcemap-codec/1.4.14 + '@jridgewell/trace-mapping': registry.npmjs.org/@jridgewell/trace-mapping/0.3.15 + + registry.npmjs.org/@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz} + name: '@jridgewell/resolve-uri' + version: 3.1.0 + engines: {node: '>=6.0.0'} + + registry.npmjs.org/@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz} + name: '@jridgewell/set-array' + version: 1.1.2 + engines: {node: '>=6.0.0'} + + registry.npmjs.org/@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz} + name: '@jridgewell/source-map' + version: 0.3.2 + dependencies: + '@jridgewell/gen-mapping': registry.npmjs.org/@jridgewell/gen-mapping/0.3.2 + '@jridgewell/trace-mapping': registry.npmjs.org/@jridgewell/trace-mapping/0.3.15 + dev: true + + registry.npmjs.org/@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz} + name: '@jridgewell/sourcemap-codec' + version: 1.4.14 + + registry.npmjs.org/@jridgewell/trace-mapping/0.3.15: + resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz} + name: '@jridgewell/trace-mapping' + version: 0.3.15 + dependencies: + '@jridgewell/resolve-uri': registry.npmjs.org/@jridgewell/resolve-uri/3.1.0 + '@jridgewell/sourcemap-codec': registry.npmjs.org/@jridgewell/sourcemap-codec/1.4.14 + + registry.npmjs.org/@popperjs/core/2.11.6: + resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz} + name: '@popperjs/core' + version: 2.11.6 + dev: false + registry.npmjs.org/@types/color-convert/2.0.0: resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz} name: '@types/color-convert' @@ -11033,3 +11313,949 @@ packages: dependencies: '@types/color-convert': registry.npmjs.org/@types/color-convert/2.0.0 dev: true + + registry.npmjs.org/@types/dompurify/2.4.0: + resolution: {integrity: sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz} + name: '@types/dompurify' + version: 2.4.0 + dependencies: + '@types/trusted-types': registry.npmjs.org/@types/trusted-types/2.0.2 + dev: true + + registry.npmjs.org/@types/eslint-scope/3.7.4: + resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz} + name: '@types/eslint-scope' + version: 3.7.4 + dependencies: + '@types/eslint': registry.npmjs.org/@types/eslint/8.4.6 + '@types/estree': registry.npmjs.org/@types/estree/1.0.0 + dev: true + + registry.npmjs.org/@types/eslint/8.4.6: + resolution: {integrity: sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz} + name: '@types/eslint' + version: 8.4.6 + dependencies: + '@types/estree': registry.npmjs.org/@types/estree/1.0.0 + '@types/json-schema': registry.npmjs.org/@types/json-schema/7.0.11 + dev: true + + registry.npmjs.org/@types/estree/0.0.51: + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz} + name: '@types/estree' + version: 0.0.51 + dev: true + + registry.npmjs.org/@types/estree/1.0.0: + resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz} + name: '@types/estree' + version: 1.0.0 + dev: true + + registry.npmjs.org/@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz} + name: '@types/json-schema' + version: 7.0.11 + dev: true + + registry.npmjs.org/@types/node/16.11.59: + resolution: {integrity: sha512-6u+36Dj3aDzhfBVUf/mfmc92OEdzQ2kx2jcXGdigfl70E/neV21ZHE6UCz4MDzTRcVqGAM27fk+DLXvyDsn3Jw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/node/-/node-16.11.59.tgz} + name: '@types/node' + version: 16.11.59 + dev: true + + registry.npmjs.org/@types/trusted-types/2.0.2: + resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz} + name: '@types/trusted-types' + version: 2.0.2 + + registry.npmjs.org/@webassemblyjs/ast/1.11.1: + resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz} + name: '@webassemblyjs/ast' + version: 1.11.1 + dependencies: + '@webassemblyjs/helper-numbers': registry.npmjs.org/@webassemblyjs/helper-numbers/1.11.1 + '@webassemblyjs/helper-wasm-bytecode': registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/1.11.1: + resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz} + name: '@webassemblyjs/floating-point-hex-parser' + version: 1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/helper-api-error/1.11.1: + resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz} + name: '@webassemblyjs/helper-api-error' + version: 1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/helper-buffer/1.11.1: + resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz} + name: '@webassemblyjs/helper-buffer' + version: 1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/helper-numbers/1.11.1: + resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz} + name: '@webassemblyjs/helper-numbers' + version: 1.11.1 + dependencies: + '@webassemblyjs/floating-point-hex-parser': registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/1.11.1 + '@webassemblyjs/helper-api-error': registry.npmjs.org/@webassemblyjs/helper-api-error/1.11.1 + '@xtuc/long': registry.npmjs.org/@xtuc/long/4.2.2 + dev: true + + registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1: + resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz} + name: '@webassemblyjs/helper-wasm-bytecode' + version: 1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/helper-wasm-section/1.11.1: + resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz} + name: '@webassemblyjs/helper-wasm-section' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/helper-buffer': registry.npmjs.org/@webassemblyjs/helper-buffer/1.11.1 + '@webassemblyjs/helper-wasm-bytecode': registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1 + '@webassemblyjs/wasm-gen': registry.npmjs.org/@webassemblyjs/wasm-gen/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/ieee754/1.11.1: + resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz} + name: '@webassemblyjs/ieee754' + version: 1.11.1 + dependencies: + '@xtuc/ieee754': registry.npmjs.org/@xtuc/ieee754/1.2.0 + dev: true + + registry.npmjs.org/@webassemblyjs/leb128/1.11.1: + resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz} + name: '@webassemblyjs/leb128' + version: 1.11.1 + dependencies: + '@xtuc/long': registry.npmjs.org/@xtuc/long/4.2.2 + dev: true + + registry.npmjs.org/@webassemblyjs/utf8/1.11.1: + resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz} + name: '@webassemblyjs/utf8' + version: 1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/wasm-edit/1.11.1: + resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz} + name: '@webassemblyjs/wasm-edit' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/helper-buffer': registry.npmjs.org/@webassemblyjs/helper-buffer/1.11.1 + '@webassemblyjs/helper-wasm-bytecode': registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1 + '@webassemblyjs/helper-wasm-section': registry.npmjs.org/@webassemblyjs/helper-wasm-section/1.11.1 + '@webassemblyjs/wasm-gen': registry.npmjs.org/@webassemblyjs/wasm-gen/1.11.1 + '@webassemblyjs/wasm-opt': registry.npmjs.org/@webassemblyjs/wasm-opt/1.11.1 + '@webassemblyjs/wasm-parser': registry.npmjs.org/@webassemblyjs/wasm-parser/1.11.1 + '@webassemblyjs/wast-printer': registry.npmjs.org/@webassemblyjs/wast-printer/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/wasm-gen/1.11.1: + resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz} + name: '@webassemblyjs/wasm-gen' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/helper-wasm-bytecode': registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1 + '@webassemblyjs/ieee754': registry.npmjs.org/@webassemblyjs/ieee754/1.11.1 + '@webassemblyjs/leb128': registry.npmjs.org/@webassemblyjs/leb128/1.11.1 + '@webassemblyjs/utf8': registry.npmjs.org/@webassemblyjs/utf8/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/wasm-opt/1.11.1: + resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz} + name: '@webassemblyjs/wasm-opt' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/helper-buffer': registry.npmjs.org/@webassemblyjs/helper-buffer/1.11.1 + '@webassemblyjs/wasm-gen': registry.npmjs.org/@webassemblyjs/wasm-gen/1.11.1 + '@webassemblyjs/wasm-parser': registry.npmjs.org/@webassemblyjs/wasm-parser/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/wasm-parser/1.11.1: + resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz} + name: '@webassemblyjs/wasm-parser' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/helper-api-error': registry.npmjs.org/@webassemblyjs/helper-api-error/1.11.1 + '@webassemblyjs/helper-wasm-bytecode': registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/1.11.1 + '@webassemblyjs/ieee754': registry.npmjs.org/@webassemblyjs/ieee754/1.11.1 + '@webassemblyjs/leb128': registry.npmjs.org/@webassemblyjs/leb128/1.11.1 + '@webassemblyjs/utf8': registry.npmjs.org/@webassemblyjs/utf8/1.11.1 + dev: true + + registry.npmjs.org/@webassemblyjs/wast-printer/1.11.1: + resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz} + name: '@webassemblyjs/wast-printer' + version: 1.11.1 + dependencies: + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@xtuc/long': registry.npmjs.org/@xtuc/long/4.2.2 + dev: true + + registry.npmjs.org/@xtuc/ieee754/1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz} + name: '@xtuc/ieee754' + version: 1.2.0 + dev: true + + registry.npmjs.org/@xtuc/long/4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz} + name: '@xtuc/long' + version: 4.2.2 + dev: true + + registry.npmjs.org/acorn-import-assertions/1.8.0_acorn@8.8.0: + resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz} + id: registry.npmjs.org/acorn-import-assertions/1.8.0 + name: acorn-import-assertions + version: 1.8.0 + peerDependencies: + acorn: ^8 + dependencies: + acorn: registry.npmjs.org/acorn/8.8.0 + dev: true + + registry.npmjs.org/acorn/8.8.0: + resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz} + name: acorn + version: 8.8.0 + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + registry.npmjs.org/ajv-keywords/3.5.2_ajv@6.12.6: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz} + id: registry.npmjs.org/ajv-keywords/3.5.2 + name: ajv-keywords + version: 3.5.2 + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: registry.npmjs.org/ajv/6.12.6 + dev: true + + registry.npmjs.org/ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz} + name: ajv + version: 6.12.6 + dependencies: + fast-deep-equal: registry.npmjs.org/fast-deep-equal/3.1.3 + fast-json-stable-stringify: registry.npmjs.org/fast-json-stable-stringify/2.1.0 + json-schema-traverse: registry.npmjs.org/json-schema-traverse/0.4.1 + uri-js: registry.npmjs.org/uri-js/4.4.1 + dev: true + + registry.npmjs.org/ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz} + name: ansi-styles + version: 3.2.1 + engines: {node: '>=4'} + dependencies: + color-convert: registry.npmjs.org/color-convert/1.9.3 + + registry.npmjs.org/browserslist/4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz} + name: browserslist + version: 4.21.4 + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: registry.npmjs.org/caniuse-lite/1.0.30001408 + electron-to-chromium: registry.npmjs.org/electron-to-chromium/1.4.256 + node-releases: registry.npmjs.org/node-releases/2.0.6 + update-browserslist-db: registry.npmjs.org/update-browserslist-db/1.0.9_browserslist@4.21.4 + + registry.npmjs.org/buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz} + name: buffer-from + version: 1.1.2 + dev: true + + registry.npmjs.org/caniuse-lite/1.0.30001408: + resolution: {integrity: sha512-DdUCktgMSM+1ndk9EFMZcavsGszV7zxV9O7MtOHniTa/iyAIwJCF0dFVBdU9SijJbfh29hC9bCs07wu8pjnGJQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001408.tgz} + name: caniuse-lite + version: 1.0.30001408 + + registry.npmjs.org/chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz} + name: chalk + version: 2.4.2 + engines: {node: '>=4'} + dependencies: + ansi-styles: registry.npmjs.org/ansi-styles/3.2.1 + escape-string-regexp: registry.npmjs.org/escape-string-regexp/1.0.5 + supports-color: registry.npmjs.org/supports-color/5.5.0 + + registry.npmjs.org/chrome-trace-event/1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz} + name: chrome-trace-event + version: 1.0.3 + engines: {node: '>=6.0'} + dev: true + + registry.npmjs.org/color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz} + name: color-convert + version: 1.9.3 + dependencies: + color-name: registry.npmjs.org/color-name/1.1.3 + + registry.npmjs.org/color-name/1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz} + name: color-name + version: 1.1.3 + + registry.npmjs.org/commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/commander/-/commander-2.20.3.tgz} + name: commander + version: 2.20.3 + dev: true + + registry.npmjs.org/convert-source-map/1.8.0: + resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz} + name: convert-source-map + version: 1.8.0 + dependencies: + safe-buffer: registry.npmjs.org/safe-buffer/5.1.2 + + registry.npmjs.org/debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/debug/-/debug-4.3.4.tgz} + name: debug + version: 4.3.4 + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: registry.npmjs.org/ms/2.1.2 + + registry.npmjs.org/dom-serializer/0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz} + name: dom-serializer + version: 0.2.2 + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + entities: registry.npmjs.org/entities/2.2.0 + + registry.npmjs.org/dom-serializer/1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz} + name: dom-serializer + version: 1.4.1 + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/4.3.1 + entities: registry.npmjs.org/entities/2.2.0 + + registry.npmjs.org/dom-serializer/2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz} + name: dom-serializer + version: 2.0.0 + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/5.0.3 + entities: registry.npmjs.org/entities/4.4.0 + dev: false + + registry.npmjs.org/domelementtype/1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz} + name: domelementtype + version: 1.3.1 + + registry.npmjs.org/domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz} + name: domelementtype + version: 2.3.0 + + registry.npmjs.org/domhandler/4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz} + name: domhandler + version: 4.3.1 + engines: {node: '>= 4'} + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + + registry.npmjs.org/domhandler/5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz} + name: domhandler + version: 5.0.3 + engines: {node: '>= 4'} + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + dev: false + + registry.npmjs.org/dompurify/2.4.0: + resolution: {integrity: sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz} + name: dompurify + version: 2.4.0 + dev: false + + registry.npmjs.org/dompurify/2.4.3: + resolution: {integrity: sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz} + name: dompurify + version: 2.4.3 + dev: false + + registry.npmjs.org/domutils/1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz} + name: domutils + version: 1.7.0 + dependencies: + dom-serializer: registry.npmjs.org/dom-serializer/0.2.2 + domelementtype: registry.npmjs.org/domelementtype/1.3.1 + + registry.npmjs.org/domutils/2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz} + name: domutils + version: 2.8.0 + dependencies: + dom-serializer: registry.npmjs.org/dom-serializer/1.4.1 + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/4.3.1 + + registry.npmjs.org/domutils/3.0.1: + resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz} + name: domutils + version: 3.0.1 + dependencies: + dom-serializer: registry.npmjs.org/dom-serializer/2.0.0 + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/5.0.3 + dev: false + + registry.npmjs.org/electron-to-chromium/1.4.256: + resolution: {integrity: sha512-x+JnqyluoJv8I0U9gVe+Sk2st8vF0CzMt78SXxuoWCooLLY2k5VerIBdpvG7ql6GKI4dzNnPjmqgDJ76EdaAKw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.256.tgz} + name: electron-to-chromium + version: 1.4.256 + + registry.npmjs.org/enhanced-resolve/5.10.0: + resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz} + name: enhanced-resolve + version: 5.10.0 + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 + tapable: registry.npmjs.org/tapable/2.2.1 + dev: true + + registry.npmjs.org/entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/entities/-/entities-2.2.0.tgz} + name: entities + version: 2.2.0 + + registry.npmjs.org/entities/4.4.0: + resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/entities/-/entities-4.4.0.tgz} + name: entities + version: 4.4.0 + engines: {node: '>=0.12'} + dev: false + + registry.npmjs.org/es-module-lexer/0.9.3: + resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz} + name: es-module-lexer + version: 0.9.3 + dev: true + + registry.npmjs.org/escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz} + name: escalade + version: 3.1.1 + engines: {node: '>=6'} + + registry.npmjs.org/escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz} + name: escape-string-regexp + version: 1.0.5 + engines: {node: '>=0.8.0'} + + registry.npmjs.org/eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz} + name: eslint-scope + version: 5.1.1 + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: registry.npmjs.org/esrecurse/4.3.0 + estraverse: registry.npmjs.org/estraverse/4.3.0 + dev: true + + registry.npmjs.org/esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz} + name: esrecurse + version: 4.3.0 + engines: {node: '>=4.0'} + dependencies: + estraverse: registry.npmjs.org/estraverse/5.3.0 + dev: true + + registry.npmjs.org/estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz} + name: estraverse + version: 4.3.0 + engines: {node: '>=4.0'} + dev: true + + registry.npmjs.org/estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz} + name: estraverse + version: 5.3.0 + engines: {node: '>=4.0'} + dev: true + + registry.npmjs.org/events/3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/events/-/events-3.3.0.tgz} + name: events + version: 3.3.0 + engines: {node: '>=0.8.x'} + dev: true + + registry.npmjs.org/fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} + name: fast-deep-equal + version: 3.1.3 + dev: true + + registry.npmjs.org/fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} + name: fast-json-stable-stringify + version: 2.1.0 + dev: true + + registry.npmjs.org/fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz} + name: fsevents + version: 2.3.2 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + registry.npmjs.org/gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz} + name: gensync + version: 1.0.0-beta.2 + engines: {node: '>=6.9.0'} + + registry.npmjs.org/glob-to-regexp/0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz} + name: glob-to-regexp + version: 0.4.1 + dev: true + + registry.npmjs.org/globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/globals/-/globals-11.12.0.tgz} + name: globals + version: 11.12.0 + engines: {node: '>=4'} + + registry.npmjs.org/graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz} + name: graceful-fs + version: 4.2.10 + + registry.npmjs.org/has-flag/3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz} + name: has-flag + version: 3.0.0 + engines: {node: '>=4'} + + registry.npmjs.org/has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz} + name: has-flag + version: 4.0.0 + engines: {node: '>=8'} + dev: true + + registry.npmjs.org/html-dom-parser/3.1.3: + resolution: {integrity: sha512-fI0yyNlIeSboxU+jnrA4v8qj4+M8SI9/q6AKYdwCY2qki22UtKCDTxvagHniECu7sa5/o2zFRdLleA67035lsA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-3.1.3.tgz} + name: html-dom-parser + version: 3.1.3 + dependencies: + domhandler: registry.npmjs.org/domhandler/5.0.3 + htmlparser2: registry.npmjs.org/htmlparser2/8.0.1 + dev: false + + registry.npmjs.org/html-react-parser/3.0.8_react@18.2.0: + resolution: {integrity: sha512-eIxPq/3Ja3+nZkx6X/BNpFy0lNuW+v3V4nzABzuL8KkRVdYY/2KyXO42epKonsEVVRSBxm2zsxWcOkT6fYL+iQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.8.tgz} + id: registry.npmjs.org/html-react-parser/3.0.8 + name: html-react-parser + version: 3.0.8 + peerDependencies: + react: 0.14 || 15 || 16 || 17 || 18 + dependencies: + domhandler: registry.npmjs.org/domhandler/5.0.3 + html-dom-parser: registry.npmjs.org/html-dom-parser/3.1.3 + react: 18.2.0 + react-property: registry.npmjs.org/react-property/2.0.0 + style-to-js: registry.npmjs.org/style-to-js/1.1.3 + dev: false + + registry.npmjs.org/htmlparser2/6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz} + name: htmlparser2 + version: 6.1.0 + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/4.3.1 + domutils: registry.npmjs.org/domutils/2.8.0 + entities: registry.npmjs.org/entities/2.2.0 + + registry.npmjs.org/htmlparser2/8.0.1: + resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz} + name: htmlparser2 + version: 8.0.1 + dependencies: + domelementtype: registry.npmjs.org/domelementtype/2.3.0 + domhandler: registry.npmjs.org/domhandler/5.0.3 + domutils: registry.npmjs.org/domutils/3.0.1 + entities: registry.npmjs.org/entities/4.4.0 + dev: false + + registry.npmjs.org/inline-style-parser/0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz} + name: inline-style-parser + version: 0.1.1 + dev: false + + registry.npmjs.org/jest-worker/27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz} + name: jest-worker + version: 27.5.1 + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': registry.npmjs.org/@types/node/16.11.59 + merge-stream: registry.npmjs.org/merge-stream/2.0.0 + supports-color: registry.npmjs.org/supports-color/8.1.1 + dev: true + + registry.npmjs.org/js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz} + name: js-tokens + version: 4.0.0 + + registry.npmjs.org/jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz} + name: jsesc + version: 2.5.2 + engines: {node: '>=4'} + hasBin: true + + registry.npmjs.org/json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz} + name: json-parse-even-better-errors + version: 2.3.1 + dev: true + + registry.npmjs.org/json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz} + name: json-schema-traverse + version: 0.4.1 + dev: true + + registry.npmjs.org/json5/2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/json5/-/json5-2.2.1.tgz} + name: json5 + version: 2.2.1 + engines: {node: '>=6'} + hasBin: true + + registry.npmjs.org/loader-runner/4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz} + name: loader-runner + version: 4.3.0 + engines: {node: '>=6.11.5'} + dev: true + + registry.npmjs.org/merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz} + name: merge-stream + version: 2.0.0 + dev: true + + registry.npmjs.org/mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz} + name: mime-db + version: 1.52.0 + engines: {node: '>= 0.6'} + dev: true + + registry.npmjs.org/mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz} + name: mime-types + version: 2.1.35 + engines: {node: '>= 0.6'} + dependencies: + mime-db: registry.npmjs.org/mime-db/1.52.0 + dev: true + + registry.npmjs.org/ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/ms/-/ms-2.1.2.tgz} + name: ms + version: 2.1.2 + + registry.npmjs.org/neo-async/2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz} + name: neo-async + version: 2.6.2 + dev: true + + registry.npmjs.org/node-releases/2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz} + name: node-releases + version: 2.0.6 + + registry.npmjs.org/picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz} + name: picocolors + version: 1.0.0 + + registry.npmjs.org/punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz} + name: punycode + version: 2.1.1 + engines: {node: '>=6'} + dev: true + + registry.npmjs.org/randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz} + name: randombytes + version: 2.1.0 + dependencies: + safe-buffer: registry.npmjs.org/safe-buffer/5.2.1 + dev: true + + registry.npmjs.org/react-property/2.0.0: + resolution: {integrity: sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz} + name: react-property + version: 2.0.0 + dev: false + + registry.npmjs.org/safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz} + name: safe-buffer + version: 5.1.2 + + registry.npmjs.org/safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz} + name: safe-buffer + version: 5.2.1 + dev: true + + registry.npmjs.org/schema-utils/3.1.1: + resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz} + name: schema-utils + version: 3.1.1 + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': registry.npmjs.org/@types/json-schema/7.0.11 + ajv: registry.npmjs.org/ajv/6.12.6 + ajv-keywords: registry.npmjs.org/ajv-keywords/3.5.2_ajv@6.12.6 + dev: true + + registry.npmjs.org/semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/semver/-/semver-6.3.0.tgz} + name: semver + version: 6.3.0 + hasBin: true + + registry.npmjs.org/serialize-javascript/6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz} + name: serialize-javascript + version: 6.0.0 + dependencies: + randombytes: registry.npmjs.org/randombytes/2.1.0 + dev: true + + registry.npmjs.org/source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz} + name: source-map-support + version: 0.5.21 + dependencies: + buffer-from: registry.npmjs.org/buffer-from/1.1.2 + source-map: registry.npmjs.org/source-map/0.6.1 + dev: true + + registry.npmjs.org/source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz} + name: source-map + version: 0.6.1 + engines: {node: '>=0.10.0'} + + registry.npmjs.org/style-to-js/1.1.3: + resolution: {integrity: sha512-zKI5gN/zb7LS/Vm0eUwjmjrXWw8IMtyA8aPBJZdYiQTXj4+wQ3IucOLIOnF7zCHxvW8UhIGh/uZh/t9zEHXNTQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.3.tgz} + name: style-to-js + version: 1.1.3 + dependencies: + style-to-object: registry.npmjs.org/style-to-object/0.4.1 + dev: false + + registry.npmjs.org/style-to-object/0.4.1: + resolution: {integrity: sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz} + name: style-to-object + version: 0.4.1 + dependencies: + inline-style-parser: registry.npmjs.org/inline-style-parser/0.1.1 + dev: false + + registry.npmjs.org/supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz} + name: supports-color + version: 5.5.0 + engines: {node: '>=4'} + dependencies: + has-flag: registry.npmjs.org/has-flag/3.0.0 + + registry.npmjs.org/supports-color/8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz} + name: supports-color + version: 8.1.1 + engines: {node: '>=10'} + dependencies: + has-flag: registry.npmjs.org/has-flag/4.0.0 + dev: true + + registry.npmjs.org/tapable/2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz} + name: tapable + version: 2.2.1 + engines: {node: '>=6'} + dev: true + + registry.npmjs.org/terser-webpack-plugin/5.3.6_webpack@5.74.0: + resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz} + id: registry.npmjs.org/terser-webpack-plugin/5.3.6 + name: terser-webpack-plugin + version: 5.3.6 + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': registry.npmjs.org/@jridgewell/trace-mapping/0.3.15 + jest-worker: registry.npmjs.org/jest-worker/27.5.1 + schema-utils: registry.npmjs.org/schema-utils/3.1.1 + serialize-javascript: registry.npmjs.org/serialize-javascript/6.0.0 + terser: registry.npmjs.org/terser/5.15.0 + webpack: registry.npmjs.org/webpack/5.74.0 + dev: true + + registry.npmjs.org/terser/5.15.0: + resolution: {integrity: sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/terser/-/terser-5.15.0.tgz} + name: terser + version: 5.15.0 + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': registry.npmjs.org/@jridgewell/source-map/0.3.2 + acorn: registry.npmjs.org/acorn/8.8.0 + commander: registry.npmjs.org/commander/2.20.3 + source-map-support: registry.npmjs.org/source-map-support/0.5.21 + dev: true + + registry.npmjs.org/to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz} + name: to-fast-properties + version: 2.0.0 + engines: {node: '>=4'} + + registry.npmjs.org/update-browserslist-db/1.0.9_browserslist@4.21.4: + resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz} + id: registry.npmjs.org/update-browserslist-db/1.0.9 + name: update-browserslist-db + version: 1.0.9 + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: registry.npmjs.org/browserslist/4.21.4 + escalade: registry.npmjs.org/escalade/3.1.1 + picocolors: registry.npmjs.org/picocolors/1.0.0 + + registry.npmjs.org/uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz} + name: uri-js + version: 4.4.1 + dependencies: + punycode: registry.npmjs.org/punycode/2.1.1 + dev: true + + registry.npmjs.org/watchpack/2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz} + name: watchpack + version: 2.4.0 + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: registry.npmjs.org/glob-to-regexp/0.4.1 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 + dev: true + + registry.npmjs.org/webpack-sources/3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz} + name: webpack-sources + version: 3.2.3 + engines: {node: '>=10.13.0'} + dev: true + + registry.npmjs.org/webpack/5.74.0: + resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz} + name: webpack + version: 5.74.0 + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': registry.npmjs.org/@types/eslint-scope/3.7.4 + '@types/estree': registry.npmjs.org/@types/estree/0.0.51 + '@webassemblyjs/ast': registry.npmjs.org/@webassemblyjs/ast/1.11.1 + '@webassemblyjs/wasm-edit': registry.npmjs.org/@webassemblyjs/wasm-edit/1.11.1 + '@webassemblyjs/wasm-parser': registry.npmjs.org/@webassemblyjs/wasm-parser/1.11.1 + acorn: registry.npmjs.org/acorn/8.8.0 + acorn-import-assertions: registry.npmjs.org/acorn-import-assertions/1.8.0_acorn@8.8.0 + browserslist: registry.npmjs.org/browserslist/4.21.4 + chrome-trace-event: registry.npmjs.org/chrome-trace-event/1.0.3 + enhanced-resolve: registry.npmjs.org/enhanced-resolve/5.10.0 + es-module-lexer: registry.npmjs.org/es-module-lexer/0.9.3 + eslint-scope: registry.npmjs.org/eslint-scope/5.1.1 + events: registry.npmjs.org/events/3.3.0 + glob-to-regexp: registry.npmjs.org/glob-to-regexp/0.4.1 + graceful-fs: registry.npmjs.org/graceful-fs/4.2.10 + json-parse-even-better-errors: registry.npmjs.org/json-parse-even-better-errors/2.3.1 + loader-runner: registry.npmjs.org/loader-runner/4.3.0 + mime-types: registry.npmjs.org/mime-types/2.1.35 + neo-async: registry.npmjs.org/neo-async/2.6.2 + schema-utils: registry.npmjs.org/schema-utils/3.1.1 + tapable: registry.npmjs.org/tapable/2.2.1 + terser-webpack-plugin: registry.npmjs.org/terser-webpack-plugin/5.3.6_webpack@5.74.0 + watchpack: registry.npmjs.org/watchpack/2.4.0 + webpack-sources: registry.npmjs.org/webpack-sources/3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true diff --git a/ui/public/index.html b/ui/public/index.html index ac5f558f..0cbf8d29 100644 --- a/ui/public/index.html +++ b/ui/public/index.html @@ -4,6 +4,7 @@ + diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index 1febc724..76583a8d 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -56,7 +56,7 @@ export interface QuestionParams { title: string; url_title?: string; content: string; - html: string; + html?: string; tags: Tag[]; } @@ -207,7 +207,7 @@ export interface AnswerItem { export interface PostAnswerReq { content: string; - html: string; + html?: string; question_id: string; } diff --git a/ui/src/components/Comment/components/Form/index.tsx b/ui/src/components/Comment/components/Form/index.tsx index 70c62fdd..bc93ddb4 100644 --- a/ui/src/components/Comment/components/Form/index.tsx +++ b/ui/src/components/Comment/components/Form/index.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, memo } from 'react'; -import { Button } from 'react-bootstrap'; +import { Button, Form } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; @@ -7,7 +7,7 @@ import classNames from 'classnames'; import { TextArea, Mentions } from '@/components'; import { usePageUsers } from '@/hooks'; -const Form = ({ +const Index = ({ className = '', value: initialValue = '', onSendReply, @@ -18,7 +18,7 @@ const Form = ({ const [value, setValue] = useState(''); const pageUsers = usePageUsers(); const { t } = useTranslation('translation', { keyPrefix: 'comment' }); - + const [validationErrorMsg, setValidationErrorMsg] = useState(''); useEffect(() => { if (!initialValue) { return; @@ -32,6 +32,13 @@ const Form = ({ const handleSelected = (val) => { setValue(val); }; + const handleSendReply = () => { + onSendReply(value).catch((ex) => { + if (ex.isError) { + setValidationErrorMsg(ex.msg); + } + }); + }; return (
- -